专栏首页Thomas的技术专栏Ffmpeg对sps/pps的解析和格式转换
原创

Ffmpeg对sps/pps的解析和格式转换

H264流的 SPS(序列参数集Sequence Parameter Set)和PPS(图像参数集Picture Parameter Set)记录了视频的基本编码信息,在进行视频处理的时候,难免会对其进行处理,下面介绍几个相关的API对其进行解析和格式转换。

首先来看两种格式:

Annex-B 和 AVCC/HVCC

H.264码流分Annex-B和AVCC两种格式。 H.265码流是Annex-B和HVCC格式。 (以下内容针对H.264,但大体也适用于H.265/HEVC)

别名

  • AVCC格式 也叫AVC1格式,MPEG-4格式,字节对齐,因此也叫Byte-Stream Format。用于mp4/flv/mkv, VideoToolbox。
  • Annex-B格式 也叫MPEG-2 transport stream format格式(ts格式), ElementaryStream格式

结构上的区别:

区别有两点:一个是参数集(SPS, PPS)组织格式;一个是分隔。 - Annex-B:使用start code分隔NAL(start code为三字节或四字节,0x000001或0x00000001,一般是四字节);SPS和PPS按流的方式写在头部。 - AVCC:使用NALU长度(固定字节,通常为4字节)分隔NAL;在头部包含extradata(或sequence header)的结构体。(extradata包含分隔的字节数、SPS和PPS)

举两个例子:

avcc格式:

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

annex-b格式

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

Annex-B格式转AVCC

int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)

在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里面

AVCC格式转Annex-B

int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)

解析Annex-B格式

    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);
    }
     

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于python计算并显示日间、星期客流高峰

    砸漏
  • XSS相关Payload及Bypass的备忘录(下)| 文末有打包好的Payload

    上述payload都打包在了下面链接中,自己现行研究一番,在哪里使用,可以做些模糊测试工作,具体自己研究研究吧,最后 全部.txt 是我将其中的payload都...

    7089bAt@PowerLi
  • 如何利用CDO从数据集中提取数据

    之前说了如何利用CDO查看数据集信息 使用CDO查看气象数据信息。这一次说一下利用CDO从数据集中提取数据。这部分是非常使用的,尤其是当涉及到大数据集的时候,其...

    bugsuse
  • Python3.7 读取音频根据文件名生成脚本的代码

    Warning: 仅适用于文件名即字幕本体,按音频时常平均拆分来生成字幕,其他情况不适合。

    砸漏
  • Camera Model

    可以看这篇文章来理解如何求解 homography H:单应性(homography)变换的推导

    caoqi95
  • Node.js调用mysql的存储过程

    例子仅在windows下测试通过,没有放在linux下测试。如有问题,可以电邮给我~

    meteoric
  • 使用android studio导入模块的两种方法(超详细)

    1,首先自己创建一个新的android项目,选择Empty Activity,一直选择默认项

    砸漏
  • UG NX软件到底需要什么样的电脑配置才不卡?

    首先我还是先说答案吧,省得看到最后失望,其实这是个伪命题,没有绝对结果,卡与不卡是相对的。

    UG数控编程
  • shell技巧分享(二)

    songleo
  • Linux 性能监控 : CPU 、Memory 、 IO 、Network

    本文收集整理了Linux性能监控的方法,监控对象包括CPU 、Memory 、IO 、Network,并记录了良好状态指标,所使用的监控工具以及参数指标。

    老刘

扫码关注云+社区

领取腾讯云代金券