zoukankan      html  css  js  c++  java
  • FFmpeg——AVCodec,AVCodecContext,AVCodecParameters 辨析

    先贴上雷神的一张FFmpeg关键结构体之间的关系图:

    再看雷神的分析:

    • 每个AVStream存储一个视频/音频流的相关数据;
    • 每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;
    • 每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。
    • 每种解码器都对应一个AVCodec结构。

    看过雷神的分析,再加上自己的使用经验,总结如下:

    AVCodec是存储编解码器信息的结构体,一般来说使用如下两个函数获得:

    /**
     * Find a registered decoder with a matching codec ID.
     *
     * @param id AVCodecID of the requested decoder
     * @return A decoder if one was found, NULL otherwise.
     */
    AVCodec *avcodec_find_decoder(enum AVCodecID id);
    
    
    /**
     * Find a registered encoder with a matching codec ID.
     *
     * @param id AVCodecID of the requested encoder
     * @return An encoder if one was found, NULL otherwise.
     */
    AVCodec *avcodec_find_encoder(enum AVCodecID id);

    AVCodecContex结构体除了包含解码器之外还包含视音频流相关的信息,如宽高,比特率,声道数等信息。一般通过如下函数获得:

    /**
     * Allocate an AVCodecContext and set its fields to default values. The
     * resulting struct should be freed with avcodec_free_context().
     *
     * @param codec if non-NULL, allocate private data and initialize defaults
     *              for the given codec. It is illegal to then call avcodec_open2()
     *              with a different codec.
     *              If NULL, then the codec-specific defaults won't be initialized,
     *              which may result in suboptimal default settings (this is
     *              important mainly for encoders, e.g. libx264).
     *
     * @return An AVCodecContext filled with default values or NULL on failure.
     */
    AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);

    通过以上函数获得之后通常要将视音频流的信息赋值过去,使用如下函数:

    /**
     * Fill the codec context based on the values from the supplied codec
     * parameters. Any allocated fields in codec that have a corresponding field in
     * par are freed and replaced with duplicates of the corresponding field in par.
     * Fields in codec that do not have a counterpart in par are not touched.
     *
     * @return >= 0 on success, a negative AVERROR code on failure.
     */
    int avcodec_parameters_to_context(AVCodecContext *codec,
                                      const AVCodecParameters *par);

    其中的参数 AVCodecParameters为编解码器的相关参数,是从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;
        /**
         * Additional information about the codec (corresponds to the 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.
         * - audio: the sample format, the value corresponds to 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
         */
        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"."
         *
         * 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).
         */
        AVRational sample_aspect_ratio;
    
        /**
         * Video only. The order of the fields in interlaced video.
         */
        enum AVFieldOrder                  field_order;
    
        /**
         * Video only. Additional colorspace characteristics.
         */
        enum AVColorRange                  color_range;
        enum AVColorPrimaries              color_primaries;
        enum AVColorTransferCharacteristic color_trc;
        enum AVColorSpace                  color_space;
        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.
         */
        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;

    这么做是因为AVCodecContext这个结构体实在是太大了。

    我们可以从 AVStream 的 codecpar 成员中直接获得AVCodecParameters。

    最后附上参考雷神的链接:

    https://blog.csdn.net/leixiaohua1020/article/details/11693997

    缅怀

  • 相关阅读:
    前端开发-模块化开发框架RequireJS-1 初识requirejs
    需整理
    SSM
    iomanip
    new与delete使用方法
    分析setting源代码获取sd卡大小
    第一次正式小用Redis存储
    blob storage第一次亲密接触
    第一次使用ashx,被震惊
    Redis中的异步Async
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/10830792.html
Copyright © 2011-2022 走看看