示例#1
0
void
VideoSourceCanvas::Grabber(void *data)
{
    nsresult rv;
    PRUint32 wr;
    VideoSourceCanvas *vs = static_cast<VideoSourceCanvas*>(data);
    
    int isize = vs->GetFrameSize();
    int fsize = vs->width * vs->height * 4;
    char *i420 = (char *)PR_Calloc(isize, 1);
    PRUint8 *rgb32 = (PRUint8 *)PR_Calloc(fsize, 1);

    PRTime epoch_c;
    PRFloat64 epoch;
    PRIntervalTime ticks = PR_TicksPerSecond() / 30;
    while (vs->running) {
        PR_Sleep(ticks);
        if (vs->is_rec == PR_FALSE) continue;
        
        rv = vs->vCanvas->GetImageData_explicit(
            0, 0, vs->width, vs->height, rgb32, fsize
        );
        if (NS_FAILED(rv)) continue;

        RGB32toI420(vs->width, vs->height, (const char *)rgb32, i420);
        
        epoch_c = PR_Now();
        epoch = (PRFloat64)(epoch_c / MICROSECONDS);
        epoch += ((PRFloat64)(epoch_c % MICROSECONDS)) / MICROSECONDS;
        rv = vs->output->Write((const char *)&epoch, sizeof(PRFloat64), &wr);
        rv = vs->output->Write((const char *)&isize, sizeof(PRUint32), &wr);
        rv = vs->output->Write((const char *)i420, isize, &wr);
    }

    PR_Free(i420);
    PR_Free(rgb32);
    return;
}
示例#2
0
STDMETHODIMP
VideoSourceWin::SampleCB(double Time, IMediaSample *pSample)
{
    HRESULT hr;
    nsresult rv;
    
    PRUint32 wr;
    BYTE *pBuffer;
    long bufferLen;
    PRUint8 *i420buf;
    int start, end, fsize, isize, bpp;
    
    bpp = 4;
    fsize = width * height * 4;
    isize = width * height * 3 / 2;
    bufferLen = pSample->GetActualDataLength();
    
    hr = pSample->GetPointer(&pBuffer);
    nsAutoArrayPtr<PRUint8> rgb32(new PRUint8[bufferLen]);
    memcpy(rgb32.get(), pBuffer, bufferLen);
    pBuffer = rgb32.get();
    
    /* Reverse RGB32 top-down */
    PRUint8 tmp;
    for (start = 0, end = bufferLen - bpp;
            start < bufferLen / 2;
            start += bpp, end -= bpp) {

        /* While we're here let's do a RGB<->BGR swap */
        tmp = pBuffer[start];
        pBuffer[start] = pBuffer[end+2];
        pBuffer[end+2] = tmp;
        
        tmp = pBuffer[start+1];
        pBuffer[start+1] = pBuffer[end+1];
        pBuffer[end+1] = tmp;
        
        tmp = pBuffer[start+2];
        pBuffer[start+2] = pBuffer[end];
        pBuffer[end] = tmp;
        
        tmp = pBuffer[start+3];
        pBuffer[start+3] = pBuffer[end+3];
        pBuffer[end+3] = tmp;
    }
    
    /* Write header: timestamp + length */
    if (is_rec != PR_TRUE)
        return S_OK;
    
    //PRFloat64 current = epoch + Time;
    PRTime epoch_c = PR_Now();
    PRFloat64 epoch = (PRFloat64)(epoch_c / MICROSECONDS);
    epoch += ((PRFloat64)(epoch_c % MICROSECONDS)) / MICROSECONDS;
    
    rv = output->Write(
        (const char *)&epoch, sizeof(PRFloat64), &wr
    );
    rv = output->Write(
        (const char *)&isize, sizeof(PRUint32), &wr
    );
    /* Write to pipe after converting to i420 */
    i420buf = (PRUint8 *)PR_Calloc(isize, sizeof(PRUint8));
    RGB32toI420(width, height, (const char *)pBuffer, (char *)i420buf);
    rv = output->Write((const char *)i420buf, isize, &wr);
    PR_Free(i420buf);
    
    /* Write sample to canvas if neccessary */
    if (vCanvas) {
        nsCOMPtr<nsIRunnable> render = new CanvasRenderer(
            vCanvas, width, height, rgb32, fsize
        );
        rv = NS_DispatchToMainThread(render);
    }
    rgb32 = NULL; // AutoPtr should free this?
    
    return S_OK;
}
示例#3
0
STDMETHODIMP
VideoSourceWinCallback::SampleCB(double Time, IMediaSample *pSample)
{
    HRESULT hr;
    nsresult rv;
    
    PRUint32 wr;
    BYTE *pBuffer;
    long bufferLen;
    PRUint8 *i420buf;
    int start, end, fsize, isize, bpp;
    
    bpp = 4;
    fsize = w * h * 4;
    isize = w * h * 3 / 2;
    bufferLen = pSample->GetActualDataLength();
    
    hr = pSample->GetPointer(&pBuffer);
    nsAutoArrayPtr<PRUint8> rgb32(new PRUint8[bufferLen]);
    memcpy(rgb32.get(), pBuffer, bufferLen);
    pBuffer = rgb32.get();
    
    /* Reverse RGB32 top-down */
    PRUint8 tmp;
    for (start = 0, end = bufferLen - bpp;
            start < bufferLen / 2;
            start += bpp, end -= bpp) {

        /* While we're here let's do a RGB<->BGR swap */
        tmp = pBuffer[start];
        pBuffer[start] = pBuffer[end+2];
        pBuffer[end+2] = tmp;
        
        tmp = pBuffer[start+1];
        pBuffer[start+1] = pBuffer[end+1];
        pBuffer[end+1] = tmp;
        
        tmp = pBuffer[start+2];
        pBuffer[start+2] = pBuffer[end];
        pBuffer[end] = tmp;
        
        tmp = pBuffer[start+3];
        pBuffer[start+3] = pBuffer[end+3];
        pBuffer[end+3] = tmp;
    }
    
    /* Write sample to canvas if neccessary */
    if (vCanvas) {
        nsCOMPtr<nsIRunnable> render = new CanvasRenderer(
            vCanvas, w, h, rgb32, fsize
        );
        rv = NS_DispatchToMainThread(render);
    }
    
    /* Write to pipe after converting to i420 */
    i420buf = (PRUint8 *)PR_Calloc(isize, sizeof(PRUint8));
    RGB32toI420(w, h, (const char *)pBuffer, (char *)i420buf);
    rv = output->Write((const char *)i420buf, isize, &wr);
    PR_Free(i420buf);
    
    return S_OK;
}