当前位置: 首页 > 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…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...