ffmpeg编解码常用接口
〇、ffmpeg初始化注册
av_register_all();//有的ffmpeg版本缺失该接口会导致avformat_open_input异常
avformat_network_init();/avformat_network_deinit();
一、媒体文件分流解析处理
libavformat库中的函数
avformat_open_input() / avformat_close_input();
avformat_find_stream_info()
av_find_best_stream()
av_dump_format()
av_seek_frame()/avformat_seek_file()
av_read_frame()
二、音视频解码器
libavcodec库中的函数
avcodec_alloc_context3() / avcodec_free_context()包含了avcodec_close()功能
avcodec_parameters_to_context()
avcodec_find_decoder()
avcodec_open2() / avcodec_close()
avcodec_send_packet() / avcodec_receive_frame(): 解码获取frame,内部执行av_frame_unref(frame)
av_packet_alloc()/av_packet_free()或av_packet_unref()
A. //方法1:计算pixfmt格式图片需要的字节数
avpicture_get_size()-->由av_image_get_buffer_size()代替,通过指定像素格式、图像宽、图像高来计算所需的内存大小
avpicture_fill() -->由av_image_fill_arrays()代替,使用前先申请内存
// libavcodec/avpicture.c
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
enum AVPixelFormat pix_fmt, int width, int height)
{
return av_image_fill_arrays(picture->data, picture->linesize,
ptr, pix_fmt, width, height, 1);
}
av_picture_copy -->由av_image_copy()代替
B. //方法2:计算pixfmt格式图片需要的字节数
av_frame_get_buffer()
在AVFrame结构体中,buf和data数组所指向的是同一块数据区域,在释放内存时调用av_frame_free时,只会释放buf。调用av_frame_get_buffer填充时,ffmpeg会将这两部分一起初始化,所以释放时只释放buf,data部分也会一起释放。
调用av_image_fill_arrays填充时,只会更改AVFrame中的data部分,不会改变buf,所以释放时data不会随着buf释放,需要自己手动释放这部分空间。
结论:
av_frame_get_buffer()可以理解为自动为AVFrame分配空间,而av_image_fill_arrays可以理解为手动填充。
在初始化一个AVFrame时,如果需要填充自己准备好的数据(如捕获到的屏幕图像数据),采用av_image_fill_arrays(),但是在使用完后,一定要注意释放data
如果用一个AVFrame初始化是为了继承sws转换的数据,可以选择av_frame_get_buffer()进行初始化,这样在释放时直接调用av_frame_free即可,不用担心内存泄漏问题。
————————————————
原文链接:https://blog.youkuaiyun.com/oooooome/article/details/111993911
libavutil函数
av_frame_alloc()/av_frame_free()
av_frame_ref()/av_frame_unref()
av_frame_clone()
三、视频格式转换
libswscale库
sws_getContext()/sws_getCachedContext():根据输入输出图像的 宽高和 像素格式 创建转换器
sws_scale():根据输入图像数据进行转换(大小缩放、图像格式、颜色空间、存储布局)操作,结果输出到输出缓冲区
sws_freeContext():释放转换器
四、音频格式转换
libswresample库
swr_alloc() / swr_free():创建/释放音频转换器
struct SwrContext *swr_ctx = swr_alloc();//调用此接口后swr_alloc_set_opts第1个参数传入其返回值
swr_alloc_set_opts() / swr_init():设置转换参数,之后需要执行swr_init()
av_rescale_rnd() / swr_get_delay() 或swr_get_out_samples() 计算每个声道输出采样数out_count
swr_convert():进行实际的音频数据转换
重点是不同采样格式、不同通道情况下,音频数据的内存布局
五、音视频编码处理
libavformat 库中的函数
avcodec_find_encoder() / avcodec_find_encoder_by_name();
avcodec_alloc_context3() / avcodec_free_context()
avcodec_open2() / avcodec_close()
avcodec_send_frame() / avcodec_receive_packet()
六、音视频混流处理
libavformat 库中的函数
avformat_alloc_output_context2() / avformat_free_context()
avformat_new_stream() 和 avcodec_parameters_from_context()
avio_open() / avio_closep()
avformat_write_header() / av_write_trailer()
av_interleaved_write_frame()
七、内存分配与释放
av_malloc() / av_mallocz() / av_calloc() / av_realloc()
av_free(ptr) / av_freep(&ptr):注意两者参数不同
参考:FFmpeg源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)_ffmpeg释放内存_雷霄骅的博客-优快云博客