ANNEXB格式.docx

上传人:b****2 文档编号:1398851 上传时间:2023-04-30 格式:DOCX 页数:11 大小:57.19KB
下载 相关 举报
ANNEXB格式.docx_第1页
第1页 / 共11页
ANNEXB格式.docx_第2页
第2页 / 共11页
ANNEXB格式.docx_第3页
第3页 / 共11页
ANNEXB格式.docx_第4页
第4页 / 共11页
ANNEXB格式.docx_第5页
第5页 / 共11页
ANNEXB格式.docx_第6页
第6页 / 共11页
ANNEXB格式.docx_第7页
第7页 / 共11页
ANNEXB格式.docx_第8页
第8页 / 共11页
ANNEXB格式.docx_第9页
第9页 / 共11页
ANNEXB格式.docx_第10页
第10页 / 共11页
ANNEXB格式.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

ANNEXB格式.docx

《ANNEXB格式.docx》由会员分享,可在线阅读,更多相关《ANNEXB格式.docx(11页珍藏版)》请在冰点文库上搜索。

ANNEXB格式.docx

ANNEXB格式

AnnexB格式:

NALU数据+开始前缀(00000001或000001,此处注意为甚么是4bit或3bit,后面有描述);针对H.320电话会议

RTP格式:

NALU数据+20个字节的类似的并不符合RTP协议的RTP头。

针对IP网络的RTP打包方式

H.264协议只规定了字节流格式,没有规定RTP格式。

可能也是因为这个原因,JM的RTP格式没有被用到任何场合场合中,成为了摆设。

下图中的RTP格式是h.264乐园的firstime从JM86中分析出来的。

实际包交换网络中必须按照RFC3984将NALU数据封装为RTP包,而不能使用JM的RTP格式。

下面引自“QUESTIONMARK”的博客

下面说明3字节起始码和4字节起始码。

以下和leading_zero_8bits、trailing_zero_8bits已无关系,忘掉。

if(next_bits(24)!

=0x000001)

zero_bytef(8)

start_code_prefix_one_3bytesf(24)

根据B.1节,可以看到所谓的4字节起始码是(zero_byte+3字节起始码)。

那么看zero_byte的说明,就可以明白zero_byte什么时候出现,也就能明白什么时候出现4字节起始码:

1.SPS、PPSnalu是4字节起始码;

2.AccessUnit的首个nalu是4字节起始码(参见7.4.1.2.3)。

这里举个例子说明,用JM可以生成这样一段码流(不要使用JM8.6,它在这部分与标准不符),这个码流可以见本楼附件:

SPS(4字节头)

PPS(4字节头)

SEI(4字节头)

I0(slice0)(4字节头)

I0(slice1)(3字节头)

P1(slice0)(4字节头)

P1(slice1)(3字节头)

P2(slice0)(4字节头)

P2(slice1)(3字节头)

I0(slice0)是序列第一帧(I帧)的第一个slice,是当前AccessUnit的首个nalu,所以是4字节头。

而I0(slice1)表示第一帧的第二个slice,所以是3字节头。

P1(slice0)、P1(slice1)同理。

总结:

1附录B字节流在一个byte_stream_nal_unit的前后可能出现若干个0x00,仅用作填充之用。

这个不常见。

24字节头只出现在SPS、PPS和7.4.1.2.3规定的AccessUnit的首个nalu。

其余情况都是3字节头

一共有两种起始码:

3字节的0x000001和4字节的0x00000001

3字节的0x000001只有一种场合下使用,就是一个完整的帧被编为多个slice的时候,包含这些slice的nalu使用3字节起始码。

其余场合都是4字节的。

NAL层处理简析

(2010-06-0916:

00:

34)

转载▼

标签:

nal层

nal

杂谈

分类:

H.264

NAL(NetworkAbstractionLayer)基本上可分两种:

1,以有序字节流方式传送的针对H.320的;2,针对IP网络的RTP打包方式的。

NAL作用:

specifiedtoformatthatdataandprovideheaderinformationinamannerappropriateforconveyanceonavarietyofcommunicationchannelsorstoragemedia.

NAL的处理过程基本上分为两步:

1,将VCL层输出的SODB封装成nal_unit.

Nal_unit是一个通用封装格式,可以适用于有序字节流方式和IP包交换方式。

2,针对不同的传送网络(电路交换|包交换),将nal_unit封装成针对不同网络的封装格式。

第一步的具体过程:

VCL层输出的比特流SODB(StringOfDataBits),到nal_unit之间,经过了以下三步处理:

1,SODB字节对齐处理后封装成RBSP(RawByteSequencePayload)。

2,为防止RBSP的字节流与有序字节流传送方式下的SCP(start_code_prefix_one_3bytes,0x000001)出现字节竞争情形,循环检测RBSP前三个字节,在出现字节竞争时在第三字节前加入emulation_prevention_three_byte(0x03),具体方法:

nal_unit(NumBytesInNALunit){

forbidden_zero_bit

nal_ref_idc

nal_unit_type

NumBytesInRBSP=0

for(i=1;i

if(i+2

rbsp_byte[NumBytesInRBSP++]

rbsp_byte[NumBytesInRBSP++]

i+=2

emulation_prevention_three_byte

}else

rbsp_byte[NumBytesInRBSP++]

}

}

3,防字节竞争处理后的RBSP再加一个字节的header(forbidden_zero_bit+nal_ref_idc+nal_unit_type),封装成nal_unit.

第二步的具体过程:

case1:

有序字节流的封装

byte_stream_nal_unit(NumBytesInNALunit){

while(next_bits(24)!

=0x000001)

zero_byte

if(more_data_in_byte_stream()){

start_code_prefix_one_3bytesnal_unit(NumBytesInNALunit)

}

}

Case2:

IP网络的RTP打包封装

IDR(刷新帧)与I帧的一些知识点

(2010-06-0820:

38:

40)

转载▼

标签:

杂谈

分类:

H.264

IDR帧属于I帧,但是I帧不一定是IDR帧。

解码器收到IDR帧时,将驱动器参数块(DPB)清空。

而I帧不会。

(我自己理解为即把参考帧列表刷新从新更新,就是不再参考idr前面的帧)由此可见,在编码器端,每发一个IDR,就相应地发一个nal。

当然在现在的编码中,为了取得更高的图像质量,在一个视频文件中有好多个IDR帧,这些IDR帧把视频文件分成了片,但是每片中第一个帧是IDR,而且仅此一个

例如:

存在这样一段视频:

码流

IDR

B

B

P

B

B

P

……

帧号

1

2

3

4

5

6

7

……

对IDR帧的处理(与I帧的处理相同):

(1)进行帧内预测,决定所采用的帧内预测模式。

(2)像素值减去预测值,得到残差。

(3)对残差进行变换和量化。

(4)变长编码和算术编码。

(5)重构图像并滤波,得到的图像作为其它帧的参考帧。

这里要提一下,当编码器处理完IDR帧遇到B帧时,编码期先把其放入缓存器中存放起来。

直接对P进行编码。

即编码器中编码的实际顺序是IDRPBBPBB…..即1423756……

有用的来了

IDR-instantaneousdecodingrefresh(IDR)picture;

AcodedpictureinwhichallslicesareIorSIslicesthatcausesthedecodingprocesstomarkallreferencepicturesas"unusedforreference"immediatelyafterdecodingtheIDRpicture.AfterthedecodingofanIDRpictureallfollowingcodedpicturesindecodingordercanbedecodedwithoutinterpredictionfromanypicturedecodedpriortotheIDRpicture.ThefirstpictureofeachcodedvideosequenceisanIDRpicture.

“也就是说,IDR的出现其实是相当于向解码器发出了一个清理referencebuffer的信号吧,上面说前于这一帧的所有已编码帧不能为inter做参考帧了。

还有:

“因为264采用了多帧预测,就有可能在displayorder下I帧后的P会参考I帧前的帧,这样在randomaccess时如果只找I帧,随后的帧的参考帧可能unavailable,IDR就是这样一种特殊的I帧,把它定义为确保后面的P一定不参考其前面的帧,可以放心地randomaccess。

多参考帧情况下。

【转】SODBRBSPEBSP的来龙去脉

(2010-06-0721:

22:

39)

转载▼

标签:

h.264

起始码

起始码竞争

数据流结构

杂谈

分类:

H.264

H.264起始码

在网络传输h264数据时,一个UDP包就是一个NALU,解码器可以很方便的检测出NAL分界和解码。

但是如果编码数据存储为一个文件,原来的解码器将无法从数据流中分别出每个NAL的起始位置和终止位置,为此h.264用起始码来解决这一问题。

H.264编码时,在每个NAL前添加起始码0x000001,解码器在码流中检测到起始码,当前NAL结束。

为了防止NAL内部出现0x000001的数据,h.264又提出'防止竞争emulationprevention"机制,在编码完一个NAL时,如果检测出有连续两个0x00字节,就在后面插入一个0x03。

当解码器在NAL内部检测到0x000003的数据,就把0x03抛弃,恢复原始数据。

0x000000>>>>>>0x00000300

0x000001>>>>>>0x00000301

0x000002>>>>>>0x00000302

0x000003>>>>>>0x00000303

附上h.264解码nalu中检测起始码的算法流程

for(;;)

{

ifnext24bitsare0x000001

{

startCodeFound=true

break;

}

else

{

flush8bits

}

}//for(;;)

if(true==startCodeFound)

{

//startcodefound

//Flushthestartcodefound

flush24bits

//Nownavigateuptonextstartcodeandputtheinbetweenstuff

//inthenalstructure.

for(;;)

{

getnext24bits&checkifitequalsto0x000001

if(false==(next24bits==000001))

{

//searchforpattern0x000000

checkifnext24bitsare0x000000

if(false==result)

{

//copythebyteintothebuffer

copyonebytetotheNalunit

}

else

{

break;

}

}

else

{

break;

}

}//for(;;)

}

2.MPEG4起始码

MPEG4的特色是VOP,没有NALU的概念,仍使用startcode对每帧进行分界。

MPEG4的起始码是0x000001.另外MPEG4中很多起始码也很有用,比如video_object_sequence_start_code0x000001B0表示一个视频对象序列的开始,VO_start_code0x000001B6表示一个VOP的开始.0x000001B6之后的两位,是00表示Iframe,01表示Pframe,10表示Bframe.

SODB 数据比特串-->最原始的编码数据

RBSP 原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSPtrailingbits 一个bit“1”)若干比特“0”,以便字节对齐。

EBSP 扩展字节序列载荷-->在RBSP基础上填加了仿校验字节(0X03)它的原因是:

 在NALU加到Annexb上时,需要填加每组NALU之前的开始码StartCodePrefix,如果该NALU对应的slice为一帧的开始则用4位字节表示,ox00000001,否则用3位字节表示ox000001.为了使NALU主体中不包括与开始码相冲突的,在编码时,每遇到两个字节连续为0,就插入一个字节的0x03。

解码时将0x03去掉。

也称为脱壳操作。

网上查询的区别:

在对整帧图像的数据比特串(SODB)添加原始字节序列载荷(RBSP)结尾比特(RBSPtrailingbits,添加一比特的“1”和若干比特“0”,以便字节对齐)后,再检查RBSP中是否存在连续的三字节“0000000000000000000000xx”;若存在这种连续的三字节码,在第三字节前插入一字节的“0×03”,以免与起始码竞争,形成EBSP码流,这需要将近两倍的整帧图像码流大小。

为了减小存储器需求,在每个宏块编码结束后即检查该宏块SODB中的起始码竞争问题,并保留SODB最后两字节的零字节个数,以便与下一宏块的SODB的开始字节形成连续的起始码竞争检测;对一帧图像的最后一个宏块,先添加结尾停止比特,再检测起始码竞争。

本文来自CSDN博客,转载请标明出处:

typedefstruct

{

intbyte_pos;//!

intbits_to_go;//!

bytebyte_buf;//!

intstored_byte_pos;//!

intstored_bits_to_go;//!

bytestored_byte_buf;//!

bytebyte_buf_skip;//!

intbyte_pos_skip;//!

intbits_to_go_skip;//!

byte*streamBuffer;//!

intwrite_flag;//!

}Bitstream; 定义比特流结构

staticbyte*NAL_Payload_buffer;

voidSODBtoRBSP(Bitstream*currStream)

{

currStream->byte_buf<<=1;  //左移1bit

currStream->byte_buf|=1;   //在尾部填一个“1”占1bit

currStream->bits_to_go--;

currStream->byte_buf<<=currStream->bits_to_go;

currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;

currStream->bits_to_go=8;

currStream->byte_buf=0;

}

intRBSPtoEBSP(byte*streamBuffer,intbegin_bytepos,intend_bytepos,intmin_num_bytes)

{

inti,j,count;

for(i=begin_bytepos;i

NAL_Payload_buffer[i]=streamBuffer[i];

count=0;

j=begin_bytepos;

for(i=begin_bytepos;i

{

if(count==ZEROBYTES_SHORTSTARTCODE&&!

(NAL_Payload_buffer[i]&0xFC))

{

streamBuffer[j]=0x03;

j++;

count=0;

}

streamBuffer[j]=NAL_Payload_buffer[i];

if(NAL_Payload_buffer[i]==0x00)

count++;

else

count=0;

j++;

}

while(j

streamBuffer[j]=0x00;//cabacstuffingword

streamBuffer[j+1]=0x00;

streamBuffer[j+2]=0x03;

j+=3;

stat->bit_use_stuffingBits[img->type]+=16;

}

returnj;

}

在2010-6-915:

33:

33我又看到了别人博客上的一句话更加深了我的理解,这里贴出来。

感谢QuestionMark

标准7.4.1.1如是说:

ThisprocesscanallowanySODBtoberepresentedinaNALunitwhileensuringthat

–……

–nosequenceof8zero-valuedbitsfollowedbyastartcodeprefix,regardlessofbyte-alignment,isemulatedwithintheNALunit.

这段的意思是在nal_unit层面,即naluheader+RBSP的结构中,不可能出现0x000001这样的片段。

这是通过SODB->RBSP->EBSP的过程中添加防冲突字节实现的。

这里多说一句

标准附录B如是说:

anybytesequalto0x00thatfollowaNALunitsyntaxstructureandprecedethefour-bytesequence0x00000001(whichistobeinterpretedasazero_bytefollowedbyastart_code_prefix_one_3bytes)willbeconsideredtobetrailing_zero_8bitssyntaxelementsthatarepartoftheprecedingbytestreamNALunit.

这一段则在说明byte_stream_nal_unit层面。

结合B.1,可以明白这段话的意思是一个nalu之后,下一个起始码0x00000001之前,可能会有若干0x00,就是所谓的trailing_zero_8bits。

此外B.1中还说明了在码流的最开始,还有可能有若干0x00,就是所谓的leading_zero_8bits。

这些leading_zero_8bits和trailing_zero_8bits可能与传输打包有关,但在实际中,我没有见过包含这种“多余”的0x00的码流。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2