VirtualBox

Changeset 68944 in vbox


Ignore:
Timestamp:
Oct 2, 2017 10:59:11 AM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
118211
Message:

VideoRec/Main: Implemented support for attaching + detaching the video recording audio driver on runtime, e.g. only when recording something.

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

Legend:

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

    r68850 r68944  
    139139#endif
    140140#ifdef VBOX_WITH_AUDIO_VIDEOREC
    141     AudioVideoRec *i_audioVideoRecGet() const { return mAudioVideoRec; }
     141    AudioVideoRec *i_getAudioVideoRec() const { return mAudioVideoRec; }
    142142    HRESULT i_audioVideoRecSendAudio(const void *pvData, size_t cbData, uint64_t uDurationMs);
    143143#endif
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r68852 r68944  
    209209
    210210#ifdef VBOX_WITH_VIDEOREC
    211     VIDEORECFEATURES i_videoCaptureGetEnabled(void);
    212     bool i_videoCaptureStarted(void);
    213     int  i_videoCaptureInvalidate(void);
    214     int  i_videoCaptureSendAudio(const void *pvData, size_t cbData, uint64_t uDurationMs);
    215     int  i_videoCaptureStart(void);
    216     void i_videoCaptureStop(void);
    217     void i_videoCaptureScreenChanged(unsigned uScreenId);
     211    PVIDEORECCFG             i_videoCaptureGetConfig(void) { return &mVideoRecCfg; }
     212    VIDEORECFEATURES         i_videoCaptureGetEnabled(void);
     213    bool                     i_videoCaptureStarted(void);
     214    int                      i_videoCaptureConfigureAudioDriver(const Utf8Str& strAdapter, unsigned uInstance, unsigned uLun, bool fAttach);
     215    static DECLCALLBACK(int) i_videoCaptureConfigure(Display *pThis, PVIDEORECCFG pCfg, bool fAttachDetach);
     216    int                      i_videoCaptureSendAudio(const void *pvData, size_t cbData, uint64_t uDurationMs);
     217    int                      i_videoCaptureStart(void);
     218    void                     i_videoCaptureStop(void);
     219    void                     i_videoCaptureScreenChanged(unsigned uScreenId);
    218220#endif
    219221
     
    471473#ifdef VBOX_WITH_VIDEOREC
    472474    /* Serializes access to video capture source bitmaps. */
    473     RTCRITSECT mVideoCaptureLock;
     475    RTCRITSECT           mVideoCaptureLock;
     476    VIDEORECCFG          mVideoRecCfg;
     477    VIDEORECCONTEXT     *mpVideoRecCtx;
     478    bool                 maVideoRecEnabled[SchemaDefs::MaxGuestMonitors];
    474479#endif
    475480
     
    510515#endif
    511516
    512 #ifdef VBOX_WITH_VIDEOREC
    513     VIDEORECCFG          mVideoRecCfg;
    514     VIDEORECCONTEXT     *mpVideoRecCtx;
    515     bool                 maVideoRecEnabled[SchemaDefs::MaxGuestMonitors];
    516 #endif
    517 
    518517private:
    519518    DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(Display); /* Shuts up MSC warning C4625. */
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r68866 r68944  
    49904990        switch (audioController)
    49914991        {
     4992            case AudioControllerType_HDA:  strDevice = "hda";     break;
    49924993            case AudioControllerType_AC97: strDevice = "ichac97"; break;
    49934994            case AudioControllerType_SB16: strDevice = "sb16";    break;
    4994             case AudioControllerType_HDA:  strDevice = "hda";     break;
    49954995            default:                                              break; /* None. */
    49964996        }
     
    55105510        if (mDisplay)
    55115511        {
    5512             int vrc = mDisplay->i_videoCaptureInvalidate();
     5512            Display *pDisplay = mDisplay;
     5513
     5514            /* Release lock because the call scheduled on EMT may also try to take it. */
     5515            alock.release();
     5516
     5517            /*
     5518             * Call worker in EMT, that's faster and safer than doing everything
     5519             * using VM3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
     5520             * here to make requests from under the lock in order to serialize them.
     5521             */
     5522            int vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY /*idDstCpu*/,
     5523                                       (PFNRT)Display::i_videoCaptureConfigure, 3,
     5524                                       pDisplay, pDisplay->i_videoCaptureGetConfig(), true /* fAttachDetach */);
    55135525            if (RT_SUCCESS(vrc))
    55145526            {
    5515 # ifdef VBOX_WITH_AUDIO_VIDEOREC
    5516                 VIDEORECFEATURES fFeatures = mDisplay->i_videoCaptureGetEnabled();
    5517 
    5518                 ComPtr<IAudioAdapter> audioAdapter;
    5519                 rc = mMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
    5520                 AssertComRC(rc);
    5521 
    5522                 Utf8Str strAudioDev = i_getAudioAdapterDeviceName(audioAdapter);
    5523                 if (!strAudioDev.isEmpty()) /* Any audio device enabled? */
    5524                 {
    5525                     for (ULONG ulLUN = 0; ulLUN < 16 /** @todo Use a define */; ulLUN++)
    5526                     {
    5527                         PPDMIBASE pBase;
    5528                         int rc2 = PDMR3QueryDriverOnLun(ptrVM.rawUVM(), strAudioDev.c_str(),
    5529                                                         0 /* iInstance */, ulLUN, "AUDIO", &pBase);
    5530                         if (RT_FAILURE(rc2))
    5531                             continue;
    5532 
    5533                         if (pBase)
    5534                         {
    5535                             PPDMIAUDIOCONNECTOR pAudioCon =
    5536                                  (PPDMIAUDIOCONNECTOR)pBase->pfnQueryInterface(pBase, PDMIAUDIOCONNECTOR_IID);
    5537 
    5538                             if (   pAudioCon
    5539                                 && pAudioCon->pfnEnable)
    5540                             {
    5541                                 rc2 = pAudioCon->pfnEnable(pAudioCon, PDMAUDIODIR_OUT,
    5542                                                            RT_BOOL(fFeatures & VIDEORECFEATURE_AUDIO));
    5543                                 if (RT_FAILURE(rc2))
    5544                                     LogRel(("VideoRec: Failed to %s audio recording (%Rrc)\n",
    5545                                             fFeatures & VIDEORECFEATURE_AUDIO ? "enable" : "disable", rc2));
    5546                             }
    5547 
    5548                             break; /* Driver found, no need to continue. */
    5549                         }
    5550                     }
    5551                 }
    5552 # endif /* VBOX_WITH_AUDIO_VIDEOREC */
     5527                /* Make sure to acquire the lock again after we're done running in EMT. */
     5528                alock.acquire();
    55535529
    55545530                if (!mDisplay->i_videoCaptureStarted())
     
    55695545#endif /* VBOX_WITH_VIDEOREC */
    55705546
    5571     /* notify console callbacks on success */
     5547    /* Notify console callbacks on success. */
    55725548    if (SUCCEEDED(rc))
    55735549    {
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r68938 r68944  
    28072807        if (fAudioEnabled)
    28082808        {
     2809            Utf8Str strAudioDevice;
     2810
    28092811            AudioControllerType_T audioController;
    28102812            hrc = audioAdapter->COMGETTER(AudioController)(&audioController);               H();
    28112813            AudioCodecType_T audioCodec;
    28122814            hrc = audioAdapter->COMGETTER(AudioCodec)(&audioCodec);                         H();
     2815
    28132816            switch (audioController)
    28142817            {
     
    28162819                {
    28172820                    /* ICH AC'97. */
    2818                     InsertConfigNode(pDevices, "ichac97", &pDev);
    2819                     InsertConfigNode(pDev,     "0", &pInst);
    2820                     InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
    2821                     hrc = pBusMgr->assignPCIDevice("ichac97", pInst);                       H();
    2822                     InsertConfigNode(pInst,    "Config", &pCfg);
     2821                    strAudioDevice = "ichac97";
     2822
     2823                    InsertConfigNode   (pDevices, strAudioDevice.c_str(),  &pDev);
     2824                    InsertConfigNode   (pDev,     "0",                     &pInst);
     2825                    InsertConfigInteger(pInst,    "Trusted",               1); /* boolean */
     2826                    hrc = pBusMgr->assignPCIDevice(strAudioDevice.c_str(), pInst);          H();
     2827                    InsertConfigNode   (pInst,    "Config",                &pCfg);
    28232828                    switch (audioCodec)
    28242829                    {
     
    28362841                {
    28372842                    /* Legacy SoundBlaster16. */
    2838                     InsertConfigNode(pDevices, "sb16", &pDev);
    2839                     InsertConfigNode(pDev,     "0", &pInst);
    2840                     InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
    2841                     InsertConfigNode(pInst,    "Config", &pCfg);
    2842                     InsertConfigInteger(pCfg,  "IRQ", 5);
    2843                     InsertConfigInteger(pCfg,  "DMA", 1);
    2844                     InsertConfigInteger(pCfg,  "DMA16", 5);
    2845                     InsertConfigInteger(pCfg,  "Port", 0x220);
    2846                     InsertConfigInteger(pCfg,  "Version", 0x0405);
     2843                    strAudioDevice = "sb16";
     2844
     2845                    InsertConfigNode   (pDevices, strAudioDevice.c_str(), &pDev);
     2846                    InsertConfigNode   (pDev,     "0", &pInst);
     2847                    InsertConfigInteger(pInst,    "Trusted",              1); /* boolean */
     2848                    InsertConfigNode   (pInst,    "Config",               &pCfg);
     2849                    InsertConfigInteger(pCfg,     "IRQ",                  5);
     2850                    InsertConfigInteger(pCfg,     "DMA",                  1);
     2851                    InsertConfigInteger(pCfg,     "DMA16",                5);
     2852                    InsertConfigInteger(pCfg,     "Port",                 0x220);
     2853                    InsertConfigInteger(pCfg,     "Version",              0x0405);
    28472854                    break;
    28482855                }
     
    28502857                {
    28512858                    /* Intel HD Audio. */
    2852                     InsertConfigNode(pDevices, "hda", &pDev);
    2853                     InsertConfigNode(pDev,     "0", &pInst);
    2854                     InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
    2855                     hrc = pBusMgr->assignPCIDevice("hda", pInst);                           H();
    2856                     InsertConfigNode(pInst,    "Config", &pCfg);
     2859                    strAudioDevice = "hda";
     2860
     2861                    InsertConfigNode   (pDevices, strAudioDevice.c_str(),  &pDev);
     2862                    InsertConfigNode   (pDev,     "0",                     &pInst);
     2863                    InsertConfigInteger(pInst,    "Trusted",               1); /* boolean */
     2864                    hrc = pBusMgr->assignPCIDevice(strAudioDevice.c_str(), pInst);          H();
     2865                    InsertConfigNode   (pInst,    "Config",                &pCfg);
    28572866                }
    28582867            }
     
    29923001
    29933002#ifdef VBOX_WITH_AUDIO_VIDEOREC
    2994             /*
    2995              * The video recording audio backend driver.
    2996              * Currently being used with VPX video recording only.
    2997              */
    2998             CFGMR3InsertNodeF(pInst, &pLunL0, "LUN#%RU8", u8AudioLUN++);
    2999             InsertConfigString(pLunL0, "Driver", "AUDIO");
    3000 
    3001             InsertConfigNode(pLunL0,   "Config", &pCfg);
    3002                 InsertConfigString (pCfg, "DriverName",    "AudioVideoRec");
    3003                 InsertConfigInteger(pCfg, "InputEnabled",  fAudioEnabledIn);
    3004                 InsertConfigInteger(pCfg, "OutputEnabled", fAudioEnabledOut);
    3005 
    3006             InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
    3007                 InsertConfigString(pLunL1, "Driver", "AudioVideoRec");
    3008 
    3009                 InsertConfigNode(pLunL1, "Config", &pCfg);
    3010                     InsertConfigString (pCfg, "StreamName",     bstr);
    3011                     InsertConfigInteger(pCfg, "Object",        (uintptr_t)mAudioVideoRec);
    3012                     InsertConfigInteger(pCfg, "ObjectConsole", (uintptr_t)this /* Console */);
     3003            Display *pDisplay = i_getDisplay();
     3004            if (pDisplay)
     3005            {
     3006                /* Note: Don't do any driver attaching (fAttachDetach) here, as this will
     3007                 *       be done automatically as part of the VM startup process. */
     3008                pDisplay->i_videoCaptureConfigure(pDisplay, pDisplay->i_videoCaptureGetConfig(), false /* fAttachDetach */);
     3009            }
    30133010#endif /* VBOX_WITH_AUDIO_VIDEOREC */
    30143011
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r68942 r68944  
    6767#  endif
    6868# endif
     69
     70# include <VBox/vmm/pdmapi.h>
     71# include <VBox/vmm/pdmaudioifs.h>
    6972#endif
    7073
     
    23942397
    23952398#ifdef VBOX_WITH_VIDEOREC
     2399/**
     2400 * Returns the currently enabled video capturing features.
     2401 *
     2402 * @returns Enables video capturing features.
     2403 */
    23962404VIDEORECFEATURES Display::i_videoCaptureGetEnabled(void)
    23972405{
     
    23992407}
    24002408
     2409/**
     2410 * Returns whether video capturing is currently is active or not.
     2411 *
     2412 * @returns True if video capturing is active, false if not.
     2413 */
    24012414bool Display::i_videoCaptureStarted(void)
    24022415{
     
    24042417}
    24052418
    2406 int Display::i_videoCaptureInvalidate(void)
    2407 {
     2419/**
     2420 * Configures the video recording audio driver in CFGM.
     2421 *
     2422 * @returns VBox status code.
     2423 * @param   strDevice           The PDM device name.
     2424 * @param   uInstance           The PDM device instance.
     2425 * @param   uLun                The PDM LUN number of the drive.
     2426 * @param   fAttach             Whether to attach or detach the driver configuration to CFGM.
     2427 *
     2428 * @thread EMT
     2429 */
     2430int Display::i_videoCaptureConfigureAudioDriver(const Utf8Str& strDevice,
     2431                                                unsigned       uInstance,
     2432                                                unsigned       uLun,
     2433                                                bool           fAttach)
     2434{
     2435    if (strDevice.isEmpty()) /* No audio device configured. Bail out. */
     2436        return VINF_SUCCESS;
     2437
    24082438    AssertPtr(mParent);
     2439
    24092440    ComPtr<IMachine> pMachine = mParent->i_machine();
    24102441    Assert(pMachine.isNotNull());
    24112442
    2412     mVideoRecCfg.enmDst = VIDEORECDEST_FILE; /** @todo Make this configurable once we have more variations. */
     2443    Console::SafeVMPtr ptrVM(mParent);
     2444    Assert(ptrVM.isOk());
     2445
     2446    PUVM pUVM = ptrVM.rawUVM();
     2447    AssertPtr(pUVM);
     2448
     2449    PCFGMNODE pRoot   = CFGMR3GetRootU(pUVM);
     2450    AssertPtr(pRoot);
     2451    PCFGMNODE pDev0   = CFGMR3GetChildF(pRoot, "Devices/%s/%u/", strDevice.c_str(), uInstance);
     2452    AssertPtr(pDev0);
     2453
     2454    PCFGMNODE pDevLun = CFGMR3GetChildF(pDev0, "LUN#%u/", uLun);
     2455
     2456    if (fAttach)
     2457    {
     2458        if (!pDevLun)
     2459        {
     2460            LogRel2(("VideoRec: Attaching audio driver\n"));
     2461
     2462            PCFGMNODE pLunL0;
     2463            CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%RU8", uLun);
     2464            CFGMR3InsertString(pLunL0, "Driver", "AUDIO");
     2465
     2466            PCFGMNODE pCfg;
     2467            CFGMR3InsertNode(pLunL0,   "Config", &pCfg);
     2468                CFGMR3InsertString (pCfg, "DriverName",    "AudioVideoRec");
     2469                CFGMR3InsertInteger(pCfg, "InputEnabled",  0);
     2470                CFGMR3InsertInteger(pCfg, "OutputEnabled", 1);
     2471
     2472            PCFGMNODE pLunL1;
     2473            CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1);
     2474                CFGMR3InsertString(pLunL1, "Driver", "AudioVideoRec");
     2475
     2476                CFGMR3InsertNode(pLunL1, "Config", &pCfg);
     2477                    CFGMR3InsertInteger(pCfg, "Object",        (uintptr_t)mParent->i_getAudioVideoRec());
     2478                    CFGMR3InsertInteger(pCfg, "ObjectConsole", (uintptr_t)mParent /* Console */);
     2479        }
     2480    }
     2481    else /* Detach */
     2482    {
     2483        if (pDevLun)
     2484        {
     2485            LogRel2(("VideoRec: Detaching audio driver\n"));
     2486            CFGMR3RemoveNode(pDevLun);
     2487        }
     2488    }
     2489
     2490    return VINF_SUCCESS;
     2491}
     2492
     2493/**
     2494 * Configures video capturing and attaches / detaches the associated driver(s).
     2495 *
     2496 * @returns IPRT status code.
     2497 * @param   pThis               Display instance to configure video capturing for.
     2498 * @param   pCfg                Video capturing configuration to use.
     2499 * @param   fAttachDetach       Whether to attach/detach associated drivers or not.
     2500 */
     2501/* static */
     2502DECLCALLBACK(int) Display::i_videoCaptureConfigure(Display *pThis, PVIDEORECCFG pCfg, bool fAttachDetach)
     2503{
     2504    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2505    AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
     2506
     2507    AssertPtr(pThis->mParent);
     2508    ComPtr<IMachine> pMachine = pThis->mParent->i_machine();
     2509    Assert(pMachine.isNotNull());
     2510
     2511    pCfg->enmDst = VIDEORECDEST_FILE; /** @todo Make this configurable once we have more variations. */
    24132512
    24142513    /*
    2415      * Get parameters from API.
     2514     * Cache parameters from API.
    24162515     */
    2417     BOOL fValue;
    2418     HRESULT rc = pMachine->COMGETTER(VideoCaptureEnabled)(&fValue);
     2516    BOOL fEnabled;
     2517    HRESULT rc = pMachine->COMGETTER(VideoCaptureEnabled)(&fEnabled);
    24192518    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    2420     mVideoRecCfg.fEnabled = RT_BOOL(fValue);
     2519    pCfg->fEnabled = RT_BOOL(fEnabled);
    24212520
    24222521    com::SafeArray<BOOL> aScreens;
     
    24242523    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    24252524
    2426     mVideoRecCfg.aScreens.resize(aScreens.size());
     2525    pCfg->aScreens.resize(aScreens.size());
    24272526    for (size_t i = 0; i < aScreens.size(); ++i)
    2428         mVideoRecCfg.aScreens[i] = aScreens[i];
    2429 
    2430     rc = pMachine->COMGETTER(VideoCaptureWidth)((ULONG *)&mVideoRecCfg.Video.uWidth);
     2527        pCfg->aScreens[i] = aScreens[i];
     2528
     2529    rc = pMachine->COMGETTER(VideoCaptureWidth)((ULONG *)&pCfg->Video.uWidth);
    24312530    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    2432     rc = pMachine->COMGETTER(VideoCaptureHeight)((ULONG *)&mVideoRecCfg.Video.uHeight);
     2531    rc = pMachine->COMGETTER(VideoCaptureHeight)((ULONG *)&pCfg->Video.uHeight);
    24332532    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    2434     rc = pMachine->COMGETTER(VideoCaptureRate)((ULONG *)&mVideoRecCfg.Video.uRate);
     2533    rc = pMachine->COMGETTER(VideoCaptureRate)((ULONG *)&pCfg->Video.uRate);
    24352534    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    2436     rc = pMachine->COMGETTER(VideoCaptureFPS)((ULONG *)&mVideoRecCfg.Video.uFPS);
     2535    rc = pMachine->COMGETTER(VideoCaptureFPS)((ULONG *)&pCfg->Video.uFPS);
    24372536    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    2438     rc = pMachine->COMGETTER(VideoCaptureFile)(&mVideoRecCfg.File.strFile);
     2537    rc = pMachine->COMGETTER(VideoCaptureFile)(&pCfg->File.strFile);
    24392538    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    2440     rc = pMachine->COMGETTER(VideoCaptureMaxFileSize)((ULONG *)&mVideoRecCfg.File.uMaxSizeMB);
     2539    rc = pMachine->COMGETTER(VideoCaptureMaxFileSize)((ULONG *)&pCfg->File.uMaxSizeMB);
    24412540    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    2442     rc = pMachine->COMGETTER(VideoCaptureMaxTime)((ULONG *)&mVideoRecCfg.uMaxTimeS);
     2541    rc = pMachine->COMGETTER(VideoCaptureMaxTime)((ULONG *)&pCfg->uMaxTimeS);
    24432542    AssertComRCReturn(rc, VERR_COM_UNEXPECTED);
    24442543    BSTR bstrOptions;
     
    24472546
    24482547    /*
    2449      * Parse options string (from API).
     2548     * Set sensible defaults.
     2549     */
     2550    pCfg->Video.fEnabled = pCfg->fEnabled;
     2551
     2552    if (!pCfg->Video.uFPS) /* Prevent division by zero. */
     2553        pCfg->Video.uFPS = 15;
     2554
     2555#ifdef VBOX_WITH_LIBVPX
     2556    pCfg->Video.Codec.VPX.uEncoderDeadline = 1000000 / pCfg->Video.uFPS;
     2557#endif
     2558
     2559    /* Note: Audio support is considered as being experimental.
     2560     * There be dragons! */
     2561#ifdef VBOX_WITH_AUDIO_VIDEOREC
     2562    pCfg->Audio.fEnabled  = pCfg->fEnabled;
     2563    /* By default we use 48kHz, 16-bit, stereo for the audio track. */
     2564    pCfg->Audio.uHz       = 48000;
     2565    pCfg->Audio.cBits     = 16;
     2566    pCfg->Audio.cChannels = 2;
     2567#endif
     2568
     2569    /*
     2570     * Parse options string.
    24502571     */
    24512572    com::Utf8Str strOptions(bstrOptions);
    24522573    size_t pos = 0;
    2453 
    2454     /*
    2455      * Set sensible defaults.
    2456      */
    2457     mVideoRecCfg.Video.fEnabled  = true;
    2458 
    2459     if (!mVideoRecCfg.Video.uFPS) /* Prevent division by zero. */
    2460         mVideoRecCfg.Video.uFPS = 15;
    2461 
    2462 #ifdef VBOX_WITH_LIBVPX
    2463     mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = 1000000 / mVideoRecCfg.Video.uFPS;
    2464 #endif
    2465 
    2466     /* Note: Audio support is considered as being experimental.
    2467      * There be dragons! */
    2468 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    2469     mVideoRecCfg.Audio.fEnabled  = true;
    2470     /* By default we use 48kHz, 16-bit, stereo for the audio track. */
    2471     mVideoRecCfg.Audio.uHz       = 48000;
    2472     mVideoRecCfg.Audio.cBits     = 16;
    2473     mVideoRecCfg.Audio.cChannels = 2;
    2474 #endif
    2475 
    2476     /*
    2477      * Parse options string.
    2478      */
    24792574    com::Utf8Str key, value;
    24802575    while ((pos = strOptions.parseKeyValue(key, value, pos)) != com::Utf8Str::npos)
     
    24842579#ifdef VBOX_WITH_LIBVPX
    24852580            if (value.compare("realtime", Utf8Str::CaseInsensitive) == 0)
    2486                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = VPX_DL_REALTIME;
     2581                pCfg->Video.Codec.VPX.uEncoderDeadline = VPX_DL_REALTIME;
    24872582            else if (value.compare("good", Utf8Str::CaseInsensitive) == 0)
    2488                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = 1000000 / mVideoRecCfg.Video.uFPS;
     2583                pCfg->Video.Codec.VPX.uEncoderDeadline = 1000000 / pCfg->Video.uFPS;
    24892584            else if (value.compare("best", Utf8Str::CaseInsensitive) == 0)
    2490                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = VPX_DL_BEST_QUALITY;
     2585                pCfg->Video.Codec.VPX.uEncoderDeadline = VPX_DL_BEST_QUALITY;
    24912586            else
    24922587            {
    24932588                LogRel(("VideoRec: Setting quality deadline to '%s'\n", value.c_str()));
    2494                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = value.toUInt32();
     2589                pCfg->Video.Codec.VPX.uEncoderDeadline = value.toUInt32();
    24952590#endif
    24962591            }
     
    25002595            if (value.compare("false", Utf8Str::CaseInsensitive) == 0)
    25012596            {
    2502                 mVideoRecCfg.Video.fEnabled = false;
     2597                pCfg->Video.fEnabled = false;
     2598#ifdef VBOX_WITH_AUDIO_VIDEOREC
    25032599                LogRel(("VideoRec: Only audio will be recorded\n"));
     2600#endif
    25042601            }
    25052602        }
     
    25092606            if (value.compare("false", Utf8Str::CaseInsensitive) == 0)
    25102607            {
    2511                 mVideoRecCfg.Audio.fEnabled = false;
     2608                pCfg->Audio.fEnabled = false;
    25122609                LogRel(("VideoRec: Only video will be recorded\n"));
    25132610            }
     
    25192616            if (value.compare("low", Utf8Str::CaseInsensitive) == 0)
    25202617            {
    2521                 mVideoRecCfg.Audio.uHz       = 8000;
    2522                 mVideoRecCfg.Audio.cBits     = 16;
    2523                 mVideoRecCfg.Audio.cChannels = 1;
     2618                pCfg->Audio.uHz       = 8000;
     2619                pCfg->Audio.cBits     = 16;
     2620                pCfg->Audio.cChannels = 1;
    25242621            }
    25252622            else if (value.startsWith("med" /* "med[ium]" */, Utf8Str::CaseInsensitive) == 0)
    25262623            {
    2527                 mVideoRecCfg.Audio.uHz       = 22050;
    2528                 mVideoRecCfg.Audio.cBits     = 16;
    2529                 mVideoRecCfg.Audio.cChannels = 2;
     2624                pCfg->Audio.uHz       = 22050;
     2625                pCfg->Audio.cBits     = 16;
     2626                pCfg->Audio.cChannels = 2;
    25302627            }
    25312628            else if (value.compare("high", Utf8Str::CaseInsensitive) == 0)
     
    25402637    } /* while */
    25412638
     2639#ifdef VBOX_WITH_AUDIO_VIDEOREC
     2640    ComPtr<IAudioAdapter> audioAdapter;
     2641    rc = pMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
     2642    AssertComRC(rc);
     2643
     2644    Utf8Str strAudioDev = pThis->mParent->i_getAudioAdapterDeviceName(audioAdapter);
     2645    if (!strAudioDev.isEmpty())
     2646    {
     2647        Console::SafeVMPtr ptrVM(pThis->mParent);
     2648        Assert(ptrVM.isOk());
     2649
     2650        unsigned uInstance = 0;
     2651        unsigned uLun      = 2; /** @todo Make this configurable. */
     2652
     2653        /*
     2654         * Configure + attach audio driver.
     2655         */
     2656        int vrc2 = VINF_SUCCESS;
     2657
     2658        LogFunc(("Audio fAttachDetach=%RTbool, fEnabled=%RTbool\n", fAttachDetach, pCfg->Audio.fEnabled));
     2659
     2660        if (pCfg->Audio.fEnabled) /* Enable */
     2661        {
     2662            vrc2 = pThis->i_videoCaptureConfigureAudioDriver(strAudioDev, uInstance, uLun, true /* fAttach */);
     2663            if (   RT_SUCCESS(vrc2)
     2664                && fAttachDetach)
     2665            {
     2666                vrc2 = PDMR3DriverAttach(ptrVM.rawUVM(), strAudioDev.c_str(), uInstance, uLun, 0 /* fFlags */, NULL /* ppBase */);
     2667            }
     2668
     2669            if (RT_FAILURE(vrc2))
     2670                LogRel(("VideoRec: Failed to attach audio driver, rc=%Rrc\n", vrc2));
     2671        }
     2672        else /* Disable */
     2673        {
     2674            if (fAttachDetach)
     2675                vrc2 = PDMR3DriverDetach(ptrVM.rawUVM(), strAudioDev.c_str(), uInstance, uLun, "AUDIO",
     2676                                         0 /* iOccurance */, 0 /* fFlags */);
     2677
     2678            if (RT_SUCCESS(vrc2))
     2679            {
     2680                vrc2 = pThis->i_videoCaptureConfigureAudioDriver(strAudioDev, uInstance, uLun, false /* fAttach */);
     2681            }
     2682
     2683            if (RT_FAILURE(vrc2))
     2684                LogRel(("VideoRec: Failed to detach audio driver, rc=%Rrc\n", vrc2));
     2685        }
     2686
     2687        AssertRC(vrc2);
     2688    }
     2689    else
     2690        LogRel2(("VideoRec: No audio hardware configured, skipping to record audio\n"));
     2691#endif
     2692
    25422693    /*
    25432694     * Invalidate screens.
    25442695     */
    2545     for (unsigned i = 0; i < mVideoRecCfg.aScreens.size(); i++)
    2546     {
    2547         bool fChanged = maVideoRecEnabled[i] != RT_BOOL(mVideoRecCfg.aScreens[i]);
    2548 
    2549         maVideoRecEnabled[i] = RT_BOOL(mVideoRecCfg.aScreens[i]);
    2550 
    2551         if (fChanged && i < mcMonitors)
    2552             i_videoCaptureScreenChanged(i);
     2696    for (unsigned i = 0; i < pCfg->aScreens.size(); i++)
     2697    {
     2698        bool fChanged = pThis->maVideoRecEnabled[i] != RT_BOOL(pCfg->aScreens[i]);
     2699
     2700        pThis->maVideoRecEnabled[i] = RT_BOOL(pCfg->aScreens[i]);
     2701
     2702        if (fChanged && i < pThis->mcMonitors)
     2703            pThis->i_videoCaptureScreenChanged(i);
    25532704
    25542705    }
     
    26122763
    26132764/**
    2614  * Stop video capturing. Does nothing if video capturing is not active.
     2765 * Stops video capturing. Does nothing if video capturing is not active.
    26152766 */
    26162767void Display::i_videoCaptureStop(void)
     
    45444695
    45454696#ifdef VBOX_WITH_VIDEOREC
    4546     int rc2 = pDisplay->i_videoCaptureInvalidate();
    45474697    if (pDisplay->i_videoCaptureGetEnabled())
    45484698    {
    4549         rc2 = pDisplay->i_videoCaptureStart();
     4699        int rc2 = pDisplay->i_videoCaptureStart();
    45504700        if (RT_SUCCESS(rc2))
    45514701            fireVideoCaptureChangedEvent(pDisplay->mParent->i_getEventSource());
Note: See TracChangeset for help on using the changeset viewer.

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