Changeset 89534 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jun 7, 2021 12:56:21 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
r89532 r89534 162 162 pa_usec_t tsLastReadWrittenUs; 163 163 #endif 164 #ifdef DEBUG165 164 /** Number of occurred audio data underflows. */ 166 165 uint32_t cUnderflows; 167 #endif168 166 /** Pulse sample format and attribute specification. */ 169 167 pa_sample_spec SampleSpec; … … 214 212 /** The name of the output device to use. Empty string for default. */ 215 213 char szOutputDev[256]; 214 215 /** Number of buffer underruns (for all streams). */ 216 STAMCOUNTER StatUnderruns; 217 /** Number of buffer overruns (for all streams). */ 218 STAMCOUNTER StatOverruns; 216 219 } DRVHSTAUDPA; 217 220 … … 800 803 } 801 804 805 806 /** 807 * Underflow notification. 808 */ 809 static void drvHstAudPaStreamUnderflowStatsCallback(pa_stream *pStream, void *pvContext) 810 { 811 PDRVHSTAUDPASTREAM pStreamPA = (PDRVHSTAUDPASTREAM)pvContext; 812 AssertPtrReturnVoid(pStreamPA); 813 AssertPtrReturnVoid(pStreamPA->pDrv); 814 815 /* This may happen when draining/corking, so don't count those. */ 816 if (!pStreamPA->pDrainOp) 817 STAM_REL_COUNTER_INC(&pStreamPA->pDrv->StatUnderruns); 818 819 pStreamPA->cUnderflows++; 820 821 LogRel2(("PulseAudio: Warning: Hit underflow #%RU32%s%s\n", pStreamPA->cUnderflows, 822 pStreamPA->pDrainOp && pa_operation_get_state(pStreamPA->pDrainOp) == PA_OPERATION_RUNNING ? " (draining)" : "", 823 pStreamPA->pCorkOp && pa_operation_get_state(pStreamPA->pCorkOp) == PA_OPERATION_RUNNING ? " (corking)" : "" )); 824 825 if (LogRelIs2Enabled() || LogIs2Enabled()) 826 { 827 pa_usec_t cUsLatency = 0; 828 int fNegative = 0; 829 pa_stream_get_latency(pStream, &cUsLatency, &fNegative); 830 LogRel2(("PulseAudio: Latency now is %'RU64 us\n", cUsLatency)); 831 832 # ifdef LOG_ENABLED 833 if (LogIs2Enabled()) 834 { 835 const pa_timing_info *pTInfo = pa_stream_get_timing_info(pStream); 836 AssertReturnVoid(pTInfo); 837 const pa_sample_spec *pSpec = pa_stream_get_sample_spec(pStream); 838 AssertReturnVoid(pSpec); 839 Log2Func(("writepos=%'RU64 us, readpost=%'RU64 us, age=%'RU64 us, latency=%'RU64 us (%RU32Hz %RU8ch)\n", 840 pa_bytes_to_usec(pTInfo->write_index, pSpec), pa_bytes_to_usec(pTInfo->read_index, pSpec), 841 pa_rtclock_now() - pStreamPA->tsStartUs, cUsLatency, pSpec->rate, pSpec->channels)); 842 } 843 # endif 844 } 845 } 846 847 848 /** 849 * Overflow notification. 850 */ 851 static void drvHstAudPaStreamOverflowStatsCallback(pa_stream *pStream, void *pvContext) 852 { 853 PDRVHSTAUDPASTREAM pStreamPA = (PDRVHSTAUDPASTREAM)pvContext; 854 AssertPtrReturnVoid(pStreamPA); 855 AssertPtrReturnVoid(pStreamPA->pDrv); 856 857 STAM_REL_COUNTER_INC(&pStreamPA->pDrv->StatOverruns); 858 LogRel2(("PulseAudio: Warning: Hit overflow.\n")); 859 RT_NOREF(pStream); 860 } 861 862 802 863 #ifdef DEBUG 803 804 864 /** 805 865 * Debug PA callback: Need data to output. … … 813 873 Log2Func(("Requesting %zu bytes; Latency: %'RU64 us (rcPa=%d n=%d)\n", cbLen, cUsLatency, rcPa, fNegative)); 814 874 } 815 816 817 /**818 * Debug PA callback: Underflow. This may happen when draining/corking.819 */820 static void drvHstAudPaStreamUnderflowDebugCallback(pa_stream *pStream, void *pvContext)821 {822 PDRVHSTAUDPASTREAM pStreamPA = (PDRVHSTAUDPASTREAM)pvContext;823 AssertPtrReturnVoid(pStreamPA);824 825 pStreamPA->cUnderflows++;826 827 LogRel2(("PulseAudio: Warning: Hit underflow #%RU32%s%s\n", pStreamPA->cUnderflows,828 pStreamPA->pDrainOp && pa_operation_get_state(pStreamPA->pDrainOp) == PA_OPERATION_RUNNING ? " (draining)" : "",829 pStreamPA->pCorkOp && pa_operation_get_state(pStreamPA->pCorkOp) == PA_OPERATION_RUNNING ? " (corking)" : "" ));830 831 # if 0 /* bird: It's certifiably insane to make buffer changes here and make DEBUG build behave differently from RELEASE builds. */832 if ( pStreamPA->cUnderflows >= 6 /** @todo Make this check configurable. */833 && pStreamPA->cUsLatency < 2U*RT_US_1SEC)834 {835 pStreamPA->cUsLatency = pStreamPA->cUsLatency * 3 / 2;836 LogRel2(("PulseAudio: Increasing output latency to %'RU64 us\n", pStreamPA->cUsLatency));837 838 pStreamPA->BufAttr.maxlength = pa_usec_to_bytes(pStreamPA->cUsLatency, &pStreamPA->SampleSpec);839 pStreamPA->BufAttr.tlength = pa_usec_to_bytes(pStreamPA->cUsLatency, &pStreamPA->SampleSpec);840 pa_operation *pOperation = pa_stream_set_buffer_attr(pStream, &pStreamPA->BufAttr, NULL, NULL);841 if (pOperation)842 pa_operation_unref(pOperation);843 else844 LogRel2(("pa_stream_set_buffer_attr failed!\n"));845 846 pStreamPA->cUnderflows = 0;847 }848 # endif849 850 pa_usec_t cUsLatency = 0;851 int fNegative = 0;852 pa_stream_get_latency(pStream, &cUsLatency, &fNegative);853 LogRel2(("PulseAudio: Latency now is %'RU64 us\n", cUsLatency));854 855 # ifdef LOG_ENABLED856 if (LogIs2Enabled())857 {858 const pa_timing_info *pTInfo = pa_stream_get_timing_info(pStream);859 AssertReturnVoid(pTInfo);860 const pa_sample_spec *pSpec = pa_stream_get_sample_spec(pStream);861 AssertReturnVoid(pSpec);862 Log2Func(("writepos=%'RU64 us, readpost=%'RU64 us, age=%'RU64 us, latency=%'RU64 us (%RU32Hz %RU8ch)\n",863 pa_bytes_to_usec(pTInfo->write_index, pSpec), pa_bytes_to_usec(pTInfo->read_index, pSpec),864 pa_rtclock_now() - pStreamPA->tsStartUs, cUsLatency, pSpec->rate, pSpec->channels));865 }866 # endif867 }868 869 870 /**871 * Debug PA callback: Overflow. This may happen when draining/corking.872 */873 static void drvHstAudPaStreamOverflowDebugCallback(pa_stream *pStream, void *pvContext)874 {875 RT_NOREF(pStream, pvContext);876 Log2Func(("Warning: Hit overflow\n"));877 }878 879 875 #endif /* DEBUG */ 880 876 … … 1009 1005 * Set the state callback, and in debug builds a few more... 1010 1006 */ 1007 pa_stream_set_state_callback(pStream, drvHstAudPaStreamStateChangedCallback, pThis); 1008 pa_stream_set_underflow_callback(pStream, drvHstAudPaStreamUnderflowStatsCallback, pStreamPA); 1009 pa_stream_set_overflow_callback(pStream, drvHstAudPaStreamOverflowStatsCallback, pStreamPA); 1011 1010 #ifdef DEBUG 1012 pa_stream_set_write_callback( pStream, drvHstAudPaStreamReqWriteDebugCallback, pStreamPA); 1013 pa_stream_set_underflow_callback( pStream, drvHstAudPaStreamUnderflowDebugCallback, pStreamPA); 1014 if (pCfgAcq->enmDir == PDMAUDIODIR_OUT) 1015 pa_stream_set_overflow_callback(pStream, drvHstAudPaStreamOverflowDebugCallback, pStreamPA); 1011 pa_stream_set_write_callback(pStream, drvHstAudPaStreamReqWriteDebugCallback, pStreamPA); 1016 1012 #endif 1017 pa_stream_set_state_callback( pStream, drvHstAudPaStreamStateChangedCallback, pThis);1018 1013 1019 1014 /* … … 2342 2337 RTSemEventDestroy(pThis->InitStateChgCtx.hEvtInit); 2343 2338 pThis->InitStateChgCtx.hEvtInit = NIL_RTSEMEVENT; 2339 2340 /* 2341 * Register statistics. 2342 */ 2343 if (RT_SUCCESS(rc)) 2344 { 2345 PDMDrvHlpSTAMRegister(pDrvIns, &pThis->StatOverruns, STAMTYPE_COUNTER, "Overruns", STAMUNIT_OCCURENCES, 2346 "Pulse-server side buffer overruns (all streams)"); 2347 PDMDrvHlpSTAMRegister(pDrvIns, &pThis->StatUnderruns, STAMTYPE_COUNTER, "Underruns", STAMUNIT_OCCURENCES, 2348 "Pulse-server side buffer underruns (all streams)"); 2349 } 2344 2350 2345 2351 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.