先贴上雷神的一张FFmpeg关键结构体之间的关系图:
再看雷神的分析:
看过雷神的分析,再加上自己的使用经验,总结如下:
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
缅怀
FFmpeg——AVCodec,AVCodecContext,AVCodecParameters 辨析
原文:https://www.cnblogs.com/zoneofmine/p/10830792.html