- 关于DirectShow - DirectShow中的时间和时钟 2005-08-06 levisqin
- Directshow中的时钟(Time and Clocks in Dshow) 2005-05-25 aoosang
- DirectShow音视频同步实验报告(3) 2004-09-13 happydeer
- DirectShow编程(3.4) - 关于DirectShow - Filter Graph中的数据流 2004-10-12 eyes4
- DirectShow编程(3.2)- 关于DirectShow - Filter Graph和它的组件 2004-10-12 eyes4
-
单片机的时间是从时钟芯片获得的么,在keilc编程中是怎么实现的?
2016-09-16 12:23:14时钟芯片是怎么同步采集和单片机之间的时间的?单片机的时间是从时钟芯片获得的么,在keilc编程中是怎么实现的? -
Linux上网、ssh远程连接、时钟同步 04
2019-03-23 18:24:431 网络原理 1.1 桥接原理 ...NAT原理本质上就是 虚拟机实现了交换机的功能, linux系统的IP地址就不会随宿主电脑的ip地址更改而更改 推荐使用这种方式 2 怎么使linux上网 2.1 确保所有关于VMWare的服务...1 网络原理
1.1 桥接原理
因为 虚拟机的linux系统的ip地址是固定的, 更换路由器后导致无法使用, 所以 不推荐使用1.2 NAT原理
如果宿主电脑可以上网, 内部的虚拟机也可以上网就好了
NAT原理本质上就是 虚拟机实现了交换机的功能, linux系统的IP地址就不会随宿主电脑的ip地址更改而更改
推荐使用这种方式2 怎么使linux上网
2.1 确保所有关于VMWare的服务都开启
计算机 --> 右键 ‘管理’
2.2 确保VMnet8 已经启动
2.3 设置VMware软件交换机的ip地址
再次确认
2.4 设置VMnet8的ip地址
网关: 192.168.220.1
2.5 更改linux系统的ip地址
vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0 TYPE=Ethernet UUID=aa810323-8568-4664-9123-221c3446eb79 ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=none DEFROUTE=yes IPV4_FAILURE_FATAL=yes IPV6INIT=no NAME="System eth0" HWADDR=00:0c:29:be:cf:7b PEERROUTES=yes IPADDR=192.168.220.250 NETMASK=255.255.255.0 GATEWAY=192.168.220.1 DNS1=8.8.8.8 USERCTL=no
改完后保存
2.6 重启网卡服务
2.7 测试
[root@my01 tmp]# wget http://pic1.win4000.com/pic/e/08/c2e2466031.jpg
3 防火墙
3.1 查看防火墙规则
查看防火墙状态
service iptables status
修改防火墙规则
vim /etc/sysconfig/iptables
放开某个端口号不被防火墙拦截,适用于部署tomcat,nginx等之类的软件:
设置完成后,需要重启防火墙.
重启防火墙service iptables restart
3.2 关闭防火墙服务
service iptables stop
3.3 禁止防火墙关机自启动
chkconfig iptables off
查看自启动状态
chkconfig iptables --list
# 0 - 停机 # 1 - 单用户模式 # 2 - 多用户,没有NFS # 3 - 完全多用户模式(标准的运行级) # 4 - 没有用到 # 5 - X11(xwindow) # 6 - 重新启动
注意: 在实际工作,大数据集群一般都是放置在内网当中,通过跳板机连接外网.**
所以一般都是直接关闭防火墙即可, 但是在实际工作中,跳板机(web服务器)关闭防火墙要谨慎,避免服务器感染病毒
服务的套路:service xxx start 开启 service xxx stop 停止 service xxx restart 重启 service xxx status 状态
4 复制linux系统
因为重新安装虚拟太慢了, 所以直接复制虚拟机
4.1 复制虚拟机
4.2 开启复制之后的虚拟机
注意:点击.vmx结尾的文件,就可以挂载上了
重命名
4.3 更改新增linux的mac地址
4.4 更改新增linux系统的网卡
vim /etc/udev/rules.d/70-persistent-net.rules
4.5 更改新增linux系统的网络设置
vim /etc/sysconfig/network-scripts/ifcfg-eth0
使用 reboot指令重启系统, 再次验证
5 时钟同步(重点重点重点)
5.1 原理
内网的所有服务器都和时钟服务器进行同步时间
5.2 如何同步
- 查看本机当前时间
date
- 设置本机当前时间
date -s "2018-08-17 20:08:09"
-
通过命名和时钟服务器同步时间:
网络计时协议(NTP) : net time protocal
ntpdate us.pool.ntp.org
-
编辑定时任务
e–> edit 编辑
crontab -e
4.1 定时任务内容如下
*/1 * * * * /usr/sbin/ntpdate us.pool.ntp.org;
每隔1分钟执行指令一次
Crontab格式详细说明,请点击此链接6 主机名
6.1 更改主机名
vim /etc/sysconfig/network
6.1.1 内容
HOSTNAME=hadoop1
同理 更改每台linux的主机名
HOSTNAME=hadoop1
HOSTNAME=hadoop2
HOSTNAME=hadoop3
注意: 必须重启系统才可以生效
6.2 更改三台机器的主机名与ip地址的映射
vim /etc/hosts
6.2.2 内容
192.168.220.250 hadoop1 192.168.220.251 hadoop2 192.168.220.252 hadoop3
6.3 三台虚拟机关闭selinux
vim /etc/selinux/config
SELINUX=disabled
关机重启才会生效.
7 SSH免密码登录
7.1 what?
7.2 远程访问方式一
[root@hadoop1 ~]# ssh hadoop2 root@hadoop2's password: Last login: Fri Aug 17 17:15:00 2018 from hadoop1 [root@hadoop2 ~]# ifconfig eth0 Link encap:Ethernet HWaddr 00:50:56:20:79:47 inet addr:192.168.220.252 Bcast:192.168.220.255 Mask:255.255.255.0 inet6 addr: fe80::250:56ff:fe20:7947/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:839 errors:0 dropped:0 overruns:0 frame:0 TX packets:580 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:77419 (75.6 KiB) TX bytes:55550 (54.2 KiB) Interrupt:19 Base address:0x2000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:114 errors:0 dropped:0 overruns:0 frame:0 TX packets:114 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:6026 (5.8 KiB) TX bytes:6026 (5.8 KiB) [root@hadoop2 ~]# exit logout Connection to hadoop2 closed.
缺点: 每次都需要输入密码
7.2 远程访问方式二:免密码
第一步: ssh-keygen -t rsa 在hadoop1和hadoop2和hadoop3上面都要执行,产生公钥和私钥 第二步:ssh-copy-id hadoop1 将公钥拷贝到hadoop1上面去 第三步: scp authorized_keys hadoop2:$PWD scp authorized_keys hadoop3:$PWD
注意1: 第三步需要在/root/.ssh/目录下.
注意2: 先测试第二台机器免密码登录, 发现有时handoop01有问题,但是 过一会就好了. -
信号波形怎么画_IC面试中常被问到:跨时钟域信号处理——握手协议(handshake)...
2021-01-05 13:16:41前面提到,用敲两级DFF的办法(两级DFF同步器)可以实现单比特信号跨时钟域处理。但你或许会有疑问,是所有的单比特信号跨时钟域都可以这么处理吗?NO!两级DFF同步器,是对信号有一定的要求的。...IC君的第36篇原创文章 (欢迎关注公众号 icstudy)
首先祝大家2019年元旦快乐,少加班多拿奖金!
之前有一篇文章讲述了跨时钟域信号的处理第1篇,IC面试中常被问到——跨时钟域信号如何处理?这是第2篇。
前面提到,用敲两级DFF的办法(两级DFF同步器)可以实现单比特信号跨时钟域处理。但你或许会有疑问,是所有的单比特信号跨时钟域都可以这么处理吗?
NO!两级DFF同步器,是对信号有一定的要求的。
想象一下,如果频率较高的时钟域A中的信号D1 要传到频率较低的时钟域B,但是D1只有一个时钟脉冲宽度(1T),clkb 就有几率采不到D1了,如图1。
图1 快时钟域信号传递到慢时钟域 因此只有当D1 在很长一段时间内为1或0,确保一定可以被clkb采样到,才能用两级DFF同步器处理。
如果信号D1 只有1T或几个T的脉宽,又需要传到时钟频率较低甚至或快或慢不确定的时钟域B,这种情况该怎么如何处理呢?
握手协议(handshake)异步信号处理是一种常见的异步信号处理方法。常见的握手协议异步信号处理行为波形图大致如下图2:
图2 一种handshake电路波形 信号d_in 所处时钟域是clk_in,且d_in只有1T 的宽度,想要传送到clk_out 时钟域(clk_out 跟clk_in不相关)。
因为clk_out 和 clk_in相位关系不确定,时钟周期大小关系不确定,无法保证一定能采样到d_in。
因此需要把d_in展宽,产生d_req 信号;
d_req 信号一直拉高,经过clk_out时钟域两级DFF 同步器后,得到d_reg_sync;
取d_req_sync 上升沿1T,即可得到传送到clk_out 时钟域的d_out。
此时,d_in 从clk_in 传送到clk_out 的任务就算是结束了。
但对于handshake 电路来说,任务还没结束,因为d_req 还一直是高电平。
因此,需要把d_req_sync 信号再用两级DFF同步器,传回clk_in 时钟域,得到d_ack信号;
当clk_in 看到d_ack拉高后,就可以把d_req 信号拉低,到这里一个handshake电路行为才算是结束了。
根据上面的波形图,可以看到握手协议异步信号处理并不复杂,但是细心的朋友应该会注意到,这个处理方法信号传递的速度相对较慢。
从图2 的波形来看,至少需要3个clk_in 和2个clk_out时钟周期。根据不同的应用需求,人们会对图2的波形做不同的改造。但万变不离其宗,原理都是一样的,电路也大同小异。
最后留4个问题供大家思考,以增进对handshake电路的理解:
1. 图2中的d_req的逻辑怎么实现?
2. 图2中的d_out的逻辑怎么实现?
3. 假设时钟域clka比clkb 频率高,如果输入信号的两个相邻脉冲D0和D1非常较近,如下图所示,如果使用握手协议处理,会发生怎样的事情?
4.问题3里面,如果要确保D1数据一定要被能传送到clkb,电路该如何实现?
请大家踊跃留言回答哦!
-
浅析DirectShow音视频同步解决方案
2008-03-04 23:43:00DirectShow是怎么来实现的呢?我们一起来学习一下。 大家知道,DirectShow结构最核心的部分是Filter Graph Manager:向下控制Graph中的所有Filter,向上对应用程序提供编程接口。其中,Filter Graph Manager实现的很...多媒体处理,不可避免地要解决音视频的同步问题。DirectShow是怎么来实现的呢?我们一起来学习一下。
大家知道,DirectShow结构最核心的部分是Filter Graph Manager:向下控制Graph中的所有Filter,向上对应用程序提供编程接口。其中,Filter Graph Manager实现的很重要一个功能,就是同步音视频的处理。简单地说,就是选一个公共的参考时钟,并且要求给每个Sample都打上时间戳,Video Renderer或Audio Renderer根据Sample的时间戳来控制播放。如果到达Renderer的Sample晚了,则加快Sample的播放;如果早了,则Renderer等待,一直到Sample时间戳的开始时间再开始播放。这个控制过程还引入一个叫Quality Control的反馈机制。
下面,我们来看一下参考时钟(Reference Clock)。所有Filter都参照于同一个时钟,才能统一步调。DirectShow引入了两种时钟时间:Reference time和Stream time。前者是从参考时钟返回的绝对时间(IReferenceClock::GetTime),数值本身的意义取决于参考时钟的内部实现,利用价值不大;后者是两次从参考时钟读取的数值的差值,实际应用于Filter Graph内部的同步。Stream time在Filter Graph不同状态的取值为:
1. Filter Graph运行时,取值为当前参考时钟时间减去Filter Graph启动时的时间(启动时间是通过调用Filter上的IMediaFilter::Run来设置的);
2. Filter Graph暂停时,保持为暂停那一刻的Stream time;
3. 执行完一次Seek操作后,复位至零;
4. Filter Graph停止时,取值不确定。
那么,参考时钟究竟是什么东西呢?其实,它只是一个实现了IReferenceClock接口的对象。也就是说,任何一个实现了IReferenceClock接口的对象都可以成为参考时钟。在Filter Graph中,这个对象一般就是一个Filter。(在GraphEdit中,实现了参考时钟的Filter上会显示一个时钟的图标;如果同一个Graph中有多个Fiter实现了参考时钟,当前被Filter Graph Manager使用的那个会高亮度显示。)而且大多数情况下,参考时钟是由Audio Renderer这个Filter提供的,因为声卡上本身带有了硬件定时器资源。接下来的问题是,如果Filter Graph中有多个对象实现了IReferenceClock接口,Filter Graph Manager是如何做出选择的呢?默认的算法如下:
1. 如果应用程序设置了一个参考时钟,则直接使用这个参考时钟。(应用程序通过IMediaFilter:: SetSyncSource设置参考时钟,参数即为参考时钟;如果参数值为NULL,表示Filter Graph不使用参考时钟,以最快的速度处理Sample;可以调用IFilterGraph:: SetDefaultSyncSource来恢复Filter Graph Manager默认的参考时钟。值得注意的是,这时候的IMediaFilter接口应该从Filter Graph Manager上获得,而不是枚举Graph中所有的Filter并分别调用Filter上的这个接口方法。)
2. 如果Graph中有支持IReferenceClock接口的Live Source,则选择这个Live Source。
3. 如果Graph中没有Live Source,则从Renderer依次往上选择一个实现IReferenceClock接口的Filter。如果连接着的Filter都不能提供参考时钟,则再从没有连接的Filter中选择。这一步算法中还有一个优先情况,就是如果Filter Graph中含有一个Audio Render的链路,则直接选择Audio Renderer这个Filter(原因上面已经提及)。
4. 如果以上方法都找不到一个适合的Filter,则选取系统参考时钟。(System Reference Clock,通过CoCreateInstance创建,CLSID为CLSID_SystemClock。)
我们再来看一下Sample的时间戳(Time Stamp)。需要注意的是,每个Sample上可以设置两种时间戳:IMediaSample::SetTime和IMediaSample::SetMediaTime。我们通常讲到时间戳,一般是指前者,它又叫Presentation time,Renderer正是根据这个时间戳来控制播放;而后者对于Filter来说不是必须的,Media time有没有用取决于你的实现,比如你给每个发出去的Sample依次打上递增的序号,在后面的Filter接收时就可以判断传输的过程中是否有Sample丢失。我们再看一下IMediaSample::SetTime的参数,两个参数类型都是REFERENCE_TIME,千万不要误解这里的时间是Reference time,其实它们用的是Stream time。还有一点,就是并不是所有的Sample都要求打上时间戳。对于一些压缩数据,时间戳是很难打的,而且意义也不是很大(不过压缩数据经过Decoder出来之后到达Renderer之前,一般都会打好时间戳了)。时间戳包括两个时间,开始时间和结束时间。当Renderer接收到一个Sample时,一般会将Sample的开始时间和当前的Stream time作比较,如果Sample来晚了或者没有时间戳,则马上播放这个Sample;如果Sample来得早了,则通过调用参考时钟的IReferenceClock::AdviseTime等待Sample的开始时间到达后再将这个Sample播放。Sample上的时间戳一般由Source Filter或Parser Filter来设置,设置的方法有如下几种情况:1. 文件回放(File playback):第一个Sample的时间戳从0开始打起,后面Sample的时间戳根据Sample有效数据的长度和回放速率来定。
2. 音视频捕捉(Video and audio capture):原则上,采集到的每一个Sample的开始时间都打上采集时刻的Stream time。对于视频帧,Preview pin出来的Sample是个例外,因为如果按上述方法打时间戳的话,每个Sample通过Filter链路传输,最后到达Video Renderer的时候都将是迟到的;Video Renderer通过Quality Control反馈给Source Filter,会导致Source Filter丢帧。所以,Preview pin出来的Sample都不打时间戳。对于音频采集,需要注意的是,Audio Capture Filter与声卡驱动程序两者各自使用了不同的缓存,采集的数据是定时从驱动程序缓存拷贝到Filter的缓存的,这里面有一定时间的消耗。
3. 合成(Mux Filters):取决于Mux后输出的数据类型,可以打时间戳,也可以不打时间戳。
大家可以看到,Sample的时间戳对于保证音视频同步是很重要的。Video Renderer和Audio Renderer作为音视频同步的最终执行者,需要做很多工作。我们或许要开发其它各种类型的Filter,但一般这两个Filter是不用再开发的。一是因为Renderer Filter本身的复杂性,二是因为微软会对这两个Filter不断升级,集成DirectX中其它模块的最新技术(如DirectSound、DirectDraw、Direct3D等)。
最后,我们再来仔细看一下Live Source的情况。Live Source又叫Push source,包括Video /Audio Capture Filter、网络广播接收器等。Filter Graph Manager是如何知道一个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对于音视频同步的影响主要是以下两个方面:Latency和Rate Matching。Latency是指Filter处理一个Sample花费的时间,对于Live Source来说,主要取决于使用缓存的大小,比如采集30fps的视频一般采集完一帧后才将数据以一个Sample发送出去,则这个Filter的Latency为33ms,而Audio一般缓存500ms后才发送一个Sample,则它的Latency就为500ms。这样的话,Audio与Video到达Renderer就会偏差470ms,造成音视频的不同步。默认情况下,Filter Graph Manager是不会对这种情况进行调整的。当然,应用程序可以通过IAMPushSource接口来进行Latency的补偿,方法是调用IAMGraphStreams::SyncUsingStreamOffset函数。Filter Graph Manager的实现如下:对所有实现IAMPushSource接口的Filter调用IAMLatency::GetLatency得到各个Source的Latency值,记下所有Latency值中的最大值,然后调用IAMPushSource::SetStreamOffset对各个Source设置偏移值。
这样,在Source Filter产生Sample时,打的时间戳就会加上这个偏移量。Rate Matching问题的引入,主要是由于Renderer Filter和Source Filter使用的是不同的参考时钟。这种情况下,Renderer对数据的播放要么太快,要么太慢。另外,一般Live Source不能控制输出数据的速率,所以必须在Renderer上进行播放速率的匹配。因为人的听觉敏感度要大于视觉敏感度,所以微软目前只在Audio Renderer上实现了Rate Matching。实现Rate Matching的算法是比较复杂的,这里就不再赘述。
看到这里,大家应该对DirectShow是如何解决音视频同步问题的方案有一点眉目了吧。深层次的研究,还需要更多的测试、Base class源码阅读,以及DirectShow相关控制机制的理解,比如Quality Control Management等Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2142384
<script src="http://localhost:82/PromoteIcon.aspx?id=2142384" type="text/javascript"></script> [收藏到我的网摘] [发送Trackback] benny5609发表于 2008年03月03日 11:09:56href="http://blog.csdn.net/benny5609/Services/Pingback.aspx" rel="pingback" /> <script type="text/javascript">function hide(){showComment();}</script>相关文章: -
浅析DirectShow音视频同步解决方案
2008-03-03 11:10:00DirectShow是怎么来实现的呢?我们一起来学习一下。 大家知道,DirectShow结构最核心的部分是Filter Graph Manager:向下控制Graph中的所有Filter,向上对应用程序提供编程接口。其中,Filter Graph Manager实现的很...多媒体处理,不可避免地要解决音视频的同步问题。DirectShow是怎么来实现的呢?我们一起来学习一下。
大家知道,DirectShow结构最核心的部分是Filter Graph Manager:向下控制Graph中的所有Filter,向上对应用程序提供编程接口。其中,Filter Graph Manager实现的很重要一个功能,就是同步音视频的处理。简单地说,就是选一个公共的参考时钟,并且要求给每个Sample都打上时间戳,Video Renderer或Audio Renderer根据Sample的时间戳来控制播放。如果到达Renderer的Sample晚了,则加快Sample的播放;如果早了,则Renderer等待,一直到Sample时间戳的开始时间再开始播放。这个控制过程还引入一个叫Quality Control的反馈机制。
下面,我们来看一下参考时钟(Reference Clock)。所有Filter都参照于同一个时钟,才能统一步调。DirectShow引入了两种时钟时间:Reference time和Stream time。前者是从参考时钟返回的绝对时间(IReferenceClock::GetTime),数值本身的意义取决于参考时钟的内部实现,利用价值不大;后者是两次从参考时钟读取的数值的差值,实际应用于Filter Graph内部的同步。Stream time在Filter Graph不同状态的取值为:
1. Filter Graph运行时,取值为当前参考时钟时间减去Filter Graph启动时的时间(启动时间是通过调用Filter上的IMediaFilter::Run来设置的);
2. Filter Graph暂停时,保持为暂停那一刻的Stream time;
3. 执行完一次Seek操作后,复位至零;
4. Filter Graph停止时,取值不确定。
那么,参考时钟究竟是什么东西呢?其实,它只是一个实现了IReferenceClock接口的对象。也就是说,任何一个实现了IReferenceClock接口的对象都可以成为参考时钟。在Filter Graph中,这个对象一般就是一个Filter。(在GraphEdit中,实现了参考时钟的Filter上会显示一个时钟的图标;如果同一个Graph中有多个Fiter实现了参考时钟,当前被Filter Graph Manager使用的那个会高亮度显示。)而且大多数情况下,参考时钟是由Audio Renderer这个Filter提供的,因为声卡上本身带有了硬件定时器资源。接下来的问题是,如果Filter Graph中有多个对象实现了IReferenceClock接口,Filter Graph Manager是如何做出选择的呢?默认的算法如下:
1. 如果应用程序设置了一个参考时钟,则直接使用这个参考时钟。(应用程序通过IMediaFilter:: SetSyncSource设置参考时钟,参数即为参考时钟;如果参数值为NULL,表示Filter Graph不使用参考时钟,以最快的速度处理Sample;可以调用IFilterGraph:: SetDefaultSyncSource来恢复Filter Graph Manager默认的参考时钟。值得注意的是,这时候的IMediaFilter接口应该从Filter Graph Manager上获得,而不是枚举Graph中所有的Filter并分别调用Filter上的这个接口方法。)
2. 如果Graph中有支持IReferenceClock接口的Live Source,则选择这个Live Source。
3. 如果Graph中没有Live Source,则从Renderer依次往上选择一个实现IReferenceClock接口的Filter。如果连接着的Filter都不能提供参考时钟,则再从没有连接的Filter中选择。这一步算法中还有一个优先情况,就是如果Filter Graph中含有一个Audio Render的链路,则直接选择Audio Renderer这个Filter(原因上面已经提及)。
4. 如果以上方法都找不到一个适合的Filter,则选取系统参考时钟。(System Reference Clock,通过CoCreateInstance创建,CLSID为CLSID_SystemClock。)
我们再来看一下Sample的时间戳(Time Stamp)。需要注意的是,每个Sample上可以设置两种时间戳:IMediaSample::SetTime和IMediaSample::SetMediaTime。我们通常讲到时间戳,一般是指前者,它又叫Presentation time,Renderer正是根据这个时间戳来控制播放;而后者对于Filter来说不是必须的,Media time有没有用取决于你的实现,比如你给每个发出去的Sample依次打上递增的序号,在后面的Filter接收时就可以判断传输的过程中是否有Sample丢失。我们再看一下IMediaSample::SetTime的参数,两个参数类型都是REFERENCE_TIME,千万不要误解这里的时间是Reference time,其实它们用的是Stream time。还有一点,就是并不是所有的Sample都要求打上时间戳。对于一些压缩数据,时间戳是很难打的,而且意义也不是很大(不过压缩数据经过Decoder出来之后到达Renderer之前,一般都会打好时间戳了)。时间戳包括两个时间,开始时间和结束时间。当Renderer接收到一个Sample时,一般会将Sample的开始时间和当前的Stream time作比较,如果Sample来晚了或者没有时间戳,则马上播放这个Sample;如果Sample来得早了,则通过调用参考时钟的IReferenceClock::AdviseTime等待Sample的开始时间到达后再将这个Sample播放。Sample上的时间戳一般由Source Filter或Parser Filter来设置,设置的方法有如下几种情况:1. 文件回放(File playback):第一个Sample的时间戳从0开始打起,后面Sample的时间戳根据Sample有效数据的长度和回放速率来定。
2. 音视频捕捉(Video and audio capture):原则上,采集到的每一个Sample的开始时间都打上采集时刻的Stream time。对于视频帧,Preview pin出来的Sample是个例外,因为如果按上述方法打时间戳的话,每个Sample通过Filter链路传输,最后到达Video Renderer的时候都将是迟到的;Video Renderer通过Quality Control反馈给Source Filter,会导致Source Filter丢帧。所以,Preview pin出来的Sample都不打时间戳。对于音频采集,需要注意的是,Audio Capture Filter与声卡驱动程序两者各自使用了不同的缓存,采集的数据是定时从驱动程序缓存拷贝到Filter的缓存的,这里面有一定时间的消耗。
3. 合成(Mux Filters):取决于Mux后输出的数据类型,可以打时间戳,也可以不打时间戳。
大家可以看到,Sample的时间戳对于保证音视频同步是很重要的。Video Renderer和Audio Renderer作为音视频同步的最终执行者,需要做很多工作。我们或许要开发其它各种类型的Filter,但一般这两个Filter是不用再开发的。一是因为Renderer Filter本身的复杂性,二是因为微软会对这两个Filter不断升级,集成DirectX中其它模块的最新技术(如DirectSound、DirectDraw、Direct3D等)。
最后,我们再来仔细看一下Live Source的情况。Live Source又叫Push source,包括Video /Audio Capture Filter、网络广播接收器等。Filter Graph Manager是如何知道一个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对于音视频同步的影响主要是以下两个方面:Latency和Rate Matching。Latency是指Filter处理一个Sample花费的时间,对于Live Source来说,主要取决于使用缓存的大小,比如采集30fps的视频一般采集完一帧后才将数据以一个Sample发送出去,则这个Filter的Latency为33ms,而Audio一般缓存500ms后才发送一个Sample,则它的Latency就为500ms。这样的话,Audio与Video到达Renderer就会偏差470ms,造成音视频的不同步。默认情况下,Filter Graph Manager是不会对这种情况进行调整的。当然,应用程序可以通过IAMPushSource接口来进行Latency的补偿,方法是调用IAMGraphStreams::SyncUsingStreamOffset函数。Filter Graph Manager的实现如下:对所有实现IAMPushSource接口的Filter调用IAMLatency::GetLatency得到各个Source的Latency值,记下所有Latency值中的最大值,然后调用IAMPushSource::SetStreamOffset对各个Source设置偏移值。
这样,在Source Filter产生Sample时,打的时间戳就会加上这个偏移量。Rate Matching问题的引入,主要是由于Renderer Filter和Source Filter使用的是不同的参考时钟。这种情况下,Renderer对数据的播放要么太快,要么太慢。另外,一般Live Source不能控制输出数据的速率,所以必须在Renderer上进行播放速率的匹配。因为人的听觉敏感度要大于视觉敏感度,所以微软目前只在Audio Renderer上实现了Rate Matching。实现Rate Matching的算法是比较复杂的,这里就不再赘述。
看到这里,大家应该对DirectShow是如何解决音视频同步问题的方案有一点眉目了吧。深层次的研究,还需要更多的测试、Base class源码阅读,以及DirectShow相关控制机制的理解,比如Quality Control Management等 -
stm32 usart 收发数据丢包怎么排查_stm32F之USART串口通信
2021-01-18 20:15:42概述 上一篇说了stm32 定时器的基本使用,这篇来说说 stm32 串口通信一.stm32F407资源 ... 在这里我们选用串口1进行简单编程:实现功能吐下:每秒发送一个数字进行数据回传其所要配置的内容如下:GPIO的时钟使能... -
c语言怎么输入n个数字_Spectrum PCIe数字化仪新增8个额外数字输入
2020-12-03 14:38:54点击上面“蓝字”关注我们Spectrum ...为了确保数字输入与模拟输入的完全同步,新增的数字输入模块与基卡共用一个时钟和触发器,该选项广泛适用于各种混合信号测试。此外,新选项用于Spectrum 44系列的全部数字化仪... -
关于Python核心框架tornado的异步协程的2种方法详解
2020-12-26 10:29:10什么是异步? 含义 :双方不需要共同...那么今天我们看怎么用2种方法用代码实现tornado的异步? 这些是导入的包: 2种方法用代码实现tornado的异步的代码实现: 下面是服务启动: 以上这篇关于Python核心框架tornad -
2007 年时做了几个传统游戏后开始研究快速动作游戏的同步问题,期间写过不少文章,算是国内比较早研究同步问题的人,然而发现不管怎么解决同步都需要在网络传输方面有所突破,后来离开游戏转行互联网后也发现不少...
-
进程通信(1)
2020-05-14 08:32:091.信号量可以实现同步,进程间通过信号量走走停停 读写信号量的代码一定是临界区。 临界区就是 一次只允许一个进程进入的 的那段代码。 但是共同修改信号量,会出现问题。 比如说一个进程只修改了信号量没保存,时间... -
LCD 裸板驱动
2014-09-14 23:05:46一 块LCD屏显示图像,不但需要LCD驱动器,还需要有相应的LCD控制器。...VCLK:时钟,每来一个时钟,就打出一个像素。 1、怎么写LCD程序? 1)设置LCD控制器 a、屏幕长、宽,打出多少个像素之后发出HSY -
DDS资料大全(调试心得 线路图 DDS-ADI)
2010-05-02 12:49:043.14 DDS 输出端DAC 为电流输出,怎么转换为电压,有什么限制 3.15 DDS 的AGND,DGND 应该怎样连接,接模拟地还是数字地 3.16 有些DDS 评估板上的MC100LVEL16 的用途是什么? 3.17 AD7008 已经停产,有什么可以替代... -
vc++ 应用源码包_1
2012-09-15 14:22:12内部包含:mp3播放器Lrc歌词同步源程序代码分析、mp3播放器+支持歌词同步显示哦、简单音乐播放器。 mfc 解码 视频音频解码部分。 MFC_MultiSender_OVER 文件传送,多文件(超大文件)传送功能的实现,含文档。 ... -
vc++ 应用源码包_2
2012-09-15 14:27:40内部包含:mp3播放器Lrc歌词同步源程序代码分析、mp3播放器+支持歌词同步显示哦、简单音乐播放器。 mfc 解码 视频音频解码部分。 MFC_MultiSender_OVER 文件传送,多文件(超大文件)传送功能的实现,含文档。 ... -
vc++ 应用源码包_6
2012-09-15 14:59:46内部包含:mp3播放器Lrc歌词同步源程序代码分析、mp3播放器+支持歌词同步显示哦、简单音乐播放器。 mfc 解码 视频音频解码部分。 MFC_MultiSender_OVER 文件传送,多文件(超大文件)传送功能的实现,含文档。 ... -
vc++ 应用源码包_5
2012-09-15 14:45:16内部包含:mp3播放器Lrc歌词同步源程序代码分析、mp3播放器+支持歌词同步显示哦、简单音乐播放器。 mfc 解码 视频音频解码部分。 MFC_MultiSender_OVER 文件传送,多文件(超大文件)传送功能的实现,含文档。 ... -
vc++ 应用源码包_4
2012-09-15 14:38:35内部包含:mp3播放器Lrc歌词同步源程序代码分析、mp3播放器+支持歌词同步显示哦、简单音乐播放器。 mfc 解码 视频音频解码部分。 MFC_MultiSender_OVER 文件传送,多文件(超大文件)传送功能的实现,含文档。 ... -
vc++ 应用源码包_3
2012-09-15 14:33:15内部包含:mp3播放器Lrc歌词同步源程序代码分析、mp3播放器+支持歌词同步显示哦、简单音乐播放器。 mfc 解码 视频音频解码部分。 MFC_MultiSender_OVER 文件传送,多文件(超大文件)传送功能的实现,含文档。 ... -
专业概念抽象级: 对抽象的专业逻辑概念具体化认知, 比如虚拟内存,老百姓是听不懂的,学过计算机的人都懂,具体怎么实现的很多人又都不懂了,但这并不妨碍成为一个优秀的上层应用程序员,因为虚拟内存已经被抽象出来,目的...
-
英特尔面试专项准备
2020-12-09 13:46:46</li><li>关于平衡二叉树的平衡方式和堆排序是怎么排序的,时间和空间复杂度</li><li>列举线程函数库</li><li>线程同步</li><li> <p>fork &pthread_create </li><li> C语言编程 </li><li> <p>const </li>... -
自己动手写操作系统(含源代码).part2
2010-10-18 19:47:45第三,实践类的操作系统书籍还是太少了,以至于你要想看看别人是怎么做的,除了读以《操作系统:设计与实现》为代表的极少数书籍之外,就是一头扎进源代码中,而结果有时相当令人气馁。我自己也气馁过,所以我在第二... -
自己动手写操作系统(含源代码).part1
2010-10-18 19:41:25第三,实践类的操作系统书籍还是太少了,以至于你要想看看别人是怎么做的,除了读以《操作系统:设计与实现》为代表的极少数书籍之外,就是一头扎进源代码中,而结果有时相当令人气馁。我自己也气馁过,所以我在第二... -
Windows.环境下32位汇编语言程序设计(第2版)扫描版带书签2/2
2012-10-29 08:48:574.1.3 窗口程序是怎么工作的 92 4.2分析窗口程序 99 4.2.1 模块和句柄 99 4.2.2 创建窗口 101 4.2.3 消息循环 107 4.2.4 窗口过程 109 4.3窗口间的通信 114 4.3.1 窗口间的消息互发 114 4.3.2 在窗口间传递数据 117 ... -
Windows.环境下32位汇编语言程序设计(第2版)扫描版带书签 1/2
2012-10-29 08:43:104.1.3 窗口程序是怎么工作的 92 4.2分析窗口程序 99 4.2.1 模块和句柄 99 4.2.2 创建窗口 101 4.2.3 消息循环 107 4.2.4 窗口过程 109 4.3窗口间的通信 114 4.3.1 窗口间的消息互发 114 4.3.2 在窗口间传递数据 117 ... -
Win32位汇编语言程序设计(第2版)完整高清版(共四部分)第四部分
2009-05-22 17:04:264.1.3 窗口程序是怎么工作的 92 4.2 分析窗口程序 99 4.2.1 模块和句柄 99 4.2.2 创建窗口 101 4.2.3 消息循环 107 4.2.4 窗口过程 109 4.3 窗口间的通信 114 4.3.1 窗口间的消息互发 114 4.3.2 在窗口间传递数据 ... -
Windows 程序设计(第5版)(上、下册)--详细书签版
2012-04-22 18:40:046.4.4 unicode怎么样? 6.4.5 truetype和大字体 6.5 插入符(不是光标) 6.5.l 插入符函数 6.5.2 typer 程序 第七章 鼠标 7.1 鼠标基础 7.1.1 一些简单的定义 7.2 客户区鼠标消息 7.2.l ... -
Windows 程序设计(第5版)(上、下册)--源代码
2012-04-22 19:21:456.4.4 unicode怎么样? 6.4.5 truetype和大字体 6.5 插入符(不是光标) 6.5.l 插入符函数 6.5.2 typer 程序 第七章 鼠标 7.1 鼠标基础 7.1.1 一些简单的定义 7.2 客户区鼠标消息 7.2.l ... -
史上最好传智播客就业班.net培训教程60G 不下会后悔的
2013-07-08 18:09:28学完了这阶段课程,学员将学会开发主流网站的前端效果,比如:焦点图、滚动展示图、网页防复制、网页自定义菜单、WebOS、美女时钟、无刷新评论、评分控件、表格特效、图片悬浮详细信息、微博界面、QQ消息框效果、Div...
-
MySQL你该了解的那些事【服务端篇】
-
ApacheFlink漫谈系列-概述
-
项目经理成长之路
-
Jenkins软件开发持续集成及自动构建
-
从理论到试验台,WiFi DCF网络的性能评估
-
MHA 高可用 MySQL 架构与 Altas 读写分离
-
HARMONY
-
2016年上半年 网络工程师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
JMETER 性能测试基础课程
-
java数独题库高效生成算法代码
-
Vue中的动画封装(5-7)
-
C++11 14 17 20 多线程从原理到线程池实战
-
RootCluster.github.io:组织网站-源码
-
在高密度软件定义的WiFi网络中实现负载平衡
-
美图大数据平台架构实践
-
龙芯生态应用开发基础:C语言精要
-
2009年上半年 网络工程师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
ASHRAE 2011 Liquid Cooling Whitepaper.pdf
-
破折号-源码
-
项目管理工具与方法