nalu格式annex-B和avcc

一 annexb和avcc

Annexb

视频编码成的包叫做Network Abstraction Layer Units, 也简称为NALU、NAL,每个NALU包都可以被单独的解析和处理,每个NALU包的第一个字节包含了NALU类型,bit3-bit7包含的内容尤其重要(bit 0一定是off的,bit1-2指定了这个NALU是否被其他NALU引用)。
NALU格式分为2类,VCL和non-VCL,总共有19种不同的NALU格式。 即常见的如0x00 00 00 01/0x00 00 01

avcc格式

另一个存储H.264流的方式是AVCC格式,在这种格式中,每一个NALU包都加上了一个指定其长度(NALU包大小)的前缀(in big endian format大端格式),这种格式的包非常容易解析,但是这种格式去掉了Annex B格式中的字节对齐特性,而且前缀可以是1、2或4字节,这让AVCC格式变得更复杂了,指定前缀字节数(1、2或4字节)的值保存在一个头部对象中(流开始的部分),这个头通常称为'extradata'或者'sequence header',

 

编码器出来的帧都是annexb格式,大部分容器会把annexb转换为avcc再进行存储。

例如mp4封装代码:

if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {

/* from x264 or from bytestream H.264 */

/* NAL reformatting needed */

if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {

ret = ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,

&size);

if (ret < 0)

return ret;

avio_write(pb, reformatted_data, size);

}

 

int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)

{

AVIOContext *pb;

int ret = avio_open_dyn_buf(&pb);

if(ret < 0)

return ret;

 

ff_avc_parse_nal_units(pb, buf_in, *size);

 

*size = avio_close_dyn_buf(pb, buf);

return 0;

}

int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)

{

const uint8_t *p = buf_in;

const uint8_t *end = p + size;

const uint8_t *nal_start, *nal_end;

 

size = 0;

nal_start = ff_avc_find_startcode(p, end);

for (;;) {

while (nal_start < end && !*(nal_start++));

if (nal_start == end)

break;

 

nal_end = ff_avc_find_startcode(nal_start, end);

avio_wb32(pb, nal_end - nal_start);

avio_write(pb, nal_start, nal_end - nal_start);

size += 4 + nal_end - nal_start;

nal_start = nal_end;

}

return size;

}

flv 封装也是用的这个函数。

通过上面的代码可以看出来,ffmpeg都是通过extradata来判断要不要做格式转换的,这个extradata和编码设置GLOBAL_HEADER有关,

所以直接设置GLOBAL_HEADER 编码后的数据就能以avcc格式写入容器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值