VirtualBox

Changeset 88693 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Apr 23, 2021 9:49:34 PM (4 years ago)
Author:
vboxsync
Message:

Audio: Added optional pfnStreamConfigHint methods to PDMIAUDIOCONNECTOR and PDMIHOSTAUDIO so the WASAPI backend can get some useful cache hints to avoid potentially horried EMT blocking when the guest tries to play audio later. This is rather crude, but with typical guest config it helps a lot. bugref:9890

Location:
trunk/src/VBox/Devices/Audio
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevHda.cpp

    r88674 r88693  
    44464446            if (ppDrv)
    44474447                *ppDrv = pDrv;
     4448
     4449            /*
     4450             * While we're here, give the windows backends a hint about our typical playback
     4451             * configuration.
     4452             * Note! If 48000Hz is advertised to the guest, add it here.
     4453             */
     4454            if (   pDrv->pConnector
     4455                && pDrv->pConnector->pfnStreamConfigHint)
     4456            {
     4457                PDMAUDIOSTREAMCFG Cfg;
     4458                RT_ZERO(Cfg);
     4459                Cfg.enmDir                        = PDMAUDIODIR_OUT;
     4460                Cfg.u.enmDst                      = PDMAUDIOPLAYBACKDST_FRONT;
     4461                Cfg.enmLayout                     = PDMAUDIOSTREAMLAYOUT_INTERLEAVED;
     4462                Cfg.Device.cMsSchedulingHint      = 10;
     4463                Cfg.Backend.cFramesPreBuffering   = UINT32_MAX;
     4464                PDMAudioPropsInit(&Cfg.Props, 2, true /*fSigned*/, 2, 44100);
     4465                RTStrPrintf(Cfg.szName, sizeof(Cfg.szName), "output 44.1kHz 2ch S16 (HDA config hint)");
     4466
     4467                pDrv->pConnector->pfnStreamConfigHint(pDrv->pConnector, &Cfg); /* (may trash CfgReq) */
     4468            }
    44484469        }
    44494470        else
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r88666 r88693  
    22682268    AssertPtrNullReturn(pHostDrvAudio->pfnGetDevices, VERR_INVALID_POINTER);
    22692269    AssertPtrNullReturn(pHostDrvAudio->pfnGetStatus, VERR_INVALID_POINTER);
     2270    AssertPtrNullReturn(pHostDrvAudio->pfnStreamConfigHint, VERR_INVALID_POINTER);
    22702271    AssertPtrReturn(pHostDrvAudio->pfnStreamCreate, VERR_INVALID_POINTER);
    22712272    AssertPtrReturn(pHostDrvAudio->pfnStreamDestroy, VERR_INVALID_POINTER);
     
    24502451
    24512452/**
     2453 * Adjusts the request stream configuration, applying our settings.
     2454 *
     2455 * This also does some basic validations.
     2456 *
     2457 * Used by both the stream creation and stream configuration hinting code.
     2458 *
     2459 * @returns VBox status code.
     2460 * @param   pThis       Pointer to the DrvAudio instance data.
     2461 * @param   pCfgReq     The request configuration that should be adjusted.
     2462 * @param   pszName     Stream name to use when logging warnings and errors.
     2463 */
     2464static int drvAudioStreamAdjustConfig(PDRVAUDIO pThis, PPDMAUDIOSTREAMCFG pCfgReq, const char *pszName)
     2465{
     2466    /* Get the right configuration for the stream to be created. */
     2467    PDRVAUDIOCFG pDrvCfg = pCfgReq->enmDir == PDMAUDIODIR_IN ? &pThis->In.Cfg : &pThis->Out.Cfg;
     2468
     2469    /* Fill in the tweakable parameters into the requested host configuration.
     2470     * All parameters in principle can be changed and returned by the backend via the acquired configuration. */
     2471
     2472    /*
     2473     * PCM
     2474     */
     2475    if (PDMAudioPropsSampleSize(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
     2476    {
     2477        PDMAudioPropsSetSampleSize(&pCfgReq->Props, PDMAudioPropsSampleSize(&pDrvCfg->Props));
     2478        LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n",
     2479                 PDMAudioPropsSampleSize(&pCfgReq->Props), pszName));
     2480    }
     2481
     2482    if (pDrvCfg->Props.uHz) /* Anything set via custom extra-data? */
     2483    {
     2484        pCfgReq->Props.uHz = pDrvCfg->Props.uHz;
     2485        LogRel2(("Audio: Using custom Hz rate %RU32 for stream '%s'\n", pCfgReq->Props.uHz, pszName));
     2486    }
     2487
     2488    if (pDrvCfg->uSigned != UINT8_MAX) /* Anything set via custom extra-data? */
     2489    {
     2490        pCfgReq->Props.fSigned = RT_BOOL(pDrvCfg->uSigned);
     2491        LogRel2(("Audio: Using custom %s sample format for stream '%s'\n",
     2492                 pCfgReq->Props.fSigned ? "signed" : "unsigned", pszName));
     2493    }
     2494
     2495    if (pDrvCfg->uSwapEndian != UINT8_MAX) /* Anything set via custom extra-data? */
     2496    {
     2497        pCfgReq->Props.fSwapEndian = RT_BOOL(pDrvCfg->uSwapEndian);
     2498        LogRel2(("Audio: Using custom %s endianess for samples of stream '%s'\n",
     2499                 pCfgReq->Props.fSwapEndian ? "swapped" : "original", pszName));
     2500    }
     2501
     2502    if (PDMAudioPropsChannels(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
     2503    {
     2504        PDMAudioPropsSetChannels(&pCfgReq->Props, PDMAudioPropsChannels(&pDrvCfg->Props));
     2505        LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", PDMAudioPropsChannels(&pDrvCfg->Props), pszName));
     2506    }
     2507
     2508    /* Validate PCM properties. */
     2509    if (!AudioHlpPcmPropsAreValid(&pCfgReq->Props))
     2510    {
     2511        LogRel(("Audio: Invalid custom PCM properties set for stream '%s', cannot create stream\n", pszName));
     2512        return VERR_INVALID_PARAMETER;
     2513    }
     2514
     2515    /*
     2516     * Period size
     2517     */
     2518    const char *pszWhat = "device-specific";
     2519    if (pDrvCfg->uPeriodSizeMs)
     2520    {
     2521        pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPeriodSizeMs);
     2522        pszWhat = "custom";
     2523    }
     2524
     2525    if (!pCfgReq->Backend.cFramesPeriod) /* Set default period size if nothing explicitly is set. */
     2526    {
     2527        pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 150 /*ms*/);
     2528        pszWhat = "default";
     2529    }
     2530
     2531    LogRel2(("Audio: Using %s period size %RU64 ms / %RU32 frames for stream '%s'\n",
     2532             pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod),
     2533             pCfgReq->Backend.cFramesPeriod, pszName));
     2534
     2535    /*
     2536     * Buffer size
     2537     */
     2538    pszWhat = "device-specific";
     2539    if (pDrvCfg->uBufferSizeMs)
     2540    {
     2541        pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uBufferSizeMs);
     2542        pszWhat = "custom";
     2543    }
     2544
     2545    if (!pCfgReq->Backend.cFramesBufferSize) /* Set default buffer size if nothing explicitly is set. */
     2546    {
     2547        pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 300 /*ms*/);
     2548        pszWhat = "default";
     2549    }
     2550
     2551    LogRel2(("Audio: Using %s buffer size %RU64 ms / %RU32 frames for stream '%s'\n",
     2552             pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize),
     2553             pCfgReq->Backend.cFramesBufferSize, pszName));
     2554
     2555    /*
     2556     * Pre-buffering size
     2557     */
     2558    pszWhat = "device-specific";
     2559    if (pDrvCfg->uPreBufSizeMs != UINT32_MAX) /* Anything set via global / per-VM extra-data? */
     2560    {
     2561        pCfgReq->Backend.cFramesPreBuffering = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPreBufSizeMs);
     2562        pszWhat = "custom";
     2563    }
     2564    else /* No, then either use the default or device-specific settings (if any). */
     2565    {
     2566        if (pCfgReq->Backend.cFramesPreBuffering == UINT32_MAX) /* Set default pre-buffering size if nothing explicitly is set. */
     2567        {
     2568            /* Pre-buffer 66% of the buffer. */
     2569            pCfgReq->Backend.cFramesPreBuffering = pCfgReq->Backend.cFramesBufferSize * 2 / 3;
     2570            pszWhat = "default";
     2571        }
     2572    }
     2573
     2574    LogRel2(("Audio: Using %s pre-buffering size %RU64 ms / %RU32 frames for stream '%s'\n",
     2575             pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering),
     2576             pCfgReq->Backend.cFramesPreBuffering, pszName));
     2577
     2578    /*
     2579     * Validate input.
     2580     */
     2581    if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPeriod)
     2582    {
     2583        LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the period size (%RU64ms)\n",
     2584                pszName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize),
     2585                PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod)));
     2586        return VERR_INVALID_PARAMETER;
     2587    }
     2588
     2589    if (   pCfgReq->Backend.cFramesPreBuffering != UINT32_MAX /* Custom pre-buffering set? */
     2590        && pCfgReq->Backend.cFramesPreBuffering)
     2591    {
     2592        if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPreBuffering)
     2593        {
     2594            LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the pre-buffering size (%RU64ms)\n",
     2595                    pszName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering),
     2596                    PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize)));
     2597            return VERR_INVALID_PARAMETER;
     2598        }
     2599    }
     2600
     2601    return VINF_SUCCESS;
     2602}
     2603
     2604/**
    24522605 * Worker for drvAudioStreamInitInternal and drvAudioStreamReInitInternal that
    24532606 * creates the backend (host driver) side of an audio stream.
     
    24732626              ("Stream '%s' already initialized in backend\n", pStreamEx->Core.szName));
    24742627
    2475     /* Get the right configuration for the stream to be created. */
    2476     PDRVAUDIOCFG pDrvCfg = pCfgReq->enmDir == PDMAUDIODIR_IN ? &pThis->In.Cfg : &pThis->Out.Cfg;
    2477 
    2478     /* Fill in the tweakable parameters into the requested host configuration.
    2479      * All parameters in principle can be changed and returned by the backend via the acquired configuration. */
    2480 
    2481     /*
    2482      * PCM
    2483      */
    2484     if (PDMAudioPropsSampleSize(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
    2485     {
    2486         PDMAudioPropsSetSampleSize(&pCfgReq->Props, PDMAudioPropsSampleSize(&pDrvCfg->Props));
    2487         LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n",
    2488                  PDMAudioPropsSampleSize(&pCfgReq->Props), pStreamEx->Core.szName));
    2489     }
    2490 
    2491     if (pDrvCfg->Props.uHz) /* Anything set via custom extra-data? */
    2492     {
    2493         pCfgReq->Props.uHz = pDrvCfg->Props.uHz;
    2494         LogRel2(("Audio: Using custom Hz rate %RU32 for stream '%s'\n", pCfgReq->Props.uHz, pStreamEx->Core.szName));
    2495     }
    2496 
    2497     if (pDrvCfg->uSigned != UINT8_MAX) /* Anything set via custom extra-data? */
    2498     {
    2499         pCfgReq->Props.fSigned = RT_BOOL(pDrvCfg->uSigned);
    2500         LogRel2(("Audio: Using custom %s sample format for stream '%s'\n",
    2501                  pCfgReq->Props.fSigned ? "signed" : "unsigned", pStreamEx->Core.szName));
    2502     }
    2503 
    2504     if (pDrvCfg->uSwapEndian != UINT8_MAX) /* Anything set via custom extra-data? */
    2505     {
    2506         pCfgReq->Props.fSwapEndian = RT_BOOL(pDrvCfg->uSwapEndian);
    2507         LogRel2(("Audio: Using custom %s endianess for samples of stream '%s'\n",
    2508                  pCfgReq->Props.fSwapEndian ? "swapped" : "original", pStreamEx->Core.szName));
    2509     }
    2510 
    2511     if (PDMAudioPropsChannels(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
    2512     {
    2513         PDMAudioPropsSetChannels(&pCfgReq->Props, PDMAudioPropsChannels(&pDrvCfg->Props));
    2514         LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", PDMAudioPropsChannels(&pDrvCfg->Props), pStreamEx->Core.szName));
    2515     }
    2516 
    2517     /* Validate PCM properties. */
    2518     if (!AudioHlpPcmPropsAreValid(&pCfgReq->Props))
    2519     {
    2520         LogRel(("Audio: Invalid custom PCM properties set for stream '%s', cannot create stream\n", pStreamEx->Core.szName));
    2521         return VERR_INVALID_PARAMETER;
    2522     }
    2523 
    2524     /*
    2525      * Period size
    2526      */
    2527     const char *pszWhat = "device-specific";
    2528     if (pDrvCfg->uPeriodSizeMs)
    2529     {
    2530         pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPeriodSizeMs);
    2531         pszWhat = "custom";
    2532     }
    2533 
    2534     if (!pCfgReq->Backend.cFramesPeriod) /* Set default period size if nothing explicitly is set. */
    2535     {
    2536         pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 150 /*ms*/);
    2537         pszWhat = "default";
    2538     }
    2539 
    2540     LogRel2(("Audio: Using %s period size %RU64 ms / %RU32 frames for stream '%s'\n",
    2541              pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod),
    2542              pCfgReq->Backend.cFramesPeriod, pStreamEx->Core.szName));
    2543 
    2544     /*
    2545      * Buffer size
    2546      */
    2547     pszWhat = "device-specific";
    2548     if (pDrvCfg->uBufferSizeMs)
    2549     {
    2550         pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uBufferSizeMs);
    2551         pszWhat = "custom";
    2552     }
    2553 
    2554     if (!pCfgReq->Backend.cFramesBufferSize) /* Set default buffer size if nothing explicitly is set. */
    2555     {
    2556         pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 300 /*ms*/);
    2557         pszWhat = "default";
    2558     }
    2559 
    2560     LogRel2(("Audio: Using %s buffer size %RU64 ms / %RU32 frames for stream '%s'\n",
    2561              pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize),
    2562              pCfgReq->Backend.cFramesBufferSize, pStreamEx->Core.szName));
    2563 
    2564     /*
    2565      * Pre-buffering size
    2566      */
    2567     pszWhat = "device-specific";
    2568     if (pDrvCfg->uPreBufSizeMs != UINT32_MAX) /* Anything set via global / per-VM extra-data? */
    2569     {
    2570         pCfgReq->Backend.cFramesPreBuffering = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPreBufSizeMs);
    2571         pszWhat = "custom";
    2572     }
    2573     else /* No, then either use the default or device-specific settings (if any). */
    2574     {
    2575         if (pCfgReq->Backend.cFramesPreBuffering == UINT32_MAX) /* Set default pre-buffering size if nothing explicitly is set. */
    2576         {
    2577             /* Pre-buffer 66% of the buffer. */
    2578             pCfgReq->Backend.cFramesPreBuffering = pCfgReq->Backend.cFramesBufferSize * 2 / 3;
    2579             pszWhat = "default";
    2580         }
    2581     }
    2582 
    2583     LogRel2(("Audio: Using %s pre-buffering size %RU64 ms / %RU32 frames for stream '%s'\n",
    2584              pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering),
    2585              pCfgReq->Backend.cFramesPreBuffering, pStreamEx->Core.szName));
    2586 
    2587     /*
    2588      * Validate input.
    2589      */
    2590     if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPeriod)
    2591     {
    2592         LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the period size (%RU64ms)\n",
    2593                 pStreamEx->Core.szName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize),
    2594                 PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod)));
    2595         return VERR_INVALID_PARAMETER;
    2596     }
    2597 
    2598     if (   pCfgReq->Backend.cFramesPreBuffering != UINT32_MAX /* Custom pre-buffering set? */
    2599         && pCfgReq->Backend.cFramesPreBuffering)
    2600     {
    2601         if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPreBuffering)
    2602         {
    2603             LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the pre-buffering size (%RU64ms)\n",
    2604                     pStreamEx->Core.szName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering),
    2605                     PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize)));
    2606             return VERR_INVALID_PARAMETER;
    2607         }
    2608     }
     2628    /*
     2629     * Adjust the requested stream config, applying our settings.
     2630     */
     2631    int rc = drvAudioStreamAdjustConfig(pThis, pCfgReq, pStreamEx->Core.szName);
     2632    if (RT_FAILURE(rc))
     2633        return rc;
    26092634
    26102635    /*
     
    26132638     */
    26142639    /** @todo r=bird: This is conveniently not documented in the interface... */
    2615     int rc = PDMAudioStrmCfgCopy(pCfgAcq, pCfgReq);
     2640    rc = PDMAudioStrmCfgCopy(pCfgAcq, pCfgReq);
    26162641    if (RT_FAILURE(rc))
    26172642    {
     
    32313256
    32323257/**
     3258 * @interface_method_impl{PDMIAUDIOCONNECTOR,pfnStreamConfigHint}
     3259 */
     3260static DECLCALLBACK(void) drvAudioStreamConfigHint(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg)
     3261{
     3262    PDRVAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVAUDIO, IAudioConnector);
     3263    AssertReturnVoid(pCfg->enmDir == PDMAUDIODIR_IN || pCfg->enmDir == PDMAUDIODIR_OUT);
     3264
     3265    int rc = RTCritSectEnter(&pThis->CritSect); /** @todo Reconsider the locking for DrvAudio */
     3266    AssertRCReturnVoid(rc);
     3267
     3268    /*
     3269     * Don't do anything unless the backend has a pfnStreamConfigHint method
     3270     * and the direction is currently enabled.
     3271     */
     3272    if (   pThis->pHostDrvAudio
     3273        && pThis->pHostDrvAudio->pfnStreamConfigHint)
     3274    {
     3275        if (pCfg->enmDir == PDMAUDIODIR_OUT ? pThis->Out.fEnabled : pThis->In.fEnabled)
     3276        {
     3277            /*
     3278             * Adjust the configuration (applying out settings) then call the backend driver.
     3279             */
     3280            rc = drvAudioStreamAdjustConfig(pThis, pCfg, pCfg->szName);
     3281            AssertLogRelRC(rc);
     3282            if (RT_SUCCESS(rc))
     3283                pThis->pHostDrvAudio->pfnStreamConfigHint(pThis->pHostDrvAudio, pCfg);
     3284        }
     3285        else
     3286            LogFunc(("Ignoring hint because direction is not currently enabled\n"));
     3287    }
     3288    else
     3289        LogFlowFunc(("Ignoring hint because backend has no pfnStreamConfigHint method.\n"));
     3290
     3291    RTCritSectLeave(&pThis->CritSect);
     3292}
     3293
     3294/**
    32333295 * @interface_method_impl{PDMIAUDIOCONNECTOR,pfnStreamGetReadable}
    32343296 */
     
    40694131    pThis->IAudioConnector.pfnGetConfig         = drvAudioGetConfig;
    40704132    pThis->IAudioConnector.pfnGetStatus         = drvAudioGetStatus;
     4133    pThis->IAudioConnector.pfnStreamConfigHint  = drvAudioStreamConfigHint;
    40714134    pThis->IAudioConnector.pfnStreamCreate      = drvAudioStreamCreate;
    40724135    pThis->IAudioConnector.pfnStreamDestroy     = drvAudioStreamDestroy;
  • trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp

    r88561 r88693  
    230230    /* .pfnGetDevices         =*/ NULL,
    231231    /* .pfnGetStatus          =*/ drvHostNullAudioHA_GetStatus,
     232    /* .pfnStreamConfigHint   =*/ NULL,
    232233    /* .pfnStreamCreate       =*/ drvHostNullAudioHA_StreamCreate,
    233234    /* .pfnStreamDestroy      =*/ drvHostNullAudioHA_StreamDestroy,
  • trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp

    r88691 r88693  
    12781278    RT_NOREF(pInterface, enmDir);
    12791279    return PDMAUDIOBACKENDSTS_RUNNING;
     1280}
     1281
     1282
     1283/**
     1284 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamConfigHint}
     1285 */
     1286static DECLCALLBACK(void) drvHostAudioWasHA_StreamConfigHint(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAMCFG pCfg)
     1287{
     1288    PDRVHOSTAUDIOWAS pThis = RT_FROM_MEMBER(pInterface, DRVHOSTAUDIOWAS, IHostAudio);
     1289    LogFlowFunc(("pCfg=%p\n", pCfg));
     1290
     1291    /*
     1292     * Get the device.
     1293     */
     1294    pThis->pNotifyClient->lockEnter();
     1295    IMMDevice *pIDevice = pCfg->enmDir == PDMAUDIODIR_IN ? pThis->pIDeviceInput : pThis->pIDeviceOutput;
     1296    if (pIDevice)
     1297        pIDevice->AddRef();
     1298    pThis->pNotifyClient->lockLeave();
     1299    if (pIDevice)
     1300    {
     1301        /*
     1302         * Look up the config and put it back.
     1303         */
     1304        PDRVHOSTAUDIOWASCACHEDEVCFG pDevCfg = drvHostAudioWasCacheLookupOrCreate(pThis, pIDevice, pCfg);
     1305        LogFlowFunc(("pDevCfg=%p\n"));
     1306        if (pDevCfg)
     1307            drvHostAudioWasCachePutBack(pThis, pDevCfg);
     1308        pIDevice->Release();
     1309    }
    12801310}
    12811311
     
    23332363    pThis->IHostAudio.pfnGetDevices         = drvHostAudioWasHA_GetDevices;
    23342364    pThis->IHostAudio.pfnGetStatus          = drvHostAudioWasHA_GetStatus;
     2365    pThis->IHostAudio.pfnStreamConfigHint   = drvHostAudioWasHA_StreamConfigHint;
    23352366    pThis->IHostAudio.pfnStreamCreate       = drvHostAudioWasHA_StreamCreate;
    23362367    pThis->IHostAudio.pfnStreamDestroy      = drvHostAudioWasHA_StreamDestroy;
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