为大量视频样本分配IMediaSample

时间:2014-01-28 11:51:41

标签: directshow

我正在为嵌入式系统编写DirectShow视频分配器/分路器滤波器。

在音频中,所有音频样本都具有相同的大小,小~~ 5-8 KB(每个音频样本适合DATA_PACKET_MAX_SIZE),因此我分配了200个DATA_PACKET_MAX_SIZE KB缓冲区,调用RequestAllocator(...)。

在视频中,视频样本的行为不同,范围在100-160,000字节之间!!!

修改 在设置分配器属性之前,我知道分割开始之前MAX样本(视频和音频)的大小,但是从嵌入式系统中保存这么多资源听起来几乎是犯罪行为......

我是否应该按需为每个“大型”视频样本创建特定的IMemAllocator?

我应该创建一些IMemAllocator,保留不同大小缓冲区的池吗?

谢谢, 拉米

2 个答案:

答案 0 :(得分:1)

标准内存分配器的工作方式是设置分配器属性,即固定缓冲区大小和缓冲区计数,然后提交操作员分配实内存,您无法更改它。这种方法存在两个问题:第一种是在开始读取实际数据之前选择缓冲区大小,另一种是如果少量样本需要比其他样本大得多的缓冲区 - 这是典型的时间压缩格式,如H .264 - 那么你需要让所有的缓冲区都很大,你需要分配比你实际需要的更多的内存。

有几种方法可以解决这个问题。

最干净的方法是实现自定义内存分配器,您可以在运行时分配/重新分配缓冲区以满足意外的大型分配。选择内存分配器的是输出引脚,所以你可以安装你的内存分配器,你很高兴。

另一种或多或少安全且一些流行的过滤器使用的方法是在需要更大的缓冲区时在运行时再次提交和提交分配器。也就是说,一旦你在运行时看到你的有效负载不适合缓冲区,你就会解除分配器的响应,更新它的属性,将其恢复并继续,好像什么也没发生过一样。这通常有效但不像第一种方法那样干净。

然后使用许多过滤器,您可以自愿分配非分配器媒体样本并将其传送到下游。这不太安全,这不是它应该在第一时间工作的方式,但是在许多情况下这仍然很好。

答案 1 :(得分:0)

也许这个建议在你的环境中不会出于某种原因,但这里有一个想法:

IMediaSample指针创建两个元素的数组。将两个元素都设置为0.当您第一次需要第一个元素时,请检查NULL并创建IMediaSample的实例,否则只需使用该媒体示例并将其传递给下一个过滤器。第二个相同,循环迭代。请注意,如果某个下游过滤器长时间没有持有ONLY(异步处理等等),这将有效IMediaSmaple。您可以通过检查引用计数来检查(如果是这种情况,您可能会在视频中看到很多伪像)。 惩罚是持有内存的额外帧,但如果你负担得起,则不必为每个新IMediaSample分配内存。

正如我所说,这可能在您的环境中无法使用.....