VirtualBox

Changeset 68485 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Aug 21, 2017 1:48:12 PM (7 years ago)
Author:
vboxsync
Message:

Audio: Implemented ability to enable / disable audio input / output on-the-fly via API.

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

Legend:

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

    r68468 r68485  
    890890               pStream->szName, pStream->enmDir));
    891891
    892     uint32_t cbWritten = 0;
     892    uint32_t cbWrittenTotal = 0;
    893893
    894894    int rc = RTCritSectEnter(&pThis->CritSect);
     
    907907    do
    908908    {
     909        if (!pThis->Out.fEnabled)
     910        {
     911            cbWrittenTotal = cbBuf;
     912            break;
     913        }
     914
    909915        if (   pThis->pHostDrvAudio
    910916            && pThis->pHostDrvAudio->pfnGetStatus
     
    934940#endif
    935941
    936 #ifdef LOG_ENABLED
    937         AssertMsg(pGstStream->fStatus & PDMAUDIOSTREAMSTS_FLAG_ENABLED,
    938                   ("Writing to disabled guest output stream \"%s\" not possible (status is %s, host status %s)\n",
    939                    pGstStream->szName, pszGstSts, pszHstSts));
    940 #endif
     942        if (!(pGstStream->fStatus & PDMAUDIOSTREAMSTS_FLAG_ENABLED))
     943        {
     944            Log3Func(("[%s] Writing to disabled guest output stream not possible (status is %s, host status %s)\n",
     945                      pGstStream->szName, pszGstSts, pszHstSts));
     946#ifdef DEBUG_andy
     947            AssertFailed();
     948#endif
     949            rc = VERR_NOT_AVAILABLE;
     950            break;
     951        }
     952
    941953        const uint32_t cbFree = AudioMixBufFreeBytes(&pGstStream->MixBuf);
    942954        if (!cbFree) /* No free guest side buffer space, bail out. */
     
    9881000                rc = rc2;
    9891001
    990             cbWritten = AUDIOMIXBUF_F2B(&pGstStream->MixBuf, cfWritten);
     1002            cbWrittenTotal = AUDIOMIXBUF_F2B(&pGstStream->MixBuf, cfWritten);
    9911003
    9921004#ifdef VBOX_WITH_STATISTICS
     
    9941006            Assert(cfWritten >= cfMixed);
    9951007            STAM_COUNTER_ADD(&pThis->Stats.TotalFramesLostOut,       cfWritten - cfMixed);
    996             STAM_COUNTER_ADD(&pThis->Stats.TotalBytesWritten,        cbWritten);
    997             STAM_COUNTER_ADD(&pGstStream->Out.StatBytesTotalWritten, cbWritten);
     1008            STAM_COUNTER_ADD(&pThis->Stats.TotalBytesWritten,        cbWrittenTotal);
     1009            STAM_COUNTER_ADD(&pGstStream->Out.StatBytesTotalWritten, cbWrittenTotal);
    9981010#endif
    9991011        }
     
    10171029    {
    10181030        if (pcbWritten)
    1019             *pcbWritten = cbWritten;
     1031            *pcbWritten = cbWrittenTotal;
    10201032    }
    10211033
     
    22742286
    22752287    PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    2276     LogFlowFunc(("pThis=%p, pDrvIns=%p\n", pThis, pDrvIns));
    22772288
    22782289    int rc = RTCritSectInit(&pThis->CritSect);
    22792290    AssertRCReturn(rc, rc);
    22802291
    2281     /** @todo Add audio driver options. */
     2292    /*
     2293     * Configure driver from CFGM stuff.
     2294     */
     2295#ifdef DEBUG
     2296    CFGMR3Dump(pCfgHandle);
     2297#endif
     2298
     2299    int rc2 = CFGMR3QueryString(pCfgHandle, "DriverName", pThis->szName, sizeof(pThis->szName));
     2300    if (RT_FAILURE(rc2))
     2301        RTStrPrintf(pThis->szName, sizeof(pThis->szName), "Untitled");
     2302
     2303    /* By default we don't enable anything if wrongly / not set-up. */
     2304    pThis->In.fEnabled  = false;
     2305    pThis->Out.fEnabled = false;
     2306
     2307    uint64_t u64Temp;
     2308    rc2 = CFGMR3QueryInteger(pCfgHandle, "InputEnabled",  &u64Temp);
     2309    if (RT_SUCCESS(rc2))
     2310        pThis->In.fEnabled  = RT_BOOL(u64Temp);
     2311
     2312    rc2 = CFGMR3QueryInteger(pCfgHandle, "OutputEnabled", &u64Temp);
     2313    if (RT_SUCCESS(rc2))
     2314        pThis->Out.fEnabled = RT_BOOL(u64Temp);
     2315
     2316    LogRel(("Audio: Initial status for driver '%s': Input is %s, output is %s\n",
     2317            pThis->szName, pThis->In.fEnabled ? "enabled" : "disabled", pThis->Out.fEnabled ? "enabled" : "disabled"));
    22822318
    22832319    /*
     
    23162352    do
    23172353    {
     2354        if (!pThis->In.fEnabled)
     2355        {
     2356            RT_BZERO(pvBuf, cbBuf);
     2357            cbReadTotal = cbBuf;
     2358            break;
     2359        }
     2360
    23182361        if (   pThis->pHostDrvAudio
    23192362            && pThis->pHostDrvAudio->pfnGetStatus
     
    26182661    LogFlowFuncLeaveRC(rc);
    26192662    return rc;
     2663}
     2664
     2665/**
     2666 * @interface_method_impl{PDMIAUDIOCONNECTOR,pfnEnable}
     2667 */
     2668static DECLCALLBACK(int) drvAudioEnable(PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir, bool fEnable)
     2669{
     2670    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     2671
     2672    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2673
     2674    int rc = RTCritSectEnter(&pThis->CritSect);
     2675    if (RT_FAILURE(rc))
     2676        return rc;
     2677
     2678    bool *pfEnabled;
     2679    if (enmDir == PDMAUDIODIR_IN)
     2680        pfEnabled = &pThis->In.fEnabled;
     2681    else if (enmDir == PDMAUDIODIR_OUT)
     2682        pfEnabled = &pThis->Out.fEnabled;
     2683    else
     2684        AssertFailedReturn(VERR_INVALID_PARAMETER);
     2685
     2686    if (fEnable != *pfEnabled)
     2687    {
     2688        PPDMAUDIOSTREAM pStream;
     2689        RTListForEach(&pThis->lstHstStreams, pStream, PDMAUDIOSTREAM, Node)
     2690        {
     2691            if (pStream->enmDir != enmDir) /* Skip unwanted streams. */
     2692                continue;
     2693
     2694            int rc2 = drvAudioStreamControlInternal(pThis, pStream,
     2695                                                    fEnable ? PDMAUDIOSTREAMCMD_ENABLE : PDMAUDIOSTREAMCMD_DISABLE);
     2696            if (RT_FAILURE(rc2))
     2697                LogRel2(("Audio: Failed to %s %s stream, rc=%Rrc\n",
     2698                         fEnable ? "enable" : "disable", enmDir == PDMAUDIODIR_IN ? "input" : "output", rc2));
     2699
     2700            if (RT_SUCCESS(rc))
     2701                rc = rc2;
     2702
     2703            /* Keep going. */
     2704        }
     2705
     2706        *pfEnabled = fEnable;
     2707    }
     2708
     2709    int rc3 = RTCritSectLeave(&pThis->CritSect);
     2710    if (RT_SUCCESS(rc))
     2711        rc = rc3;
     2712
     2713    LogFlowFuncLeaveRC(rc);
     2714    return rc;
     2715}
     2716
     2717/**
     2718 * @interface_method_impl{PDMIAUDIOCONNECTOR,pfnIsEnabled}
     2719 */
     2720static DECLCALLBACK(bool) drvAudioIsEnabled(PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir)
     2721{
     2722    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     2723
     2724    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2725
     2726    int rc2 = RTCritSectEnter(&pThis->CritSect);
     2727    if (RT_FAILURE(rc2))
     2728        return false;
     2729
     2730    bool *pfEnabled;
     2731    if (enmDir == PDMAUDIODIR_IN)
     2732        pfEnabled = &pThis->In.fEnabled;
     2733    else if (enmDir == PDMAUDIODIR_OUT)
     2734        pfEnabled = &pThis->Out.fEnabled;
     2735    else
     2736        AssertFailedReturn(VERR_INVALID_PARAMETER);
     2737
     2738    const bool fIsEnabled = *pfEnabled;
     2739
     2740    rc2 = RTCritSectLeave(&pThis->CritSect);
     2741    AssertRC(rc2);
     2742
     2743    return fIsEnabled;
    26202744}
    26212745
     
    31583282    pDrvIns->IBase.pfnQueryInterface            = drvAudioQueryInterface;
    31593283    /* IAudioConnector. */
     3284    pThis->IAudioConnector.pfnEnable            = drvAudioEnable;
     3285    pThis->IAudioConnector.pfnIsEnabled         = drvAudioIsEnabled;
    31603286    pThis->IAudioConnector.pfnGetConfig         = drvAudioGetConfig;
    31613287    pThis->IAudioConnector.pfnGetStatus         = drvAudioGetStatus;
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r68468 r68485  
    9393typedef struct DRVAUDIO
    9494{
    95     /** Input/output processing thread. */
    96     RTTHREAD                hThread;
     95    /** Friendly name of the driver. */
     96    char                    szName[64];
    9797    /** Critical section for serializing access. */
    9898    RTCRITSECT              CritSect;
     
    130130    DRVAUDIOSTATS           Stats;
    131131#endif
     132    struct
     133    {
     134        /** Whether this driver's input streams are enabled or not.
     135         *  This flag overrides all the attached stream statuses. */
     136        bool                fEnabled;
     137    } In;
     138    struct
     139    {
     140        /** Whether this driver's output streams are enabled or not.
     141         *  This flag overrides all the attached stream statuses. */
     142        bool                fEnabled;
     143    } Out;
    132144} DRVAUDIO, *PDRVAUDIO;
    133145
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