mpeg4 esds及帧判断
2013-12-13 16:47
330 查看
esds box中主要是存放Element Stream Descriptors(ESDs),该box的前四个字节为version&flag,一般为0x 00 00 00 00;
从偏移第四个字节开始,为ESDs。
ESDs中可以分为三层,每层为包含关系,分别为MP4ESDescr,MP4DecConfigDescr,MP4DecSpecificDescr,每层的结构都类似如下:
typedef esdsStruct{
uint8_t tag;
<不定长,最长4字节> size;
uint8_t[size] data;
}esdsStruct;
各层的起始标签如下:
[cpp]
view plaincopy
#define MP4ESDescrTag 0x03
#define MP4DecConfigDescrTag 0x04
#define MP4DecSpecificDescrTag 0x05
起始标签后,为data size(不包含tag和size字节数),指示该层data的字节数。
其中,MP4DecConfigDescr层的data[0] 为objectTypeIndication<http://www.mp4ra.org/object.html>(一般来说,为esds box的data[11]),用于指示codec类型,定义如下:
[cpp]
view plaincopy
/* http://www.mp4ra.org */
/* ordered by muxing preference */
const AVCodecTag ff_mp4_obj_type[] = {
{ CODEC_ID_MOV_TEXT , 0x08 },
{ CODEC_ID_MPEG4 , 0x20 },
{ CODEC_ID_H264 , 0x21 },
{ CODEC_ID_AAC , 0x40 },
{ CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */
{ CODEC_ID_MPEG2VIDEO, 0x61 }, /* MPEG2 Main */
{ CODEC_ID_MPEG2VIDEO, 0x60 }, /* MPEG2 Simple */
{ CODEC_ID_MPEG2VIDEO, 0x62 }, /* MPEG2 SNR */
{ CODEC_ID_MPEG2VIDEO, 0x63 }, /* MPEG2 Spatial */
{ CODEC_ID_MPEG2VIDEO, 0x64 }, /* MPEG2 High */
{ CODEC_ID_MPEG2VIDEO, 0x65 }, /* MPEG2 422 */
{ CODEC_ID_AAC , 0x66 }, /* MPEG2 AAC Main */
{ CODEC_ID_AAC , 0x67 }, /* MPEG2 AAC Low */
{ CODEC_ID_AAC , 0x68 }, /* MPEG2 AAC SSR */
{ CODEC_ID_MP3 , 0x69 }, /* 13818-3 */
{ CODEC_ID_MP2 , 0x69 }, /* 11172-3 */
{ CODEC_ID_MPEG1VIDEO, 0x6A }, /* 11172-2 */
{ CODEC_ID_MP3 , 0x6B }, /* 11172-3 */
{ CODEC_ID_MJPEG , 0x6C }, /* 10918-1 */
{ CODEC_ID_PNG , 0x6D },
{ CODEC_ID_JPEG2000 , 0x6E }, /* 15444-1 */
{ CODEC_ID_VC1 , 0xA3 },
{ CODEC_ID_DIRAC , 0xA4 },
{ CODEC_ID_AC3 , 0xA5 },
{ CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */
{ CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */
{ CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */
{ CODEC_ID_QCELP , 0xE1 },
{ CODEC_ID_MPEG4SYSTEMS, 0x01 },
{ CODEC_ID_MPEG4SYSTEMS, 0x02 },
{ CODEC_ID_NONE , 0 },
};
当objectTypeIndication为0x40时,为MPEG-4 Audio(MPEG-4 Audio generally is thought of as AAC but there is a whole framework of audio codecs that can go in MPEG-4 Audio including AAC, BSAC, ALS, CELP, and something called MP3On4),如果想更细分format为aac还是mp3,可以读取MP4DecSpecificDescr层data[0]的前五位,详细可以参考另一篇文章:
[mp4]The audio codec for mp4 atom
MP4DecSpecificDescr层(一般来说,该层在esds box中的偏移为objectTypeIndication+13,即esds box的data[24])的data为初始化解码器的私有数据,如aac音频的头信息,mpeg4视频的vos,vo等头信息。
帧类型判断
mpeg4的每一帧开头是固定的:00 00 01 b6,那么我们如何判断当前帧属于什么帧呢?在接下来的2bit,将会告诉我们答案。注意:是2bit,不是byte,下面是各类型帧与2bit的对应关系:
00: I Frame
01: P Frame
10: B Frame
为了更好地说明,我们举几个例子,以下是16进制显示的视频编码:
00 00 01 b6 10 34 78 97 09 87 06 57 87 …… I帧
00 00 01 b6 50 78 34 20 cc 66 b3 89 …… P帧
00 00 01 b6 96 88 99 06 54 34 78 90 98 …… B帧
下面我们来分析一下为什么他们分别是I、P、B帧
0x10 = 0001 0000
0x50 = 0101 0000
0x96 = 1001 0100
大家看红色的2bit,再对照开头说的帧与2bit的对应关系,是不是符合了呢?
下面给出一段c++代码供大家参考:
从偏移第四个字节开始,为ESDs。
ESDs中可以分为三层,每层为包含关系,分别为MP4ESDescr,MP4DecConfigDescr,MP4DecSpecificDescr,每层的结构都类似如下:
typedef esdsStruct{
uint8_t tag;
<不定长,最长4字节> size;
uint8_t[size] data;
}esdsStruct;
各层的起始标签如下:
[cpp]
view plaincopy
#define MP4ESDescrTag 0x03
#define MP4DecConfigDescrTag 0x04
#define MP4DecSpecificDescrTag 0x05
起始标签后,为data size(不包含tag和size字节数),指示该层data的字节数。
其中,MP4DecConfigDescr层的data[0] 为objectTypeIndication<http://www.mp4ra.org/object.html>(一般来说,为esds box的data[11]),用于指示codec类型,定义如下:
[cpp]
view plaincopy
/* http://www.mp4ra.org */
/* ordered by muxing preference */
const AVCodecTag ff_mp4_obj_type[] = {
{ CODEC_ID_MOV_TEXT , 0x08 },
{ CODEC_ID_MPEG4 , 0x20 },
{ CODEC_ID_H264 , 0x21 },
{ CODEC_ID_AAC , 0x40 },
{ CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */
{ CODEC_ID_MPEG2VIDEO, 0x61 }, /* MPEG2 Main */
{ CODEC_ID_MPEG2VIDEO, 0x60 }, /* MPEG2 Simple */
{ CODEC_ID_MPEG2VIDEO, 0x62 }, /* MPEG2 SNR */
{ CODEC_ID_MPEG2VIDEO, 0x63 }, /* MPEG2 Spatial */
{ CODEC_ID_MPEG2VIDEO, 0x64 }, /* MPEG2 High */
{ CODEC_ID_MPEG2VIDEO, 0x65 }, /* MPEG2 422 */
{ CODEC_ID_AAC , 0x66 }, /* MPEG2 AAC Main */
{ CODEC_ID_AAC , 0x67 }, /* MPEG2 AAC Low */
{ CODEC_ID_AAC , 0x68 }, /* MPEG2 AAC SSR */
{ CODEC_ID_MP3 , 0x69 }, /* 13818-3 */
{ CODEC_ID_MP2 , 0x69 }, /* 11172-3 */
{ CODEC_ID_MPEG1VIDEO, 0x6A }, /* 11172-2 */
{ CODEC_ID_MP3 , 0x6B }, /* 11172-3 */
{ CODEC_ID_MJPEG , 0x6C }, /* 10918-1 */
{ CODEC_ID_PNG , 0x6D },
{ CODEC_ID_JPEG2000 , 0x6E }, /* 15444-1 */
{ CODEC_ID_VC1 , 0xA3 },
{ CODEC_ID_DIRAC , 0xA4 },
{ CODEC_ID_AC3 , 0xA5 },
{ CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */
{ CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */
{ CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */
{ CODEC_ID_QCELP , 0xE1 },
{ CODEC_ID_MPEG4SYSTEMS, 0x01 },
{ CODEC_ID_MPEG4SYSTEMS, 0x02 },
{ CODEC_ID_NONE , 0 },
};
当objectTypeIndication为0x40时,为MPEG-4 Audio(MPEG-4 Audio generally is thought of as AAC but there is a whole framework of audio codecs that can go in MPEG-4 Audio including AAC, BSAC, ALS, CELP, and something called MP3On4),如果想更细分format为aac还是mp3,可以读取MP4DecSpecificDescr层data[0]的前五位,详细可以参考另一篇文章:
[mp4]The audio codec for mp4 atom
MP4DecSpecificDescr层(一般来说,该层在esds box中的偏移为objectTypeIndication+13,即esds box的data[24])的data为初始化解码器的私有数据,如aac音频的头信息,mpeg4视频的vos,vo等头信息。
帧类型判断
mpeg4的每一帧开头是固定的:00 00 01 b6,那么我们如何判断当前帧属于什么帧呢?在接下来的2bit,将会告诉我们答案。注意:是2bit,不是byte,下面是各类型帧与2bit的对应关系:
00: I Frame
01: P Frame
10: B Frame
为了更好地说明,我们举几个例子,以下是16进制显示的视频编码:
00 00 01 b6 10 34 78 97 09 87 06 57 87 …… I帧
00 00 01 b6 50 78 34 20 cc 66 b3 89 …… P帧
00 00 01 b6 96 88 99 06 54 34 78 90 98 …… B帧
下面我们来分析一下为什么他们分别是I、P、B帧
0x10 = 0001 0000
0x50 = 0101 0000
0x96 = 1001 0100
大家看红色的2bit,再对照开头说的帧与2bit的对应关系,是不是符合了呢?
下面给出一段c++代码供大家参考:
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->switch(buf[i] & (BYTE)0xc0) { case 0x00: //I Frame break; case 0x40: //P Frame break; case 0x80: //B Frame break; default: break; }
相关文章推荐
- Compile wpa_supplicant2.0 for IPNC
- 时过境迁后。。。。。。。。。。
- Session blocked itself
- C语言头文件的作用
- 用于验证码图片识别的类(C#源码)
- 作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这
- C++ 基类私有纯虚函数 在派生类中的实现
- OpenGLes2.0 什么是Pbuffer
- Ferris教程学习笔记:js示例3.8 简易网页时钟
- 我的战场 -- 书
- 机器学习算法与Python实践之(三)支持向量机(SVM)进阶
- 【Android】Android之Action Bar
- 冒泡排序
- SSH登录报错Permission denied (publickey)
- iOS 7 教程:定制iOS 7中的导航栏和状态栏
- 每周日与周四《红酒屋》探戈舞会"Wine Bar" Milonga_原生态拉丁_新浪博客
- 消息提示demo
- Ferris教程学习笔记:js示例3.6 判断数字是否为两位数
- LIKE 某个变量
- VM 下安装fedora19问题的解决办法