MPEG4码流格式分析

您所在的位置:网站首页 mpeg4转mp4格式一样吗 MPEG4码流格式分析

MPEG4码流格式分析

2024-06-11 16:50| 来源: 网络整理| 查看: 265

参考:

MPEG4码流简单分析:http://blog.csdn.net/axdc_qa_team/article/details/4042762

关于MPEG4 码流(mpeg4 raw data)的格式分析:http://blog.csdn.net/vblittleboy/article/details/6695973

mpeg4 码流格式:http://blog.csdn.net/wuzhong325/article/details/7195171

=====================================================================

MPEG4码流视频关键帧头部16个字节,非关键帧8个字节(均包含四字节ID),说明如下:

关键帧:

字节

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E

F

0

0

1

FB

XX

R

W&H

Date time

Length

含义

ID

图像大小

时间戳

帧长度

非关键帧

字节

0

1

2

3

4

5

6

7

0

0

1

FA

Length

含义

ID

帧长度

XX:保留。

RATE:帧率,低5位表示帧率,目前取值从1到30,高三位表示解交错,可选0,1,2其中0做解交错,2不做解交错。

WIDTH和HEIGHT表示视频数据高度和宽度,一个字节最大256,所以存储的信息为真实高度和宽度的1/8。

TIMESTAMP:帧时间戳:

struct DateTime

{

DWORDsecond :6; // 秒 1-60

DWORDminute :6; // 分 1-60

DWORDhour :5; // 时 1-24

DWORDday :5; // 日 1-31

DWORDmonth :4; // 月 1-12

DWORDyear :6; // 年 2000-2063

};

非关键帧的时间戳是根据帧率和对关键帧的偏移计数计算出来的。

LENGTH:帧长度,低字节优先,不包括帧头长度(16字节或者8字节,这个需要注意)

H.264码流跟MPEG4的最大不同在于ID,关键帧ID为000001FD,非关键帧ID为000001FC。

给一个例子:



===============================================================================

测试解码器测试了很久,由于需要将H264和MPEG4的码流进行分析和判断,并逐帧输入解码器进行测试,如何正确的分析码流,并将Video送给我们的解码器做Decode的呢?耐着性子找了很多资料,主要也因为我本身对MPEG4和H264的码流的格式并不懂,自己在视频编码方面的积累也实在是太少了,所以也确实挺头疼的。后来就直接在网上找是否有对码流的各个部分意义的解释,开始搜索码流中的的StartCode。高兴的是,最终找到了一些有用的讯息,得以继续进行测试代码的撰写。

今天就把MPEG4码流的分析和它的I,P,B Frame的判定方法在这里简要记录一下吧,供日后的翻看和大家的参考。!

MPEG4码流分析:

0x00, 0x00, 0x01, 0xB0作为一个VOS的开始;

0x00, 0x00, 0x01, 0xB6作为一个VOP的开始,紧跟着VOP开始的,有一个2bit 的标志,用来表示这个Frame到底是一个 I Frame,P Frame,B Frame抑或是S Frame(GMS-VOP)

标志如下:

00: I Frame

01: P Frame

10: B Frame

11: S Frame

但是,有关这 2bit 是在0xB6的后面字节的高位还是低位,却没有很明确的描述。

于是又回头开始针对某个MPEG4编码好的文件开始分析,结果终于发现,判定方法如下:

1.可以写一个判定VOP,或者VOS开头的函数:

static unsigned char *Find_VOP_Start(unsigned char *addrp, unsigned int FindSizes) { while(pos < FindSizes) { if(addrp[pos] == 0x00) if(addrp[pos + 1] == 0x00) if(addrp[pos + 2] == 0x01) if(addrp[pos + 3] == 0xB0) break; //判断是否是VOS头; if(addrp[pos] == 0x00) if(addrp[pos + 1] == 0x00) if(addrp[pos + 2] == 0x01) if(addrp[pos + 3] == 0xB6) break; //判断是否是VOP头 pos++; } if(pos< FindSizes - 4) { return addrp+pos+4; } else return NULL; } 2. 读一个MPEG4码流文件,然后利用刚才写的函数搜索StartCode:

size_t nRead = fread(lpSrc, 1, lSize, fp); fseek(fp, 0, SEEK_SET); while (!feof(fp)) { unsigned char *p=Find_VOP_Start(lpSrc,lSize); if (pos) //pos为文件当前指针 { length=pos-poslast+header; //每帧长度为两个StartCode之间的字节数; if (lengthm4v

    xvid_encraw.exe -i foreman_cif.yuv -w 352 -h 288  -framerate 15 -csp i420 -o foreman_cif.m4v

    ffmpeg m4v->mp4

    ffmpeg -s cif -vcodec mpeg4 -i foreman_cif.m4v foreman_cif.mp4



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3