DirectShow数据流
本节介绍DirectShow的数据的工作方式进行介绍。
通过滤器之间数据交互一节可知,数据是存在buffer中的。而每个buffer都由一个名为media sample的COM对象包装,该对象实现了IMediaSample接口。Sample由另一种类型的对象(称为分配器)创建的,它由IMemAllocator接口实现。每个管脚(Pin)连接分配一个分配器,但多个管脚之间可以共享同一个分配器(allocator )。
media sample由IMemAllocator接口创建,每个media sample代表一个IMediaSample接口,其含有一个指向实际内存数据的指针。
分配器使用 IMemAllocator::GetBuffer函数来分配一个sample。如果当前分配器有空闲的sample则立即返回,如果当前分配器没有空余的sample,则阻塞直到有一个可用的sample。当返回一个可用的sample时,过滤器填充相关的数据并设置相关的标识(如时间戳),然后投递数据到下游过滤器。
当render过滤器接收到sample时,它会检查时间戳并保留sample,直到过滤器图的参考时钟指示应该render数据为止。过滤器render数据后,将释放sample。在sample的引用计数为零之前,sample不会返回分配器的sample池,这意味着每个过滤器都必须已释放了sample方可回收。下图说明了此过程。
前面的图只显示了一个分配器,但是每个流通常有几个分配器。因此,当渲染器释放一个sample时,它可以产生级联效果。下图显示了解码器在等待呈现器释放sample时保持压缩视频帧的情况。解析器过滤器也在等待解码器释放sample。