VirtualBox

Opened 4 years ago

Last modified 4 years ago

#19834 new defect

VM slow down when video recording enabled

Reported by: gim Owned by:
Component: other Version: VirtualBox 6.1.10
Keywords: video, recording, slow Cc:
Guest type: Linux Host type: all

Description

To reproduce bug you can try create VM with one core and start it with and without video recording. With video recording enabled you must see some slow down of working VM.

This happens because of slow working vpx_codec_encode call under lock inside RecordingStream::Process:

https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Main/src-client/RecordingStream.cpp#L373

int RecordingStream::Process(RecordingBlockMap &mapBlocksCommon)
{
    LogFlowFuncEnter();

    lock();

    ...
                    rc2 = writeVideoVPX(msTimestamp, pVideoFrame);
    ...

    unlock();

    LogFlowFuncLeaveRC(rc);
    return rc;
}

And writeVideoVPX calls vpx_codec_encode: https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Main/src-client/RecordingStream.cpp#L1161

vpx_codec_err_t rcv = vpx_codec_encode(&pCodec->VPX.Ctx,
                                           &pCodec->VPX.RawImage,
                                           pts                          /* Timestamp */,
                                           this->Video.uDelayMs         /* How long to show this frame */,
                                           0                            /* Flags */,
                                           pCodec->VPX.uEncoderDeadline /* Quality setting */);

In fact vpx_codec_encode working slow beacuse of last parameter "deadline" by default is zero (which means infinite deadline for encoding)

Interesting part is that in 5.x virtualbox branch there was a code which fill the default value of uEncoderDeadline but this code not present in 6.0/6.1 branches...

/**
 * Invalidates the video recording configuration.
 */
void Display::i_videoRecInvalidate(void)
{
    AssertPtr(mParent);
    ComPtr<IMachine> pMachine = mParent->i_machine();
    Assert(pMachine.isNotNull());

    mVideoRecCfg.enmDst = VIDEORECDEST_FILE; /** @todo Make this configurable once we have more variations. */

    /*
     * Cache parameters from API.
     */
    com::SafeArray<BOOL> aScreens;
    HRESULT hrc = pMachine->COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(aScreens));
    AssertComRCReturnVoid(hrc);

    mVideoRecCfg.aScreens.resize(aScreens.size());
    for (size_t i = 0; i < aScreens.size(); ++i)
        mVideoRecCfg.aScreens[i] = aScreens[i];

    hrc = pMachine->COMGETTER(VideoCaptureWidth)((ULONG *)&mVideoRecCfg.Video.uWidth);
    AssertComRCReturnVoid(hrc);
    hrc = pMachine->COMGETTER(VideoCaptureHeight)((ULONG *)&mVideoRecCfg.Video.uHeight);
    AssertComRCReturnVoid(hrc);
    hrc = pMachine->COMGETTER(VideoCaptureRate)((ULONG *)&mVideoRecCfg.Video.uRate);
    AssertComRCReturnVoid(hrc);
    hrc = pMachine->COMGETTER(VideoCaptureFPS)((ULONG *)&mVideoRecCfg.Video.uFPS);
    AssertComRCReturnVoid(hrc);
    hrc = pMachine->COMGETTER(VideoCaptureFile)(mVideoRecCfg.File.strName.asOutParam());
    AssertComRCReturnVoid(hrc);
    hrc = pMachine->COMGETTER(VideoCaptureMaxFileSize)((ULONG *)&mVideoRecCfg.File.uMaxSizeMB);
    AssertComRCReturnVoid(hrc);
    hrc = pMachine->COMGETTER(VideoCaptureMaxTime)((ULONG *)&mVideoRecCfg.uMaxTimeS);
    AssertComRCReturnVoid(hrc);
    BSTR bstrOptions;
    hrc = pMachine->COMGETTER(VideoCaptureOptions)(&bstrOptions);
    AssertComRCReturnVoid(hrc);

    /*
     * Set sensible defaults.
     */
    mVideoRecCfg.Video.fEnabled = true; /* Enabled by default. */

    if (!mVideoRecCfg.Video.uFPS) /* Prevent division by zero. */
        mVideoRecCfg.Video.uFPS = 15;

#ifdef VBOX_WITH_LIBVPX
    mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = 1000000 / mVideoRecCfg.Video.uFPS;
#endif

#ifdef VBOX_WITH_AUDIO_VIDEOREC
    mVideoRecCfg.Audio.fEnabled  = false; /* Disabled by default, unless set otherwise below. */
    /* By default we use 48kHz, 16-bit, stereo for the audio track. */
    mVideoRecCfg.Audio.uHz       = 48000;
    mVideoRecCfg.Audio.cBits     = 16;
    mVideoRecCfg.Audio.cChannels = 2;
#endif

Here is:

mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = 1000000 / mVideoRecCfg.Video.uFPS;

Change History (1)

comment:1 by gim, 4 years ago

Actually this problem exists more than one year probably: https://forums.virtualbox.org/viewtopic.php?f=1&t=93307

Note: See TracTickets for help on using tickets.

© 2023 Oracle
ContactPrivacy policyTerms of Use