收藏 分享(赏)

浅析DirectShow音视频同步解决完整方案.doc

上传人:scg750829 文档编号:8924854 上传时间:2019-07-17 格式:DOC 页数:3 大小:34.50KB
下载 相关 举报
浅析DirectShow音视频同步解决完整方案.doc_第1页
第1页 / 共3页
浅析DirectShow音视频同步解决完整方案.doc_第2页
第2页 / 共3页
浅析DirectShow音视频同步解决完整方案.doc_第3页
第3页 / 共3页
亲,该文档总共3页,全部预览完了,如果喜欢就下载吧!
资源描述

1、浅析 DirectShow 音视频同步解决完整方案多媒体处理,不可避免地要解决音视频的同步问题。DirectShow 是怎么来实现的呢?我们一起来学习一下。大家知道,DirectShow 结构最核心的部分是 Filter Graph Manager:向下控制 Graph 中的所有 Filter,向上对 贸绦蛱峁 喑探涌凇渲校現 ilter Graph Manager 实现的很重要一个功能,就是同步音视频的处理。简单地说,就是选一个公共的参考时钟,并且要求给每个 Sample 都打上时间戳,Video Renderer 或Audio Renderer 根据 Sample 的时间戳来控制播放。如果

2、到达 Renderer 的 Sample 晚了,则加快 Sample 的播放;如果早了,则 Renderer 等待,一直到 Sample 时间戳的开始时间再开始播放。这个控制过程还引入一个叫 Quality Control 的反馈机制。下面,我们来看一下参考时钟(Reference Clock)。所有 Filter 都参照于同一个时钟,才能统一步调。DirectShow 引入了两种时钟时间:Reference time 和 Stream time。前者是从参考时钟返回的绝对时间(IReferenceClock:GetTime),数值本身的意义取决于参考时钟的内部实现,利用价值不大;后者是两次从

3、参考时钟读取的数值的差值,实际应用于 Filter Graph 内部的同步。Stream time 在 Filter Graph 不同状态的取值为:1. Filter Graph 运行时,取值为当前参考时钟时间减去 Filter Graph 启动时的时间( 启动时间是通过调用Filter 上的 IMediaFilter:Run 来设置的) ;2. Filter Graph 暂停时,保持为暂停那一刻的 Stream time;3. 执行完一次 Seek 操作后,复位至零;4. Filter Graph 停止时,取值不确定。那么,参考时钟究竟是什么东西呢?其实,它只是一个实现了 IReferenc

4、eClock 接口的对象。也就是说,任何一个实现了 IReferenceClock 接口的对象都可以成为参考时钟。在 Filter Graph 中,这个对象一般就是一个 Filter。(在 GraphEdit 中,实现了参考时钟的 Filter 上会显示一个时钟的图标;如果同一个 Graph中有多个 Fiter 实现了参考时钟,当前被 Filter Graph Manager 使用的那个会高亮度显示。 )而且大多数情况下,参考时钟是由 Audio Renderer 这个 Filter 提供的,因为声卡上本身带有了硬件定时器资源。接下来的问题是,如果 Filter Graph 中有多个对象实现了

5、 IReferenceClock 接口,Filter Graph Manager 是如何做出选择的呢?默认的算法如下:1. 如果应用程序设置了一个参考时钟,则直接使用这个参考时钟。(应用程序通过 IMediaFilter: SetSyncSource 设置参考时钟,参数即为参考时钟;如果参数值为 NULL,表示 Filter Graph 不使用参考时钟,以最快的速度处理 Sample;可以调用 IFilterGraph: SetDefaultSyncSource 来恢复 Filter Graph Manager默认的参考时钟。值得注意的是,这时候的 IMediaFilter 接口应该从 Fil

6、ter Graph Manager 上获得,而不是枚举 Graph 中所有的 Filter 并分别调用 Filter 上的这个接口方法。)2. 如果 Graph 中有支持 IReferenceClock 接口的 Live Source,则选择这个 Live Source。3. 如果 Graph 中没有 Live Source,则从 Renderer 依次往上选择一个实现 IReferenceClock 接口的Filter。如果连接着的 Filter 都不能提供参考时钟,则再从没有连接的 Filter 中选择。这一步算法中还有一个优先情况,就是如果 Filter Graph 中含有一个 Audi

7、o Render 的链路,则直接选择 Audio Renderer 这个Filter(原因上面已经提及) 。4. 如果以上方法都找不到一个适合的 Filter,则选取系统参考时钟。(System Reference Clock,通过CoCreateInstance 创建,CLSID 为 CLSID_SystemClock。)我们再来看一下 Sample 的时间戳(Time Stamp)。需要注意的是,每个 Sample 上可以设置两种时间戳:IMediaSample:SetTime 和 IMediaSample:SetMediaTime。我们通常讲到时间戳,一般是指前者,它又叫Presenta

8、tion time,Renderer 正是根据这个时间戳来控制播放;而后者对于 Filter 来说不是必须的,Media time 有没有用取决于你的实现,比如你给每个发出去的 Sample 依次打上递增的序号,在后面的 Filter 接收时就可以判断传输的过程中是否有 Sample 丢失。我们再看一下 IMediaSample:SetTime 的参数,两个参数类型都是 REFERENCE_TIME,千万不要误解这里的时间是 Reference time,其实它们用的是 Stream time。还有一点,就是并不是所有的 Sample 都要求打上时间戳。对于一些压缩数据,时间戳是很难打的,而且

9、意义也不是很大(不过压缩数据经过 Decoder 出来之后到达 Renderer 之前,一般都会打好时间戳了) 。时间戳包括两个时间,开始时间和结束时间。当 Renderer 接收到一个 Sample 时,一般会将 Sample 的开始时间和当前的 Stream time 作比较,如果 Sample 来晚了或者没有时间戳,则马上播放这个 Sample;如果Sample 来得早了,则通过调用参考时钟的 IReferenceClock:AdviseTime 等待 Sample 的开始时间到达后再将这个 Sample 播放。Sample 上的时间戳一般由 Source Filter 或 Parser

10、 Filter 来设置,设置的方法有如下几种情况:1. 文件回放(File playback):第一个 Sample 的时间戳从 0 开始打起,后面 Sample 的时间戳根据Sample 有效数据的长度和回放速率来定。2. 音视频捕捉(Video and audio capture):原则上,采集到的每一个 Sample 的开始时间都打上采集时刻的 Stream time。对于视频帧,Preview pin 出来的 Sample 是个例外,因为如果按上述方法打时间戳的话,每个 Sample 通过 Filter 链路传输,最后到达 Video Renderer 的时候都将是迟到的;Video

11、Renderer 通过Quality Control 反馈给 Source Filter,会导致 Source Filter 丢帧。所以,Preview pin 出来的 Sample 都不打时间戳。对于音频采集,需要注意的是,Audio Capture Filter 与声卡驱动程序两者各自使用了不同的缓存,采集的数据是定时从驱动程序缓存拷贝到 Filter 的缓存的,这里面有一定时间的消耗。3. 合成(Mux Filters):取决于 Mux 后输出的数据类型,可以打时间戳,也可以不打时间戳。大家可以看到,Sample 的时间戳对于保证音视频同步是很重要的。Video Renderer 和 A

12、udio Renderer作为音视频同步的最终执行者,需要做很多工作。我们或许要开发其它各种类型的 Filter,但一般这两个Filter 是不用再开发的。一是因为 Renderer Filter 本身的复杂性,二是因为微软会对这两个 Filter 不断升级,集成 DirectX 中其它模块的最新技术( 如 DirectSound、DirectDraw、Direct3D 等)。最后,我们再来仔细看一下 Live Source 的情况。Live Source 又叫 Push source,包括 Video /Audio Capture Filter、网络广播接收器等。Filter Graph M

13、anager 是如何知道一个 Filter 是 Live Source 的呢?通过如下任何一个条件判断:1. 调用 Filter 上的 IAMFilterMiscFlags:GetMiscFlags 返回有 AM_FILTER_MISC_FLAGS_IS_SOURCE 标记,并且至少有一个 Output pin 实现了 IAMPushSource 接口。2. Filter 实现了 IKsPropertySet 接口,并且有一个 Capture output pin(Pin 的类型为PIN_CATEGORY_CAPTURE)。Live Source 对于音视频同步的影响主要是以下两个方面: La

14、tency 和 Rate Matching。Latency 是指Filter 处理一个 Sample 花费的时间,对于 Live Source 来说,主要取决于使用缓存的大小,比如采集 30fps的视频一般采集完一帧后才将数据以一个 Sample 发送出去,则这个 Filter 的 Latency 为 33ms,而 Audio一般缓存 500ms 后才发送一个 Sample,则它的 Latency 就为 500ms。这样的话,Audio 与 Video 到达Renderer 就会偏差 470ms,造成音视频的不同步。默认情况下, Filter Graph Manager 是不会对这种情况进行调

15、整的。当然,应用程序可以通过 IAMPushSource 接口来进行 Latency 的补偿,方法是调用IAMGraphStreams:SyncUsingStreamOffset 函数。Filter Graph Manager 的实现如下:对所有实现IAMPushSource 接口的 Filter 调用 IAMLatency:GetLatency 得到各个 Source 的 Latency 值,记下所有Latency 值中的最大值,然后调用 IAMPushSource:SetStreamOffset 对各个 Source 设置偏移值。这样,在 Source Filter 产生 Sample 时

16、,打的时间戳就会加上这个偏移量。Rate Matching 问题的引入,主要是由于 Renderer Filter 和 Source Filter 使用的是不同的参考时钟。这种情况下,Renderer 对数据的播放要么太快,要么太慢。另外,一般 Live Source 不能控制输出数据的速率,所以必须在 Renderer 上进行播放速率的匹配。因为人的听觉敏感度要大于视觉敏感度,所以微软目前只在 Audio Renderer 上实现了Rate Matching。实现 Rate Matching 的算法是比较复杂的,这里就不再赘述。看到这里,大家应该对 DirectShow 是如何解决音视频同步问题的方案有一点眉目了吧。深层次的研究,还需要更多的测试、Base class 源码阅读,以及 DirectShow 相关控制机制的理解,比如 Quality Control Management 等。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报