VirtualBox

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


Ignore:
Timestamp:
Aug 18, 2022 7:11:55 AM (2 years ago)
Author:
vboxsync
Message:

Recording/Main: Fixed audio/video sync issues, made timestamp documentation more uniform. bugref:10275

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

Legend:

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

    r96265 r96284  
    282282typedef struct RECORDINGCODECSTATE
    283283{
    284     /** Timestamp (in ms, absolute) of the last frame was encoded. */
     284    /** Timestamp Timestamp (PTS, in ms) of the last frame was encoded. */
    285285    uint64_t            tsLastWrittenMs;
    286286    /** Number of encoding errors. */
     
    389389typedef struct RECORDINGFRAME
    390390{
     391    /** Timestamp (PTS, in ms). */
    391392    uint64_t                msTimestamp;
    392393    union
     
    485486int recordingCodecEncode(PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded);
    486487int recordingCodecFinalize(PRECORDINGCODEC pCodec);
     488uint32_t recordingCodecGetWritable(PRECORDINGCODEC pCodec, uint64_t msTimestamp);
    487489#endif /* !MAIN_INCLUDED_RecordingInternals_h */
    488490
  • trunk/src/VBox/Main/src-client/DrvAudioRec.cpp

    r96262 r96284  
    601601            if (cbSrc == cbFrame) /* Only send full codec frames. */
    602602            {
    603                 vrc = pRecStream->SendAudioFrame(pStreamAV->pvSrcBuf, cbSrc, 0);
     603                vrc = pRecStream->SendAudioFrame(pStreamAV->pvSrcBuf, cbSrc, RTTimeProgramMilliTS());
    604604                if (RT_FAILURE(vrc))
    605605                    break;
  • trunk/src/VBox/Main/src-client/Recording.cpp

    r96283 r96284  
    727727 * @returns @c true if the specified screen is ready, @c false if not.
    728728 * @param   uScreen             Screen ID.
    729  * @param   msTimestamp         Current timestamp (in ms). Currently not being used.
     729 * @param   msTimestamp         Timestamp (PTS, in ms). Currently not being used.
    730730 */
    731731bool RecordingContext::IsReady(uint32_t uScreen, uint64_t msTimestamp)
     
    792792 * @returns true if any limit has been reached.
    793793 * @param   uScreen             Screen ID.
    794  * @param   msTimestamp         Timestamp (in ms) to check for.
     794 * @param   msTimestamp         Timestamp (PTS, in ms) to check for.
    795795 */
    796796bool RecordingContext::IsLimitReached(uint32_t uScreen, uint64_t msTimestamp)
     
    830830
    831831/**
    832  * Sends an audio frame to the video encoding thread.
     832 * Sends an audio frame to the recording thread.
    833833 *
    834834 * @returns VBox status code.
    835835 * @param   pvData              Audio frame data to send.
    836836 * @param   cbData              Size (in bytes) of (encoded) audio frame data.
    837  * @param   msTimestamp         Timestamp (in ms) of audio playback.
     837 * @param   msTimestamp         Timestamp (PTS, in ms) of audio playback.
    838838 */
    839839int RecordingContext::SendAudioFrame(const void *pvData, size_t cbData, uint64_t msTimestamp)
     
    849849
    850850/**
    851  * Copies a source video frame to the intermediate RGB buffer.
    852  * This function is executed only once per time.
     851 * Sends a video frame to the recording thread.
    853852 *
    854853 * @thread  EMT
     
    864863 * @param   uSrcHeight         Height of the video frame.
    865864 * @param   puSrcData          Pointer to video frame data.
    866  * @param   msTimestamp        Timestamp (in ms).
     865 * @param   msTimestamp        Timestamp (PTS, in ms).
    867866 */
    868867int RecordingContext::SendVideoFrame(uint32_t uScreen, uint32_t x, uint32_t y,
  • trunk/src/VBox/Main/src-client/RecordingCodec.cpp

    r96229 r96284  
    4343    AssertPtrReturn(pCodec->pvScratch, VERR_NO_MEMORY);
    4444
     45    pCodec->Parms.csFrame  = 0;
     46    pCodec->Parms.cbFrame  = pCodec->Parms.Video.uWidth * pCodec->Parms.Video.uHeight * 4 /* 32-bit */;
     47    pCodec->Parms.msFrame  = 1; /* 1ms per frame. */
     48
    4549# ifdef VBOX_WITH_LIBVPX_VP9
    4650    vpx_codec_iface_t *pCodecIface = vpx_codec_vp9_cx();
     
    6367    /* Frame height. */
    6468    pVPX->Cfg.g_h = pCodec->Parms.Video.uHeight;
    65     /* 1ms per frame. */
    66     pVPX->Cfg.g_timebase.num = 1;
     69    /* ms per frame. */
     70    pVPX->Cfg.g_timebase.num = pCodec->Parms.msFrame;
    6771    pVPX->Cfg.g_timebase.den = 1000;
    6872    /* Disable multithreading. */
     
    185189                                      * (uint64_t)pCodec->Video.VPX.Cfg.g_timebase.num / pCodec->Video.VPX.Cfg.g_timebase.den;
    186190
    187                 pCodec->State.tsLastWrittenMs += pCodec->Parms.msFrame;
    188 
    189191                const bool fKeyframe = RT_BOOL(pPkt->data.frame.flags & VPX_FRAME_IS_KEY);
    190192
     
    333335                                             RECORDINGCODEC_ENC_F_BLOCK_IS_KEY /* Every Opus frame is a key frame */,
    334336                                             pCodec->Callbacks.pvUser);
    335         if (RT_SUCCESS(vrc))
    336             pCodec->State.tsLastWrittenMs += pCodec->Parms.msFrame;
    337337    }
    338338
     
    509509        }
    510510
    511         uint64_t const uDurationMs = pCodec->Parms.msFrame;
    512 
    513511        /* Vorbis expects us to flush packets one at a time directly to the container.
    514512         *
     
    524522                                                 RECORDINGCODEC_ENC_F_BLOCK_IS_KEY /* Every Vorbis frame is a key frame */,
    525523                                                 pCodec->Callbacks.pvUser);
    526             if (RT_SUCCESS(vrc))
    527                 pCodec->State.tsLastWrittenMs += uDurationMs;
    528524        }
    529525
     
    954950    if (RT_SUCCESS(vrc))
    955951    {
     952        pCodec->State.tsLastWrittenMs = pFrame->msTimestamp;
     953
    956954#ifdef VBOX_WITH_STATISTICS
    957955        pCodec->STAM.cEncBlocks += cEncoded;
     
    980978}
    981979
     980/**
     981 * Returns the number of writable bytes for a given timestamp.
     982 *
     983 * This basically is a helper function to respect the set frames per second (FPS).
     984 *
     985 * @returns Number of writable bytes.
     986 * @param   pCodec              Codec to return number of writable bytes for.
     987 * @param   msTimestamp         Timestamp (PTS, in ms) return number of writable bytes for.
     988 */
     989uint32_t recordingCodecGetWritable(PRECORDINGCODEC pCodec, uint64_t msTimestamp)
     990{
     991    Log3Func(("%RU64 -- tsLastWrittenMs=%RU64 + uDelayMs=%RU32\n",
     992              msTimestamp, pCodec->State.tsLastWrittenMs,pCodec->Parms.Video.uDelayMs));
     993
     994    if (msTimestamp < pCodec->State.tsLastWrittenMs + pCodec->Parms.Video.uDelayMs)
     995        return 0; /* Too early for writing (respect set FPS). */
     996
     997    /* For now we just return the complete frame space. */
     998    AssertMsg(pCodec->Parms.cbFrame, ("Codec not initialized yet\n"));
     999    return pCodec->Parms.cbFrame;
     1000}
     1001
  • trunk/src/VBox/Main/src-client/RecordingStream.cpp

    r96265 r96284  
    175175 * Checks if a specified limit for a recording stream has been reached, internal version.
    176176 *
    177  * @returns true if any limit has been reached.
    178  * @param   msTimestamp     Timestamp (in ms) to check for.
     177 * @returns \c true if any limit has been reached, \c false if not.
     178 * @param   msTimestamp         Timestamp (PTS, in ms) to check for.
    179179 */
    180180bool RecordingStream::isLimitReachedInternal(uint64_t msTimestamp) const
     
    221221 *
    222222 * @returns VBox status code.
    223  * @param   msTimestamp         Current timestamp (in ms).
     223 * @param   msTimestamp         Timestamp (PTS, in ms).
    224224 */
    225225int RecordingStream::iterateInternal(uint64_t msTimestamp)
     
    261261 * Checks if a specified limit for a recording stream has been reached.
    262262 *
    263  * @returns true if any limit has been reached.
    264  * @param   msTimestamp         Timestamp (in ms) to check for.
     263 * @returns \c true if any limit has been reached, \c false if not.
     264 * @param   msTimestamp         Timestamp (PTS, in ms) to check for.
    265265 */
    266266bool RecordingStream::IsLimitReached(uint64_t msTimestamp) const
     
    427427 * @param   pvData              Pointer to audio data.
    428428 * @param   cbData              Size (in bytes) of \a pvData.
    429  * @param   msTimestamp         Absolute PTS timestamp (in ms).
     429 * @param   msTimestamp         Timestamp (PTS, in ms).
    430430 */
    431431int RecordingStream::SendAudioFrame(const void *pvData, size_t cbData, uint64_t msTimestamp)
    432432{
     433    AssertPtrReturn(m_pCtx, VERR_WRONG_ORDER);
     434
     435    Log3Func(("cbData=%zu, msTimestamp=%RU64\n", cbData, msTimestamp));
     436
    433437    /* As audio data is common across all streams, re-route this to the recording context, where
    434438     * the data is being encoded and stored in the common blocks queue. */
     
    450454 * @param   uSrcHeight          Height (in pixels) of the video frame.
    451455 * @param   puSrcData           Actual pixel data of the video frame.
    452  * @param   msTimestamp         Absolute PTS timestamp (in ms).
     456 * @param   msTimestamp         Timestamp (PTS, in ms).
    453457 */
    454458int RecordingStream::SendVideoFrame(uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
     
    457461    lock();
    458462
    459     LogFlowFunc(("tsAbsPTSMs=%RU64\n", msTimestamp));
     463    Log3Func(("[%RU32 %RU32 %RU32 %RU32] msTimestamp=%RU64\n", x , y, uSrcWidth, uSrcHeight, msTimestamp));
    460464
    461465    PRECORDINGCODEC pCodec = &this->CodecVideo;
     
    472476    do
    473477    {
    474         if (msTimestamp < pCodec->State.tsLastWrittenMs + pCodec->Parms.Video.uDelayMs)
    475         {
    476             vrc = VINF_RECORDING_THROTTLED; /* Respect maximum frames per second. */
    477             break;
    478         }
    479 
    480         pCodec->State.tsLastWrittenMs = msTimestamp;
     478        if (recordingCodecGetWritable(pCodec, msTimestamp) == 0)
     479        {
     480            vrc = VINF_RECORDING_THROTTLED; /* Respect maximum frames per second (FPS). */
     481            break;
     482        }
    481483
    482484        int xDiff = ((int)this->ScreenSettings.Video.ulWidth - (int)uSrcWidth) / 2;
     
    671673    unlock();
    672674
     675    LogFlowFuncLeaveRC(vrc);
    673676    return vrc;
    674677}
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