8.我的Graph 是:视频: 采集Filter ->帧率控制Filter ->编码Filter->发送Filter ->接收Filter->解码Filter->播放Filter
音频:采集Filter ->编码Filter->发送Filter ->接收Filter->解码Filter->播放Filter1.REFERENCE_TIME 的单位是多少的?我在发送Filter里面:pSample->GetTime(&stimer,&etimer);
视频过来的Sample :etimer - stimer = 333'333 一直不变(100ns的话正好30帧/s)。
音频过来的Sample:etimer - stimer= 600'000-700'000左右晃动, 而且音频的Sample过来的频率比视频高,难道REFERENCE_TIME针对视频、音频的单位是不一样的? 还是我音频的编码Filter把时戳给弄乱了。音频编码器是"MPEG Layer-3"2.数据接收过来后要怎么定义时戳?用什么标准来定义开始时间和结束时间?接收部分的Graph要自己来定义一个参考时钟吗?我在接收Filter里pSample->GetTime(&stimer,&etimer);stimer =300 etimer=7......... 发送是Sample带过来的时戳要怎么用?(我把stimer和etimer拿出来放到数据包头传输过去)
音频:采集Filter ->编码Filter->发送Filter ->接收Filter->解码Filter->播放Filter1.REFERENCE_TIME 的单位是多少的?我在发送Filter里面:pSample->GetTime(&stimer,&etimer);
视频过来的Sample :etimer - stimer = 333'333 一直不变(100ns的话正好30帧/s)。
音频过来的Sample:etimer - stimer= 600'000-700'000左右晃动, 而且音频的Sample过来的频率比视频高,难道REFERENCE_TIME针对视频、音频的单位是不一样的? 还是我音频的编码Filter把时戳给弄乱了。音频编码器是"MPEG Layer-3"2.数据接收过来后要怎么定义时戳?用什么标准来定义开始时间和结束时间?接收部分的Graph要自己来定义一个参考时钟吗?我在接收Filter里pSample->GetTime(&stimer,&etimer);stimer =300 etimer=7......... 发送是Sample带过来的时戳要怎么用?(我把stimer和etimer拿出来放到数据包头传输过去)
在graph里,以音频的时间戳为基准
我现在一个同步的思路是这样的:在接收端一直记录音频Sample过来的采集开始时间,作为当期时刻(m_nowtime),当一个视频Sample过来的时候,取这个视频Sample的采集时间 跟 当前时刻(m_nowtime)做比较,在一定范围内直接播放。大于这个范围就等待,小于这个范围就丢帧。
现在在发送端拿到的时戳,音频和视频感觉都不是一个标准的~就无法来做比较了。
----视频帧“等待”这个处理也还不知道要怎么实现。
我上面采集到的音频采集开始时间 和视频的采集开始时间,数值上的差距是越来越大,我都不知道怎么做比较~
这个采集的时间间隔是根据你所采集的视频帧率和音频参数来决定的,知道了每个Sample的采集间隔也就可以进行设置了。
不过,对采集来说,可能会存在误差的。
现在我试了两种同步的方法,效果都不好:
1.在视频接收Filter做个while循环。if(m_Vstimer >m_Astimer)//m_Vstimer 是这个视频数据包的时间,m_Astimer每当一个音频数据包过来了就更新下m_Astimer
{
while(1)
{
::Sleep(1);
//这样的实验效果视频比较卡,不能接收,同步效果好像不错(就做了几次测试),SLeep的时间越长图像卡的厉害
if(m_Vstimer <m_Astimer)
break;
}
}
mVideoReceiver->DeliverHoldingSample(samplelen,true);第二种方法:我在接收部分Graph里面把声音显示FILTER(是不是声卡) 的IReferenceClock接口作为参考时钟,
然后把发送端 视音频Sample的采集时戳直接设置成了 接收端这边的时戳。实现效果不行,图像卡的厉害,声音还行,同步效果感觉应该有效果的。视音频都比不设置时戳滞后了,同步上也感觉可以,但就是图像太卡,有丢帧。音频的效果一如既往的还是不错if(type)
{
// Do not use time stamp for video
REFERENCE_TIME rtEnd = pKlsMsg->m_Vstimer + 2*(UNITS/30);
// 奇特的是我采集的结束时戳放在包头传不过来,一直是一个负的很长值,REFERENCE_TIME 不就是LONGLONG数据类型吗。占8个字节。 所以我结束时戳都自己算出来加上去的,视频本来是30,我发送端控制了帧率变成了15帧。
//2*(UNITS/30); 和UNITS/30 的效果感觉差不多。
mSample->SetTime(&pKlsMsg->m_Vstimer,&rtEnd);
}
else
{
REFERENCE_TIME rtEnd =pKlsMsg->m_Astimer +(UNITS * inSampleSize / mAudioBytesPerSecond);
mSample->SetTime(&pKlsMsg->m_Astimer, &rtEnd);
}想问下两种方法可不可行,第二种方法还少了什么方面的设置?REFERENCE_TIME 的长度是不是8个字节的? 是不是LONGLONG 类型?(采集结束时戳的传递我等下搞搞)
第一种方法可不可行的?
还有其它好的方法吗?