检测MPEG-4传输流中的I帧数据

时间:2013-09-11 13:32:59

标签: c mpeg-4 mpeg2-ts transport-stream

我正在测试一个项目。我需要将来自用户的百分比的MPEG-4 ts数据包的有效载荷数据(零个字节)分开。我是通过按包读取“.ts”文件(188字节)来完成的。但视频正在变得非常泥泞。 (顺便说一下,我用C编写程序)

所以我决定找到属于I帧的数据/数据包,然后不接触它们,而是按百分比加扰其他数据。我可以在下面找到

(十六进制) 00 00 00 01 E0开始视频PES包 .. .. 00 00 01 B8组图片标题开始 .. .. 00 00 01 00图片起始码。这是32位。紧随其后的10位称为时间参考。因此,时间参考将包括图像起始码之后的字节和图像起始码之后的第二字节的前两位,即一个字节(8位)+2位。这些我们需要跳过。现在存在的三个位(来自图像起始码的第二个字节的3,4和5位)将指示帧类型,即I,B或P.因此,为了使这简单地逻辑AND&图像起始码的第二个字节为0x38,右移>>用3。

例如数据就是这样;

<00> 00 00 01 00 00 0F FF F8 00 00 01 B5 ...........依此类推。

这里前四个字节0​​0 00 01 00是图像起始码。 第六字节的第五字节和前两位是时间参考。 所以我们关注的是第六个字节 - &gt; 0F

((0F & 38)>>3)

帧类型= 1 ==&gt;我框架

禁止帧类型000

帧类型001帧内编码(I) - iframe

帧类型010预测编码(P) - p帧

帧类型011双向预测编码(B) - b帧

但这适用于MPEG-2。是否有一些这样的模式,所以我认识并获得MPEG-4传输流的按位操作的帧类型(扩展名为“.ts”)?

我需要知道该帧有多少字节或数据包?

非常感谢你的帮助

2 个答案:

答案 0 :(得分:5)

我会解析完整的TS数据包。因此,首先确定您的视频流属于哪个PID(通过解析PAT和PMT)。然后通过在“适应”字段中查找“随机访问指示符”位来查找关键帧。

uint8_t *pkt = <your 188 byte TS packet>;
assert( 0x47 == pkt[0] );
int16_t pid = ( ( pkt[1] & 0x1F) << 8 ) | pkt[2];
if ( pid == video_pid ) {
    // found video stream
    if( ( pkt[3] & 0x20 ) && ( pkt[4] > 0 ) ) {
        // have AF
        if ( pkt[5] & 0x40 ) {
          // found keyframe
} } }

答案 1 :(得分:-1)

如果您使用的是H.264,那么I和P帧应该有特定的字节流。 像I帧的0x0000000165和P帧的0x00000001XX。 所以只需解析并查找连续的字节流,这样就可以识别I帧或P帧。 上面的字节流再次依赖于编解码器实现.. 有关更多信息,请查看FFMPEG ..