簡體   English   中英

MS Mpeg-2 解復用器過濾器中的緩沖區不足

[英]Buffer starvation inside MS Mpeg-2 Demultiplexer filter

我的捕獲圖快死了。 我已將問題追溯到 Microsoft Mpeg-2 解復用器過濾器內的媒體樣本緩沖區不足。

處理在 CBaseAllocator::GetBuffer 內停止。 池耗盡,線程無限期地休眠等待緩沖區被回收。

0:866> ~~[3038]s
ntdll!NtWaitForSingleObject+0x14:
00007ffe`49199f74 c3              ret
0:094> k
 # Child-SP          RetAddr           Call Site
00 00000035`807fede8 00007ffe`460b9252 ntdll!NtWaitForSingleObject+0x14
01 00000035`807fedf0 00007ffe`22a35f4e KERNELBASE!WaitForSingleObjectEx+0xa2
02 00000035`807fee90 00007ffe`35609460 QUARTZ!CBaseAllocator::GetBuffer+0x7e
03 00000035`807feec0 00007ffe`3560697a mpg2splt!CMediaSampleCopyBuffer::GetCopyBuffer+0x60
04 00000035`807fef60 00007ffe`35606cc9 mpg2splt!CBufferSourceManager::GetNewCopyBuffer+0x3a
05 00000035`807fefa0 00007ffe`356073de mpg2splt!CStreamParser::CopyStream+0x89
06 00000035`807feff0 00007ffe`35608325 mpg2splt!CMpeg2PESStreamParser::ProcessBuffer_+0x15a
07 00000035`807ff040 00007ffe`35610724 mpg2splt!CMpeg2PESStreamParser::ProcessSysBuffer+0x135
08 00000035`807ff090 00007ffe`3560fb2e mpg2splt!CStreamMapContext::Process+0xb4
09 00000035`807ff110 00007ffe`3560f621 mpg2splt!CTransportStreamMapper::ProcessTSPacket_+0x30e
0a 00000035`807ff2d0 00007ffe`355fd0c1 mpg2splt!CTransportStreamMapper::Process+0xf1
0b 00000035`807ff320 00007ffe`355f4eb8 mpg2splt!CMPEG2Controller::ProcessMediaSampleLocked+0x111
0c 00000035`807ff3a0 00007ffe`355f98a7 mpg2splt!CMPEG2Demultiplexer::ProcessMediaSampleLocked+0x7c
0d 00000035`807ff3f0 00007ffd`ba58cba3 mpg2splt!CMPEG2DemuxInputPin::Receive+0x87
0e 00000035`807ff480 00007ffd`ba58ca4d 0x00007ffd`ba58cba3
0f 00000035`807ff530 00007ffd`ba58c92e 0x00007ffd`ba58ca4d
10 00000035`807ff590 00007ffe`19b5222e 0x00007ffd`ba58c92e
11 00000035`807ff5d0 00007ffe`246e5402 clr!UMThunkStub+0x6e
12 00000035`807ff660 00007ffe`2472aa23 qedit!CSampleGrabber::Receive+0x1b2
13 00000035`807ff6d0 00007ffe`287ea6d6 qedit!CTransformInputPin::Receive+0x53
14 00000035`807ff700 00007ffe`287ea459 Obsidian_DSP_DirectShow!MulticastSourceFilter::UDP_consumerThreadProc+0x276 [s:\library\obsidian.dsp.directshow\multicastsourcefilter.cpp @ 475] 
15 00000035`807ff7f0 00007ffe`46f73034 Obsidian_DSP_DirectShow!MulticastSourceFilter::UDP_consumerThreadEntry+0x9 [s:\library\obsidian.dsp.directshow\multicastsourcefilter.cpp @ 445] 
16 00000035`807ff820 00007ffe`49171461 KERNEL32!BaseThreadInitThunk+0x14
17 00000035`807ff850 00000000`00000000 ntdll!RtlUserThreadStart+0x21

以下是有關此特定圖表的一些事實:

  • 源媒體采用高度復用的 MPEG2-TS UDP 流的形式。
  • 該流包含 14 個標清電視節目,消耗 37.5Mbps 的網絡帶寬。
  • 在流變得嚴重碎片化(音頻和視頻解碼器使用IsDiscontinuity() in TRUE發出IsDiscontinuity()樣本IsDiscontinuity()期間,該問題可預見地發生。
  • 根據windbg(和SOS)沒有托管或非托管鎖競爭(沒有死鎖的可能性)。
  • 沒有證據表明“失控”線程(沒有陷入無限循環)。
  • 圖的最終過濾器是 GDCL 橋接盒,然后將解碼的樣本橋接到 MP4 多路復用器盒。
  • 解復用器視頻輸出連接到 ffdshow 解碼器過濾器的實例。 分路器音頻輸出連接到 lav 音頻解碼器過濾器的實例。

我懷疑問題可能出在 ffdshow 或 lav 過濾器內部是否正確? (還有誰可以持有多路分配器緩沖區?)

關於如何跟蹤分路器內的緩沖池為何耗盡的任何指示或建議?

看起來某些引腳連接上的內存分配器在用戶中具有外部引用的所有緩沖區,因此它睡着了,等待新緩沖區返回以進行回收。

這是預期的行為,問題是緩沖區太少或引用過多。

您似乎能夠使用調用堆棧識別引腳連接,並且您可以增加緩沖區的數量或提供按需擴展的自定義內存分配器。

最簡單的方法是當您的過濾器是連接的一部分時,您可以在協商階段通過提供分配器要求或直接更新分配器屬性來影響分配器。 在更復雜的情況下,您可以在激活之前找到現有連接並更改屬性。 在更復雜的情況下,您可以將 no-op 過濾器插入處理鏈,只是為了介於兩者之間並直接訪問有效的分配器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM