从mpeg ts文件中提取I帧(4):es包的解析
去掉了pes头剩下的数据就是es包,es就是一帧压缩了的视频或者音频。
对应mpeg2的视频序列语法格式如下图:
按照上图语法格式进行解析,有如下几点需要注意:
一、pes对es的封装有2种形式
1、一个pes包只包含一个es包。
2、一个pes包包含多个es包,即一组视频帧序列。
二、关于start_code
1、每个起始码由一个起始码前缀加一个起始码值组成。
2、起始码前缀的比特串为 "0000 0000 0000 0000 0000 0001" 即0x000001
3、起始码值是一个8比特整数,用于标识起始码类型。具体见下图。
4、所有的起始码应是字节对准的,这可在起始码之前插入0值来实现。
如上图所示 picture_coding_extension 标准上占10个字节,红圈里的00便是插入的。
因此计算next_start_code时需要跳过这2个字节。代码如下:
static int next_strat_code(uint8_t *data, uint32_t size, uint8_t *code, int32_t *offset)
{
uint8_t *ptr = data;
*code = 0xff;
*offset = 0;
while (!ptr[0]) {
if ((0x00==ptr[0]) && (0x00==ptr[1]) && (0x01==ptr[2])) {
*code = ptr[3];
*offset = ptr - data;
break;
}
ptr ++;
if ((ptr-data) > size) {
print_err("size=%d\n", size);
return -1;
}
}
return 0;
}
三、I帧的判断
通过解析picture_header中的picture_coding_type进行判断
picture_header语法结构:
picture_coding_type 含义:
至此我们已经可以判断出一个pes是否是I帧了,当然我也可以通过video_sequence的解析获取其他有用的信息。
例如:
sequence_header中可以获取:
视频宽度horizontal_size_vale 视频高度vertical_size_value 帧率frame_rate_code
sequence_extention中可以获取:
色彩格式chroma_format 也就是yuv格式 4:2:0
具体请参考mpeg2视频标准
mpeg2标准:https://download.csdn.net/download/maxzero/10402761
完整的代码:https://download.csdn.net/download/maxzero/10572383