Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16498977
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:30:58

下载本文示例代码
  摘要:本篇文档简单介绍了DirectShow中用来标记数据同步的时钟。   在 Filter Graph中,数据流就是依靠时钟来进行同步的,数据流中的每一个sample上都会标记一个时间戳,Video Renderer和Audio Renderer就根据sample上的时间戳来控制sample所携带的数据流的提交。如果到达Renderer的sample的时间比它携带的时间戳晚,则加快sample的播放,或者丢弃这个sample里的内容,如果sample上的时间戳的时间还未到,则sample要等待,一直等到sample时间戳的开始时间再开始播放。   下面我们先看看参考时钟。   参考时钟   参考时钟是Filter用来同步Filter 图表管理器中的所有的Filter的。   任何一个引出IReferenceClock 接口的对象都可以作为参考时钟。参考时钟可以是Filter提供(例如声卡就可以提供一个硬件的时钟),当然,可靠的时钟就是采用系统的时间。   名义上,参考时钟的精确度在100纳秒,但实际上,没有那么精确。调用IReferenceClock::GetTime可以获取时钟的当前时间。   尽管时钟的精确性还有所变动,但是GetTime方法返回的保证时间是增加的。也就是说,时钟不会倒退回去,比如,对硬件时钟进行了调整,GetTime方法就返回上次的时间。   如果Filter Graph中有多个对象实现了IReferenceClock接口,Filter Graph Manager是如何做出选择的呢?默认的算法如下:   当Graph运行的时候,Filter图表管理器会自动选择一个参考时钟的,选择时钟的法则如下   1、如果应用程序选择了时钟,就采用应用程序选择的时钟   2、如果Graph包含一个活动的源Filter(Live Source),并且这个filter有IReferenceClock接口,那么就用这个时钟。   3、如果Graph中不含有任何活动的源Filter,就选用graph中任何暴露IReferenceClock接口的Filter,选择的方法是从Renderers逆流向上,连接的filter优先,没有连接的filter次之。   4、如果没有任何filter符合条件,就采用系统参考时钟System Reference Clock   设置参考时钟   如果你想为graph设置新的时钟,应用程序可以调用图表管理器的接口IMediaFilter::SetSyncSource方法来选择一个参考时钟。   如果你给SetSyncSource传递的参数为NULL,Graph就不设置任何的参考时钟了。如果想恢复缺省的时钟,调用IFilterGraph::SetDefaultSyncSource方法。   当graph的参考时钟改变时,Graph通过the reference clock changes, the Filter Graph Manager notifies each filter by calling its IMediaFilter::SetSyncSource通知所有的Filter。   Clock Times   Directshow定义了两个相关的时间,参考时间Reference time和 数据流时间Stream time   前者是从参考时钟返回的绝对时间(IReferenceClock::GetTime),数值本身的意义取决于参考时钟的内部实现,利用价值不大;后者是两次从参考时钟读取的数值的差值,实际应用于Filter Graph内部的同步   当Filter graph正在运行,流时间的值为当前参考时钟时间减去Filter Graph启动的时间,也就是一个差值,当Filter graph暂停,流时间就等于它暂停时的stream时间,当Filter graph停止时,流时间不确定。   当一个sample具有时间戳t,就意味着这个sample应该在流时间t播放,因此,流时间也叫播放时间。   当应用程序通过IMediaControl::Run来运行graph时,在graph内部也调用了IMediaFilter::Run   时间戳   时间戳采用的是流时间,它在sample标上开始和结束时间。时间戳也叫播放时间,通过后面的知识你会了解到,并不是所有格式的数据流都采用同一种样式的时间戳。   当renderer Filter接收到sample,它会根据sample的时间戳进行排序,等到该sample的播放时间到了,就开始播放该sample,从到达到开始播放的时间,可以通过IReferenceClock::AdviseTime获得。如果sample来晚了,或者sample没有时间戳,filter就立即播放sample。如果Sample来得早了,则通过调用参考时钟的IReferenceClock::AdviseTime等待Sample的开始时间到达后再将这个Sample播放。Sample上的时间戳一般由Source Filter或Parser Filter来设置,设置的方法有如下几种情况:   1、文件回放   第一个sample的时间戳为0,随后的时间戳根据sample的大小和播放的速率来确定。这都由分解文件的Filter来计算和确定,例如AVI Splitter   2、视频和音频的捕捉   所有的sample在捕捉的时候就被打上时间戳了,时间等于流时间   3、混和Filter   根据输出数据流的格式,混和filter也许需要时间戳,也许不需要,   可以通过调用IMediaSample::SetTime来给sample设置时间   4、活动的源 Live Source   活动的源Filter,就是推模式的源,实时的接收数据。视频捕捉和网络广播就是例子,活动得源无法控制数据流得速率。   下面的Filter通常被认为是活动的源filter   ·Filter调用IAMFilterMiscFlags::GetMiscFlags方法时返回AM_FILTER_MISC_FLAGS_IS_SOURCE,并且至少有一个输出pin暴露了IAMPushSource接口。   ·Filter暴露IKsPropertySet接口,并且有个捕捉pin(PIN_CATEGORY_CAPTURE),如果活动的源能够提供参考时钟,那么Graph首先采用。   反应时间(Latency)   过滤器(filter)的反应时间就是Filter处理sample所花费的时间。对于活动的源filter,反应时间由容纳sample的内存大小决定。例如,假设一个filter有一个视频源具有33ms的反应时间,一个音频源有500ms的反应时间,每一个视频祯(video frame)比相应的音频sample要早470ms,除非graph进行补偿,否则视频和音频是不同步的。   活动的源可以通过IAMPushSource接口来进行同步。除非应用程序调用IAMGraphStreams::SyncUsingStreamOffset方法对源进行同步,一般来说Filter图表管理器是不会对源进行同步的。图表管理器对源进行同步时,向各个源filter查询IAMPushSource 接口,如果filter支持IAMPushSource ,图表管理器就会通过IAMLatency::GetLatency来得到filter期望的反应时间。注:IAMPushSource继承与 IAMLatency。通过组合这些反应值,filter图表管理器Graph最大反应时间,然后调用IAMPushSource::SetStreamOffset给每个源filter设置一个数据流偏移时间,当filter给它产生的sample打时间戳的时候,要加上偏移时间的。   现在,VFW Capture filter 和 Audio Capture filter.都支持IAMPushSource接口。   速率匹配(Rate Matching)   当renderer Filter利用参考时钟安排播放顺序的时候,如果源filter采用另一种时钟,在重放的时候就会发生故障。播放的速度大于源产生的速度,就会产生间隙停顿,或者播放速度小于源的产生速度,就会形成数据的堆积,造成内存出错。源一般来说是无法控制数据的产生速度的,因此,播放速度要随着源的速度改变而改变。   现在,只有在音频播放filter才能进行速率匹配,因为音频中的glitches比视频中的更容易捕捉到。为了匹配音频播放速率,要注意下列事情。   1、如果graph没有使用参考时钟,没法进行速率匹配。   2、上游要有一个活动的源   3、源filter的输出pin要支持IAMPushSource接口,当请求IAMPushSource::GetPushSourceFlags.要返回下面的值   AM_PUSHSOURCECAPS_INTERNAL_RM   AM_PUSHSOURCECAPS_NOT_LIVE   AM_PUSHSOURCECAPS_PRIVATE_CLOCK   4、如果GetPushSourceFlags返回0,播放filter就根据graph时钟和sample的时间戳来自己决定播放速率   摘要:本篇文档简单介绍了DirectShow中用来标记数据同步的时钟。   在 Filter Graph中,数据流就是依靠时钟来进行同步的,数据流中的每一个sample上都会标记一个时间戳,Video Renderer和Audio Renderer就根据sample上的时间戳来控制sample所携带的数据流的提交。如果到达Renderer的sample的时间比它携带的时间戳晚,则加快sample的播放,或者丢弃这个sample里的内容,如果sample上的时间戳的时间还未到,则sample要等待,一直等到sample时间戳的开始时间再开始播放。   下面我们先看看参考时钟。   参考时钟   参考时钟是Filter用来同步Filter 图表管理器中的所有的Filter的。   任何一个引出IReferenceClock 接口的对象都可以作为参考时钟。参考时钟可以是Filter提供(例如声卡就可以提供一个硬件的时钟),当然,可靠的时钟就是采用系统的时间。   名义上,参考时钟的精确度在100纳秒,但实际上,没有那么精确。调用IReferenceClock::GetTime可以获取时钟的当前时间。   尽管时钟的精确性还有所变动,但是GetTime方法返回的保证时间是增加的。也就是说,时钟不会倒退回去,比如,对硬件时钟进行了调整,GetTime方法就返回上次的时间。   如果Filter Graph中有多个对象实现了IReferenceClock接口,Filter Graph Manager是如何做出选择的呢?默认的算法如下:   当Graph运行的时候,Filter图表管理器会自动选择一个参考时钟的,选择时钟的法则如下   1、如果应用程序选择了时钟,就采用应用程序选择的时钟   2、如果Graph包含一个活动的源Filter(Live Source),并且这个filter有IReferenceClock接口,那么就用这个时钟。   3、如果Graph中不含有任何活动的源Filter,就选用graph中任何暴露IReferenceClock接口的Filter,选择的方法是从Renderers逆流向上,连接的filter优先,没有连接的filter次之。   4、如果没有任何filter符合条件,就采用系统参考时钟System Reference Clock   设置参考时钟   如果你想为graph设置新的时钟,应用程序可以调用图表管理器的接口IMediaFilter::SetSyncSource方法来选择一个参考时钟。   如果你给SetSyncSource传递的参数为NULL,Graph就不设置任何的参考时钟了。如果想恢复缺省的时钟,调用IFilterGraph::SetDefaultSyncSource方法。   当graph的参考时钟改变时,Graph通过the reference clock changes, the Filter Graph Manager notifies each filter by calling its IMediaFilter::SetSyncSource通知所有的Filter。   Clock Times   Directshow定义了两个相关的时间,参考时间Reference time和 数据流时间Stream time   前者是从参考时钟返回的绝对时间(IReferenceClock::GetTime),数值本身的意义取决于参考时钟的内部实现,利用价值不大;后者是两次从参考时钟读取的数值的差值,实际应用于Filter Graph内部的同步   当Filter graph正在运行,流时间的值为当前参考时钟时间减去Filter Graph启动的时间,也就是一个差值,当Filter graph暂停,流时间就等于它暂停时的stream时间,当Filter graph停止时,流时间不确定。   当一个sample具有时间戳t,就意味着这个sample应该在流时间t播放,因此,流时间也叫播放时间。   当应用程序通过IMediaControl::Run来运行graph时,在graph内部也调用了IMediaFilter::Run   时间戳   时间戳采用的是流时间,它在sample标上开始和结束时间。时间戳也叫播放时间,通过后面的知识你会了解到,并不是所有格式的数据流都采用同一种样式的时间戳。   当renderer Filter接收到sample,它会根据sample的时间戳进行排序,等到该sample的播放时间到了,就开始播放该sample,从到达到开始播放的时间,可以通过IReferenceClock::AdviseTime获得。如果sample来晚了,或者sample没有时间戳,filter就立即播放sample。如果Sample来得早了,则通过调用参考时钟的IReferenceClock::AdviseTime等待Sample的开始时间到达后再将这个Sample播放。Sample上的时间戳一般由Source Filter或Parser Filter来设置,设置的方法有如下几种情况:   1、文件回放   第一个sample的时间戳为0,随后的时间戳根据sample的大小和播放的速率来确定。这都由分解文件的Filter来计算和确定,例如AVI Splitter   2、视频和音频的捕捉   所有的sample在捕捉的时候就被打上时间戳了,时间等于流时间   3、混和Filter   根据输出数据流的格式,混和filter也许需要时间戳,也许不需要,   可以通过调用IMediaSample::SetTime来给sample设置时间   4、活动的源 Live Source   活动的源Filter,就是推模式的源,实时的接收数据。视频捕捉和网络广播就是例子,活动得源无法控制数据流得速率。   下面的Filter通常被认为是活动的源filter   ·Filter调用IAMFilterMiscFlags::GetMiscFlags方法时返回AM_FILTER_MISC_FLAGS_IS_SOURCE,并且至少有一个输出pin暴露了IAMPushSource接口。   ·Filter暴露IKsPropertySet接口,并且有个捕捉pin(PIN_CATEGORY_CAPTURE),如果活动的源能够提供参考时钟,那么Graph首先采用。   反应时间(Latency)   过滤器(filter)的反应时间就是Filter处理sample所花费的时间。对于活动的源filter,反应时间由容纳sample的内存大小决定。例如,假设一个filter有一个视频源具有33ms的反应时间,一个音频源有500ms的反应时间,每一个视频祯(video frame)比相应的音频sample要早470ms,除非graph进行补偿,否则视频和音频是不同步的。   活动的源可以通过IAMPushSource接口来进行同步。除非应用程序调用IAMGraphStreams::SyncUsingStreamOffset方法对源进行同步,一般来说Filter图表管理器是不会对源进行同步的。图表管理器对源进行同步时,向各个源filter查询IAMPushSource 接口,如果filter支持IAMPushSource ,图表管理器就会通过IAMLatency::GetLatency来得到filter期望的反应时间。注:IAMPushSource继承与 IAMLatency。通过组合这些反应值,filter图表管理器Graph最大反应时间,然后调用IAMPushSource::SetStreamOffset给每个源filter设置一个数据流偏移时间,当filter给它产生的sample打时间戳的时候,要加上偏移时间的。   现在,VFW Capture filter 和 Audio Capture filter.都支持IAMPushSource接口。   速率匹配(Rate Matching)   当renderer Filter利用参考时钟安排播放顺序的时候,如果源filter采用另一种时钟,在重放的时候就会发生故障。播放的速度大于源产生的速度,就会产生间隙停顿,或者播放速度小于源的产生速度,就会形成数据的堆积,造成内存出错。源一般来说是无法控制数据的产生速度的,因此,播放速度要随着源的速度改变而改变。   现在,只有在音频播放filter才能进行速率匹配,因为音频中的glitches比视频中的更容易捕捉到。为了匹配音频播放速率,要注意下列事情。   1、如果graph没有使用参考时钟,没法进行速率匹配。   2、上游要有一个活动的源   3、源filter的输出pin要支持IAMPushSource接口,当请求IAMPushSource::GetPushSourceFlags.要返回下面的值   AM_PUSHSOURCECAPS_INTERNAL_RM   AM_PUSHSOURCECAPS_NOT_LIVE   AM_PUSHSOURCECAPS_PRIVATE_CLOCK   4、如果GetPushSourceFlags返回0,播放filter就根据graph时钟和sample的时间戳来自己决定播放速率 下载本文示例代码


DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟DirectShow快速入门之参考时钟
阅读(111) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~