群里经常有人问IPB帧的判断,然后研究了一下,发现了这篇帖子,转过来给大伙看看
目前AVI Player的进展不太顺利,虽然AVI文件本身的解析没有问题,完全可以将Video & Audio data正确的抓取出来,但是将Video送给 SPCE3200 做 Decode的时候就完蛋了。真是郁闷~!! 耐着性子跟踪了一下,企图可以找到不能Decode的原因(其实这些都是徒劳的,因为我本身对MPEG4的码流的格式并不懂),但是一无所获。因为自己在MPEG4编码方面的积累实在是太少了!! 后来突然想到,干脆去网上看看,是否有对码流的各个部分的意义的解释吧。于是,就拿0x00, 0x00, 0x01, 0xb6这个 Match Code 开始搜索。 让我高兴的是,竟然真的找到了一些有用的讯息:I,P,B Frame的判定方法! 0x00, 0x00, 0x01, 0xb6作为一个VOL(VOP?)的开始,紧跟着它的,有 2bit 的标志,用来表征这个 Frame到底是一个 I Frame还是 P Frame,抑或是 B Frame:
- 00: I Frame
- 01: P Frame
- 10: B Frame
复制代码
但是,有关这 2bit 是在0xb6的后面字节的高位还是低位,却没有很明确的描述。
于是又回头开始针对某个AVI文件开始分析,结果终于发现,判定方法原来是这个样子滴: - static char *Find_VOP_Start(unsigned char *addrp, unsigned int FindSizes)
- {
- int i = 0;
- while(i < FindSizes)
- {
- if(addrp[i] == 0x00)
- if(addrp[i + 1] == 0x00)
- if(addrp[i + 2] == 0x01)
- if(addrp[i + 3] == 0xB6)
- break;
- i++;
- }[/font][/color][/p][p=25, null, left][color=#333333][font=Verdana, Arial, Tahoma]if(i < FindSizes - 4)
- return addrp + i + 4;
- else
- return 0;
- }[/font][/color][/p][p=25, null, left][color=#333333][font=Verdana, Arial, Tahoma]unsigned int *p = Find_VOP_Start(VLCData, VLCSize);
- switch(*p & 0xC0)
- {
- case 0x00:
- // I Frame
- break;
- case 0x40:
- // P Frame
- break;
- case 0x80:
- // B Frame
- break;
- }[/font][/color][/p][p=25, null, left][color=#333333][font=Verdana, Arial, Tahoma]
复制代码 还是拿图来说明一下吧。下图中,第一个Frame是B Frame,第二个是一个P Frame:
|