DirectShow SDK笔记【关于DirectShow(4)】(转载)

转载 2007年10月14日 13:30:00
6      Time and Clocks in DirectShow
 
       6.1    Reference Clocks
       参考时钟是Filter Graph Manager用来同步所有Filter的。任何一个暴露了IReferenceClock 接口的对象都可以作为参考时钟。参考时钟可以是Filter提供,例如声卡就可以提供一个硬件的时钟。作为应变,Filter Graph Manager也可采用系统的时间。名义上,参考时钟的精确度在100纳秒,但实际上,没有那么精确。调用IReferenceClock::GetTime可以获取时钟的当前时间。时间的基准是开始计时的时间,根据实现的不同,GetTime的返回值不是绝对的。关键的是从时间开始的变化量。
       尽管时钟的精确性还有所变动,但是GetTime方法返回的保证时间是增加的。也就是说,时钟不会倒退回去,比如,对硬件时钟进行了调整,GetTime方法就返回上次的时间,直到硬件时钟赶上。更多信息可参考CBaseReferenceClock类。
 
       6.1.1 Default Reference Clock
       Graph运行的时候,Filter Graph Manager会自动选择一个参考时钟的,选择的法则如下
       1、如果应用程序选择了时钟,就采用应用程序选择的时钟
       2、如果Graph包含活动的源Filter,并且有IReferenceClock接口,那么就用这个时钟。
       3、如果Graph没有活动的源Filter,就用Graph中任何有IReferenceClock接口的Filter,选择的方法是从Renderers逆流向上,连接的Filter优先,没有连接的Filter次之。
       4、如果没有任何Filter符合条件,就采用系统参考时钟System Reference Clock
 
       6.1.2 Setting the Reference Clock
       应用程序可以调用Filter Graph Manager的接口IMediaFilterSetSyncSource方法来设置新的参考时钟。只有因为特殊原因需要设置其他时钟时才调用此函数。
       如果你给SetSyncSource传递的参数为NULLGraph不设置任何参考时钟。如果想恢复缺省的时钟,调用IFilterGraph::SetDefaultSyncSource。当Graph的参考时钟改变时, Filter Graph Manager调用IMediaFilter::SetSyncSource通知所有的每个Filter
 
       6.3    Clock Times
       DirectShow定义了两个相关的时间:参考时间和流时间。
       ·参考时间:是参考时钟返回的绝对时间
       ·流时间:和Graph最近异常开始运行的时间有关。
              ·当Graph正在运行,流时间就等于从开始时间减去开始时间
              ·当Graph暂停,流时间就等于它暂停开始的时间
              ·在进行Seek操作后,流时间重新设置为0
              ·当Graph停止时,流时间没有定义。
       当一个Sample具有时间戳T,就表示Sample应该在流时间T播放,因此流时间也叫播放时间。
       应用程序调用IMediaControl::Run运行Graph时,Filter Graph Manager会调用每个FilterIMediaFilter::Run方法。为了补偿调用每个Filter的时间延迟,Filter Graph Manager会指定一个稍微将来的时间进行补偿。
 
       6.4    Time Stamps
       时间戳定义了媒体Sample的开始和结束时间,用流时间表示。时间戳也叫播放时间。通过后面的知识你会了解到,并不是所有格式的数据流都采用同一种样式的时间戳。比如,并不是所有的MPEG Sample都有时间戳。在MPEG Filter Graph,时间戳并不应用在每帧上直到它们从解码器输出。
       Render Filter接收到Sample,根据Sample的时间戳进行提交。如果Sample达到晚了或者没有时间戳, Filter立即提交Sample。否则,在提交Sample前,Filter会一直等到Sample的开始时间。(通过调用IReferenceClock::AdviseTime方法等待开始时间。)
       Source FilterParse Filter有责任给处理的Sample设置正确的时间戳。使用如下规则:
       ·文件回放:第一个Sample的时间戳为0,随后的时间戳根据Sample的长度和播放的速率来确定。这些又由文件格式确定。解析Filter有责任计算正确的时间戳(例如AVI Splitter)。
       ·视频和音频的捕捉:每个Sample都打上开始时间,它等于捕捉的流时间。注意下面两点:
              ·预览PIN(与捕捉PIN相反)出来的视频帧没有时间戳。因为Graph延迟,打上捕捉时间的视频帧到达视频Renerer时总是有延迟。这样就会使Renderer丢帧以尝试质量控制。关于质量控制可参考Quality-Control Management
              ·音频捕捉:音频捕捉Filter使用自己的缓冲,与音频驱动所使用的不同。音频捕捉驱动以固定间隔时间填充捕捉Filter的缓冲。间隔时间取决于驱动,但通常不超过10毫秒。在音频Sample上的时间戳反应了驱动填充捕捉Filter缓冲的时间。这些时间有稍微不准确,特别是如果应用程序使用更小的缓冲。但是,媒体时间能准确反应缓冲中音频Sample的数量。
       ·Mux Filter: 根据输出数据流的格式,Mux Filter可能需要生成时间戳,也许不需要。比如AVI文件格式使用固定的帧率,没有时间戳,因此AVI Mux Filter假定Sample都是在大约正确的时间达到。如果到达时间比时间戳晚就会丢帧。而对于文件回放,新的时间戳是运行时生成的。
       可以通过调用IMediaSample::SetTime来给Sample设置时间。
       另一个可选功能是Filter可以给Sample指定Media Time。在视频流,Media Time表示帧数。在音频流,表示数据包中的Sample数量。比如,如果每个包有1秒的444.1KHZ的音频,第一个包的媒体开始时间是0媒体结束时间是44100。在支持Seek的流,总是与流的开始时间有关。比如,如果对一个15FPS的视频从开始定位到2秒。定位后的Media Sample的时间戳是0但是Media Time30
       RendererMux Filter可通过检测间隔用Media Time判断帧或者Sample是否被丢弃。但是,Filter并不要求设置Media Time。设置Media Time可调用IMediaSample::SetMediaTime.
 
       6.5    Live Source
       活动的Live Filter,就是推模式的源,实时的接收数据。视频捕捉和网络广播就是例子,活动源通常无法控制数据流得速率。
       Filter如果有下面的任意一个特征,通常被认为是Live Filter
       1IAMFilterMiscFlags::GetMiscFlags时返回AM_FILTER_MISC_FLAGS_IS_SOURCE,并且至少有一个输出Pin暴露了IAMPushSource接口
       2Filter暴露IKsPropertySet接口,并且有个捕捉PinPIN_CATEGORY_CAPTURE),更多信息可参考Pin Property Set.
       如果Live Source Filter提供时钟,那么Filter Graph Manager首先采用它作为参考时钟。
 
       6.5.1 Latency
       Filter的反映时间就是Filter处理Sample所花费的时间。对于Live Source,反应时间由Sample的内存大小决定。例如,假设一个Filter有一个33ms反应时间的视频源,一个500ms反应时间的音频源,每一个视频祯(video frame)比相应的音频Sample要早470ms,除非Graph进行补偿,否则视频和音频是不同步的。
       Live Source可以通过IAMPushSource接口来进行同步。Filter Graph Manager在应用程序调用IAMGraphStreams::SyncUsingStreamOffset方法后就不会对源进行同步。如果开启同步,Filter Graph Manager在每个Source Filter查询IAMPushSource接口,如果支持接口,Filter Graph Manager就用IAMLatency::GetLatency来得到Filter期望的反应时间。(IAMPushSourceIAMLatency继承)。通过组合这些反应值,Filter Graph Manager 决定Graph的最大反应时间。然后调用IAMPushSource::SetStreamOffset给每个源Filter设置一个数据流偏移时间,Filter给它产生的Sample打时间戳的时候会加上偏移时间的。
     这种方法主要用于实时预览。但是,实时捕捉设备的(比如摄像机)并不在Sample上设置时间戳。因此,在实时捕捉设备上用此方法,必须从捕捉PIN进行预览。可参考DirectShow Video Capture Filter.   现在,VFW Capture Filter Audio Capture Filter.都支持IAMPushSource接口。
 
       6.5.2 Rate Matching
       Render Filter利用参考时钟安排播放顺序的时候,如果源Filter采用另一种时钟,在重放的时候就会发生故障。播放的速度大于源产生的速度,就会产生间隙停顿,或者播放速度小于源的产生速度,就会形成数据的堆积,直到Graph丢帧。源一般来说是无法控制数据的产生速度的,因此,播放速度要随着源的速度改变而改变。
       现在,只有在音频播放Filter才能进行速率匹配,因为音频中的故障比视频中的更容易捕捉到。为了匹配播放速率,音频Renderer必须要选择一个匹配标准。使用如下规则:
       ·如果Graph没有使用参考时钟,没法进行速率匹配。(只要没有参考时钟Sample都是立即提交)
       ·如果Graph有参考时钟,Renderer的上一级必须要有一个活动的源。否则不进行匹配。
       ·如果上一级有Live Source, 并且支持IAMPushSource接口,调用GetPushSourceFlags
              ·返回AM_PUSHSOURCECAPS_INTERNAL_RM,表示Source有自己的匹配机制
              ·返回AM_PUSHSOURCECAPS_NOT_LIVE,表示不是Live Source,即使有IAMPushSource接口,因此Audio Renderer不匹配。
              ·返回AM_PUSHSOURCECAPS_PRIVATE_CLOCK,表示Source用私有时钟生成时间戳。此时,Audio Renderer用时间戳匹配。(如果没有时间戳,但是Renderer忽略Flag.
       ·如果GetPushSourceFlags返回0,播放Filter就根据Graph时钟和Sample的时间戳来自己决定播放速率。
              ·如果Audio Renderer不是Graph时钟并且Sample有时间戳,就与时间戳匹配。
              ·如果Sample没有时间戳,Audio Renderer尝试与进入Audio Data的频率匹配。
              ·如果Audio RendererGraph时钟,尝试与进入Audio Data匹配。

       最后一种情况的原因是:如果Audio Renderer是参考时钟,Source Filter用同样的时钟生成时间戳,然后Audio Renderer不能与时间戳匹配。如果这么做了,就可能尝试与自己匹配,这样会引起时钟混乱。因此,Audio Renderer就与进入Audio Data的频率匹配。 

 

Android 快速开发 第三方SDK 百度定位SDK

百度地图Android定位SDK是为Android移动端应用提供的一套简单易用的LBS定位服务接口,专注于为广大开发者提供最好的综合定位服务,通过使用百度定位SDK,开发者可以轻松为应用程序实现智能、精准、高效的定位功能。 主要内容包括简介 密钥申请 环境配置、定位SDK使用,获取当前位置信息 等知识
  • 2016年08月08日 10:49

DirectShow编程(2)- 开始DirectShow旅程

2. 开始DirectShow旅程    这个章节的内容主要是编写DirectShow应用所需的一些基本概念,可以把它当作一个高级介绍,理解这些内容只需具备一般的编程和有关多媒体的知识。2.1. 设置...
  • eyes4
  • eyes4
  • 2004-10-12 09:57:00
  • 13906

再发自己的翻译的《Directshow(SDK)帮助文档 ---------智慧的鱼

很久以前在CSDN的论坛发过类似的帖子,当时也曾经给N多朋友发过这份文档,也有朋友在公司的服务器上放置了一段时间,供大家下载,但是,一直以来,还是不断的有朋友发email来要这份文档,有时候工作繁忙,...
  • aoosang
  • aoosang
  • 2007-09-28 13:03:00
  • 5814

win10 SDK 找不到DirectShow目录 解决小技巧

在系统升级为win10之后,由于老项目需要,我分别在系统上面安装了VS2008和VS2010。根据以往Win7 SDK的经验和DirectShow的迁移介绍,我安装了win10 SDK,但是在寻找Di...
  • u013617648
  • u013617648
  • 2016-06-30 16:41:59
  • 2726

win10 + VS2013下载directshow相关示例代码及directshow库文件调用

最近需要做虚拟摄像头,网上下载了一个现成的代码调试,用directshow,记录一下环境配置和修改部分,给有需要的朋友 1,环境配置:下载dierectshow vs2013可以自行扩展下载相关代码,...
  • u011668104
  • u011668104
  • 2016-11-14 19:26:19
  • 3737

DirectShow SDK

  • 2011年09月29日 01:38
  • 35.63MB
  • 下载

DirectShow编程(3.4) - 关于DirectShow - Filter Graph中的数据流

3.4. Filter Graph中的数据流    这一节主要描述媒体数据是如何在filter graph中流动的。如果你只是为了编写DirectShow应用程序,你不需要知道这些细节,当然,知道这些...
  • eyes4
  • eyes4
  • 2004-10-12 10:02:00
  • 5851

关于DirectShow SDK版本变迁说明及解决找不到streams.h文件

1.DirectShow SDK版本变迁说明 做视频聊天和视频播放器程序的时候会涉及到使用DirectShow SDK,原本DirectShow SDK是集成在DirectX中,但自从DirectX ...
  • u011028345
  • u011028345
  • 2017-02-18 19:34:23
  • 1185

windows 10+VS2015配置directshow

这段时间要做虚拟摄像头,其中要用到directshow的库,在网上找都是很久以前的,最近说directX的SDK集中在windows的SDK中了,下windows的SDK安装好久好久,还有文章说win...
  • u011668104
  • u011668104
  • 2016-11-14 19:24:43
  • 5986

【1】C#下的Directshow

因为Directshow是C++的东西,后来为了方便,才有牛人们在C#把directshow重写,但是相关文档很少,所以为了了解DIrectshow ,从C++下的directshow开始是最合理不过...
  • yixiantian7
  • yixiantian7
  • 2014-03-02 22:26:19
  • 2319
收藏助手
不良信息举报
您举报文章:DirectShow SDK笔记【关于DirectShow(4)】(转载)
举报原因:
原因补充:

(最多只允许输入30个字)