MS Mpeg-2解复用器过滤器内部的缓冲区不足 [英] Buffer starvation inside MS Mpeg-2 Demultiplexer filter

查看:129
本文介绍了MS Mpeg-2解复用器过滤器内部的缓冲区不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的捕获图快死了.我已将问题归结为Microsoft Mpeg-2多路分解器过滤器中的媒体样本缓冲区不足.

My capture graph is dying. I have traced the problem to a media-sample buffer starvation inside the Microsoft Mpeg-2 Demultiplexer filter.

处理在CBaseAllocator :: GetBuffer内部停止.池已用完,线程会无限期地睡眠,等待缓冲区被回收.

Processing stops inside CBaseAllocator::GetBuffer. The pool is exhausted and the thread sleeps waiting indefinitely for a buffer to be recycled.

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

以下是有关此特定图形的一些事实:

Here are a few facts about this particular graph:

  • 源媒体采用高度复用的MPEG2-TS UDP的形式 溪流.
  • 此流包含14个SD电视节目,消耗37.5Mbps的 网络带宽.
  • 该问题可以预测地发生 流变得严重分散的地方(音频和视频解码器 用TRUE中的IsDiscontinuity()发出一连串的采样.
  • 根据windbg(和SOS),没有争用的托管或非托管锁(不可能发生死锁).
  • 没有证据表明失控" 线程(不卡在无限循环中).
  • 图形的最终过滤器是 GDCL桥接器,然后将解码的样本桥接到MP4多路复用器 盒子.
  • 解复用器视频输出连接到ffdshow实例 解码器过滤器.解复用器音频输出连接到实例 lav音频解码器过滤器.
  • The source media is in the form of a heavily multiplexed MPEG2-TS UDP stream.
  • This stream contains 14 SD TV programs, consuming 37.5Mbps of network bandwidth.
  • The problem occurs predictably during periods where the stream becomes heavily fragmented (the audio and video decoders emit a burst of samples with IsDiscontinuity() in TRUE.
  • According to windbg (and SOS) There are No managed or unmanaged locks contended (no possibility of a deadlock).
  • There is no evidence of a "runaway" thread (not stuck on an infinite loop).
  • The graph's final filter is a GDCL bridge box, that then bridges the decoded sample to an MP4 muxer box.
  • The demuxer video output is connected to an instance of ffdshow decoder filter. The demuxer audio output is connected to an instance of lav audio decoder filter.

我是否可以怀疑问题可能在ffdshow或lav过滤器内部? (还有谁可以持有解复用器缓冲区?)

Am I right to suspect the problem could be inside either the ffdshow or the lav filter? (who else could be holding demuxer buffers?)

关于如何跟踪解复用器内部缓冲池耗尽的任何指示或建议?

推荐答案

看起来某些引脚连接上的内存分配器在用户中具有带有外部引用的所有缓冲区,因此它睡着了,等待返回新的缓冲区以进行回收.

It looks like memory allocator on certain pin connection has all buffers in user with external references, and so it fell asleep waiting for new buffer to be returned for recycling.

这是预期的行为,问题是缓冲区太少或引用过多.

This is expected behavior, and the problem is either too few buffers or excessive referencing.

您似乎能够使用调用堆栈识别引脚连接,并且可以增加缓冲区数量或提供自定义内存分配器,该分配器可以按需扩展.

You seem to be able to identify pin connection using call stack, and you could either increase amount of buffers or provide a custom memory allocator which expands on demand.

最简单的情况是,当您的过滤器是连接的一部分时,您可以在协商阶段通过提供分配器要求或直接更新分配器属性来影响分配器.在更复杂的情况下,您可以在激活之前找到现有连接并更改属性.甚至更复杂的是,您可以将无操作过滤器插入处理链中,只是为了介于两者之间并直接访问有效分配器.

The easiest is when it's your filter is a part of the connection, and you can affect allocator during negotiation phase by either providing allocator requirements or directly updating the allocator properties. In more complicated cases you could locate existing connection and change properties before going active. In even more complicated you could insert your no-op filter into processing chain just for the purpose of getting in between and having direct access to effective allocator.

这篇关于MS Mpeg-2解复用器过滤器内部的缓冲区不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆