VirtualBox

Changeset 65429 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Jan 24, 2017 3:35:58 PM (8 years ago)
Author:
vboxsync
Message:

VideoRec: Update.

Location:
trunk/src/VBox/Main/src-client
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp

    r65416 r65429  
    543543 */
    544544static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface,
    545                                                     PPDMAUDIOSTREAM pStream, const void *pvBuf2, uint32_t cbBuf2,
     545                                                    PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
    546546                                                    uint32_t *pcbWritten)
    547547{
    548     RT_NOREF2(pvBuf2, cbBuf2);
    549 
    550548    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    551549    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     
    555553    RT_NOREF(pThis);
    556554    PAVRECSTREAMOUT   pStreamOut = (PAVRECSTREAMOUT)pStream;
     555
     556    RT_NOREF(pvBuf, cbBuf);
    557557
    558558    uint32_t csLive = AudioMixBufUsed(&pStream->MixBuf);
     
    578578    AssertPtr(pCircBuf);
    579579
    580     void  *pvBuf;
    581     size_t cbBuf;
     580    void  *pvCircBuf;
     581    size_t cbCircBuf;
    582582
    583583    /*
     
    586586    while (RTCircBufFree(pCircBuf))
    587587    {
    588         RTCircBufAcquireWriteBlock(pCircBuf, RTCircBufFree(pCircBuf), &pvBuf, &cbBuf);
     588        RTCircBufAcquireWriteBlock(pCircBuf, RTCircBufFree(pCircBuf), &pvCircBuf, &cbCircBuf);
    589589
    590590        uint32_t cbRead = 0;
    591591
    592         if (cbBuf)
     592        if (cbCircBuf)
    593593        {
    594594            uint32_t csRead = 0;
    595             rc = AudioMixBufReadCirc(&pStream->MixBuf, pvBuf, cbBuf, &csRead);
     595            rc = AudioMixBufReadCirc(&pStream->MixBuf, pvCircBuf, cbCircBuf, &csRead);
    596596            if (   RT_SUCCESS(rc)
    597597                && csRead)
     
    630630        while (cbSrc < cbFrame)
    631631        {
    632             RTCircBufAcquireReadBlock(pCircBuf, cbFrame - cbSrc, &pvBuf, &cbBuf);
    633 
    634             if (cbBuf)
     632            RTCircBufAcquireReadBlock(pCircBuf, cbFrame - cbSrc, &pvCircBuf, &cbCircBuf);
     633
     634            if (cbCircBuf)
    635635            {
    636                 memcpy(&abSrc[cbSrc], pvBuf, cbBuf);
    637 
    638                 cbSrc += cbBuf;
     636                memcpy(&abSrc[cbSrc], pvCircBuf, cbCircBuf);
     637
     638                cbSrc += cbCircBuf;
    639639                Assert(cbSrc <= sizeof(abSrc));
    640640            }
    641641
    642             RTCircBufReleaseReadBlock(pCircBuf, cbBuf);
    643 
    644             if (!cbBuf)
     642            RTCircBufReleaseReadBlock(pCircBuf, cbCircBuf);
     643
     644            if (!cbCircBuf)
    645645                break;
    646646        }
  • trunk/src/VBox/Main/src-client/VideoRec.cpp

    r65426 r65429  
    127127    uint64_t            uCurTimeStampMs;
    128128
     129    /** Whether the RGB buffer is filled or not. */
     130    bool                fHasVideoData;
     131
    129132    struct
    130133    {
     
    137140        /** Y resolution of the last encoded frame. */
    138141        uint32_t            uSrcLastHeight;
    139         /** Current frame number. */
    140         uint64_t            cFrame;
    141         /** RGB buffer containing the most recent frame of the framebuffer. */
     142        /** RGB buffer containing the most recent frame of Main's framebuffer. */
    142143        uint8_t            *pu8RgbBuf;
    143144        /** YUV buffer the encode function fetches the frame from. */
    144145        uint8_t            *pu8YuvBuf;
    145         /** Whether the RGB buffer is filled or not. */
    146         bool                fRgbFilled;
    147146        /** Pixel format of the current frame. */
    148147        uint32_t            uPixelFormat;
    149         /** Minimal delay between two frames. */
    150         uint32_t            uDelay;
     148        /** Minimal delay (in ms) between two frames. */
     149        uint32_t            uDelayMs;
    151150        /** Encoder deadline. */
    152151        unsigned int        uEncoderDeadline;
    153152    } Video;
    154 
    155153} VIDEORECSTREAM, *PVIDEORECSTREAM;
    156154
     
    177175    /** Vector of current video recording stream contexts. */
    178176    VideoRecStreams     vecStreams;
     177#ifdef VBOX_WITH_AUDIO_VIDEOREC
     178    bool                fHasAudioData;
     179    struct
     180    {
     181        uint8_t         buf[_64K];
     182    } Audio;
     183#endif
    179184} VIDEORECCONTEXT, *PVIDEORECCONTEXT;
    180185
     
    461466            break;
    462467
     468#ifdef VBOX_WITH_AUDIO_VIDEOREC
     469        const bool fHasAudioData = ASMAtomicReadBool(&pCtx->fHasAudioData);
     470#endif
     471        /** @todo r=andy This is inefficient -- as we already wake up this thread
     472         *               for every screen from Main, we here go again (on every wake up) through
     473         *               all screens.  */
    463474        for (VideoRecStreams::iterator it = pCtx->vecStreams.begin(); it != pCtx->vecStreams.end(); it++)
    464475        {
    465476            PVIDEORECSTREAM pStream = (*it);
    466477
    467             if (   pStream->fEnabled
    468                 && ASMAtomicReadBool(&pStream->Video.fRgbFilled))
     478            if (!pStream->fEnabled)
     479                continue;
     480
     481            if (ASMAtomicReadBool(&pStream->fHasVideoData))
    469482            {
    470483                rc = videoRecRGBToYUV(pStream);
    471484
    472                 ASMAtomicWriteBool(&pStream->Video.fRgbFilled, false);
     485                ASMAtomicWriteBool(&pStream->fHasVideoData, false);
    473486
    474487                if (RT_SUCCESS(rc))
     
    485498                }
    486499            }
    487         }
     500
     501#ifdef VBOX_WITH_AUDIO_VIDEOREC
     502            /* Each (enabled) screen has to get the audio data. */
     503            if (fHasAudioData)
     504            {
     505                WebMWriter::BlockData_Opus blockData = { pCtx->Audio.buf,  };
     506                rc = pStream->pEBML->WriteBlock(pStream->uTrackAudio, &blockData, sizeof(blockData));
     507            }
     508#endif
     509        } /* for */
     510
     511#ifdef VBOX_WITH_AUDIO_VIDEOREC
     512        ASMAtomicWriteBool(&pCtx->fHasAudioData, false);
     513#endif
    488514    }
    489515
     
    650676 * Retrieves a specific recording stream of a recording context.
    651677 *
    652  * @returns Pointer to recording if found, or NULL if not found.
    653  * @param                       Recording context to look up stream for.
    654  * @param                       Screen number of recording stream to look up.
     678 * @returns Pointer to recording stream if found, or NULL if not found.
     679 * @param   pCtx                Recording context to look up stream for.
     680 * @param   uScreen             Screen number of recording stream to look up.
    655681 */
    656682DECLINLINE(PVIDEORECSTREAM) videoRecStreamGet(PVIDEORECCONTEXT pCtx, uint32_t uScreen)
     
    801827    }
    802828
    803     pStream->Video.uDelay = 1000 / uFPS;
     829    pStream->Video.uDelayMs = 1000 / uFPS;
    804830
    805831    if (fHasVideoTrack)
     
    863889    pStream->fEnabled = true;
    864890
    865 
    866 
    867891    return VINF_SUCCESS;
    868892}
     
    889913 * @param   pCtx                Pointer to video recording context.
    890914 * @param   uScreen             Screen ID.
    891  * @param   u64TimeStampMs      Current time stamp (in ms).
    892  */
    893 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStampMs)
     915 * @param   uTimeStampMs        Current time stamp (in ms).
     916 */
     917bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t uTimeStampMs)
    894918{
    895919    uint32_t enmState = ASMAtomicReadU32(&g_enmState);
     
    904928    }
    905929
    906     if (u64TimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelay)
     930    if (uTimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelayMs)
    907931        return false;
    908932
    909     if (ASMAtomicReadBool(&pStream->Video.fRgbFilled))
     933    if (ASMAtomicReadBool(&pStream->fHasVideoData))
    910934        return false;
    911935
     
    971995                                           &pStream->Codec.VPX.RawImage,
    972996                                           pts                           /* Time stamp */,
    973                                            pStream->Video.uDelay               /* How long to show this frame */,
     997                                           pStream->Video.uDelayMs               /* How long to show this frame */,
    974998                                           0                             /* Flags */,
    975999                                           pStream->Video.uEncoderDeadline     /* Quality setting */);
     
    10031027        }
    10041028    }
    1005 
    1006     pStream->Video.cFrame++;
    10071029#else
    10081030    RT_NOREF(pStream);
     
    10161038 *
    10171039 * @returns IPRT status code.
    1018  * @param   pStrm      Strm.
     1040 * @param   pStream             Recording stream to convert RGB to YUV video frame buffer for.
    10191041 */
    10201042static int videoRecRGBToYUV(PVIDEORECSTREAM pStream)
     
    10551077 * Sends an audio frame to the video encoding thread.
    10561078 *
     1079 * @thread  EMT
     1080 *
    10571081 * @returns IPRT status code.
    10581082 * @param   pCtx                Pointer to the video recording context.
     
    10641088{
    10651089    RT_NOREF(pCtx, pvData, cbData, uTimestampMs);
     1090
     1091    /* To save time spent in EMT, do the required audio multiplexing in the encoding thread.
     1092     *
     1093     * The multiplexing is needed to supply all recorded (enabled) screens with the same
     1094     * audio data at the same given point in time.
     1095     */
     1096
     1097
    10661098    return VINF_SUCCESS;
    10671099}
     
    10841116 * @param   uSrcHeight         Height of the video frame.
    10851117 * @param   puSrcData          Pointer to video frame data.
    1086  * @param   u64TimeStampMs     Time stamp (in ms).
     1118 * @param   uTimeStampMs       Time stamp (in ms).
    10871119 */
    10881120int VideoRecSendVideoFrame(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint32_t x, uint32_t y,
     
    11121144        if (!pStream->fEnabled)
    11131145        {
    1114             rc = VINF_TRY_AGAIN; /* not (yet) enabled */
    1115             break;
    1116         }
    1117         if (uTimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelay)
    1118         {
    1119             rc = VINF_TRY_AGAIN; /* respect maximum frames per second */
    1120             break;
    1121         }
    1122         if (ASMAtomicReadBool(&pStream->Video.fRgbFilled))
    1123         {
    1124             rc = VERR_TRY_AGAIN; /* previous frame not yet encoded */
     1146            rc = VINF_TRY_AGAIN; /* Not (yet) enabled. */
     1147            break;
     1148        }
     1149
     1150        if (uTimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelayMs)
     1151        {
     1152            rc = VINF_TRY_AGAIN; /* Respect maximum frames per second. */
     1153            break;
     1154        }
     1155
     1156        if (ASMAtomicReadBool(&pStream->fHasVideoData))
     1157        {
     1158            rc = VERR_TRY_AGAIN; /* Previous frame not yet encoded. */
    11251159            break;
    11261160        }
     
    11301164        int xDiff = ((int)pStream->Video.uDstWidth - (int)uSrcWidth) / 2;
    11311165        uint32_t w = uSrcWidth;
    1132         if ((int)w + xDiff + (int)x <= 0)  /* nothing visible */
     1166        if ((int)w + xDiff + (int)x <= 0)  /* Nothing visible. */
    11331167        {
    11341168            rc = VERR_INVALID_PARAMETER;
     
    11481182        uint32_t h = uSrcHeight;
    11491183        int yDiff = ((int)pStream->Video.uDstHeight - (int)uSrcHeight) / 2;
    1150         if ((int)h + yDiff + (int)y <= 0)  /* nothing visible */
     1184        if ((int)h + yDiff + (int)y <= 0)  /* Nothing visible. */
    11511185        {
    11521186            rc = VERR_INVALID_PARAMETER;
     
    11671201            || destY > pStream->Video.uDstHeight)
    11681202        {
    1169             rc = VERR_INVALID_PARAMETER;  /* nothing visible */
     1203            rc = VERR_INVALID_PARAMETER;  /* Nothing visible. */
    11701204            break;
    11711205        }
     
    12191253        for (unsigned int i = 0; i < h; i++)
    12201254        {
    1221             /* Overflow check */
     1255            /* Overflow check. */
    12221256            Assert(offSrc + w * bpp <= uSrcHeight * uBytesPerLine);
    12231257            Assert(offDst + w * bpp <= pStream->Video.uDstHeight * pStream->Video.uDstWidth * bpp);
     1258
    12241259            memcpy(pStream->Video.pu8RgbBuf + offDst, puSrcData + offSrc, w * bpp);
     1260
    12251261            offSrc += uBytesPerLine;
    12261262            offDst += pStream->Video.uDstWidth * bpp;
     
    12291265        pStream->uCurTimeStampMs = uTimeStampMs;
    12301266
    1231         ASMAtomicWriteBool(&pStream->Video.fRgbFilled, true);
     1267        ASMAtomicWriteBool(&pStream->fHasVideoData, true);
    12321268        RTSemEventSignal(pCtx->WaitEvent);
    12331269
  • trunk/src/VBox/Main/src-client/VideoRec.h

    r65418 r65429  
    2929
    3030int  VideoRecStreamInit(PVIDEORECCONTEXT pCtx, uint32_t uScreen, const char *pszFile,
    31                         uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFps,
    32                         uint32_t uMaxTime, uint32_t uMaxFileSize, const char *pszOptions);
     31                        uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFPS,
     32                        uint32_t uMaxTimeS, uint32_t uMaxFileSizeMB, const char *pszOptions);
    3333
    3434bool VideoRecIsEnabled(PVIDEORECCONTEXT pCtx);
    3535int  VideoRecSendAudioFrame(PVIDEORECCONTEXT pCtx, const void *pvData, size_t cbData, uint64_t uTimestampMs);
    3636int  VideoRecSendVideoFrame(PVIDEORECCONTEXT pCtx, uint32_t uScreen,
    37                             uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBitsPerPixel,
    38                             uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
    39                             uint8_t *pu8BufferAddress, uint64_t u64TimeStampMs);
    40 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStampMs);
    41 bool VideoRecIsLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStampMs);
     37                            uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP,
     38                            uint32_t uBytesPerLine, uint32_t uSrcWidth, uint32_t uSrcHeight,
     39                            uint8_t *puSrcData, uint64_t uTimeStampMs);
     40bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t uTimeStampMs);
     41bool VideoRecIsLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t tsNowMs);
    4242
    4343#endif /* !____H_VIDEOREC */
Note: See TracChangeset for help on using the changeset viewer.

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