ffmpeg4.2.2-avpicture_fill()的使用心得
1. avpicture_fill()的声明
/**
* @deprecated use av_image_fill_arrays() instead.
*/
attribute_deprecated
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
enum AVPixelFormat pix_fmt, int width, int height);
FF_DISABLE_DEPRECATION_WARNINGS
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);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
由上可见, avpicture_fill()函数在ffmpeg4.2.2中就已经被抛弃了, 取而代之的是av_image_fill_arrays()函数. avpicture_fill()中实际调用的也是av_image_fill_arrays()函数, 所以我们拿av_image_fill_arrays()来分析.
2. av_image_fill_arrays()的形参说明
@param dst_data 要填充的数据指针
@param dst_linesize dst_data中要被填充的线条大小(即linesize, 行宽)
@param src 包含实际图像的缓冲区(可以为空).
@param pix_fmt 图像的像素格式
@param width 图像的像素宽度
@param height 图像的像素高度
@param align 在src中用于行宽对齐的值
@return the size in bytes required for src, a negative error code in case of failure
该函数返回src所需的大小(以字节为单位), 失败时返回一个负数(错误代码).
1
2
3
4
5
6
7
8
9
10
3. av_image_fill_arrays()的作用
根据指定的图像参数和提供的数组设置数据指针和行宽(linesizes). avpicture_fill函数将ptr指向的数据填充到picture内,但并没有拷贝,只是将picture结构内的data指针指向了ptr的数据!
4. av_image_fill_arrays()的流程解析
// ffmpeg-4.2.2\libavutil\imgutils.c
int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
const uint8_t *src, enum AVPixelFormat pix_fmt,
int width, int height, int align)
{
int ret, i;
// 检查输入的width和height是否可用.
ret = av_image_check_size(width, height, 0, NULL);
if (ret < 0)
return ret;
/**
* 1. memset(linesizes, 0, 4*sizeof(linesizes[0])); 将dst_linesize数组的内容清零;
* 2. 利用av_pix_fmt_desc_get函数得到输入格式的AVPixFmtDescriptor指针;
* 3. 最后利用image_get_linesize函数设置linesizes数组中每个元素的值.
*
* 可见该函数是用于填充dst_linesize数组.
*/
ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width);
if (ret < 0)
return ret;
for (i = 0; i < 4; i++)
/**
* 由上面的第一节avpicture_fill的实现中可知align=1, 故该宏返回的值还是linesizes[i].
*/
dst_linesize[i] = FFALIGN(dst_linesize[i], align);
/**
* 1. memset(data, 0, sizeof(data[0])*4); 将data数组内的指针置空
* 2. data[i] = data[i-1] + size[i-1]; 将data数组内的指针分别指向ptr内的数据
*/
return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
5. 以前对avpicture_fill()的错误理解
uint8_t *out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
AVFrame *pFrameRGB = av_frame_alloc();
ret = avpicture_fill((AVPicture *) pFrameRGB, out_buffer, AV_PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
1
2
3
4
5
错误理解:
pFrameRGB和out_buffer都是已经申请到的一段内存, 会将pFrameRGB的数据按RGB24格式自动"关联(转换并放置)"到out_buffer。
正确理解:
pFrameRGB和out_buffer都是已经申请到的一段内存, 但是pFrameRGB只是申请了一段结构体内存, 结构体里面的值是空的, 我们需要使用avpicture_fill()函数来使得pFrameRGB和out_buffer关联起来, pFrameRGB里面使用的是out_buffer所指向的内存空间.
from:https://blog.csdn.net/MACMACip/article/details/105463390
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2017-07-21 基于libRTMP的流媒体直播之 AAC、H264 推送
2017-07-21 视频、音频打时间戳的方法及其音视频同步(播放)原理
2017-07-21 RTP协议分析和详解
2014-07-21 C++11 FAQ中文版--转
2014-07-21 rtsp交互命令简介及过程参数描述
2014-07-21 PS流格式