VirtualBox

Changeset 65401 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 23, 2017 1:33:45 PM (8 years ago)
Author:
vboxsync
Message:

VideoRec: Update.

Location:
trunk/src/VBox/Main
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r65381 r65401  
    504504
    505505#ifdef VBOX_WITH_VIDEOREC
    506     VIDEORECCONTEXT *mpVideoRecCtx;
    507     bool maVideoRecEnabled[SchemaDefs::MaxGuestMonitors];
     506    VIDEORECCONTEXT     *mpVideoRecCtx;
     507    bool                 maVideoRecEnabled[SchemaDefs::MaxGuestMonitors];
    508508#endif
    509509
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r65381 r65401  
    23492349        if (RT_SUCCESS(rc))
    23502350        {
    2351 #ifndef DEUBG_andy
    23522351            if (mcMonitors > 1)
    23532352                rc = RTStrAPrintf(&pszName, "%s-%u%s", pszAbsPath, uScreen+1, pszSuff);
    23542353            else
    23552354                rc = RTStrAPrintf(&pszName, "%s%s", pszAbsPath, pszSuff);
    2356 #else
    2357             if (mcMonitors > 1)
    2358                 rc = RTStrAPrintf(&pszName, "/tmp/avcap-%u.webm", uScreen+1);
    2359             else
    2360                 rc = RTStrAPrintf(&pszName, "/tmp/avcap.webm");
    2361 #endif
    23622355        }
    23632356        if (RT_SUCCESS(rc))
     
    23922385        if (RT_SUCCESS(rc))
    23932386        {
    2394             LogRel(("Display::VideoCaptureStart: WebM/VP8 video recording screen #%u with %ux%u @ %u kbps, %u fps to '%s' "
    2395                     "enabled\n", uScreen, ulWidth, ulHeight, ulRate, ulFPS, pszName));
    2396 
    23972387            videoCaptureScreenChanged(uScreen);
    23982388        }
    23992389        else
    2400             LogRel(("Display::VideoCaptureStart: Failed to initialize video recording context #%u (%Rrc)!\n", uScreen, rc));
     2390            LogRel(("Display::VideoCaptureStart: Failed to initialize video recording context #%u, (%Rrc)\n", uScreen, rc));
     2391
    24012392        RTStrFree(pszName);
    24022393        RTStrFree(pszSuff);
     
    24152406{
    24162407#ifdef VBOX_WITH_VIDEOREC
    2417     if (VideoRecIsEnabled(mpVideoRecCtx))
    2418         LogRel(("Display::VideoCaptureStop: WebM/VP8 video recording stopped\n"));
     2408    if (!VideoRecIsEnabled(mpVideoRecCtx))
     2409        return;
     2410
    24192411    VideoRecContextDestroy(mpVideoRecCtx);
    24202412    mpVideoRecCtx = NULL;
     
    24292421void Display::videoCaptureScreenChanged(unsigned uScreenId)
    24302422{
     2423    if (   !VideoRecIsEnabled(mpVideoRecCtx)
     2424        || !maVideoRecEnabled[uScreenId])
     2425    {
     2426        /* Skip recording this screen. */
     2427        return;
     2428    }
     2429
     2430    /* Get a new source bitmap which will be used by video capture code. */
    24312431    ComPtr<IDisplaySourceBitmap> pSourceBitmap;
    2432 
    2433     if (VideoRecIsEnabled(mpVideoRecCtx) && maVideoRecEnabled[uScreenId])
    2434     {
    2435         /* Get a new source bitmap which will be used by video capture code. */
    2436         QuerySourceBitmap(uScreenId, pSourceBitmap.asOutParam());
    2437     }
    2438 
    2439     int rc = RTCritSectEnter(&mVideoCaptureLock);
    2440     if (RT_SUCCESS(rc))
     2432    QuerySourceBitmap(uScreenId, pSourceBitmap.asOutParam());
     2433
     2434    int rc2 = RTCritSectEnter(&mVideoCaptureLock);
     2435    if (RT_SUCCESS(rc2))
    24412436    {
    24422437        maFramebuffers[uScreenId].videoCapture.pSourceBitmap = pSourceBitmap;
    2443         RTCritSectLeave(&mVideoCaptureLock);
     2438
     2439        rc2 = RTCritSectLeave(&mVideoCaptureLock);
     2440        AssertRC(rc2);
    24442441    }
    24452442}
     
    31863183                    continue;
    31873184
    3188                 if (VideoRecIsFull(pDisplay->mpVideoRecCtx, uScreenId, u64Now))
     3185                if (VideoRecLimitReached(pDisplay->mpVideoRecCtx, uScreenId, u64Now))
    31893186                {
    31903187                    pDisplay->i_VideoCaptureStop();
  • trunk/src/VBox/Main/src-client/VideoRec.cpp

    r65330 r65401  
    1818#define LOG_GROUP LOG_GROUP_MAIN
    1919
     20#include <stdexcept>
    2021#include <vector>
    2122
     
    7980
    8081/* Must be always accessible and therefore cannot be part of VIDEORECCONTEXT */
    81 static uint32_t g_enmState = VIDEORECSTS_UNINITIALIZED;
     82static uint32_t g_enmState = VIDEORECSTS_UNINITIALIZED; /** @todo r=andy Make this part of VIDEORECCONTEXT + remove busy waiting. */
    8283
    8384/**
     
    109110    /** Container context. */
    110111    WebMWriter         *pEBML;
     112    /** Track number of audio stream. */
     113    uint8_t             uTrackAudio;
    111114    /** Track number of video stream. */
    112115    uint8_t             uTrackVideo;
    113116    /** Codec data. */
    114117    VIDEORECCODEC       Codec;
     118    /** Screen ID. */
     119    uint16_t            uScreen;
    115120    /** Target X resolution (in pixels). */
    116121    uint32_t            uTargetWidth;
     
    135140    /** Minimal delay between two frames. */
    136141    uint32_t            uDelay;
    137     /** Time stamp of the last frame we encoded. */
    138     uint64_t            u64LastTimeStamp;
    139     /** Time stamp of the current frame. */
    140     uint64_t            u64TimeStamp;
     142    /** Time stamp (in ms) of the last frame we encoded. */
     143    uint64_t            uLastTimeStampMs;
     144    /** Time stamp (in ms) of the current frame. */
     145    uint64_t            uCurTimeStampMs;
    141146    /** Encoder deadline. */
    142147    unsigned int        uEncoderDeadline;
     
    159164    /** Worker thread. */
    160165    RTTHREAD            Thread;
    161     /** Maximal time stamp. */
    162     uint64_t            u64MaxTimeStamp;
    163     /** Maximal file size in MB. */
    164     uint32_t            uMaxFileSize;
     166    uint64_t            tsStartMs;
     167    /** Maximal time (in ms) to record. */
     168    uint64_t            uMaxTimeMs;
     169    /** Maximal file size (in MB) to record. */
     170    uint32_t            uMaxSizeMB;
    165171    /** Vector of current video recording stream contexts. */
    166172    VideoRecStreams     vecStreams;
     
    440446    RT_NOREF(hThreadSelf);
    441447    PVIDEORECCONTEXT pCtx = (PVIDEORECCONTEXT)pvUser;
     448
    442449    for (;;)
    443450    {
     
    509516        try
    510517        {
     518            pStream->uScreen = uScreen;
     519
    511520            pCtx->vecStreams.push_back(pStream);
    512521
     
    610619                pStream->pu8RgbBuf = NULL;
    611620            }
     621
     622            LogRel(("VideoRec: Recording screen #%u stopped\n", pStream->uScreen));
    612623        }
    613624
     
    628639
    629640    ASMAtomicWriteU32(&g_enmState, VIDEORECSTS_UNINITIALIZED);
     641}
     642
     643/**
     644 * Retrieves a specific recording stream of a recording context.
     645 *
     646 * @returns Pointer to recording if found, or NULL if not found.
     647 * @param                       Recording context to look up stream for.
     648 * @param                       Screen number of recording stream to look up.
     649 */
     650DECLINLINE(PVIDEORECSTREAM) videoRecStreamGet(PVIDEORECCONTEXT pCtx, uint32_t uScreen)
     651{
     652    AssertPtrReturn(pCtx, NULL);
     653
     654    PVIDEORECSTREAM pStream;
     655
     656    try
     657    {
     658        pStream = pCtx->vecStreams.at(uScreen);
     659    }
     660    catch (std::out_of_range)
     661    {
     662        pStream = NULL;
     663    }
     664
     665    return pStream;
    630666}
    631667
     
    634670 *
    635671 * @returns IPRT status code.
    636  * @param   pCtx                Pointer to video recording context to initialize Framebuffer width.
    637  * @param   uScreen             Screen number.
    638  * @param   pszFile             File to save the recorded data
    639  * @param   uWidth              Width of the target image in the video recoriding file (movie)
    640  * @param   uHeight             Height of the target image in video recording file.
    641  * @param   uRate               Rate.
    642  * @param   uFps                FPS.
    643  * @param   uMaxTime
    644  * @param   uMaxFileSize
    645  * @param   pszOptions
     672 * @param   pCtx                Pointer to video recording context.
     673 * @param   uScreen             Screen number to record.
     674 * @param   pszFile             File to save recording to.
     675 * @param   uWidth              Target video resolution (width).
     676 * @param   uHeight             Target video resolution (height).
     677 * @param   uRate               Target encoding bit rate.
     678 * @param   uFps                Target FPS (Frame Per Second).
     679 * @param   uMaxTimeS           Maximum time (in s) to record, or 0 for no time limit.
     680 * @param   uMaxFileSizeMB      Maximum file size (in MB) to record, or 0 for no limit.
     681 * @param   pszOptions          Additional options in "key=value" array format. Optional.
    646682 */
    647683int VideoRecStreamInit(PVIDEORECCONTEXT pCtx, uint32_t uScreen, const char *pszFile,
    648                        uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFps,
    649                        uint32_t uMaxTime, uint32_t uMaxFileSize, const char *pszOptions)
    650 {
    651     AssertPtrReturn(pCtx,                           VERR_INVALID_PARAMETER);
    652     AssertReturn(uScreen < pCtx->vecStreams.size(), VERR_INVALID_PARAMETER);
    653 
    654     pCtx->u64MaxTimeStamp = (uMaxTime > 0 ? RTTimeProgramMilliTS() + uMaxTime * 1000 : 0);
    655     pCtx->uMaxFileSize = uMaxFileSize;
    656 
    657     PVIDEORECSTREAM pStream = pCtx->vecStreams.at(uScreen);
     684                       uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFPS,
     685                       uint32_t uMaxTimeS, uint32_t uMaxSizeMB, const char *pszOptions)
     686{
     687    AssertPtrReturn(pCtx,    VERR_INVALID_POINTER);
     688    AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
     689    AssertReturn(uWidth,     VERR_INVALID_PARAMETER);
     690    AssertReturn(uHeight,    VERR_INVALID_PARAMETER);
     691    AssertReturn(uRate,      VERR_INVALID_PARAMETER);
     692    AssertReturn(uFPS,       VERR_INVALID_PARAMETER);
     693    /* pszOptions is optional. */
     694
     695    PVIDEORECSTREAM pStream = videoRecStreamGet(pCtx, uScreen);
     696    if (!pStream)
     697        return VERR_NOT_FOUND;
     698
     699    pCtx->uMaxTimeMs = (uMaxTimeS > 0 ? RTTimeProgramMilliTS() + uMaxTimeS * 1000 : 0);
     700    pCtx->uMaxSizeMB = uMaxSizeMB;
    658701
    659702    pStream->uTargetWidth  = uWidth;
     
    699742            else if (value.compare("good", Utf8Str::CaseInsensitive) == 0)
    700743            {
    701                 pStream->uEncoderDeadline = 1000000 / uFps;
     744                pStream->uEncoderDeadline = 1000000 / uFPS;
    702745            }
    703746            else if (value.compare("best", Utf8Str::CaseInsensitive) == 0)
     
    752795    }
    753796
    754     pStream->uDelay = 1000 / uFps;
     797    pStream->uDelay = 1000 / uFPS;
    755798
    756799    if (fHasVideoTrack)
    757800    {
    758         rc = pStream->pEBML->AddVideoTrack(uWidth, uHeight, uFps, &pStream->uTrackVideo);
     801        rc = pStream->pEBML->AddVideoTrack(uWidth, uHeight, uFPS, &pStream->uTrackVideo);
    759802        if (RT_FAILURE(rc))
    760803        {
     
    764807    }
    765808
     809#ifdef VBOX_WITH_AUDIO_VIDEOREC
     810    if (fHasAudioTrack)
     811    {
     812        rc = pStream->pEBML->AddAudioTrack(48000, 2, 16, &pStream->uTrackAudio);
     813        if (RT_FAILURE(rc))
     814        {
     815            LogRel(("VideoRec: Failed to add audio track to output file '%s' (%Rrc)\n", pszFile, rc));
     816            return rc;
     817        }
     818    }
     819#endif
     820
    766821#ifdef VBOX_WITH_LIBVPX
    767     /* target bitrate in kilobits per second */
     822    /* Target bitrate in kilobits per second. */
    768823    pStream->Codec.VPX.Config.rc_target_bitrate = uRate;
    769     /* frame width */
     824    /* Frame width. */
    770825    pStream->Codec.VPX.Config.g_w = uWidth;
    771     /* frame height */
     826    /* Frame height. */
    772827    pStream->Codec.VPX.Config.g_h = uHeight;
    773     /* 1ms per frame */
     828    /* 1ms per frame. */
    774829    pStream->Codec.VPX.Config.g_timebase.num = 1;
    775830    pStream->Codec.VPX.Config.g_timebase.den = 1000;
    776     /* disable multithreading */
     831    /* Disable multithreading. */
    777832    pStream->Codec.VPX.Config.g_threads = 0;
    778833
     
    796851    pCtx->fEnabled = true;
    797852    pStream->fEnabled = true;
     853
     854    LogRel(("VideoRec: Recording screen #%u with %ux%u @ %u kbps, %u fps to '%s' started\n",
     855            uScreen, uWidth, uHeight, uRate, uFPS, pszFile));
    798856
    799857    return VINF_SUCCESS;
     
    821879 * @param   pCtx                Pointer to video recording context.
    822880 * @param   uScreen             Screen ID.
    823  * @param   u64TimeStamp        Current time stamp.
    824  */
    825 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStamp)
     881 * @param   u64TimeStampMs      Current time stamp (in ms).
     882 */
     883bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStampMs)
    826884{
    827885    uint32_t enmState = ASMAtomicReadU32(&g_enmState);
     
    829887        return false;
    830888
    831     PVIDEORECSTREAM pStream = pCtx->vecStreams.at(uScreen);
    832     if (!pStream->fEnabled)
     889    PVIDEORECSTREAM pStream = videoRecStreamGet(pCtx, uScreen);
     890    if (   !pStream
     891        || !pStream->fEnabled)
     892    {
    833893        return false;
    834 
    835     if (u64TimeStamp < pStream->u64LastTimeStamp + pStream->uDelay)
     894    }
     895
     896    if (u64TimeStampMs < pStream->uLastTimeStampMs + pStream->uDelay)
    836897        return false;
    837898
     
    843904
    844905/**
    845  * VideoRec utility function to check if the file size has reached
    846  * specified limits (if any).
     906 * VideoRec utility function to check if a specified limit for recording
     907 * has been reached.
    847908 *
    848909 * @returns true if any limit has been reached.
    849910 * @param   pCtx                Pointer to video recording context.
    850911 * @param   uScreen             Screen ID.
    851  * @param   u64TimeStamp        Current time stamp.
    852  */
    853 
    854 bool VideoRecIsFull(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStamp)
    855 {
    856     PVIDEORECSTREAM pStream = pCtx->vecStreams.at(uScreen);
    857     if(!pStream->fEnabled)
     912 * @param   tsNowMs             Current time stamp (in ms).
     913 */
     914
     915bool VideoRecLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t tsNowMs)
     916{
     917    PVIDEORECSTREAM pStream = videoRecStreamGet(pCtx, uScreen);
     918    if (   !pStream
     919        || !pStream->fEnabled)
     920    {
    858921        return false;
    859 
    860     if(pCtx->u64MaxTimeStamp > 0 && u64TimeStamp >= pCtx->u64MaxTimeStamp)
     922    }
     923
     924    if (   pCtx->uMaxTimeMs
     925        && (tsNowMs - pCtx->tsStartMs) >= pCtx->uMaxTimeMs)
     926    {
    861927        return true;
    862 
    863     if (pCtx->uMaxFileSize > 0)
     928    }
     929
     930    if (pCtx->uMaxSizeMB)
    864931    {
    865932        uint64_t sizeInMB = pStream->pEBML->GetFileSize() / (1024 * 1024);
    866         if(sizeInMB >= pCtx->uMaxFileSize)
     933        if(sizeInMB >= pCtx->uMaxSizeMB)
    867934            return true;
    868935    }
     
    890957#ifdef VBOX_WITH_LIBVPX
    891958    /* presentation time stamp */
    892     vpx_codec_pts_t pts = pStream->u64TimeStamp;
     959    vpx_codec_pts_t pts = pStream->uCurTimeStampMs;
    893960    vpx_codec_err_t rcv = vpx_codec_encode(&pStream->Codec.VPX.CodecCtx,
    894961                                           &pStream->Codec.VPX.RawImage,
     
    921988
    922989            default:
    923                 LogFlow(("Unexpected CODEC packet kind %ld\n", pPacket->kind));
     990                AssertFailed();
     991                LogFunc(("Unexpected CODEC packet kind %ld\n", pPacket->kind));
    924992                break;
    925993        }
     
    9911059 * @param   uSourceHeight      Height of the source image (framebuffer).
    9921060 * @param   pu8BufAddr         Pointer to source image(framebuffer).
    993  * @param   u64TimeStamp       Time stamp (milliseconds).
     1061 * @param   u64TimeStampMs     Time stamp (in ms).
    9941062 */
    9951063int VideoRecCopyToIntBuf(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint32_t x, uint32_t y,
    9961064                         uint32_t uPixelFormat, uint32_t uBitsPerPixel, uint32_t uBytesPerLine,
    9971065                         uint32_t uSourceWidth, uint32_t uSourceHeight, uint8_t *pu8BufAddr,
    998                          uint64_t u64TimeStamp)
     1066                         uint64_t uTimeStampMs)
    9991067{
    10001068    /* Do not execute during termination and guard against termination */
     
    10051073    do
    10061074    {
    1007         AssertPtrBreakStmt(pu8BufAddr,                     rc = VERR_INVALID_PARAMETER);
    1008         AssertBreakStmt(uSourceWidth,                      rc = VERR_INVALID_PARAMETER);
    1009         AssertBreakStmt(uSourceHeight,                     rc = VERR_INVALID_PARAMETER);
    1010         AssertBreakStmt(uScreen < pCtx->vecStreams.size(), rc = VERR_INVALID_PARAMETER);
    1011 
    1012         PVIDEORECSTREAM pStream = pCtx->vecStreams.at(uScreen);
     1075        AssertPtrBreakStmt(pCtx,       rc = VERR_INVALID_POINTER);
     1076        AssertPtrBreakStmt(pu8BufAddr, rc = VERR_INVALID_POINTER);
     1077        AssertBreakStmt(uSourceWidth,  rc = VERR_INVALID_PARAMETER);
     1078        AssertBreakStmt(uSourceHeight, rc = VERR_INVALID_PARAMETER);
     1079
     1080        PVIDEORECSTREAM pStream = videoRecStreamGet(pCtx, uScreen);
     1081        if (!pStream)
     1082        {
     1083            rc = VERR_NOT_FOUND;
     1084            break;
     1085        }
     1086
    10131087        if (!pStream->fEnabled)
    10141088        {
     
    10161090            break;
    10171091        }
    1018         if (u64TimeStamp < pStream->u64LastTimeStamp + pStream->uDelay)
     1092        if (uTimeStampMs < pStream->uLastTimeStampMs + pStream->uDelay)
    10191093        {
    10201094            rc = VINF_TRY_AGAIN; /* respect maximum frames per second */
     
    10271101        }
    10281102
    1029         pStream->u64LastTimeStamp = u64TimeStamp;
     1103        pStream->uLastTimeStampMs = uTimeStampMs;
    10301104
    10311105        int xDiff = ((int)pStream->uTargetWidth - (int)uSourceWidth) / 2;
     
    11271201        }
    11281202
    1129         pStream->u64TimeStamp = u64TimeStamp;
     1203        pStream->uCurTimeStampMs = uTimeStampMs;
    11301204
    11311205        ASMAtomicWriteBool(&pStream->fRgbFilled, true);
  • trunk/src/VBox/Main/src-client/VideoRec.h

    r65173 r65401  
    3636                          uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBitsPerPixel,
    3737                          uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
    38                           uint8_t *pu8BufferAddress, uint64_t u64TimeStamp);
    39 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStamp);
    40 bool VideoRecIsFull(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStamp);
     38                          uint8_t *pu8BufferAddress, uint64_t u64TimeStampMs);
     39bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStampMs);
     40bool VideoRecLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStampMs);
    4141
    4242#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