VirtualBox

Changeset 62323 in vbox for trunk


Ignore:
Timestamp:
Jul 19, 2016 2:32:42 PM (9 years ago)
Author:
vboxsync
Message:

Audio/DrvAudio.cpp: Added some more checking.

File:
1 edited

Legend:

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

    r62297 r62323  
    137137    AssertPtrReturn(pStream, NULL);
    138138
    139     PPDMAUDIOSTREAM pStreamHst = pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST
     139    if (!pStream)
     140        return NULL;
     141
     142    PPDMAUDIOSTREAM pHstStream = pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST
    140143                               ? pStream
    141144                               : pStream->pPair;
    142     if (pStreamHst)
    143     {
    144         Assert(pStreamHst->enmCtx == PDMAUDIOSTREAMCTX_HOST);
     145    if (pHstStream)
     146    {
     147        Assert(pHstStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    145148    }
    146149    else
    147150        LogFlowFunc(("%s: Warning: Does not have a host stream (anymore)\n", pStream->szName));
    148151
    149     return pStreamHst;
     152    return pHstStream;
    150153}
    151154
     
    625628               pStream->szName, pStream->enmDir));
    626629
    627     Log3Func(("[%s]: cbBuf=%RU32\n", pStream->szName, cbBuf));
     630    uint32_t cbWritten = 0;
    628631
    629632    int rc = RTCritSectEnter(&pThis->CritSect);
     
    631634        return rc;
    632635
    633     if (!pThis->pHostDrvAudio->pfnGetStatus(pThis->pHostDrvAudio, PDMAUDIODIR_OUT))
    634     {
    635         rc = RTCritSectLeave(&pThis->CritSect);
    636         AssertRC(rc);
    637 
    638         return VERR_NOT_AVAILABLE;
    639     }
    640 
    641     PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
    642     PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
    643 
    644     AssertMsg(pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED,
    645               ("Writing to disabled guest output stream \"%s\" not possible\n", pGstStream->szName));
    646 
    647     if (!AudioMixBufFreeBytes(&pGstStream->MixBuf))
     636    do
     637    {
     638        if (   pThis->pHostDrvAudio
     639            && pThis->pHostDrvAudio->pfnGetStatus
     640            && pThis->pHostDrvAudio->pfnGetStatus(pThis->pHostDrvAudio, PDMAUDIODIR_OUT) != PDMAUDIOBACKENDSTS_RUNNING)
     641        {
     642            rc = VERR_NOT_AVAILABLE;
     643            break;
     644        }
     645
     646        PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
     647        if (!pHstStream)
     648        {
     649            rc = VERR_NOT_AVAILABLE;
     650            break;
     651        }
     652
     653        PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
     654
     655        AssertMsg(pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED,
     656                  ("Writing to disabled guest output stream \"%s\" not possible\n", pGstStream->szName));
     657
     658        if (!AudioMixBufFreeBytes(&pGstStream->MixBuf))
     659        {
     660            LogRel2(("Audio: Guest stream '%s' full, expect stuttering audio output\n", pGstStream->szName));
     661            break;
     662        }
     663
     664        uint32_t cWritten = 0;
     665        rc = AudioMixBufWriteCirc(&pGstStream->MixBuf, pvBuf, cbBuf, &cWritten);
     666        if (rc == VINF_BUFFER_OVERFLOW)
     667        {
     668            LogRel2(("Audio: Lost audio samples from guest stream '%s', expect stuttering audio output\n", pGstStream->szName));
     669            rc = VINF_SUCCESS;
     670            break;
     671        }
     672
     673        cbWritten = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cWritten);
     674
     675        Log3Func(("[%s] cUsed=%RU32, cLive=%RU32\n",
     676                  pGstStream->szName, AudioMixBufUsed(&pGstStream->MixBuf), AudioMixBufLive(&pGstStream->MixBuf)));
     677
     678    } while (0);
     679
     680    int rc2 = RTCritSectLeave(&pThis->CritSect);
     681    if (RT_SUCCESS(rc))
     682        rc = rc2;
     683
     684    if (RT_SUCCESS(rc))
    648685    {
    649686        if (pcbWritten)
    650             *pcbWritten = 0;
    651 
    652         return RTCritSectLeave(&pThis->CritSect);
    653     }
    654 
    655     uint32_t cWritten = 0;
    656     rc = AudioMixBufWriteCirc(&pGstStream->MixBuf, pvBuf, cbBuf, &cWritten);
    657     if (rc == VINF_BUFFER_OVERFLOW)
    658     {
    659         LogRel2(("Audio: Lost audio samples from guest stream '%s', expect stuttering audio output\n", pGstStream->szName));
    660         rc = VINF_SUCCESS;
    661     }
    662 
    663     if (RT_SUCCESS(rc))
    664     {
    665         if (pcbWritten)
    666             *pcbWritten = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cWritten);
    667     }
    668 
    669     Log3Func(("cWritten=%RU32 (%RU32 bytes), rc=%Rrc\n", cWritten, AUDIOMIXBUF_S2B(&pHstStream->MixBuf, cWritten), rc));
    670 
    671     int rc2 = RTCritSectLeave(&pThis->CritSect);
    672     if (RT_SUCCESS(rc))
    673         rc = rc2;
     687            *pcbWritten = cbWritten;
     688    }
    674689
    675690    return rc;
     
    841856               pStream->szName, pStream->enmDir));
    842857
    843     Log3Func(("[%s]\n", pStream->szName));
    844 
    845858    uint32_t cSamplesPlayed = 0;
    846859
    847860    do
    848861    {
     862        if (!pThis->pHostDrvAudio)
     863        {
     864            rc = VERR_NOT_AVAILABLE;
     865            break;
     866        }
     867
    849868        /* Backend output (temporarily) disabled / unavailable? */
    850         if (pThis->pHostDrvAudio->pfnGetStatus(pThis->pHostDrvAudio, PDMAUDIODIR_OUT) != PDMAUDIOBACKENDSTS_RUNNING)
     869        if (   pThis->pHostDrvAudio->pfnGetStatus
     870            && pThis->pHostDrvAudio->pfnGetStatus(pThis->pHostDrvAudio, PDMAUDIODIR_OUT) != PDMAUDIOBACKENDSTS_RUNNING)
    851871        {
    852872            /* Pull the new config from the backend and check again. */
     
    867887        AssertPtr(pGstStream);
    868888
     889        AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus);
    869890        PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream);
    870891        if (!(strmSts & PDMAUDIOSTRMSTS_FLAG_INITIALIZED))
     
    872893            LogFunc(("[%s] Backend not initialized (anymore), re-initializing ...\n", pHstStream->szName));
    873894            rc = drvAudioStreamReInitInternal(pThis, pStream);
    874             break;
     895            if (RT_FAILURE(rc))
     896            {
     897                LogFunc(("[%s] Failed to re-initialize backend, rc=%Rrc\n", pHstStream->szName, rc));
     898                break;
     899            }
    875900        }
    876901
     
    881906                && (strmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE))
    882907            {
     908                AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay);
    883909                rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed);
    884910                if (RT_FAILURE(rc))
     
    911937    } while (0);
    912938
     939    int rc2 = RTCritSectLeave(&pThis->CritSect);
     940    if (RT_SUCCESS(rc))
     941        rc = rc2;
     942
    913943    if (RT_SUCCESS(rc))
    914944    {
     
    916946            *pcSamplesPlayed = cSamplesPlayed;
    917947    }
    918 
    919     int rc2 = RTCritSectLeave(&pThis->CritSect);
    920     if (RT_SUCCESS(rc))
    921         rc = rc2;
    922948
    923949    if (RT_FAILURE(rc))
     
    12481274    /* pcbWritten is optional. */
    12491275
    1250     int rc = RTCritSectEnter(&pThis->CritSect);
    1251     if (RT_FAILURE(rc))
    1252         return rc;
    1253 
    12541276    AssertMsg(pStream->enmDir == PDMAUDIODIR_IN,
    12551277              ("Stream '%s' is not an input stream and therefore cannot be read from (direction is 0x%x)\n",
    12561278               pStream->szName, pStream->enmDir));
    12571279
    1258     if (pThis->pHostDrvAudio->pfnGetStatus(pThis->pHostDrvAudio, PDMAUDIODIR_IN) != PDMAUDIOBACKENDSTS_RUNNING)
     1280    uint32_t cbRead = 0;
     1281
     1282    int rc = RTCritSectEnter(&pThis->CritSect);
     1283    if (RT_FAILURE(rc))
     1284        return rc;
     1285
     1286    do
     1287    {
     1288        if (   pThis->pHostDrvAudio
     1289            && pThis->pHostDrvAudio->pfnGetStatus
     1290            && pThis->pHostDrvAudio->pfnGetStatus(pThis->pHostDrvAudio, PDMAUDIODIR_IN) != PDMAUDIOBACKENDSTS_RUNNING)
     1291        {
     1292            rc = VERR_NOT_AVAILABLE;
     1293            break;
     1294        }
     1295
     1296        PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
     1297        if (pHstStream)
     1298        {
     1299            rc = VERR_NOT_AVAILABLE;
     1300            break;
     1301        }
     1302
     1303        PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
     1304
     1305        AssertMsg(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED,
     1306                  ("Reading from disabled host input stream '%s' not possible\n", pHstStream->szName));
     1307
     1308        Log3Func(("%s\n", pStream->szName));
     1309
     1310        /*
     1311         * Read from the parent buffer (that is, the guest buffer) which
     1312         * should have the audio data in the format the guest needs.
     1313         */
     1314        uint32_t cRead;
     1315        rc = AudioMixBufReadCirc(&pGstStream->MixBuf, pvBuf, cbBuf, &cRead);
     1316        if (RT_SUCCESS(rc))
     1317        {
     1318            if (cRead)
     1319            {
     1320                AudioMixBufFinish(&pGstStream->MixBuf, cRead);
     1321
     1322                cbRead = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead);
     1323            }
     1324        }
     1325
     1326        Log3Func(("cRead=%RU32 (%RU32 bytes), rc=%Rrc\n", cRead, AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead), rc));
     1327
     1328    } while (0);
     1329
     1330    int rc2 = RTCritSectLeave(&pThis->CritSect);
     1331    if (RT_SUCCESS(rc))
     1332        rc = rc2;
     1333
     1334    if (RT_SUCCESS(rc))
    12591335    {
    12601336        if (pcbRead)
    1261             *pcbRead = 0;
    1262 
    1263         return RTCritSectLeave(&pThis->CritSect);
    1264     }
    1265 
    1266     PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
    1267     PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
    1268 
    1269     AssertMsg(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED,
    1270               ("Reading from disabled host input stream '%s' not possible\n", pHstStream->szName));
    1271 
    1272     Log3Func(("%s\n", pStream->szName));
    1273 
    1274     /*
    1275      * Read from the parent buffer (that is, the guest buffer) which
    1276      * should have the audio data in the format the guest needs.
    1277      */
    1278     uint32_t cRead;
    1279     rc = AudioMixBufReadCirc(&pGstStream->MixBuf, pvBuf, cbBuf, &cRead);
    1280     if (RT_SUCCESS(rc))
    1281     {
    1282         if (cRead)
    1283             AudioMixBufFinish(&pGstStream->MixBuf, cRead);
    1284 
    1285         if (pcbRead)
    1286             *pcbRead = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead);
    1287     }
    1288 
    1289     Log3Func(("cRead=%RU32 (%RU32 bytes), rc=%Rrc\n", cRead, AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead), rc));
    1290 
    1291     int rc2 = RTCritSectLeave(&pThis->CritSect);
    1292     if (RT_SUCCESS(rc))
    1293         rc = rc2;
     1337            *pcbRead = cbRead;
     1338    }
    12941339
    12951340    return rc;
     
    14861531    }
    14871532    else
    1488         AssertFailed();
     1533        AssertFailed();
    14891534
    14901535    int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    16071652    AssertRC(rc2);
    16081653
     1654    PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_NONE;
     1655
    16091656    PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
    1610     PDMAUDIOSTRMSTS strmSts    = pHstStream->fStatus;
    1611 
    1612     Log3Func(("%s: strmSts=0x%x\n", pHstStream->szName, strmSts));
     1657    if (pHstStream)
     1658    {
     1659        strmSts = pHstStream->fStatus;
     1660        Log3Func(("%s: strmSts=0x%x\n", pHstStream->szName, strmSts));
     1661    }
    16131662
    16141663    rc2 = RTCritSectLeave(&pThis->CritSect);
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