H264流的 SPS(序列参数集Sequence Parameter Set)和PPS(图像参数集Picture Parameter Set)记录了视频的基本编码信息,在进行视频处理的时候,难免会对其进行处理,下面介绍几个相关的API对其进行解析和格式转换。
首先来看两种格式:
H.264码流分Annex-B和AVCC两种格式。 H.265码流是Annex-B和HVCC格式。 (以下内容针对H.264,但大体也适用于H.265/HEVC)
区别有两点:一个是参数集(SPS, PPS)组织格式;一个是分隔。 - Annex-B:使用start code分隔NAL(start code为三字节或四字节,0x000001或0x00000001,一般是四字节);SPS和PPS按流的方式写在头部。 - AVCC:使用NALU长度(固定字节,通常为4字节)分隔NAL;在头部包含extradata(或sequence header)的结构体。(extradata包含分隔的字节数、SPS和PPS)
举两个例子:
01 64 00 1f ff e1 00 19 67 64 00 1f ac d9 40 50 05 ba 10 00 00 03 00 10 00 00 03 03 c8 f1 83 19 60 01 00 05 68 ea ec b2 2c
00 00 00 01 67 64 00 28 ac b3 00 a0 0b 74 20 00 00 03 00 20 00 00 fa 01 e3 06 4d 00 00 00 01 68 e9 73 2c 8b
其中0x67表示SPS,0x68表示PPS
在flvenc.c里面可以看到有以下调用:
avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
avio_w8(pb, 0); // AVC sequence header
avio_wb24(pb, 0); // composition time
ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
将extradata以avcc的格式写入avc sequence header里面
AVCodec *const codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (codec != NULL)
{
AVCodecContext* ctx = avcodec_alloc_context3(codec);
ctx->debug = ~0;
ctx->extradata = (uint8_t *)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
ctx->extradata_size = size;
memcpy(ctx->extradata, data,size);
memset(&ctx->extradata[ctx->extradata_size], 0, FF_INPUT_BUFFER_PADDING_SIZE);
if (avcodec_open2(ctx, codec, NULL) < 0)
{
fprintf(stderr, "Failed to open codec\n");
}
else
{
char buf[1024];
avcodec_string(buf, sizeof(buf), ctx, 0);
fprintf(stderr, "[%s\n", buf);
}
avcodec_close(ctx);
av_free(ctx);
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。