VirtualBox

忽略:
時間撮記:
2013-5-8 下午01:00:13 (12 年 以前)
作者:
vboxsync
訊息:

Main/VPX: multimonitor (needs more cleanup)

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Main/src-client/VideoRec.cpp

    r45941 r45950  
    3737#define DEFAULTCODEC (vpx_codec_vp8_cx())
    3838
    39 static int videoRecEncodeAndWrite(PVIDEORECCONTEXT pVideoRecCtx);
    40 static int videoRecRGBToYUV(PVIDEORECCONTEXT pVideoRecCtx);
     39static int videoRecEncodeAndWrite(PVIDEORECSTREAM pStrm);
     40static int videoRecRGBToYUV(PVIDEORECSTREAM pStrm);
    4141
    4242/* encoding */
     
    5252};
    5353
    54 typedef struct VIDEORECCONTEXT
     54typedef struct VIDEORECSTREAM
    5555{
    5656    /* container context */
    57     EbmlGlobal          ebml;
     57    EbmlGlobal          Ebml;
    5858    /* VPX codec context */
    5959    vpx_codec_ctx_t     VpxCodec;
     
    7676    /* VPX image context */
    7777    vpx_image_t         VpxRawImage;
    78     /* semaphore */
    79     RTSEMEVENT          WaitEvent;
    8078    /* true if video recording is enabled */
    8179    bool                fEnabled;
     
    9492    /* time stamp of the current frame */
    9593    uint64_t            u64TimeStamp;
     94} VIDEORECSTREAM;
     95
     96typedef struct VIDEORECCONTEXT
     97{
     98    /* semaphore */
     99    RTSEMEVENT          WaitEvent;
     100    /* true if video recording is enabled */
     101    bool                fEnabled;
     102    /* worker thread */
     103    RTTHREAD            Thread;
     104    /* see VIDREC_xxx */
     105    uint32_t            u32State;
     106    /* number of stream contexts */
     107    uint32_t            cScreens;
     108    /* video recording stream contexts */
     109    VIDEORECSTREAM      Strm[1];
    96110} VIDEORECCONTEXT;
    97111
     
    365379
    366380/**
    367  * VideoRec utility function to create video recording context.
    368  *
    369  * @returns IPRT status code.
    370  * @param   ppVideoRecCtx video recording context
    371  */
    372 int VideoRecContextCreate(PVIDEORECCONTEXT *ppVideoRecCtx)
    373 {
    374     PVIDEORECCONTEXT pVideoRecCtx = (PVIDEORECCONTEXT)RTMemAllocZ(sizeof(VIDEORECCONTEXT));
    375     *ppVideoRecCtx = pVideoRecCtx;
    376     AssertReturn(pVideoRecCtx, VERR_NO_MEMORY);
    377 
    378     pVideoRecCtx->ebml.last_pts_ms = -1;
    379     return VINF_SUCCESS;
    380 }
    381 
    382 /**
    383  * Worker thread.
     381 * Worker thread for all streams.
    384382 *
    385383 * RGB/YUV conversion and encoding.
    386384 */
    387 DECLCALLBACK(int) VideoRecThread(RTTHREAD ThreadSelf, void *pvUser)
    388 {
    389     PVIDEORECCONTEXT pVideoRecCtx = (PVIDEORECCONTEXT)pvUser;
     385DECLCALLBACK(int) videoRecThread(RTTHREAD ThreadSelf, void *pvUser)
     386{
     387    PVIDEORECCONTEXT pCtx = (PVIDEORECCONTEXT)pvUser;
    390388    for (;;)
    391389    {
    392         int rc = RTSemEventWait(pVideoRecCtx->WaitEvent, RT_INDEFINITE_WAIT);
     390        int rc = RTSemEventWait(pCtx->WaitEvent, RT_INDEFINITE_WAIT);
    393391        AssertRCBreak(rc);
    394392
    395         if (ASMAtomicReadU32(&pVideoRecCtx->u32State) == VIDREC_TERMINATING)
     393        if (ASMAtomicReadU32(&pCtx->u32State) == VIDREC_TERMINATING)
    396394            break;
    397         else if (ASMAtomicReadBool(&pVideoRecCtx->fRgbFilled))
    398         {
    399             rc = videoRecRGBToYUV(pVideoRecCtx);
    400             ASMAtomicWriteBool(&pVideoRecCtx->fRgbFilled, false);
    401             if (RT_SUCCESS(rc))
    402                 rc = videoRecEncodeAndWrite(pVideoRecCtx);
    403            if (RT_FAILURE(rc))
    404                 LogRel(("Error %Rrc encoding video frame\n", rc));
    405         }
    406     }
    407 
    408     ASMAtomicWriteU32(&pVideoRecCtx->u32State, VIDREC_TERMINATED);
     395        for (unsigned uScreen = 0; uScreen < pCtx->cScreens; uScreen++)
     396        {
     397            PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen];
     398            if (ASMAtomicReadBool(&pStrm->fRgbFilled))
     399            {
     400                rc = videoRecRGBToYUV(pStrm);
     401                ASMAtomicWriteBool(&pStrm->fRgbFilled, false);
     402                if (RT_SUCCESS(rc))
     403                    rc = videoRecEncodeAndWrite(pStrm);
     404                if (RT_FAILURE(rc))
     405                    LogRel(("Error %Rrc encoding video frame\n", rc));
     406            }
     407        }
     408    }
     409
     410    ASMAtomicWriteU32(&pCtx->u32State, VIDREC_TERMINATED);
    409411    RTThreadUserSignal(ThreadSelf);
    410412    return VINF_SUCCESS;
     
    412414
    413415/**
     416 * VideoRec utility function to create video recording context.
     417 *
     418 * @returns IPRT status code.
     419 * @param   ppCtx            Video recording context
     420 * @param   cScreens         Number of screens.
     421 */
     422int VideoRecContextCreate(PVIDEORECCONTEXT *ppCtx, uint32_t cScreens)
     423{
     424    PVIDEORECCONTEXT pCtx = (PVIDEORECCONTEXT)RTMemAllocZ(RT_OFFSETOF(VIDEORECCONTEXT, Strm[cScreens]));
     425    *ppCtx = pCtx;
     426    AssertPtrReturn(pCtx, VERR_NO_MEMORY);
     427
     428    pCtx->cScreens = cScreens;
     429    for (unsigned uScreen = 0; uScreen < cScreens; uScreen++)
     430        pCtx->Strm[uScreen].Ebml.last_pts_ms = -1;
     431   
     432    int rc = RTSemEventCreate(&pCtx->WaitEvent);
     433    AssertRCReturn(rc, rc);
     434
     435    rc = RTThreadCreate(&pCtx->Thread, videoRecThread, (void*)pCtx, 0,
     436                        RTTHREADTYPE_MAIN_WORKER, 0, "VideoRec");
     437    AssertRCReturn(rc, rc);
     438
     439    return VINF_SUCCESS;
     440}
     441
     442/**
    414443 * VideoRec utility function to initialize video recording context.
    415444 *
    416445 * @returns IPRT status code.
    417  * @param   pVideoRecCtx        Pointer to video recording context to initialize Framebuffer width.
     446 * @param   pCtx                Pointer to video recording context to initialize Framebuffer width.
     447 * @param   uScreeen            Screen number.
    418448 * @param   strFile             File to save the recorded data
    419449 * @param   uTargetWidth        Width of the target image in the video recoriding file (movie)
    420450 * @param   uTargetHeight       Height of the target image in video recording file.
    421451 */
    422 int VideoRecContextInit(PVIDEORECCONTEXT pVideoRecCtx, const char *pszFile,
    423                         uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFps)
    424 {
    425     pVideoRecCtx->uTargetWidth  = uWidth;
    426     pVideoRecCtx->uTargetHeight = uHeight;
    427     pVideoRecCtx->pu8RgbBuf = (uint8_t *)RTMemAllocZ(uWidth * uHeight * 4);
    428     AssertReturn(pVideoRecCtx->pu8RgbBuf, VERR_NO_MEMORY);
    429 
    430     int rc = RTFileOpen(&pVideoRecCtx->ebml.file, pszFile,
     452int VideoRecStrmInit(PVIDEORECCONTEXT pCtx, uint32_t uScreen, const char *pszFile,
     453                     uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFps)
     454{
     455    AssertPtrReturn(pCtx, VERR_INVALID_PARAMETER);
     456    AssertReturn(uScreen < pCtx->cScreens, VERR_INVALID_PARAMETER);
     457
     458    PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen];
     459    pStrm->uTargetWidth  = uWidth;
     460    pStrm->uTargetHeight = uHeight;
     461    pStrm->pu8RgbBuf = (uint8_t *)RTMemAllocZ(uWidth * uHeight * 4);
     462    AssertReturn(pStrm->pu8RgbBuf, VERR_NO_MEMORY);
     463
     464    int rc = RTFileOpen(&pStrm->Ebml.file, pszFile,
    431465                        RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    432466    if (RT_FAILURE(rc))
     
    436470    }
    437471
    438     vpx_codec_err_t rcv = vpx_codec_enc_config_default(DEFAULTCODEC, &pVideoRecCtx->VpxConfig, 0);
     472    vpx_codec_err_t rcv = vpx_codec_enc_config_default(DEFAULTCODEC, &pStrm->VpxConfig, 0);
    439473    if (rcv != VPX_CODEC_OK)
    440474    {
     
    444478
    445479    /* target bitrate in kilobits per second */
    446     pVideoRecCtx->VpxConfig.rc_target_bitrate = uRate;
     480    pStrm->VpxConfig.rc_target_bitrate = uRate;
    447481    /* frame width */
    448     pVideoRecCtx->VpxConfig.g_w = uWidth;
     482    pStrm->VpxConfig.g_w = uWidth;
    449483    /* frame height */
    450     pVideoRecCtx->VpxConfig.g_h = uHeight;
     484    pStrm->VpxConfig.g_h = uHeight;
    451485    /* 1ms per frame */
    452     pVideoRecCtx->VpxConfig.g_timebase.num = 1;
    453     pVideoRecCtx->VpxConfig.g_timebase.den = 1000;
     486    pStrm->VpxConfig.g_timebase.num = 1;
     487    pStrm->VpxConfig.g_timebase.den = 1000;
    454488    /* disable multithreading */
    455     pVideoRecCtx->VpxConfig.g_threads = 0;
    456     pVideoRecCtx->uDelay = 1000 / uFps;
     489    pStrm->VpxConfig.g_threads = 0;
     490    pStrm->uDelay = 1000 / uFps;
    457491
    458492    struct vpx_rational arg_framerate = {30, 1};
    459     rc = Ebml_WriteWebMFileHeader(&pVideoRecCtx->ebml, &pVideoRecCtx->VpxConfig, &arg_framerate);
     493    rc = Ebml_WriteWebMFileHeader(&pStrm->Ebml, &pStrm->VpxConfig, &arg_framerate);
    460494    AssertRCReturn(rc, rc);
    461495
    462496    /* Initialize codec */
    463     rcv = vpx_codec_enc_init(&pVideoRecCtx->VpxCodec, DEFAULTCODEC,
    464                              &pVideoRecCtx->VpxConfig, 0);
     497    rcv = vpx_codec_enc_init(&pStrm->VpxCodec, DEFAULTCODEC, &pStrm->VpxConfig, 0);
    465498    if (rcv != VPX_CODEC_OK)
    466499    {
     
    469502    }
    470503
    471     ASMAtomicWriteU32(&pVideoRecCtx->u32State, VIDREC_INITIALIZED);
    472 
    473     if (!vpx_img_alloc(&pVideoRecCtx->VpxRawImage, VPX_IMG_FMT_I420, uWidth, uHeight, 1))
     504    ASMAtomicWriteU32(&pStrm->u32State, VIDREC_INITIALIZED);
     505
     506    if (!vpx_img_alloc(&pStrm->VpxRawImage, VPX_IMG_FMT_I420, uWidth, uHeight, 1))
    474507    {
    475508        LogFlow(("Failed to allocate image %dx%d", uWidth, uHeight));
    476509        return VERR_NO_MEMORY;
    477510    }
    478     pVideoRecCtx->pu8YuvBuf = pVideoRecCtx->VpxRawImage.planes[0];
    479 
    480     rc = RTSemEventCreate(&pVideoRecCtx->WaitEvent);
    481     AssertRCReturn(rc, rc);
    482 
    483     rc = RTThreadCreate(&pVideoRecCtx->Thread, VideoRecThread,
    484                         (void*)pVideoRecCtx, 0,
    485                         RTTHREADTYPE_MAIN_WORKER, 0, "VideoRec");
    486     AssertRCReturn(rc, rc);
    487 
    488     pVideoRecCtx->fEnabled = true;
     511    pStrm->pu8YuvBuf = pStrm->VpxRawImage.planes[0];
     512
     513    pCtx->fEnabled = true;
    489514    return VINF_SUCCESS;
    490515}
     
    493518 * VideoRec utility function to close the video recording context.
    494519 *
    495  * @param   pVideoRecCtx   Pointer to video recording context.
    496  */
    497 void VideoRecContextClose(PVIDEORECCONTEXT pVideoRecCtx)
    498 {
    499     if (ASMAtomicReadU32(&pVideoRecCtx->u32State) == VIDREC_UNINITIALIZED)
     520 * @param   pCtx   Pointer to video recording context.
     521 */
     522void VideoRecContextClose(PVIDEORECCONTEXT pCtx)
     523{
     524    if (ASMAtomicReadU32(&pCtx->u32State) == VIDREC_UNINITIALIZED)
    500525        return;
    501526
    502     if (pVideoRecCtx->ebml.file != NIL_RTFILE)
    503     {
    504         int rc = Ebml_WriteWebMFileFooter(&pVideoRecCtx->ebml, 0);
    505         AssertRC(rc);
    506         RTFileClose(pVideoRecCtx->ebml.file);
    507         pVideoRecCtx->ebml.file = NIL_RTFILE;
    508     }
    509     if (pVideoRecCtx->ebml.cue_list)
    510     {
    511         RTMemFree(pVideoRecCtx->ebml.cue_list);
    512         pVideoRecCtx->ebml.cue_list = NULL;
    513     }
    514     if (pVideoRecCtx->fEnabled)
    515     {
    516         ASMAtomicWriteU32(&pVideoRecCtx->u32State, VIDREC_TERMINATING);
    517         RTSemEventSignal(pVideoRecCtx->WaitEvent);
    518         RTThreadUserWait(pVideoRecCtx->Thread, 10000);
    519         RTSemEventDestroy(pVideoRecCtx->WaitEvent);
    520         vpx_img_free(&pVideoRecCtx->VpxRawImage);
    521         vpx_codec_destroy(&pVideoRecCtx->VpxCodec);
    522         RTMemFree(pVideoRecCtx->pu8RgbBuf);
    523         pVideoRecCtx->pu8RgbBuf = NULL;
     527    if (pCtx->fEnabled)
     528    {
     529        ASMAtomicWriteU32(&pCtx->u32State, VIDREC_TERMINATING);
     530        RTSemEventSignal(pCtx->WaitEvent);
     531        RTThreadUserWait(pCtx->Thread, 10000);
     532        RTSemEventDestroy(pCtx->WaitEvent);
     533    }
     534
     535    for (unsigned uScreen = 0; uScreen < pCtx->cScreens; uScreen++)
     536    {
     537        PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen];
     538        if (pStrm->Ebml.file != NIL_RTFILE)
     539        {
     540            int rc = Ebml_WriteWebMFileFooter(&pStrm->Ebml, 0);
     541            AssertRC(rc);
     542            RTFileClose(pStrm->Ebml.file);
     543            pStrm->Ebml.file = NIL_RTFILE;
     544        }
     545        if (pStrm->Ebml.cue_list)
     546        {
     547            RTMemFree(pStrm->Ebml.cue_list);
     548            pStrm->Ebml.cue_list = NULL;
     549        }
     550        vpx_img_free(&pStrm->VpxRawImage);
     551        vpx_codec_destroy(&pStrm->VpxCodec);
     552        RTMemFree(pStrm->pu8RgbBuf);
     553        pStrm->pu8RgbBuf = NULL;
    524554    }
    525555}
     
    529559 *
    530560 * @returns true if recording is enabled
    531  * @param   pVideoRecCtx   Pointer to video recording context.
    532  */
    533 bool VideoRecIsEnabled(PVIDEORECCONTEXT pVideoRecCtx)
    534 {
    535     if (!pVideoRecCtx)
     561 * @param   pCtx   Pointer to video recording context.
     562 */
     563bool VideoRecIsEnabled(PVIDEORECCONTEXT pCtx)
     564{
     565    if (!pCtx)
    536566        return false;
    537567
    538     return pVideoRecCtx->fEnabled;
     568    return pCtx->fEnabled;
    539569}
    540570
     
    544574 *
    545575 * @returns IPRT status code.
    546  * @param   pVideoRecCtx  Pointer to video recording context.
     576 * @param   pCtx  Pointer to video recording context.
    547577 * @param   uSourceWidth      Width of the source image.
    548578 * @param   uSourceHeight     Height of the source image.
    549579 */
    550 static int videoRecEncodeAndWrite(PVIDEORECCONTEXT pVideoRecCtx)
     580static int videoRecEncodeAndWrite(PVIDEORECSTREAM pStrm)
    551581{
    552582    /* presentation time stamp */
    553     vpx_codec_pts_t pts = pVideoRecCtx->u64TimeStamp;
    554     vpx_codec_err_t rcv = vpx_codec_encode(&pVideoRecCtx->VpxCodec,
    555                                            &pVideoRecCtx->VpxRawImage,
     583    vpx_codec_pts_t pts = pStrm->u64TimeStamp;
     584    vpx_codec_err_t rcv = vpx_codec_encode(&pStrm->VpxCodec,
     585                                           &pStrm->VpxRawImage,
    556586                                           pts /* time stamp */,
    557587                                           10  /* how long to show this frame */,
     
    568598    for (;;)
    569599    {
    570         const vpx_codec_cx_pkt_t *pkt = vpx_codec_get_cx_data(&pVideoRecCtx->VpxCodec, &iter);
     600        const vpx_codec_cx_pkt_t *pkt = vpx_codec_get_cx_data(&pStrm->VpxCodec, &iter);
    571601        if (!pkt)
    572602            break;
     
    574604        {
    575605            case VPX_CODEC_CX_FRAME_PKT:
    576                 rc = Ebml_WriteWebMBlock(&pVideoRecCtx->ebml, &pVideoRecCtx->VpxConfig, pkt);
     606                rc = Ebml_WriteWebMBlock(&pStrm->Ebml, &pStrm->VpxConfig, pkt);
    577607                break;
    578608            default:
     
    582612    }
    583613
    584     pVideoRecCtx->cFrame++;
     614    pStrm->cFrame++;
    585615    return rc;
    586616}
     
    590620 *
    591621 * @returns IPRT status code.
    592  * @param   pVideoRecCtx      Pointer to video recording context.
    593  */
    594 static int videoRecRGBToYUV(PVIDEORECCONTEXT pVideoRecCtx)
    595 {
    596     switch (pVideoRecCtx->u32PixelFormat)
     622 * @param   pCtx      Pointer to video recording context.
     623 */
     624static int videoRecRGBToYUV(PVIDEORECSTREAM pStrm)
     625{
     626    switch (pStrm->u32PixelFormat)
    597627    {
    598628        case VPX_IMG_FMT_RGB32:
    599629            LogFlow(("32 bit\n"));
    600             if (!colorConvWriteYUV420p<ColorConvBGRA32Iter>(pVideoRecCtx->uTargetWidth,
    601                                                             pVideoRecCtx->uTargetHeight,
    602                                                             pVideoRecCtx->pu8YuvBuf,
    603                                                             pVideoRecCtx->pu8RgbBuf))
     630            if (!colorConvWriteYUV420p<ColorConvBGRA32Iter>(pStrm->uTargetWidth,
     631                                                            pStrm->uTargetHeight,
     632                                                            pStrm->pu8YuvBuf,
     633                                                            pStrm->pu8RgbBuf))
    604634                return VERR_GENERAL_FAILURE;
    605635            break;
    606636        case VPX_IMG_FMT_RGB24:
    607637            LogFlow(("24 bit\n"));
    608             if (!colorConvWriteYUV420p<ColorConvBGR24Iter>(pVideoRecCtx->uTargetWidth,
    609                                                            pVideoRecCtx->uTargetHeight,
    610                                                            pVideoRecCtx->pu8YuvBuf,
    611                                                            pVideoRecCtx->pu8RgbBuf))
     638            if (!colorConvWriteYUV420p<ColorConvBGR24Iter>(pStrm->uTargetWidth,
     639                                                           pStrm->uTargetHeight,
     640                                                           pStrm->pu8YuvBuf,
     641                                                           pStrm->pu8RgbBuf))
    612642                return VERR_GENERAL_FAILURE;
    613643            break;
    614644        case VPX_IMG_FMT_RGB565:
    615645            LogFlow(("565 bit\n"));
    616             if (!colorConvWriteYUV420p<ColorConvBGR565Iter>(pVideoRecCtx->uTargetWidth,
    617                                                             pVideoRecCtx->uTargetHeight,
    618                                                             pVideoRecCtx->pu8YuvBuf,
    619                                                             pVideoRecCtx->pu8RgbBuf))
     646            if (!colorConvWriteYUV420p<ColorConvBGR565Iter>(pStrm->uTargetWidth,
     647                                                            pStrm->uTargetHeight,
     648                                                            pStrm->pu8YuvBuf,
     649                                                            pStrm->pu8RgbBuf))
    620650                return VERR_GENERAL_FAILURE;
    621651            break;
     
    631661 *
    632662 * @returns IPRT status code.
    633  * @param   pVideoRecCtx       Pointer to video recording context.
     663 * @param   pCtx               Pointer to the video recording context.
     664 * @param   uScreen            Screen number.
    634665 * @param   x                  Starting x coordinate of the source buffer (Framebuffer).
    635666 * @param   y                  Starting y coordinate of the source buffer (Framebuffer).
     
    642673 * @param   u64TimeStamp       Time stamp (milliseconds).
    643674 */
    644 int VideoRecCopyToIntBuf(PVIDEORECCONTEXT pVideoRecCtx, uint32_t x, uint32_t y,
     675int VideoRecCopyToIntBuf(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint32_t x, uint32_t y,
    645676                         uint32_t uPixelFormat, uint32_t uBitsPerPixel, uint32_t uBytesPerLine,
    646677                         uint32_t uSourceWidth, uint32_t uSourceHeight, uint8_t *pu8BufAddr,
     
    650681    AssertReturn(uSourceWidth, VERR_INVALID_PARAMETER);
    651682    AssertReturn(uSourceHeight, VERR_INVALID_PARAMETER);
    652 
    653     if (u64TimeStamp < pVideoRecCtx->u64LastTimeStamp + pVideoRecCtx->uDelay)
     683    AssertReturn(uScreen < pCtx->cScreens, VERR_INVALID_PARAMETER);
     684
     685    PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen];
     686
     687    if (u64TimeStamp < pStrm->u64LastTimeStamp + pStrm->uDelay)
    654688        return VINF_TRY_AGAIN;
    655     pVideoRecCtx->u64LastTimeStamp = u64TimeStamp;
    656 
    657     if (ASMAtomicReadBool(&pVideoRecCtx->fRgbFilled))
     689    pStrm->u64LastTimeStamp = u64TimeStamp;
     690
     691    if (ASMAtomicReadBool(&pStrm->fRgbFilled))
    658692        return VERR_TRY_AGAIN;
    659693
    660     int xDiff = ((int)pVideoRecCtx->uTargetWidth - (int)uSourceWidth) / 2;
     694    int xDiff = ((int)pStrm->uTargetWidth - (int)uSourceWidth) / 2;
    661695    uint32_t w = uSourceWidth;
    662696    if ((int)w + xDiff + (int)x <= 0)  /* nothing visible */
     
    674708
    675709    uint32_t h = uSourceHeight;
    676     int yDiff = ((int)pVideoRecCtx->uTargetHeight - (int)uSourceHeight) / 2;
     710    int yDiff = ((int)pStrm->uTargetHeight - (int)uSourceHeight) / 2;
    677711    if ((int)h + yDiff + (int)y <= 0)  /* nothing visible */
    678712        return VERR_INVALID_PARAMETER;
     
    688722        destY = y + yDiff;
    689723
    690     if (   destX > pVideoRecCtx->uTargetWidth
    691         || destY > pVideoRecCtx->uTargetHeight)
     724    if (   destX > pStrm->uTargetWidth
     725        || destY > pStrm->uTargetHeight)
    692726        return VERR_INVALID_PARAMETER;  /* nothing visible */
    693727
    694     if (destX + w > pVideoRecCtx->uTargetWidth)
    695         w = pVideoRecCtx->uTargetWidth - destX;
    696 
    697     if (destY + h > pVideoRecCtx->uTargetHeight)
    698         h = pVideoRecCtx->uTargetHeight - destY;
     728    if (destX + w > pStrm->uTargetWidth)
     729        w = pStrm->uTargetWidth - destX;
     730
     731    if (destY + h > pStrm->uTargetHeight)
     732        h = pStrm->uTargetHeight - destY;
    699733
    700734    /* Calculate bytes per pixel */
     
    705739        {
    706740            case 32:
    707                 pVideoRecCtx->u32PixelFormat = VPX_IMG_FMT_RGB32;
     741                pStrm->u32PixelFormat = VPX_IMG_FMT_RGB32;
    708742                bpp = 4;
    709743                break;
    710744            case 24:
    711                 pVideoRecCtx->u32PixelFormat = VPX_IMG_FMT_RGB24;
     745                pStrm->u32PixelFormat = VPX_IMG_FMT_RGB24;
    712746                bpp = 3;
    713747                break;
    714748            case 16:
    715                 pVideoRecCtx->u32PixelFormat = VPX_IMG_FMT_RGB565;
     749                pStrm->u32PixelFormat = VPX_IMG_FMT_RGB565;
    716750                bpp = 2;
    717751                break;
     
    726760    /* One of the dimensions of the current frame is smaller than before so
    727761     * clear the entire buffer to prevent artifacts from the previous frame */
    728     if (   uSourceWidth  < pVideoRecCtx->uLastSourceWidth
    729         || uSourceHeight < pVideoRecCtx->uLastSourceHeight)
    730     {
    731         memset(pVideoRecCtx->pu8RgbBuf, 0,
    732                pVideoRecCtx->uTargetWidth * pVideoRecCtx->uTargetHeight * 4);
    733     }
    734     pVideoRecCtx->uLastSourceWidth  = uSourceWidth;
    735     pVideoRecCtx->uLastSourceHeight = uSourceHeight;
     762    if (   uSourceWidth  < pStrm->uLastSourceWidth
     763        || uSourceHeight < pStrm->uLastSourceHeight)
     764        memset(pStrm->pu8RgbBuf, 0, pStrm->uTargetWidth * pStrm->uTargetHeight * 4);
     765
     766    pStrm->uLastSourceWidth  = uSourceWidth;
     767    pStrm->uLastSourceHeight = uSourceHeight;
    736768
    737769    /* Calculate start offset in source and destination buffers */
    738770    uint32_t offSrc = y * uBytesPerLine + x * bpp;
    739     uint32_t offDst = (destY * pVideoRecCtx->uTargetWidth + destX) * bpp;
     771    uint32_t offDst = (destY * pStrm->uTargetWidth + destX) * bpp;
    740772    /* do the copy */
    741773    for (unsigned int i = 0; i < h; i++)
     
    743775        /* Overflow check */
    744776        Assert(offSrc + w * bpp <= uSourceHeight * uBytesPerLine);
    745         Assert(offDst + w * bpp <= pVideoRecCtx->uTargetHeight * pVideoRecCtx->uTargetWidth * bpp);
    746         memcpy(pVideoRecCtx->pu8RgbBuf + offDst, pu8BufAddr + offSrc, w * bpp);
     777        Assert(offDst + w * bpp <= pStrm->uTargetHeight * pStrm->uTargetWidth * bpp);
     778        memcpy(pStrm->pu8RgbBuf + offDst, pu8BufAddr + offSrc, w * bpp);
    747779        offSrc += uBytesPerLine;
    748         offDst += pVideoRecCtx->uTargetWidth * bpp;
    749     }
    750 
    751     pVideoRecCtx->u64TimeStamp = u64TimeStamp;
    752 
    753     ASMAtomicWriteBool(&pVideoRecCtx->fRgbFilled, true);
    754     RTSemEventSignal(pVideoRecCtx->WaitEvent);
     780        offDst += pStrm->uTargetWidth * bpp;
     781    }
     782
     783    pStrm->u64TimeStamp = u64TimeStamp;
     784
     785    ASMAtomicWriteBool(&pStrm->fRgbFilled, true);
     786    RTSemEventSignal(pCtx->WaitEvent);
    755787
    756788    return VINF_SUCCESS;
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette