VirtualBox

Changeset 88909 in vbox


Ignore:
Timestamp:
May 6, 2021 4:37:24 PM (4 years ago)
Author:
vboxsync
Message:

AudioMixer: Ignore pfnStreamControl failures and most definitely don't report them to the device (as that will throw a wrench in the works and most likely give us no sound). bugref:9890

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

Legend:

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

    r88907 r88909  
    105105static int audioMixerSinkSetRecSourceInternal(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
    106106
    107 static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl);
     107static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd);
    108108static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pStream, PPDMDEVINS pDevIns);
    109109static int audioMixerStreamUpdateStatus(PAUDMIXSTREAM pMixStream);
     
    484484    AssertPtrReturn(pSink,   VERR_INVALID_POINTER);
    485485    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     486    AssertPtrReturn(pStream->pConn, VERR_AUDIO_STREAM_NOT_READY);
     487    AssertReturn(pStream->pSink == NULL, VERR_ALREADY_EXISTS);
    486488
    487489    int rc = RTCritSectEnter(&pSink->CritSect);
    488490    AssertRCReturn(rc, rc);
     491
    489492    AssertLogRelMsgReturnStmt(pSink->cStreams < UINT8_MAX, ("too many streams!\n"), RTCritSectLeave(&pSink->CritSect),
    490493                              VERR_TOO_MANY_OPEN_FILES);
    491494
    492 
    493     /** @todo Check if stream already is assigned to (another) sink. */
    494 
    495     /* If the sink is running and not in pending disable mode,
    496      * make sure that the added stream also is enabled. */
     495    /*
     496     * If the sink is running and not in pending disable mode, make sure that
     497     * the added stream also is enabled.   Ignore any failure to enable it.
     498     */
    497499    if (    (pSink->fStatus & AUDMIXSINK_STS_RUNNING)
    498500        && !(pSink->fStatus & AUDMIXSINK_STS_PENDING_DISABLE))
    499501    {
    500         rc = audioMixerStreamCtlInternal(pStream, PDMAUDIOSTREAMCMD_ENABLE, AUDMIXSTRMCTL_F_NONE);
    501         if (rc == VERR_AUDIO_STREAM_NOT_READY)
    502             rc = VINF_SUCCESS; /* Not fatal here, stream can become available at some later point in time. */
    503     }
    504 
    505     if (RT_SUCCESS(rc) && pSink->enmDir != AUDMIXSINKDIR_OUTPUT)
     502        audioMixerStreamCtlInternal(pStream, PDMAUDIOSTREAMCMD_ENABLE);
     503    }
     504
     505    if (pSink->enmDir != AUDMIXSINKDIR_OUTPUT)
    506506    {
    507507        /* Apply the sink's combined volume to the stream. */
    508         rc = pStream->pConn->pfnStreamSetVolume(pStream->pConn, pStream->pStream, &pSink->VolumeCombined);
    509         AssertRC(rc);
    510     }
    511 
    512     if (RT_SUCCESS(rc))
    513     {
    514         /* Save pointer to sink the stream is attached to. */
    515         pStream->pSink = pSink;
    516 
    517         /* Append stream to sink's list. */
    518         RTListAppend(&pSink->lstStreams, &pStream->Node);
    519         pSink->cStreams++;
    520     }
     508        int rc2 = pStream->pConn->pfnStreamSetVolume(pStream->pConn, pStream->pStream, &pSink->VolumeCombined);
     509        AssertRC(rc2);
     510    }
     511
     512    /* Save pointer to sink the stream is attached to. */
     513    pStream->pSink = pSink;
     514
     515    /* Append stream to sink's list. */
     516    RTListAppend(&pSink->lstStreams, &pStream->Node);
     517    pSink->cStreams++;
    521518
    522519    LogFlowFunc(("[%s] cStreams=%RU8, rc=%Rrc\n", pSink->pszName, pSink->cStreams, rc));
    523 
    524     int rc2 = RTCritSectLeave(&pSink->CritSect);
    525     AssertRC(rc2);
    526 
     520    RTCritSectLeave(&pSink->CritSect);
    527521    return rc;
    528522}
     
    671665
    672666/**
    673  * Static helper function to translate a sink command
    674  * to a PDM audio stream command.
    675  *
    676  * @returns PDM audio stream command, or PDMAUDIOSTREAMCMD_UNKNOWN if not found.
    677  * @param   enmCmd              Mixer sink command to translate.
    678  */
    679 static PDMAUDIOSTREAMCMD audioMixerSinkToStreamCmd(AUDMIXSINKCMD enmCmd)
    680 {
    681     switch (enmCmd)
    682     {
    683         case AUDMIXSINKCMD_ENABLE:   return PDMAUDIOSTREAMCMD_ENABLE;
    684         case AUDMIXSINKCMD_DISABLE:  return PDMAUDIOSTREAMCMD_DISABLE;
    685         case AUDMIXSINKCMD_PAUSE:    return PDMAUDIOSTREAMCMD_PAUSE;
    686         case AUDMIXSINKCMD_RESUME:   return PDMAUDIOSTREAMCMD_RESUME;
    687         default:                     break;
    688     }
    689 
    690     AssertMsgFailed(("Unsupported sink command %d\n", enmCmd));
    691     return PDMAUDIOSTREAMCMD_INVALID;
    692 }
    693 
    694 /**
    695667 * Controls a mixer sink.
    696668 *
    697669 * @returns VBox status code.
     670 *          Generally always VINF_SUCCESS unless the input is invalid.
     671 *          Individual driver errors are suppressed and ignored.
    698672 * @param   pSink               Mixer sink to control.
    699673 * @param   enmSinkCmd          Sink command to set.
     
    703677    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
    704678
    705     PDMAUDIOSTREAMCMD enmCmdStream = audioMixerSinkToStreamCmd(enmSinkCmd);
    706     if (enmCmdStream == PDMAUDIOSTREAMCMD_INVALID)
    707         return VERR_NOT_SUPPORTED;
     679    /* Only ENABLE/DISABLE is implemented. */
     680    AssertMsgReturn(   enmSinkCmd == AUDMIXSINKCMD_ENABLE
     681                    || enmSinkCmd == AUDMIXSINKCMD_DISABLE,
     682                   ("enmSinkCmd=%d\n", enmSinkCmd),
     683                    VERR_INVALID_FUNCTION);
     684    PDMAUDIOSTREAMCMD const enmCmdStream = enmSinkCmd == AUDMIXSINKCMD_ENABLE
     685                                         ? PDMAUDIOSTREAMCMD_ENABLE : PDMAUDIOSTREAMCMD_DISABLE;
    708686
    709687    int rc = RTCritSectEnter(&pSink->CritSect);
    710     if (RT_FAILURE(rc))
    711         return rc;
    712 
    713     /* Input sink and no recording source set? Bail out early. */
     688    AssertRCReturn(rc, rc);
     689
     690    /*
     691     * Input sink and no recording source set? Return early without updating the stream status...
     692     */
    714693    if (   pSink->enmDir == AUDMIXSINKDIR_INPUT
    715694        && pSink->In.pStreamRecSource == NULL)
    716695    {
    717         int rc2 = RTCritSectLeave(&pSink->CritSect);
    718         AssertRC(rc2);
    719 
    720         return rc;
    721     }
    722 
    723 /** @todo r=bird: There almost serious issue here.  One stupid/buggy audio
    724  *        driver chain will mess up the whole thing.  Either we or DrvAudio
    725  *        need to take note of this and somehow gloss over it...  DevHDA with a
    726  *        linux guest completely freezes up the audio in the guest if we fail
    727  *        here. (Buggy VRDE code, see r144223.) */
    728     PAUDMIXSTREAM pStream;
    729     if (   pSink->enmDir == AUDMIXSINKDIR_INPUT
    730         && pSink->In.pStreamRecSource) /* Any recording source set? */
    731     {
    732         RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node)
    733         {
    734             if (pStream == pSink->In.pStreamRecSource)
     696        /** @todo r=bird: will the cause trouble for the stream status management? */
     697    }
     698    else
     699    {
     700        /*
     701         * Send the command to the streams.
     702         */
     703        if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
     704        {
     705            /** @todo r=bird: we already check this. duh.   */
     706            if (pSink->In.pStreamRecSource) /* Any recording source set? */
    735707            {
    736                 int rc2 = audioMixerStreamCtlInternal(pStream, enmCmdStream, AUDMIXSTRMCTL_F_NONE);
    737                 if (rc2 == VERR_NOT_SUPPORTED)
    738                     rc2 = VINF_SUCCESS;
    739 
    740                 if (RT_SUCCESS(rc))
    741                     rc = rc2;
    742                 /* Keep going. Flag? */
     708                PAUDMIXSTREAM pStream;
     709                RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node)
     710                {
     711                    if (pStream == pSink->In.pStreamRecSource)
     712                    {
     713                        audioMixerStreamCtlInternal(pStream, enmCmdStream);
     714                        break;
     715                    }
     716                }
    743717            }
    744718        }
    745     }
    746     else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)
    747     {
    748         RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node)
    749         {
    750             int rc2 = audioMixerStreamCtlInternal(pStream, enmCmdStream, AUDMIXSTRMCTL_F_NONE);
    751             if (rc2 == VERR_NOT_SUPPORTED)
    752                 rc2 = VINF_SUCCESS;
    753 
    754             if (RT_SUCCESS(rc))
    755                 rc = rc2;
    756             /* Keep going. Flag? */
    757         }
    758     }
    759 
    760     switch (enmSinkCmd)
    761     {
    762         case AUDMIXSINKCMD_ENABLE:
    763         {
    764             /* Make sure to clear any other former flags again by assigning AUDMIXSINK_STS_RUNNING directly. */
    765             pSink->fStatus = AUDMIXSINK_STS_RUNNING;
    766             break;
    767         }
    768 
    769         case AUDMIXSINKCMD_DISABLE:
    770         {
    771             if (pSink->fStatus & AUDMIXSINK_STS_RUNNING)
     719        else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)
     720        {
     721            PAUDMIXSTREAM pStream;
     722            RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node)
    772723            {
    773                 /* Set the sink in a pending disable state first.
    774                  * The final status (disabled) will be set in the sink's iteration. */
    775                 pSink->fStatus |= AUDMIXSINK_STS_PENDING_DISABLE;
     724                audioMixerStreamCtlInternal(pStream, enmCmdStream);
    776725            }
    777             break;
    778         }
    779 
    780         default:
    781             AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
    782             break;
    783     }
    784 
    785 #if defined(RTLOG_REL_ENABLED) || defined(LOG_ENABLED)
     726        }
     727
     728        /*
     729         * Update the sink status.
     730         */
     731        switch (enmSinkCmd)
     732        {
     733            case AUDMIXSINKCMD_ENABLE:
     734                /* Make sure to clear any other former flags again by assigning AUDMIXSINK_STS_RUNNING directly. */
     735                pSink->fStatus = AUDMIXSINK_STS_RUNNING;
     736                break;
     737
     738            case AUDMIXSINKCMD_DISABLE:
     739                if (pSink->fStatus & AUDMIXSINK_STS_RUNNING)
     740                {
     741                    /* Set the sink in a pending disable state first.
     742                     * The final status (disabled) will be set in the sink's iteration. */
     743                    pSink->fStatus |= AUDMIXSINK_STS_PENDING_DISABLE;
     744                }
     745                break;
     746
     747            default:
     748                AssertFailed(/*impossible!*/);
     749        }
     750    }
     751
    786752    char szStatus[AUDIOMIXERSINK_STATUS_STR_MAX];
    787 #endif
    788     LogRel2(("Audio Mixer: Set new status of sink '%s': %s (enmCmd=%RU32 rc=%Rrc)\n",
    789              pSink->pszName, dbgAudioMixerSinkStatusToStr(pSink->fStatus, szStatus), enmSinkCmd, rc));
    790 
    791     int rc2 = RTCritSectLeave(&pSink->CritSect);
    792     AssertRC(rc2);
    793 
    794     return rc;
     753    LogRel2(("Audio Mixer: Set new status of sink '%s': %s (enmCmd=%RU32)\n",
     754             pSink->pszName, dbgAudioMixerSinkStatusToStr(pSink->fStatus, szStatus), enmSinkCmd));
     755
     756    RTCritSectLeave(&pSink->CritSect);
     757    return VINF_SUCCESS;
    795758}
    796759
     
    19631926 * Controls a mixer stream, internal version.
    19641927 *
    1965  * @returns VBox status code.
     1928 * @returns VBox status code (generally ignored).
    19661929 * @param   pMixStream          Mixer stream to control.
    19671930 * @param   enmCmd              Mixer stream command to use.
    1968  * @param   fCtl                Additional control flags. Pass 0.
    1969  */
    1970 static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl)
    1971 {
    1972     AssertPtr(pMixStream->pConn);
    1973     AssertPtr(pMixStream->pStream);
    1974 
    1975     RT_NOREF(fCtl);
     1931 */
     1932static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd)
     1933{
     1934    AssertPtrReturn(pMixStream->pConn, VERR_AUDIO_STREAM_NOT_READY);
     1935    AssertPtrReturn(pMixStream->pStream, VERR_AUDIO_STREAM_NOT_READY);
    19761936
    19771937    int rc = pMixStream->pConn->pfnStreamControl(pMixStream->pConn, pMixStream->pStream, enmCmd);
    19781938
    1979     LogFlowFunc(("[%s] enmCmd=%ld, rc=%Rrc\n", pMixStream->pszName, enmCmd, rc));
     1939    LogFlowFunc(("[%s] enmCmd=%d, rc=%Rrc\n", pMixStream->pszName, enmCmd, rc));
    19801940
    19811941    return rc;
  • trunk/src/VBox/Devices/Audio/AudioMixer.h

    r88907 r88909  
    255255} AUDMIXOP;
    256256
    257 /** No flags specified. */
    258 #define AUDMIXSTRMCTL_F_NONE            0
    259 
    260257/** No mixer flags specified. */
    261258#define AUDMIXER_FLAGS_NONE             0
     
    273270void AudioMixerDebug(PAUDIOMIXER pMixer, PCDBGFINFOHLP pHlp, const char *pszArgs);
    274271
    275 int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
     272int     AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
    276273int     AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg,
    277274                                   AUDMIXSTREAMFLAGS fFlags, PPDMDEVINS pDevIns, PAUDMIXSTREAM *ppStream);
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