ffmpeg中AVCodecContext等数据结构中extradata成员的数据格式及其设置

1、引用AVCodecContext中对该数据成员的解释

/**
     * some codecs need / can use extradata like Huffman tables.
     * MJPEG: Huffman tables
     * rv10: additional flags
     * MPEG-4: global headers (they can be in the bitstream or here)
     * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger
     * than extradata_size to avoid problems if it is read with the bitstream reader.
     * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
     * - encoding: Set/allocated/freed by libavcodec.
     * - decoding: Set/allocated/freed by user.
     */
    uint8_t *extradata;
    int extradata_size;

可见它针对不同的情况有不同的格式,而比较常用的情况就是我们对视频流进行写入文件操作时(某些情况下,如通过NV12格式编码的视频流数据),或则解码视频文件时需要我们去设置。此时extradata作为一个global headers,主要保存SPS、PPS等信息,下面就针对此种情况进行说明。


2、格式规定

MPEG-4 Part 15 "Advanced Video Coding (AVC) file format" section 5.2.4.1 的规定如下:

aligned(8) class AVCDecoderConfigurationRecord { 
   unsigned int(8) configurationVersion = 1; 
   unsigned int(8) AVCProfileIndication; 
   unsigned int(8) profile_compatibility; 
   unsigned int(8) AVCLevelIndication;  
   bit(6) reserved = ‘111111’b;
   unsigned int(2) lengthSizeMinusOne;  
   bit(3) reserved = ‘111’b;
   unsigned int(5) numOfSequenceParameterSets; 
   for (i=0; i< numOfSequenceParameterSets;  i++) { 
      unsigned int(16) sequenceParameterSetLength ; 
  bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit; 
 } 
   unsigned int(8) numOfPictureParameterSets; 
   for (i=0; i< numOfPictureParameterSets;  i++) { 
  unsigned int(16) pictureParameterSetLength; 
  bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; 
 } 
}


引用一个MP4文件中包含sps、pps数据的数据段

其中有一个sps块(e1 & 1F),长度为26字节(0x00 1a),后面就是这个序列参数集的真正内容;

一个pps块(01  & FF),长度为4字节(0x04),后面就是这个图像参数集的真正类容

如何提取提取数据参见:http://blog.csdn.net/a812073479/article/details/74716476


3、extradata的设置

      (1)直接设置原始的PPS、SPS数据

               数据格式如下(黄色部分为SPS数据、红色部分为PPS数据)


               将这部分数直接送给extradata的前面即可,后面填充AV_INPUT_BUFFER_PADDING_SIZE 个字节的0数据

      (2)某些情况下需要按照文档中定义的那样来设置

              参考链接:https://stackoverflow.com/questions/15263458/h-264-muxed-to-mp4-using-libavformat-not-playing-back

                                  https://devtalk.nvidia.com/default/topic/718718/-howto-h-264-mp4-container/?offset=1

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FFmpeg,可以使用AVCParser来从H.264数据流解析NAL单元。以下是一个简单的示例代码,展示如何使用AVCParser从H.264数据流解析出NAL单元: ``` C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <libavcodec/avcodec.h> int main(int argc, char *argv[]) { AVCodecParserContext *parser; AVCodecContext *codec; uint8_t *data; int data_size; int parsed_len; // 初始化FFmpeg库 av_register_all(); // 创建AVCParser parser = av_parser_init(AV_CODEC_ID_H264); if (!parser) { printf("Failed to create AVCParser\n"); return -1; } // 创建AVCodecContext codec = avcodec_alloc_context3(NULL); if (!codec) { printf("Failed to create AVCodecContext\n"); return -1; } // 设置AVCodecContext参数 codec->codec_type = AVMEDIA_TYPE_VIDEO; codec->codec_id = AV_CODEC_ID_H264; // 分配输入缓冲区 data_size = 4096; data = (uint8_t *)av_malloc(data_size); // 读取H.264数据流 while (1) { int len = fread(data, 1, data_size, stdin); if (len == 0) { break; } // 解析NAL单元 parsed_len = av_parser_parse2(parser, codec, &data, &len, data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); if (parsed_len < 0) { printf("Failed to parse H.264 stream\n"); return -1; } // 打印NAL单元信息 if (parsed_len > 0) { int i; for (i = 0; i < parsed_len; i++) { if (i % 16 == 0) { printf("\n"); } printf("%02x ", data[i]); } printf("\n"); } } // 释放资源 av_parser_close(parser); avcodec_free_context(&codec); av_free(data); return 0; } ``` 在上述代码,我们首先创建了一个AVCParserContext和一个AVCodecContext,用于解析和解码H.264数据流。然后我们分配了一个输入缓冲区,并从标准输入读取H.264数据流。每次读取一段数据后,我们调用av_parser_parse2函数来解析NAL单元。如果解析成功,我们就打印出NAL单元的内容。最后我们释放了所有的资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值