如何获得给定h264流(Silverlight)的准确持续时间?

时间:2012-02-21 22:18:39

标签: c#-4.0 silverlight-4.0 h.264

背景 我使用ffmpeg编码了一个原始的h264文件。我正在尝试创建自己的容器,就像Smooth Streaming如何使用碎片化的mp4容器一样。我对平滑流的安全性不满意,因为任何人都可以通过适当的身份验证从IIS中完全删除文件。

问题 无论如何,我的原始h264流播放“有点”使用Silverlight中的MediaStreamSource并启用了ssl,但是我无法获得正确的时间戳,因为我将从服务器端发送到Silverlight客户端中的MediaStreamSource。我用sps Nals解析的h264数据块之间存在延迟。我看到了this question的持续时间。想知道是否有一种简单的方法来计算h264流中的帧并获得持续时间,以便我可以将准确的时间戳传递给MediaSampleSource。如果有人可以A:指向我的开源帧计数器的方向或给我一些伪代码解析帧(也许一些十六进制解析提示)。或者也许有人对这个确切的问题有一些经验会很棒。任何帮助都会非常感激。提前致谢。

2 个答案:

答案 0 :(得分:0)

我挖掘了ISO 14496-10文档,发现了一些用于在原始h264流中查找帧的十六进制字符串:

<强> 0x00000141, 0x00000101, 0x00000165

如果你浏览你的流并使用ffmpeg和libx264计算这些十六进制字符串和你的编码,这应该会给你一个非常可靠的帧数。 (如果我错了,请有人纠正我)。因此,如果您拥有h264视频的总持续时间并且您拥有可以从ffmpeg轻松获得的FPS,那么您可以使用在传递给MediaStreamSource的任何给定数据块中计算的帧数来获得适用于MediaSampleSource的TimeStamp非常准确。希望这对某人有所帮助,因为几天前我的播放时间非常不稳定,这让我非常沮丧。

修改

由于我在directshow中测试了我的播放功能,我注意到这并不完美,只适用于使用ffmpeg进行简单编码的h264流。 h264具有可变帧速率和比特率。虽然视频运行得非常流畅,但眼光敏锐的眼睛可以看到,在视频中更复杂的序列时,时间有点尴尬。我认为对于粗略的视频流播放器来说,这是一种很好的方法,尤其是在频繁使用关键帧的情况下。我认为在点击回答之前加上这个是公平的。

答案 1 :(得分:0)

这实际上是一个兔子洞。从ISO 14496第10部分开始,然后转到第7.3节进行语法处理。

第一个近似值是使用vui_parameters(num_units_in_tick / time_scale)中的字段速率和slice_header()s的数量。

如果您正在处理高清内容并且您的编码器每张图片使用多个slice_header(),则会出现故障(然后您必须检查first_mb_in_slice == 0)。

你必须注意frame_mbs_only_flag和field_pic_flag。

另一个毛球是表D-1,其解释了pic_timing SEI消息的pic_struct字段。这包括场重复(TBT或BTB),帧倍增和帧三倍等。

如果您有传输流,则可以通过检查第一个和最后一个访问单元的PES标头(ISO 13818第1部分)上的DTS值来结束此操作。