FFmpeg
文章平均质量分 94
探索ffmpeg的内部工作原理
安步当歌
这是我的学习日记,希望你能开心
展开
-
【FFmpeg】av_write_trailer函数
函数的主要功能是向输出的媒体文件中写入流的尾部信息,同时释放文件的私有数据。从注释上看,这个函数只能在成功调用了avformat_write_header之后进行调用原创 2024-07-05 09:48:24 · 968 阅读 · 0 评论 -
【FFmpeg】内存分配和释放(av_malloc、av_realloc等)
av_malloc在FFmpeg中用于分配内存地址,先检查输入的size是否大于了内存分配的最大限制,如果不大于,则调用_aligned_malloc按照对齐的方式分配内存。使用内存对齐的方式进行内存分配,有利于CPU的读取原创 2024-07-04 16:27:15 · 961 阅读 · 0 评论 -
【FFmpeg】avcodec_send_packet函数
函数的定义位于libavcodec\decode.c中,如下所示。这里最重要的地方在于检查cb_type,如果使用硬件解码器,则使用receive_frame,否则使用decode_simple_receive_frame执行软解过程原创 2024-07-04 14:58:24 · 1004 阅读 · 0 评论 -
【FFmpeg】avcodec_send_frame函数
avcodec_send_frame函数的主要功能是将外部输入的frame送入到编码器中实现编码,函数的实现位于libavcodec\encode.c中,从代码看,主要进行的流程为:(1)输入信息avctx的检查(2)如果输入的帧frame不存在,设置draining为1,随后将输入的frame存入avctx的buffer中,存入的过程使用encode_send_frame_internal实现(3)将frame送入编码器进行编码,使用encode_receive_packet_internal实现原创 2024-07-03 16:03:39 · 1389 阅读 · 0 评论 -
【FFmpeg】avcodec_open2函数
函数的定义位于libavcodec\avcodec.c中,从注释上看,主要的功能是使用给定的AVCodec情况下,来初始化AVCodecContext。在使用此函数之前,必须使用avcodec_alloc_context3来分配上下文,可以在外面配置options,作为codec初始化的参数原创 2024-07-03 09:04:23 · 1080 阅读 · 0 评论 -
【FFmpeg】关键结构体的初始化和释放(AVFormatContext、AVIOContext等)
在记录了一些主要函数的执行流程之后,可以看看几个关键结构体的初始化函数和释放函数,这样对整个FFmpeg更加熟悉一些。需要说明的是,在FFmpeg当中,很多函数都能够实现关键结构体的初始化,举例来说,对于AVFormatContext,可以使用avformat_alloc_output_context2初始化,这个函数会根据输出的format来初始化AVFormatContext,这样的操作避免了先进行malloc,然后手动赋值的流程。不过本文记录的函数是最基本的函数,尽量避免与其他结构体交织在一起原创 2024-07-02 14:43:33 · 819 阅读 · 0 评论 -
【FFmpeg】avcodec_find_encoder和avcodec_find_decoder
函数的功能是用于查找一个编码器,定义位于libavcodec\allcodecs.c,函数调用了find_codec查找一个编码器。find_codec的定义如下,其中先调用了remap_deprecated_codec_id进行id的重映射,随后调用av_codec_iterate从codec_list当中取出一个codec,随后判断这个codec的id是否与输入的id匹配,如果匹配再检查这个codec的编码能力(capabilities)是否是experimental,如果不是experimental则原创 2024-07-01 16:48:43 · 982 阅读 · 0 评论 -
【FFmpeg】av_write_frame函数
在参考雷博的文章时,发现他在进行函数分析时,分析了av_write_frame但是在实际工程之中应用了av_interleaved_write_frame,为什么有这个区别?这两个函数有什么异同,对于不同的格式而言,应该使用什么函数来实现frame写入比较好?本文先记录av_write_frame是如何实现的,在FFmpeg7.0中,av_write_frame和老版本的av_write_frame有一些改动,av_write_frame函数的内部调用关系如下,其中最核心的部分是调用的write_pack原创 2024-07-01 16:04:24 · 777 阅读 · 0 评论 -
【FFmpeg】av_read_frame函数
返回流的下一帧1.此函数返回存储在文件中的内容,而不验证是否存在用于解码器的有效帧。它将把存储在文件中的内容分割成帧,并为每次调用返回一个帧。它不会省略有效帧之间的无效数据,以便为解码器提供可能用于解码的最大信息2.如果成功,返回的数据包将被引用计数(pkt->但已设置)并无限期有效。当不再需要该数据包时,必须使用av_packet_unref()释放该数据包。对于视频,数据包只包含一帧。对于音频,如果每帧有一个已知的固定大小(例如PCM或ADPCM数据),它包原创 2024-07-01 10:37:04 · 1289 阅读 · 0 评论 -
【FFmpeg】avformat_write_header函数
函数的功能:分配流私有数据并将流标头写入输出媒体文件;函数的定义位于libavformat\mux.c中,主要的工作流程为:(1)如果没有进行初始化,则进行初始化输出(avformat_init_output)(2)进行头信息的写入(write_header)(3)如果流还没有被初始化,则写入pts(init_pts)原创 2024-06-28 11:28:57 · 1094 阅读 · 0 评论 -
【FFmpeg】avio_open2函数
avio_open2函数的定义位于libavformat\avio.c中,功能是打开URL,之后方便进行读写操作。这里的URL是广义的地址,对于文件而言,就是文件的路径,如"C:\xxx\test.flv",也可以是地址例如"rtmp://127.0.0.1:1935/live/stream",flag表示控制如何打开url所指示的资源的标志,如AVIO_FLAG_READ和AVIO_FLAG_WRITE原创 2024-06-27 16:55:12 · 874 阅读 · 0 评论 -
【FFmpeg】avformat_alloc_output_context2函数
avformat_alloc_output_context2内函数调用关系如下。函数的主要功能是分配一个输出的context,利用输入的format和filename来确定output format,主要工作流程为:(1)初始化AVFormatContext(avformat_alloc_context)(2)如果没有指定输出format,需要根据输入信息来猜测一个format(av_guess_format)(3)根据输出的format,来对AVFormatContext中的priv_data初始原创 2024-06-27 12:20:46 · 957 阅读 · 0 评论 -
【FFmpeg】avformat_find_stream_info函数
FFmpeg版本为7.0,函数的主要功能是根据前面获取的AVFormatContext,结合输入的options,分析每个流(AVStream)的信息,主要内容包括:(1)确定分析的最大时长(2)对每个流当中的codec信息的获取(2.1)初始化解析器(av_parser_init)(2.2)查找探测解码器(find_probe_decoder)(2.3)尝试打开解码器(avcodec_open2)(3)frame信息的获取(3.1)编解码器的检原创 2024-06-27 10:43:32 · 981 阅读 · 0 评论 -
【FFmpeg】avformat_open_input函数
函数的定义位于libavformat\demux.c中,定义如下,主要的工作流程为:(1)为avformat分配空间(avformat_alloc_context)(2)初始化输入格式(init_input)(3)黑白名单的检查(4)其他信息的检查(5)读取头信息(read_header)(6)更新流的音频/视频上下文(update_stream_avctx)在函数执行的过程中,最核心的函数为初始化输入格式(init_input)原创 2024-06-25 16:25:08 · 1052 阅读 · 0 评论 -
【FFmpeg】AVFrame结构体
AVFrame结构体中记录的比较关键的信息包括:(1)uint8_t *data[AV_NUM_DATA_POINTERS]:存储frame数据(2)int linesize[AV_NUM_DATA_POINTERS]:帧当中一行有多少像素(3)int width, height:视频的宽高(4)int format:frame的格式(5)int key_frame:是否是关键帧(6)enum AVPictureType pict_type:帧的类型(7)int64_t pts:present原创 2024-06-24 11:55:15 · 875 阅读 · 0 评论 -
【FFmpeg】AVPacket结构体
AVPacket结构体的定义与老版本相似,基本没有大的改动,其中比较关键的内容包括:(1)uint8_t *data:存储压缩数据的变量(2)int size:数据大小(3)int stream_index:流的索引号(4)int flags:描述当前pkt的使用情况(5)int64_t pts:解压后的数据包呈现给用户的时间(6)int64_t dts:数据包被解压的时间原创 2024-06-24 09:15:35 · 394 阅读 · 0 评论 -
【FFmpeg】AVIOContext结构体
AVIOContext当中比较重要的信息包括:(1)unsigned char *buffer:buffer的起始地址(2)int buffer_size:buffer的大小(3)unsigned char *buf_ptr:buffer当前的指针(4)unsigned char *buf_end:buffer末尾的地址(5)void *opaque:URLContext(6)int (*read_packet)(void *opaque, uint8_t *buf, int buf_size)原创 2024-06-21 17:51:59 · 1094 阅读 · 0 评论 -
【FFmpeg】AVFormatContext结构体
从AVFormatContext的定义来看,除了定义了AVInputFormat和AVOutputFormat两种format结构体之外,还定义了输入输出上下文结构体AVIOContext、文件中流的list结构体AVStream、黑白名单list和流的打开关闭函数,这里与老版本的FFmpeg不同的地方包括:(1)将以前的char filename[1024]改成了现在的char* url,不再限制长度;(2)将AVCodec存放在AVFormatContext之中而不是AVStream之中,这里有一点将A原创 2024-06-21 12:08:46 · 701 阅读 · 0 评论 -
【FFmpeg】AVStream结构体
粗略来看,AVCodecParameters之中存储的信息和AVCodecContext之间的关系更像是子集关系,AVCodecParameters只包含部分的变量,例如长宽、格式和帧率等等,AVCodecContext既包含了这些变量,还包含了如qp控制、bitrate控制、硬件编解码等等一系列变量,此外AVCodecContext之中还定义了一些函数指针,如get_format和get_buffer等。在新版本中将编解码器参数和上下文信息隔离开来,应该是不希望在stream这个级别去改变codec的一些原创 2024-06-20 18:23:00 · 774 阅读 · 0 评论 -
【FFmpeg】AVCodecContext结构体
这里一些关键结构体如AVMediaType、AVCodec、AVCodecID、AVRational和AVPixelFormat在[【FFmpeg】AVCodec结构体](https://blog.csdn.net/weixin_42877471/article/details/139748762)一文中记录原创 2024-06-19 16:54:38 · 986 阅读 · 0 评论 -
【FFmpeg】AVCodec结构体
AVCodec是FFmpeg中最重要的结构体之一,它记录了编解码器中的重要信息,其定义位于libavcodec\codec.h中,如下所示原创 2024-06-19 09:48:16 · 644 阅读 · 0 评论 -
【FFmpeg】解码链路上主要函数的简单分析
本文分析的FFmpeg版本是FFmpeg-7.0,只考虑视频解码部分的流程,不考虑音频部分FFmpeg进行解码器的调用时,主要工作流程大约是解码器: 1. 查找解码器(avcodec_find_decoder) 2. 创建解码器上下文(avcodec_alloc_context3) 3. 创建输入信息的结构体(av_packet_alloc) 4. 创建输出信息的结构体(av_frame_alloc) 5. 创建解析器(av_parser_init) 6. 打开解码器(avcodec_op原创 2024-05-15 16:16:00 · 678 阅读 · 0 评论 -
【FFmpeg】编码链路上主要函数的简单分析
从编码链路这一整体系统上看,大致的输入是AVFrame,处理系统是AVCodec,记录信息是AVCodecContext,推送输入的引擎是avcodec_send_frame,接收输出的引擎是avcodec_receive_packet,输出是AVPacket。对于编码器而言,输入的AVFrame主要是以yuv420p的格式进行存储。AVCodecContext记录了编码流程中的信息,包括码流帧的长宽,高度,AVCodec信息,Log信息,时间,色度格式等等一系列的信息,它纵览全局,是极其重要的结构体。原创 2024-05-15 11:59:15 · 909 阅读 · 0 评论 -
【FFmpeg】调用ffmpeg库进行RTMP推流和拉流
从使用的函数来看,主要的操作流程和数据流走向大约为: 1. 初始化网络模块,为RTMP传输进行准备(avformat_network_init) 2. 打开输入文件,创建输入文件结构体并且读取输入文件信息(avformat_open_input),此时也会创建输入的流信息 3. 根据输入文件查找流信息(avformat_find_stream_info) 4. 查看输入文件信息(av_dump_format) 5. 根据输出文件信息来创建输出文件结构体(avformat_alloc_output原创 2024-05-10 15:35:29 · 1447 阅读 · 5 评论 -
【FFmpeg】调用ffmpeg进行H264软解
参考FFmpeg当中的/doc/examples当中的video_decode.c文件,进行调用过程的理解和实现原创 2024-05-06 16:32:00 · 1162 阅读 · 1 评论 -
【FFmpeg】调用ffmpeg进行H264软编
从上面这一系列的函数调用来看,大致操作流程和数据走向大约是1.编码器的创建和初始化(avcodec_find_encoder)2.编码器上下文的创建和初始化(avcodec_alloc_context3)3.创建编码器输出信息,使用AVPacket进行存储(av_packet_alloc)4.打开编码器(avcodec_open2)5.创建编码器输入信息,使用AVFrame进行存储(av_frame_alloc)6.获取编码器输入信息的数据Buffer(av_frame_get_buffer)原创 2024-04-29 11:35:55 · 718 阅读 · 1 评论