• 音视频从入门到精通——FFmpeg数据结构分析


    FFmpeg数据结构分析

    FFmpeg解码流程
    FFmpeg结构体

    重要结构体之间的关系

    在这里插入图片描述

    AVFormatContext

    • iformat:输入媒体的AVInputFormat,比如指向AVInputFormat ff_flv_demuxer
    • nb_streams:输入媒体的AVStream 个数
    • streams:输入媒体的AVStream []数组
    • duration:输入媒体的时长(以微秒为单位),计算方式可以参考av_dump_format()函数。
    • bit_rate:输入媒体的码率

    AVInputFormat

    • name:封装格式名称
    • extensions:封装格式的扩展名
    • 一些封装格式处理的接口函数,比如read_packet()

    AVStream

    AVStream 是存储每一个音频/视频流信息的结构体。其重要的变量如下所示:

    int index // 标识该视频/音频流
    AVCodecContext *codec // 解码器,4.0 版本后已弃用
    AVRational time_base // 时基。通过该值可以把PTS,DTS转化为实际的时间(单位为秒s)
    int64_t duration // 该视频/音频流时长,单位为 ms
    AVRational avg_frame_rate // 帧率(注:对视频来说,这个挺重要的)
    AVPacket attached_pic // 附带的图片。比如说一些 MP3,AAC 音频文件附带的专辑封面
    AVCodecParameters *codecpar // 音视频参数,新增用来替换AVCodecContext *codec
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    AVCodecParameters

    AVCodecParamteres结构体是将AVCodecContext中编解码器参数抽取出而形成的新的结构体。

    /**
     * This struct describes the properties of an encoded stream. 此结构描述编码流的属性
     *
     * sizeof(AVCodecParameters) is not a part of the public ABI, this struct must
     * be allocated with avcodec_parameters_alloc() and freed with
     * avcodec_parameters_free().
     */
    typedef struct AVCodecParameters {
        /**
         * General type of the encoded data.编码数据的一般类型
         */
        enum AVMediaType codec_type; //编解码器的类型 
        /**
         * Specific type of the encoded data (the codec used). 编码数据的特定类型(使用的编解码器)
         */
        enum AVCodecID   codec_id; //编解码器的id
        /**
         * Additional information about the codec (corresponds to the AVI FOURCC).
    	 * 有关编解码器的附加信息(对应于AVI FOURCC
         */
        uint32_t         codec_tag;
    
        /**
         * Extra binary data needed for initializing the decoder, codec-dependent.
         *
         * Must be allocated with av_malloc() and will be freed by
         * avcodec_parameters_free(). The allocated size of extradata must be at
         * least extradata_size + AV_INPUT_BUFFER_PADDING_SIZE, with the padding
         * bytes zeroed.
         */
        uint8_t *extradata;
        /**
         * Size of the extradata content in bytes.
         */
        int      extradata_size;
    
        /**
         * - video: the pixel format, the value corresponds to enum AVPixelFormat. 像素格式,该值对应于enum AVPixelFormat
         * - audio: the sample format, the value corresponds to enum AVSampleFormat. 采样格式,该值对应于enum AVSampleFormat
         */
        int format;
    
        /**
         * The average bitrate of the encoded data (in bits per second). 编码数据的平均比特率(以比特/秒为单位)
         */
        int64_t bit_rate;
    
        /**
         * The number of bits per sample in the codedwords. 编码字中每个样本的位数
         *
         * This is basically the bitrate per sample. It is mandatory for a bunch of
         * formats to actually decode them. It's the number of bits for one sample in
         * the actual coded bitstream. 这基本上是每个样本的比特率。对于一组格式来说,必须对它们进行实际解码。它是实际编码比特流中一个样本的比特数
         *
         * This could be for example 4 for ADPCM
         * For PCM formats this matches bits_per_raw_sample
         * Can be 0 例如,对于ADPCM格式,这可以是4。对于PCM格式,它匹配bits_per_raw_sample可以是0
         */
        int bits_per_coded_sample;
    
        /**
         * This is the number of valid bits in each output sample. If the
         * sample format has more bits, the least significant bits are additional
         * padding bits, which are always 0. Use right shifts to reduce the sample
         * to its actual size. For example, audio formats with 24 bit samples will
         * have bits_per_raw_sample set to 24, and format set to AV_SAMPLE_FMT_S32.
         * To get the original sample use "(int32_t)sample >> 8"."
    	 *
         *   这是每个输出样本中的有效位数。如果样本格式有更多的位,最低有效位是额外的填充位,通常为0。
    	 *	 使用右移将样本减少到实际大小。例如,具有24位样本的音频格式将bits_per_raw_sample设置为24,
    	 *	 格式设置为AV_sample_FMT_S32。要获得原始样本,请使用“(int32_t)样本>>8
         * For ADPCM this might be 12 or 16 or similar
         * Can be 0
         */
        int bits_per_raw_sample;
    
        /**
         * Codec-specific bitstream restrictions that the stream conforms to. 
    	 * 流符合的编解码器特定位流限制
         */
        int profile; //配置类型
        int level;   //配置级别
    
        /**
         * Video only. The dimensions of the video frame in pixels. 仅视频。视频帧的尺寸(以像素为单位)
         */
        int width;
        int height;
    
        /**
         * Video only. The aspect ratio (width / height) which a single pixel
         * should have when displayed. 仅视频。显示单个像素时应具有的纵横比(宽度/高度)
         *
         * When the aspect ratio is unknown / undefined, the numerator should be
         * set to 0 (the denominator may have any value). 当纵横比未知/未定义时,分子应设置为0(分母可以有任何值
         */
        AVRational sample_aspect_ratio;
    
        /**
         * Video only. The order of the fields in interlaced video. 隔行扫描视频中的场顺序
         */
        enum AVFieldOrder                  field_order;
    
        /**
         * Video only. Additional colorspace characteristics. 附加色空间特性
    	 * 1, color space: YUV是基于RGB的颜色空间,color space属性是决定了YUV2RGB/RGB2YUV的转换计算matrix
    	 * 2, color primaries:基于的RGB空间对应的绝对颜色XYZ的变换,决定了最终三原色RGB分别是什么颜色
    	 * 3, color transfer:定义了transfer funciton的gamma值,从RGB到最终显示的值需要进行gamma压暗,比如bt709的平均gamma为1.96
    	 * 4,color range:pc range和tv range(又叫video range和full range),full range中YUV的取值[0-255],video range中Y[16-235],UV [16-240]
         */
        enum AVColorRange                  color_range;  //MPEG JPEG YUV范围
        enum AVColorPrimaries              color_primaries;
        enum AVColorTransferCharacteristic color_trc;
        enum AVColorSpace                  color_space; //YUV色彩空间类型
        enum AVChromaLocation              chroma_location;
    
        /**
         * Video only. Number of delayed frames. 仅视频。延迟帧数
         */
        int video_delay;
    
        /**
         * Audio only. The channel layout bitmask. May be 0 if the channel layout is
         * unknown or unspecified, otherwise the number of bits set must be equal to
         * the channels field. 仅音频。通道布局位掩码。如果通道布局未知或未指定,则可以为0,否则设置的位数必须等于通道字段
         */
        uint64_t channel_layout;
        /**
         * Audio only. The number of audio channels. 仅音频。音频通道数
         */
        int      channels;
        /**
         * Audio only. The number of audio samples per second. 仅音频。每秒的音频采样数
         */
        int      sample_rate;
        /**
         * Audio only. The number of bytes per coded audio frame, required by some formats.
         * 仅音频。某些格式所需的每个编码音频帧的字节数
         *
         * Corresponds to nBlockAlign in WAVEFORMATEX.
         */
        int      block_align;
        /**
         * Audio only. Audio frame size, if known. Required by some formats to be static.
    	 * 仅音频。音频帧大小(如果已知)。某些格式要求是静态的
         */
        int      frame_size; //每个音频帧中每个声道的采样数量
    
        /**
    	 *
         * Audio only. The amount of padding (in samples) inserted by the encoder at
         * the beginning of the audio. I.e. this number of leading decoded samples
         * must be discarded by the caller to get the original audio without leading
         * padding.
    	 *  仅音频。编码器相关参数。编码器在音频开始时插入的填充量(以样本为单位)。调用者必须丢弃该数量的前导解码样本,以获得原始音频,而不需要前导填充
         */
        int initial_padding;
        /**
         * Audio only. The amount of padding (in samples) appended by the encoder to
         * the end of the audio. I.e. this number of decoded samples must be
         * discarded by the caller from the end of the stream to get the original
         * audio without any trailing padding.
    	 * 仅音频。编码器相关参数。编码器附加到音频结尾的填充量(以样本为单位)
    	 * 调用者必须从流的末尾丢弃此数量的解码样本,以获得原始音频,而无任何尾随填充
         */
        int trailing_padding;
        /**
         * Audio only. Number of samples to skip after a discontinuity.
    	 * 仅音频。不连续后要跳过的采样数
         */
        int seek_preroll;
    	
    } AVCodecParameters;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174

    AVCodecContext

    • codec:编解码器的AVCodec,比如指向AVCodec
    ff_aac_latm_decoder
    • width, height:图像的宽高(只针对视频)
    • pix_fmt:像素格式(只针对视频)
    • sample_rate:采样率(只针对音频)
    • channels:声道数(只针对音频)
    • sample_fmt:采样格式(只针对音频)

    AVCodec

    • name:编解码器名称
    • type:编解码器类型
    • id:编解码器ID
    • 一些编解码的接口函数,比如int (*decode)()

    AVPacket

    • pts:显示时间戳
    • dts:解码时间戳
    • data:压缩编码数据
    • size:压缩编码数据大小
    • pos:数据的偏移地址
    • stream_index:所属的AVStream,1表示音频,0表示视频

    AVFrame

    • data:解码后的图像像素数据(音频采样数据)
    • linesize:对视频来说是图像中一行像素的大小;对音频来说是
    整个音频帧的大小
    • width, height:图像的宽高(只针对视频)
    • key_frame:是否为关键帧(只针对视频) 。
    • pict_type:帧类型(只针对视频) 。例如I, P, B
    • sample_rate:音频采样率(只针对音频)
    • nb_samples:音频每通道采样数(只针对音频)
    • pts:显示时间戳

    AVMediaType

    AVMediaType 枚举表示,AVMEDIA_TYPE_VIDEO为视频数据,值为0,AVMEDIA_TYPE_AUDIO为音频视频,值为1.

    /**
     * @addtogroup lavu_media Media Type
     * @brief Media Type
     */
    
    enum AVMediaType {
        AVMEDIA_TYPE_UNKNOWN = -1,  ///< Usually treated as AVMEDIA_TYPE_DATA
        AVMEDIA_TYPE_VIDEO,
        AVMEDIA_TYPE_AUDIO,
        AVMEDIA_TYPE_DATA,          ///< Opaque data information usually continuous
        AVMEDIA_TYPE_SUBTITLE,
        AVMEDIA_TYPE_ATTACHMENT,    ///< Opaque data information usually sparse
        AVMEDIA_TYPE_NB
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    AVPixelFormat 像素格式

    像素格式

    enum AVPixelFormat {
        AV_PIX_FMT_NONE = -1,
        AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
        AV_PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
        AV_PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
        AV_PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
        AV_PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
        AV_PIX_FMT_YUV444P,   ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
        AV_PIX_FMT_YUV410P,   ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
        AV_PIX_FMT_YUV411P,   ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
        AV_PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
        ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    AVSampleFormat 采样格式

    enum AVSampleFormat {
        AV_SAMPLE_FMT_NONE = -1,
        AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
        AV_SAMPLE_FMT_S16,         ///< signed 16 bits
        AV_SAMPLE_FMT_S32,         ///< signed 32 bits
        AV_SAMPLE_FMT_FLT,         ///< float,4 个字节	
        AV_SAMPLE_FMT_DBL,         ///< double,8 个字节	
        ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    FFmpeg解码流程

    旧版本的ffmpeg程序, 程序开头处, 一般总是av_register_allffmpeg 4.x之后, 该函数已经废弃,不需要调用了. 在这里插入图片描述

    ffmpeg官方文档网址以及参考博客

    ffmpeg官方文档网址:
    1、http://www.ffmpeg.org/doxygen/trunk/examples.html

    这个文档是官方真正的,里面的要一个一个点击看
    2、http://ffmpeg.org/documentation.html
    这里是一本书:
    http://www.astro-electronic.de/FFmpeg_Book.pdf

    所有书:
    https://trac.ffmpeg.org/wiki/BooksAndOtherExternalResources

    ffmpeg参考博客
    https://blog.csdn.net/u012117034/category_11652554.html

    参考

    FFmpeg视频播放器开发 - 解封装解码流程、常用API和结构体简介(一)
    5.AVStream和AVCodecParameters

    FFMPEG结构体分析:AVFrame
    FFMPEG结构体分析:AVFormatContext
    FFMPEG结构体分析:AVCodecContext
    FFMPEG结构体分析:AVIOContext
    FFMPEG结构体分析:AVCodec
    FFMPEG结构体分析:AVStream
    FFMPEG结构体分析:AVPacket

  • 相关阅读:
    谷歌浏览器打开白屏 后台还有还有很多google chrome进程在运行
    第十八章《JDBC》第1节:JDBC简介
    设计模式学习(十):门面模式
    如何备份和恢复数据库
    认识RocketMQ4.x架构设计
    Linux高级I/O:非阻塞IO fcntl | 多路转接之select | poll
    恒运资本:三大利好来袭,人民币直线拉升!股市能否大反攻?
    ClickHouse入门手册1.0
    Spark学习笔记(三):使用Java调用Spark集群
    【图像处理OpenCV(C++版)】——初学OpenCV
  • 原文地址:https://blog.csdn.net/e891377/article/details/126710350