单一视频流 Filter Graph 如图 2 : 图 2 单一视频流的 Filter Graph 注意: 紧靠 Video Renderer 的上一级 Filter 的 Video 输出 Pin ,其 GetMediaType 函数提供的 Media Type 的 VIDEOINFOHEADER 结构要求填写完整,不仅包括图像的宽度、高度、像素位数,
单一视频流
Filter Graph 如图 2 :
图 2 单一视频流的 Filter Graph
注意: 紧靠 Video Renderer 的上一级 Filter 的 Video 输出 Pin ,其 GetMediaType 函数提供的 Media Type 的 VIDEOINFOHEADER 结构要求填写完整,不仅包括图像的宽度、高度、像素位数,还包括 BITMAPINFOHEADER 结构的大小( biSize ,指定为 sizeof(BITMAPINFOHEADER) )、平面数( biPlanes ,指定为 1 )。如果需要调色板, BITMAPINFOHEADER 数据结构后面还要带上调色板数据;如果是 16 位的 RGB 格式, BITMAPINFOHEADER 数据结构后面则要带上 RGB 分量提取的掩码。代码参考如下:
VIDEOINFO mVideoInfo;
ZeroMemory(&mVideoInfo, sizeof(mVideoInfo));
mVideoInfo.AvgTimePerFrame = 333667;
mVideoInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
mVideoInfo.bmiHeader.biWidth = 352;
mVideoInfo.bmiHeader.biHeight = 240;
mVideoInfo.bmiHeader.biBitCount = 16;
mVideoInfo.bmiHeader.biPlanes = 1;
mVideoInfo.bmiHeader.biCompression = BI_BITFIELDS;
mVideoInfo.bmiHeader.biSizeImage = mVideoInfo.bmiHeader.biWidth *
mVideoInfo.bmiHeader.biHeight * mVideoInfo.bmiHeader.biBitCount / 8;
for (int i = 0; i
{
mVideoInfo.dwBitMasks[i] = bits565[i];
}
1. 使用 Filter Graph Manager 默认的参考时钟
注 :如果 Filter Graph 中没有一个 Filter 实现 IReferenceClock 接口,则该 Filter Graph 默认使用系统时钟作为参考时钟。
1.1 Video Sample 不打时间戳 、连续送出
现象:视频以最快的速度播放。 Video Renderer 不发送 Quality Control 消息。 流时间线性增加。
Msiavsrc.ax(tid 920) 2307 : stream time: 120000
Msiavsrc.ax(tid 920) 2309 : stream time: 140000
Msiavsrc.ax(tid 920) 2311 : stream time: 160000
Msiavsrc.ax(tid 920) 2314 : stream time: 190000
Msiavsrc.ax(tid 920) 2316 : stream time: 210000
Msiavsrc.ax(tid 920) 2318 : stream time: 230000
Msiavsrc.ax(tid 920) 2320 : stream time: 250000
……
Msiavsrc.ax(tid 920) 3569 : stream time: 12740000 (最后一个 Sample )
1.2 Video Sample 不打时间戳 、间隙送出(模拟网络阻塞情况)
现象:视频播放一顿一顿。 Video Renderer 不发送 Quality Control 消息。 视频数据流的阻塞不会影响流时间。 流时间线性增加,间隙休眠的时间反映在前后两次获得的流时间上。
Msiavsrc.ax(tid 970) 2385 : stream time: 680000
Msiavsrc.ax(tid 970) 2389 : stream time: 720000
Msiavsrc.ax(tid 970) 4390 : Sleep(2000)... (出现视频播放的停顿)
Msiavsrc.ax(tid 970) 4391 : stream time: 20740000 (流时间反映出 Sleep 的 2s )
Msiavsrc.ax(tid 970) 4393 : stream time: 20760000
Msiavsrc.ax(tid 970) 4395 : stream time: 20780000
……
Msiavsrc.ax(tid 970) 39826 : stream time: 375090000 (最后一个 Sample )
1.3 Video Sample 打(连续)时间戳、连续送出
现象:视频连续播放。 Video Renderer 发送 Quality Control 消息进行反馈控制。 流时间线性增加,两次获取的流时间差大致是一帧的显示时间。
Msiavsrc.ax(tid 970) 4105 : stream time: 3600000
Msiavsrc.ax(tid 970) 4106 : Quality control (Famine) received.
Msiavsrc.ax(tid 970) 4139 : stream time: 3940000
Msiavsrc.ax(tid 970) 4140 : Quality control (Famine) received.
Msiavsrc.ax(tid 970) 4171 : stream time: 4260000
Msiavsrc.ax(tid 970) 4172 : Quality control (Famine) received.
Msiavsrc.ax(tid 970) 4205 : stream time: 4600000
Msiavsrc.ax(tid 970) 4206 : Quality control (Famine) received.
Msiavsrc.ax(tid 970) 4238 : stream time: 4930000
Msiavsrc.ax(tid 970) 4239 : Quality control (Famine) received.
……
Msiavsrc.ax(tid 970) 21922 : stream time: 181770000 (最后一个 Sample )
1.4 Video Sample 打时间戳(中途复位一次,时间戳从 0 重打)、连续送出
现象:播放较连续。 Video Renderer 发送 Quality Control 消息进行反馈控制。 时间戳复位后有一个[快镜头],相邻两次 Sample 发送的时间差较小(正常时应该是一帧图像的显示时间),说明 Video Renderer 收到 Sample 后马上返回,以最快速度处理 Sample ,使 Sample 时间戳能够再次赶上流时间。
Msiavsrc.ax(tid 964) 2133 : stream time: 12280000
Msiavsrc.ax(tid 964) 2165 : stream time: 12600000
Msiavsrc.ax(tid 964) 2166 : Reset time stamp...
Msiavsrc.ax(tid 964) 2199 : stream time: 12940000 (流时间递增缓慢)
Msiavsrc.ax(tid 964) 2201 : stream time: 12960000
Msiavsrc.ax(tid 964) 2203 : stream time: 12980000
Msiavsrc.ax(tid 964) 2205 : stream time: 13000000
Msiavsrc.ax(tid 964) 2208 : stream time: 13030000
Msiavsrc.ax(tid 964) 2210 : stream time: 13050000
Msiavsrc.ax(tid 964) 2212 : stream time: 13070000
Msiavsrc.ax(tid 964) 2214 : stream time: 13090000
……
Msiavsrc.ax(tid 964) 17748 : stream time: 168430000 (最后一个 Sample )
1.5 Video Sample 打时间戳(时间戳超前流时间一个 delta )、连续送出
现象:等待 delta 后播放连续。 Video Renderer 发送 Quality Control 消息进行反馈控制。
Msiavsrc.ax(tid 848) 821 : stream time: 4167195720000 (随机值,此 Sample 送出后被 Video Renderer 阻塞)
Msiavsrc.ax(tid 848) 5828 : stream time: 49940000 ( delta 在此反映出来)
Msiavsrc.ax(tid 848) 5860 : stream time: 50250000
Msiavsrc.ax(tid 848) 5892 : stream time: 50580000
Msiavsrc.ax(tid 848) 5927 : stream time: 50930000
……
Msiavsrc.ax(tid 848) 22677 : stream time: 218430000 (最后一个 Sample )
1.6 Video Sample 打时间戳(时间戳随机乱序)、连续送出
现象:播放有断续、有快镜头。 Video Renderer 发送 Quality Control 消息进行反馈控制。整个播放过程中,如果新 Sample 的时间戳比流时间超前,则 Sample 会被 Video Renderer 阻塞住,直到流时间到达 Sample 时间后才开始播放;如果新 Sample 的时间戳比流时间滞后, Sample 到达 Video Renderer 后会被立即播放,因此出现快镜头,直到 Sample 的时间戳赶上流时间后视频才恢复正常速度。 总之,视频流不会影响参考时钟的正常运作。
Msiavsrc.ax(tid 610) 1774 : stream time: 5590000
Msiavsrc.ax(tid 610) 1807 : stream time: 5930000
Msiavsrc.ax(tid 610) 1808 : Add 5 second delta...
Msiavsrc.ax(tid 610) 1841 : stream time: 6270000 (此 Sample 送出后阻塞)
Msiavsrc.ax(tid 610) 6873 : stream time: 56590000 (流时间到达 Sample 上的时间戳后再继续播放)
Msiavsrc.ax(tid 610) 6906 : stream time: 56920000
Msiavsrc.ax(tid 610) 6940 : stream time: 57260000
……
Msiavsrc.ax(tid 610) 7440 : stream time: 62260000
Msiavsrc.ax(tid 610) 7473 : stream time: 62590000
Msiavsrc.ax(tid 610) 7474 : Add -3 second delta...
Msiavsrc.ax(tid 610) 7508 : stream time: 62940000 (出现快镜头, Sample 以很快的速度发送给 Video Renderer )
Msiavsrc.ax(tid 610) 7509 : stream time: 62950000
Msiavsrc.ax(tid 610) 7511 : stream time: 62970000
Msiavsrc.ax(tid 610) 7512 : stream time: 62980000
Msiavsrc.ax(tid 610) 7513 : stream time: 62990000
……
Msiavsrc.ax(tid 610) 7563 : stream time: 63490000
Msiavsrc.ax(tid 610) 7564 : stream time: 63500000
Msiavsrc.ax(tid 610) 7566 : Do not add delta...
Msiavsrc.ax(tid 610) 7566 : stream time: 63520000
Msiavsrc.ax(tid 610) 7567 : stream time: 63530000
Msiavsrc.ax(tid 610) 7568 : stream time: 63540000
Msiavsrc.ax(tid 610) 7570 : stream time: 63560000
……
Msiavsrc.ax(tid 610) 7719 : stream time: 65050000
Msiavsrc.ax(tid 610) 7721 : stream time: 65070000
Msiavsrc.ax(tid 610) 7722 : stream time: 65080000
Msiavsrc.ax(tid 610) 7746 : stream time: 65320000 ( Sample 时间戳终于赶上了流时间)
Msiavsrc.ax(tid 610) 7779 : stream time: 65650000
……
Msiavsrc.ax(tid 610) 19390 : stream time: 181760000 (最后一个 Sample )
1.7 Video Sample 打(连续)时间戳、间隙送出(模拟网络阻塞情况)
现象:视频播放一顿一顿。 Video Renderer 发送 Quality Control 消息进行反馈控制。无数据时,流时间仍然在走;于是紧接着下一个 Sample 到达 Video Renderer 时已经[迟到],所以会出现快镜头。
Msiavsrc.ax(tid 678) 1667 : stream time: 8940000
Msiavsrc.ax(tid 678) 1700 : stream time: 9270000
Msiavsrc.ax(tid 678) 3701 : Sleep(2000)... (此时阻塞显示上一个 Sample 的图像)
Msiavsrc.ax(tid 678) 3702 : stream time: 29290000 (出现快镜头)
Msiavsrc.ax(tid 678) 3704 : stream time: 29310000
Msiavsrc.ax(tid 678) 3706 : stream time: 29330000
……
Msiavsrc.ax(tid 678) 3762 : stream time: 29890000
Msiavsrc.ax(tid 678) 3766 : stream time: 29930000
Msiavsrc.ax(tid 678) 5767 : Sleep(2000)... (此时阻塞显示上一个 Sample 的图像)
Msiavsrc.ax(tid 678) 5768 : stream time: 49950000 (出现快镜头)
Msiavsrc.ax(tid 678) 5770 : stream time: 49970000
Msiavsrc.ax(tid 678) 5772 : stream time: 49990000
……
Msiavsrc.ax(tid 678) 38788 : stream time: 380150000 (最后一个 Sample )
2. Filter Graph 不使用参考时钟
现象:不管 Video Sample 打不打时间戳,也不管时间戳打得是否正确,视频都是以最快的速度播放。并且 Video Renderer 不发送 Quality Control 消息。如果 Video Sample 送出过程中有间隙性停顿,视频也会出现间隙性的停顿。
3. Filter Graph 中残留(处于未连接状态)一个 Audio Renderer
注 :默认情况下, Audio Renderer 会被选中为 Filter Graph 的参考时钟。
Filter Graph 如图 3 :
图 3 残留一个 Audio Renderer 的单一视频流 Filter Graph
测试结果均与以系统时钟作为 Filter Graph 的参考时钟的情况类似。
小结:
v 在任何时候, Video Sample 上的时间戳都不会影响 Filter Graph 的流时间。
v 如果 Video Sample 上没有时间戳,则 Video Renderer 以最快速度处理 Sample 数据;如果有时间戳,则根据时间戳以及当前的流时间来安排 Sample 内容(视频图像)的显示。若 Sample 上的时间戳超前流时间, Video Renderer 将该 Sample 阻塞,直到流时间到达 Sample 时间戳后再开始播放;若 Sample 上的时间戳滞后于流时间, Video Renderer 将 Sample 内容立即显示后返回,以最快速度处理 Sample ,以使 Sample 时间戳尽快追赶流时间。
v 视频流播放过程中有一个 Quality Control 机制; Quality Control 消息发送者是 Video Renderer ,反馈给数据发送线程,以加快或减慢数据发送速度,试图提高服务质量。
v
如果您能从上述数据中得到更多重要的结论,请告诉我 luqiming@263.net 。
查看更多关于DirectShow音视频同步实验报告(2)的详细内容...