当前位置: 首页 > news >正文

FFmpeg架构全面分析

一、简介

它的官网为:https://ffmpeg.org/,由Fabrice Bellard(法国著名程序员Born in 1972)于2000年发起创建的开源项目。该人是个牛人,在很多领域都有很大的贡献。

FFmpeg是多媒体领域的万能工具。只要涉及音视频领域的处理,基本上没有它做不了的事情!通俗点讲,从视频录制、视频编辑再到播放,它都能做!

最近比较火的抖音,还有国内的一些视频点播厂商,像爱奇艺、腾讯视频、优酷视频,还有播放器,像QQ影音、暴风影音等,都离不开它!否则非常痛苦!为什么呢?

因为又要招一大帮人来把多媒体领域内的基础工具(音视频编解码器、文件格式和协议库、滤镜库等等)实现掉。

二、源码获取及编译

2.1、源码获取

git clone https://github.com/FFmpeg/FFmpeg.git正克隆到 'FFmpeg'...
remote: Enumerating objects: 694571, done.
remote: Counting objects: 100% (234/234), done.
remote: Compressing objects: 100% (96/96), done.
remote: Total 694571 (delta 141), reused 226 (delta 138), pack-reused 694337
接收对象中: 100% (694571/694571), 348.75 MiB | 798.00 KiB/s, 完成.
处理 delta 中: 100% (545422/545422), 完成.

2.2、编译安装

1、执行X86下需执行:./configure --disable-x86asm命令进行配置 2、执行make -j16命令进行编译。 3、执行sudo make install命令进行安装。

执行过程中会有如下内容输出:

 xxx@xxx:~/workspace/learn/FFmpeg/FFmpeg$ ./configure --disable-x86asminstall prefix            /usr/localsource path               .C compiler                gccC library                 glibcARCH                      x86 (generic)big-endian                noruntime cpu detection     yesstandalone assembly       no
x86 assembler             nasm
MMX enabled               yes
MMXEXT enabled            yes
3DNow! enabled            yes
3DNow! extended enabled   yes
SSE enabled               yes
SSSE3 enabled             yes
AESNI enabled             yes
AVX enabled               yes
AVX2 enabled              yes
AVX-512 enabled           yes
AVX-512ICL enabled        yes
XOP enabled               yes
FMA3 enabled              yes
FMA4 enabled              yes
i686 features enabled     yes
CMOV is fast              yes
EBX available             yes
EBP available             yes
debug symbols             yes
strip symbols             yes
optimize for size         no
optimizations             yes
static                    yes
shared                    no
postprocessing support    no
network support           yes
threading support         pthreads
safe bitstream reader     yes
texi2html enabled         no
perl enabled              yes
pod2man enabled           yes
makeinfo enabled          yes
makeinfo supports HTML    yes
xmllint enabled           yes
pseudocolor             splitEnabled bsfs:
aac_adtstoasc           dts2pts                 filter_units            hevc_mp4toannexb        mp3_header_decompress   pcm_rechunk             trace_headers
av1_frame_merge         dump_extradata          h264_metadata           imx_dump_header         mpeg2_metadata          pgs_frame_merge         truehd_core
av1_frame_split         dv_error_marker         h264_mp4toannexb        media100_to_mjpegb      mpeg4_unpack_bframes    prores_metadata         vp9_metadata
av1_metadata            eac3_core               h264_redundant_pps      mjpeg2jpeg              noise                   remove_extradata        vp9_raw_reorder
chomp                   evc_frame_merge         hapqa_extract           mjpega_dump_header      null                    setts                   vp9_superframe
dca_core                extract_extradata       hevc_metadata           mov2textsub             opus_metadata           text2movsub             vp9_superframe_splitEnabled indevs:
alsa                    fbdev                   lavfi                   oss                     v4l2                    xcbgrabEnabled outdevs:
alsa                    fbdev                   oss                     v4l2License: LGPL version 2.1 or later

4、执行ffmpeg -version命令查看版本信息

xxx@xxx:~/workspace/learn/FFmpeg/FFmpeg$ ffmpeg -version
ffmpeg version N-111280-gd51b0580e4 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --disable-x86asm
libavutil      58. 13.101 / 58. 13.101
libavcodec     60. 21.100 / 60. 21.100
libavformat    60.  9.100 / 60.  9.100
libavdevice    60.  2.100 / 60.  2.100
libavfilter     9.  8.102 /  9.  8.102
libswscale      7.  3.100 /  7.  3.100
libswresample   4. 11.100 /  4. 11.100
xxx@xxx:~/workspace/learn/FFmpeg/FFmpeg$

三、架构及流程分析

3.1、整体架构

1、AVUtil:核心工具库,许多其他模块都会依赖该库做一些基本的音视频处理操作,如log信息、版本信息等。

2、AVFormat: 文件格式和协议库,封装了Protocol层和Demuxer、Muxer层。其中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。

3、AVCodec: 编解码库,封装了Codec库,AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,即支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x264编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式,或者硬件编解码,则需要在AVCodec中增加相应的编解码模块。默认不会添加libx264、libfdk_aac等三方库的,但可以插件形式添加,然后提供统一接口。

4、AVFilter: 提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。

5、AVDevice: 输入输出设备库,音/视频的输入输出需要确保该模块已经打开

6、SwrRessample: 该模块可用于音频重采样,可以对数字音频进行声道数、数据格式、采样率、等多种基本信息的转换,同时支持音频通道布局转换与布局调整。

7、SWScale: 提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420p转换成YUYV,或者YUV转RGB等图像格式转换。

8、PostProc: 该模块可用于进行后期处理,当我们使用AVFilter的时 候需要打开该模块的开关,因为Filter中会使用到该模块的一些基础函数。

相关视频推荐

ffmpeg实战教程:ffmpeg命令,ffmpeg过滤器,ffplay播放器,ffmpeg进阶学习icon-default.png?t=N7T8https://www.bilibili.com/video/BV1zC4y127uj/

【免费】FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发免费学习地址

【纯干货免费分享】C++音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击671977938加群免费领取哦~

3.2、音视频播放流程

3.3、组件注册流程

3.4、解复用流程

1、avformat_alloc_context():负责申请一个AVFormatContext结构的内存,并进行简单初始化。

2、avformat_free_context(): 释放该结构里的所有东西以及该结构本身。

3、avformat_close_input(): 关闭解复用器。关闭后就不再需要使用avformat_free_context 进行释放。

4、avformat_open_input(): 打开输入视频文件。

5、avformat_find_stream_info(): 获取音视频文件信息。

6、av_read_frame(): 读取音视频包。

7、avformat_seek_file(): 定位文件。

8、av_seek_frame(): 定位文件。

3.5、解封装流程

ffmpeg 的 Mux 主要分为 三步操作:

1、avformat_write_header:写文件头

2、av_write_frame/av_interleaved_write_frame:写packet

3、av_write_trailer:写⽂件尾

3.6、编码流程

1、avcodec_find_encoder:根据指定的AVCodecID查找注册的编码器。

2、avcodec_alloc_context3: 为AVCodecContext分配内存。

3、avcodec_open2: 打开编码器。

4、avcodec_send_frame: 将AVFrame⾮压缩数据给编码器。

5、avcodec_receive_packet: 获取到编码后的AVPacket数据,收到的packet需要⾃⼰释放内存。

6、av_frame_get_buffer: 为⾳频或视频帧分配新的buffer。在调⽤这个函数之前,必须在AVFame上设置好以下属性:format(视频为像素格式,⾳频为样本格式)、nb_samples(样本个数,针对⾳频)、channel_layout(通道类型,针对⾳频)、width/height(宽⾼,针对视频)。

7、av_frame_make_writable: 确保AVFrame是可写的,使av_frame_make_writable()的问题是,在最坏的情况下,它会在您使⽤encode再次更改整个输⼊frame之前复制它. 如果frame不可写,av_frame_make_writable()将分配新的缓冲区,并复制这个输⼊input frame数据,避免和编码器需要缓存该帧时造成冲突。

8、av_samples_fill_arrays: 填充⾳频帧。

3.7、解码流程

1、avcodec_alloc_context3():分配解码器上下文 avcodec_find_decoder():根据ID查找解码器。

2、avcodec_find_decoder_by_name(): 根据解码器名字 avcodec_open2():打开编解码器。

3、avcodec_decode_video2(): 解码一帧视频数据。

4、avcodec_decode_audio4(): 解码一帧音频数据。

5、avcodec_send_packet(): 发送编码数据包 avcodec_receive_frame(): 接收解码后数据。

6、avcodec_free_context(): 释放解码器上下文,包含了 avcodec_close()。

7、avcodec_close(): 关闭解码器。

四、重点数据结构分析

4.1、重点数据结构

4.1.1、AVFormatContext

封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息。AVInputFormat。

typedef struct AVFormatContext {const AVClass *av_class;const struct AVInputFormat *iformat;const struct AVOutputFormat *oformat;void *priv_data;AVIOContext *pb;int ctx_flags;unsigned int nb_streams;AVStream **streams;char *url;int64_t start_time;int64_t duration;int64_t bit_rate;unsigned int packet_size;int max_delay;int flags;
#define AVFMT_FLAG_GENPTS       0x0001 ///< Generate missing pts even if it requires parsing future frames.
#define AVFMT_FLAG_IGNIDX       0x0002 ///< Ignore index.
#define AVFMT_FLAG_NONBLOCK     0x0004 ///< Do not block when reading packets from input.
#define AVFMT_FLAG_IGNDTS       0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
#define AVFMT_FLAG_NOFILLIN     0x0010 ///< Do not infer any values from other values, just return what is stored in the container
#define AVFMT_FLAG_NOPARSE      0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
#define AVFMT_FLAG_NOBUFFER     0x0040 ///< Do not buffer frames when possible
#define AVFMT_FLAG_CUSTOM_IO    0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
#define AVFMT_FLAG_DISCARD_CORRUPT  0x0100 ///< Discard frames marked corrupted
#define AVFMT_FLAG_FLUSH_PACKETS    0x0200 ///< Flush the AVIOContext every packet.
#define AVFMT_FLAG_BITEXACT         0x0400
#define AVFMT_FLAG_SORT_DTS    0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
#define AVFMT_FLAG_FAST_SEEK   0x80000 ///< Enable fast, but inaccurate seeks for some formats
#define AVFMT_FLAG_SHORTEST   0x100000 ///< Stop muxing when the shortest stream stops.
#define AVFMT_FLAG_AUTO_BSF   0x200000 ///< Add bitstream filters as requested by the muxerint64_t probesize;int64_t max_analyze_duration;const uint8_t *key;int keylen;unsigned int nb_programs;AVProgram **programs;enum AVCodecID video_codec_id;enum AVCodecID audio_codec_id;enum AVCodecID subtitle_codec_id;unsigned int max_index_size;unsigned int max_picture_buffer;unsigned int nb_chapters;AVChapter **chapters;AVDictionary *metadata;int64_t start_time_realtime;int fps_probe_size;int error_recognition;AVIOInterruptCB interrupt_callback;int debug;
#define FF_FDEBUG_TS        0x0001int64_t max_interleave_delta;int strict_std_compliance;int event_flags;
#define AVFMT_EVENT_FLAG_METADATA_UPDATED 0x0001int max_ts_probe;int avoid_negative_ts;
#define AVFMT_AVOID_NEG_TS_AUTO             -1 ///< Enabled when required by target format
#define AVFMT_AVOID_NEG_TS_DISABLED          0 ///< Do not shift timestamps even when they are negative.
#define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they are non negative
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO         2 ///< Shift timestamps so that they start at 0int ts_id;int audio_preload;int max_chunk_duration;int max_chunk_size;int use_wallclock_as_timestamps;int avio_flags;enum AVDurationEstimationMethod duration_estimation_method;int64_t skip_initial_bytes;unsigned int correct_ts_overflow;int seek2any;int flush_packets;int probe_score;int format_probesize;char *codec_whitelist;char *format_whitelist;int io_repositioned;const AVCodec *video_codec;const AVCodec *audio_codec;const AVCodec *subtitle_codec;const AVCodec *data_codec;int metadata_header_padding;void *opaque;av_format_control_message control_message_cb;int64_t output_ts_offset;uint8_t *dump_separator;enum AVCodecID data_codec_id;char *protocol_whitelist;int (*io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url,int flags, AVDictionary **options);
#if FF_API_AVFORMAT_IO_CLOSEattribute_deprecatedvoid (*io_close)(struct AVFormatContext *s, AVIOContext *pb);
#endifchar *protocol_blacklist;int max_streams;int skip_estimate_duration_from_pts;int max_probe_packets;int (*io_close2)(struct AVFormatContext *s, AVIOContext *pb);
} AVFormatContext;

4.1.2、Demuxer

每种封装格式(例如FLV, MKV, MP4, AVI)对应一个该结构体。

typedef struct Demuxer {InputFile f;// name used for loggingchar log_name[32];int64_t wallclock_start;/*** Extra timestamp offset added by discontinuity handling.*/int64_t ts_offset_discont;int64_t last_ts;/* number of times input stream should be looped */int loop;/* actual duration of the longest stream in a file at the moment when* looping happens */int64_t duration;/* time base of the duration */AVRational time_base;/* number of streams that the user was warned of */int nb_streams_warn;double readrate_initial_burst;AVThreadMessageQueue *in_thread_queue;int                   thread_queue_size;pthread_t             thread;int                   non_blocking;int                   read_started;
} Demuxer;

4.1.3、AVOutputFormat muxer

typedef struct AVOutputFormat {const char *name;/*** Descriptive name for the format, meant to be more human-readable* than name. You should use the NULL_IF_CONFIG_SMALL() macro* to define it.*/const char *long_name;const char *mime_type;const char *extensions; /**< comma-separated filename extensions *//* output support */enum AVCodecID audio_codec;    /**< default audio codec */enum AVCodecID video_codec;    /**< default video codec */enum AVCodecID subtitle_codec; /**< default subtitle codec *//*** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER,* AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,* AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH,* AVFMT_TS_NONSTRICT, AVFMT_TS_NEGATIVE*/int flags;/*** List of supported codec_id-codec_tag pairs, ordered by "better* choice first". The arrays are all terminated by AV_CODEC_ID_NONE.*/const struct AVCodecTag * const *codec_tag;const AVClass *priv_class; ///< AVClass for the private context
} AVOutputFormat;

4.1.4、AVStream

视频文件中每个视频(音频)流对应一个该结构体。

AVCodecContext编解码器上下文结构体,保存了视频(音频)编解码相关信息。

typedef struct AVStream {/*** A class for @ref avoptions. Set on stream creation.*/const AVClass *av_class;int index;    /**< stream index in AVFormatContext *//*** Format-specific stream ID.* decoding: set by libavformat* encoding: set by the user, replaced by libavformat if left unset*/int id;/*** Codec parameters associated with this stream. Allocated and freed by* libavformat in avformat_new_stream() and avformat_free_context()* respectively.** - demuxing: filled by libavformat on stream creation or in*             avformat_find_stream_info()* - muxing: filled by the caller before avformat_write_header()*/AVCodecParameters *codecpar;void *priv_data;/*** This is the fundamental unit of time (in seconds) in terms* of which frame timestamps are represented.** decoding: set by libavformat* encoding: May be set by the caller before avformat_write_header() to*           provide a hint to the muxer about the desired timebase. In*           avformat_write_header(), the muxer will overwrite this field*           with the timebase that will actually be used for the timestamps*           written into the file (which may or may not be related to the*           user-provided one, depending on the format).*/AVRational time_base;/*** Decoding: pts of the first frame of the stream in presentation order, in stream time base.* Only set this if you are absolutely 100% sure that the value you set* it to really is the pts of the first frame.* This may be undefined (AV_NOPTS_VALUE).* @note The ASF header does NOT contain a correct start_time the ASF* demuxer must NOT set this.*/int64_t start_time;/*** Decoding: duration of the stream, in stream time base.* If a source file does not specify a duration, but does specify* a bitrate, this value will be estimated from bitrate and file size.** Encoding: May be set by the caller before avformat_write_header() to* provide a hint to the muxer about the estimated duration.*/int64_t duration;int64_t nb_frames;                 ///< number of frames in this stream if known or 0/*** Stream disposition - a combination of AV_DISPOSITION_* flags.* - demuxing: set by libavformat when creating the stream or in*             avformat_find_stream_info().* - muxing: may be set by the caller before avformat_write_header().*/int disposition;enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed./*** sample aspect ratio (0 if unknown)* - encoding: Set by user.* - decoding: Set by libavformat.*/AVRational sample_aspect_ratio;AVDictionary *metadata;/*** Average framerate** - demuxing: May be set by libavformat when creating the stream or in*             avformat_find_stream_info().* - muxing: May be set by the caller before avformat_write_header().*/AVRational avg_frame_rate;/*** For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet* will contain the attached picture.** decoding: set by libavformat, must not be modified by the caller.* encoding: unused*/AVPacket attached_pic;/*** An array of side data that applies to the whole stream (i.e. the* container does not allow it to change between packets).** There may be no overlap between the side data in this array and side data* in the packets. I.e. a given side data is either exported by the muxer* (demuxing) / set by the caller (muxing) in this array, then it never* appears in the packets, or the side data is exported / sent through* the packets (always in the first packet where the value becomes known or* changes), then it does not appear in this array.** - demuxing: Set by libavformat when the stream is created.* - muxing: May be set by the caller before avformat_write_header().** Freed by libavformat in avformat_free_context().** @see av_format_inject_global_side_data()*/AVPacketSideData *side_data;/*** The number of elements in the AVStream.side_data array.*/int            nb_side_data;/*** Flags indicating events happening on the stream, a combination of* AVSTREAM_EVENT_FLAG_*.** - demuxing: may be set by the demuxer in avformat_open_input(),*   avformat_find_stream_info() and av_read_frame(). Flags must be cleared*   by the user once the event has been handled.* - muxing: may be set by the user after avformat_write_header(). to*   indicate a user-triggered event.  The muxer will clear the flags for*   events it has handled in av_[interleaved]_write_frame().*/int event_flags;
/*** - demuxing: the demuxer read new metadata from the file and updated*     AVStream.metadata accordingly* - muxing: the user updated AVStream.metadata and wishes the muxer to write*     it into the file*/
#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED 0x0001
/*** - demuxing: new packets for this stream were read from the file. This*   event is informational only and does not guarantee that new packets*   for this stream will necessarily be returned from av_read_frame().*/
#define AVSTREAM_EVENT_FLAG_NEW_PACKETS (1 << 1)/*** Real base framerate of the stream.* This is the lowest framerate with which all timestamps can be* represented accurately (it is the least common multiple of all* framerates in the stream). Note, this value is just a guess!* For example, if the time base is 1/90000 and all frames have either* approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.*/AVRational r_frame_rate;/*** Number of bits in timestamps. Used for wrapping control.** - demuxing: set by libavformat* - muxing: set by libavformat**/int pts_wrap_bits;
} AVStream;

4.1.5、AVCodec

每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体。

typedef struct AVCodec {/*** Name of the codec implementation.* The name is globally unique among encoders and among decoders (but an* encoder and a decoder can share the same name).* This is the primary way to find a codec from the user perspective.*/const char *name;/*** Descriptive name for the codec, meant to be more human readable than name.* You should use the NULL_IF_CONFIG_SMALL() macro to define it.*/const char *long_name;enum AVMediaType type;enum AVCodecID id;/*** Codec capabilities.* see AV_CODEC_CAP_**/int capabilities;uint8_t max_lowres;                     ///< maximum value for lowres supported by the decoderconst AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
#if FF_API_OLD_CHANNEL_LAYOUT/*** @deprecated use ch_layouts instead*/attribute_deprecatedconst uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
#endifconst AVClass *priv_class;              ///< AVClass for the private contextconst AVProfile *profiles;              ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}/*** Group name of the codec implementation.* This is a short symbolic name of the wrapper backing this codec. A* wrapper uses some kind of external implementation for the codec, such* as an external library, or a codec implementation provided by the OS or* the hardware.* If this field is NULL, this is a builtin, libavcodec native codec.* If non-NULL, this will be the suffix in AVCodec.name in most cases* (usually AVCodec.name will be of the form "<codec_name>_<wrapper_name>").*/const char *wrapper_name;/*** Array of supported channel layouts, terminated with a zeroed layout.*/const AVChannelLayout *ch_layouts;
} AVCodec;

4.1.6、AVPacket

存储一帧压缩编码数据。

typedef struct AVPacket {/*** A reference to the reference-counted buffer where the packet data is* stored.* May be NULL, then the packet data is not reference-counted.*/AVBufferRef *buf;/*** Presentation timestamp in AVStream->time_base units; the time at which* the decompressed packet will be presented to the user.* Can be AV_NOPTS_VALUE if it is not stored in the file.* pts MUST be larger or equal to dts as presentation cannot happen before* decompression, unless one wants to view hex dumps. Some formats misuse* the terms dts and pts/cts to mean something different. Such timestamps* must be converted to true pts/dts before they are stored in AVPacket.*/int64_t pts;/*** Decompression timestamp in AVStream->time_base units; the time at which* the packet is decompressed.* Can be AV_NOPTS_VALUE if it is not stored in the file.*/int64_t dts;uint8_t *data;int   size;int   stream_index;/*** A combination of AV_PKT_FLAG values*/int   flags;/*** Additional packet data that can be provided by the container.* Packet can contain several types of side information.*/AVPacketSideData *side_data;int side_data_elems;/*** Duration of this packet in AVStream->time_base units, 0 if unknown.* Equals next_pts - this_pts in presentation order.*/int64_t duration;int64_t pos;                            ///< byte position in stream, -1 if unknown/*** for some private data of the user*/void *opaque;/*** AVBufferRef for free use by the API user. FFmpeg will never check the* contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when* the packet is unreferenced. av_packet_copy_props() calls create a new* reference with av_buffer_ref() for the target packet's opaque_ref field.** This is unrelated to the opaque field, although it serves a similar* purpose.*/AVBufferRef *opaque_ref;/*** Time base of the packet's timestamps.* In the future, this field may be set on packets output by encoders or* demuxers, but its value will be by default ignored on input to decoders* or muxers.*/AVRational time_base;
} AVPacket;

4.1.7、AVFrame

存储一帧解码后像素(采样)数据

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8uint8_t *data[AV_NUM_DATA_POINTERS];int linesize[AV_NUM_DATA_POINTERS];uint8_t **extended_data;int width, height;int nb_samples;int format;#if FF_API_FRAME_KEYattribute_deprecatedint key_frame;
#endifenum AVPictureType pict_type;AVRational sample_aspect_ratio;int64_t pts;int64_t pkt_dts;AVRational time_base;#if FF_API_FRAME_PICTURE_NUMBERattribute_deprecatedint coded_picture_number;attribute_deprecatedint display_picture_number;
#endifint quality;void *opaque;int repeat_pict;#if FF_API_INTERLACED_FRAMEattribute_deprecatedint interlaced_frame;attribute_deprecatedint top_field_first;
#endif#if FF_API_PALETTE_HAS_CHANGEDattribute_deprecatedint palette_has_changed;
#endif#if FF_API_REORDERED_OPAQUEattribute_deprecatedint64_t reordered_opaque;
#endifint sample_rate;#if FF_API_OLD_CHANNEL_LAYOUTattribute_deprecateduint64_t channel_layout;
#endifAVBufferRef *buf[AV_NUM_DATA_POINTERS];AVBufferRef **extended_buf;int        nb_extended_buf;AVFrameSideData **side_data;int            nb_side_data;#define AV_FRAME_FLAG_CORRUPT       (1 << 0)#define AV_FRAME_FLAG_KEY (1 << 1)#define AV_FRAME_FLAG_DISCARD   (1 << 2)#define AV_FRAME_FLAG_INTERLACED (1 << 3)#define AV_FRAME_FLAG_TOP_FIELD_FIRST (1 << 4)int flags;enum AVColorRange color_range;enum AVColorPrimaries color_primaries;enum AVColorTransferCharacteristic color_trc;enum AVColorSpace colorspace;enum AVChromaLocation chroma_location;int64_t best_effort_timestamp;#if FF_API_FRAME_PKTattribute_deprecatedint64_t pkt_pos;
#endif#if FF_API_PKT_DURATIONattribute_deprecatedint64_t pkt_duration;
#endifAVDictionary *metadata;int decode_error_flags;
#define FF_DECODE_ERROR_INVALID_BITSTREAM   1
#define FF_DECODE_ERROR_MISSING_REFERENCE   2
#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE  4
#define FF_DECODE_ERROR_DECODE_SLICES       8#if FF_API_OLD_CHANNEL_LAYOUTattribute_deprecatedint channels;
#endif#if FF_API_FRAME_PKTattribute_deprecatedint pkt_size;
#endifAVBufferRef *hw_frames_ctx;AVBufferRef *opaque_ref;size_t crop_top;size_t crop_bottom;size_t crop_left;size_t crop_right;AVBufferRef *private_ref;AVChannelLayout ch_layout;int64_t duration;
} AVFrame;

4.2、重点数据结构之间的关系

4.2.1、AVFormatContext和AVInputFormat之间的关系

AVFormatContext API调用 AVInputFormat 主要是FFMPEG内部调用 数据: AVFormatContext 封装格式上下文结构体 struct AVInputFormat iformat;

方法: AVInputFormat 每种封装格式(例如FLV, MKV, MP4) int (read_header)(struct AVFormatContext * ); int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);

4.2.2、AVCodecContext和AVCodec之间的关系

数据: AVCodecContext 编码器上下文结构体 struct AVCodec codec;

方法: AVCodec 每种视频(音频)编解码器 int (decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr);

4.2.3、AVFormatContext、AVStream和AVCodecContext之间的关系

4.2.4、AVPacket和AVFrame之间的关系

 

相关文章:

FFmpeg架构全面分析

一、简介 它的官网为&#xff1a;https://ffmpeg.org/&#xff0c;由Fabrice Bellard&#xff08;法国著名程序员Born in 1972&#xff09;于2000年发起创建的开源项目。该人是个牛人&#xff0c;在很多领域都有很大的贡献。 FFmpeg是多媒体领域的万能工具。只要涉及音视频领…...

OAuth(开放授权)介绍

OAuth&#xff08;开放授权&#xff09;是一个开放标准&#xff0c;允许用户授权第三方应用访问他们存储在另一服务提供商上的信息&#xff0c;而无需将用户名和密码直接暴露给第三方应用。这个过程提供了一种安全的授权方式&#xff0c;常用于允许用户让第三方应用访问例如邮箱…...

Online ddl和replace ddl

在这个之前我们先来了解两种文件类型 1. .ibd文件 表数据文件&#xff0c;存储了表的数据和索引信息&#xff0c;从Mysql8开始表定义信息&#xff0c;从.frm文件改为.dcl文件存储&#xff0c;而表数据和索引信息仍然储存在.ibd文件&#xff0c;.idb文件通常在书籍库目录下。 …...

WEB渗透—反序列化(九)

Web渗透—反序列化 课程学习分享&#xff08;课程非本人制作&#xff0c;仅提供学习分享&#xff09; 靶场下载地址&#xff1a;GitHub - mcc0624/php_ser_Class: php反序列化靶场课程&#xff0c;基于课程制作的靶场 课程地址&#xff1a;PHP反序列化漏洞学习_哔哩哔_…...

蓝桥杯day02——第三大的数

题目 给你一个非空数组&#xff0c;返回此数组中 第三大的数 。如果不存在&#xff0c;则返回数组中最大的数。 示例 1&#xff1a; 输入&#xff1a;[3, 2, 1] 输出&#xff1a;1 解释&#xff1a;第三大的数是 1 。 示例 2&#xff1a; 输入&#xff1a;[1, 2] 输出&…...

linux shell中set -e命令的作用

set -e 是一个在shell脚本中常用的命令&#xff0c;它的含义是在脚本执行过程中&#xff0c;如果出现任何一个命令的执行结果不是零&#xff08;即命令执行失败&#xff09;&#xff0c;则立即退出整个脚本。 set -e 的用途是在脚本中进行错误处理和控制流程。通过设置set -e&…...

linux shell 字符替换命令

sed 文本 2.txt 内容如下&#xff1a; 1 2 3 4 511 121abcabcc1.替换文本指定字符或字符串&#xff0c;不更改原文件 将文本内容替换并输出&#xff0c;但不直接在原文档中修改: sed "s/旧字符串/新字符串/g" 文档 范例,将文本中的 1 替换为 b rootheihei:/# sed &…...

Vue3生命周期函数(简述题)

1.图示 2.说明 3.补充 1.在vue3组合式API中&#xff0c;我们需要将生命周期函数先导入&#xff0c;然后才能使用。 import {onMounted} from vue2.beforeCreate和created被setup()方法所代替...

11月29日,每日信息差//雷军个人向武汉大学捐赠13亿元现金//看电视默认设置新规一览:开机广告不超 5 秒、不设置一键付费

&#x1f396; 继长安汽车后&#xff0c;蔚来将与吉利控股达成换电业务合作 &#x1f384; 中国飞鹤入选工信部质量提升典型案例 &#x1f386; 雷军个人向武汉大学捐赠13亿元现金 &#x1f387; 奢侈品电商Farfetch或将私有化 &#x1f381; 亚马逊云科技宣布推出Amazon Q ✨ …...

融资经理简历模板

这份简历内容&#xff0c;以综合柜员招聘需求为背景&#xff0c;我们制作了1份全面、专业且具有参考价值的简历案例&#xff0c;大家可以灵活借鉴。 融资经理简历在线编辑下载&#xff1a;百度幻主简历 求职意向 求职类型&#xff1a;全职 意向岗位&#xff1a;融资经理 …...

iptables防火墙之SNAT与DNET

NAT 1.SNAT&#xff1a;让内网可以访问外网 2.DNAT&#xff1a;让外网可以访问到内网的机器 网关服务器&#xff0c;要开启路由功能 内核功能&#xff1a; sysctl -a 列出所有参数 内核参数&#xff0c;然后grep可以查看到默认的内核参数 内核参数配置文件 /etc/sysctl.…...

mysql使用--备份与恢复

1.mysqldump 1.1.使用mysqldump备份数据 1.1.1.备份指定数据库中的指定表 如&#xff1a;mysqldump [其他选项] 数据库名 [表1名 表2名 …] 如&#xff1a;mysqldump -uroot -hlocalhost -p1234 database1 student_score > student_score.sql 上述采用-u和-p完成用户登录&am…...

【vue实战项目】通用管理系统:信息列表,信息录入

本文为博主的vue实战小项目系列中的第六篇&#xff0c;很适合后端或者才入门的小伙伴看&#xff0c;一个前端项目从0到1的保姆级教学。前面的内容&#xff1a; 【vue实战项目】通用管理系统&#xff1a;登录页-CSDN博客 【vue实战项目】通用管理系统&#xff1a;封装token操作…...

【驱动】SPI驱动分析(六)-RK SPI驱动分析

前言 Linux的spi接口驱动实现目录在kernel\drivers\spi下。这个目录和一些层次比较明显的驱动目录布局不同&#xff0c;全放在这个文件夹下&#xff0c;因此还是只好通过看Kconfig 和 Makefile来找找思路 先看Makefile&#xff0c;里面关键几行&#xff1a; obj-$(CONFIG_SPI…...

【Linux】基础IO--文件基础知识/文件操作/文件描述符

文章目录 一、文件相关基础知识二、文件操作1.C语言文件操作2.操作系统文件操作2.1 比特位传递选项2.2 文件相关系统调用2.3 文件操作接口的使用 三、文件描述符fd1.什么是文件描述符2.文件描述符的分配规则 一、文件相关基础知识 我们对文件有如下的认识&#xff1a; 1.文件 …...

Intellij IDEA 的安装和使用以及配置

IDE有很多种&#xff0c;常见的Eclipse、MyEclipse、Intellij IDEA、JBuilder、NetBeans等。但是这些IDE中目前比较火的是Intellij IDEA&#xff08;以下简称IDEA&#xff09;&#xff0c;被众多Java程序员视为最好用的Java集成开发环境&#xff0c;今天的主题就是IDEA为开发工…...

Zynq-Linux移植学习笔记之67- 国产ZYNQ上通过GPIO模拟MDC/MDIO协议

1、背景介绍 模块上有9个PHY&#xff0c;其中两个PHY通过ZYNQ PS端的MDIO总线连接&#xff0c;其余7个PHY单独通过GPIO进行控制&#xff0c;需要实现GPIO模拟MDC/MDIO协议。 2、vivado工程设计 vivado工程内为每个PHY建立两个GPIO IP核&#xff0c;分别用来代表MDC和MDIO&…...

Zookeeper(一)在WSL单机搭建Zookeeper伪集群

目录 Zookeeper1 启动单个Zookeeper实例1.1 下载Zookeeper安装包并解压1.2 添加环境变量1.3 修改默认配置1.4 新建数据存储目录和日志目录1.5 启动Zookeeper1.6 停止Zookeeper 2 搭建Zookeeper集群2.1 新建集群目录2.2 配置环境变量2.3 创建节点目录2.4 修改配置2.5 创建节点ID…...

QT(18):QString

目录 QStringQTypedArrayDataQTypedArrayDataQLatin1StringQStringLiteral乱码 QStringRef QString QString 存储16位QChar的字符串&#xff0c;其中每个QChar对应一个 UTF-16代码单元。QString 使用&#xff08;写入时复制copy-on-write&#xff09;来减少内存使用并避免不必…...

宏工科技通过CMMI三级认证,软件研发能力获国际权威认可

近日&#xff0c;宏工科技子公司湖南宏工软件成功通过CMMI三级认证并正式获得资质证书&#xff0c;斩获全球软件领域最权威的认证之一&#xff0c;标志着宏工科技在软件技术开发、研发管理、项目管理等多方面获得国际权威认证。 CMMI全称是Capability Maturity Model Integrati…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...