一、ffmpeg中av_image_alloc()是这样定义的。此函数的功能是按照指定的宽、高、像素格式来分析图像内存。
参数说明:
pointers[4]:保存图像通道的地址。如果是RGB,则前三个指针分别指向R,G,B的内存地址。第四个指针保留不用
linesizes[4]:保存图像每个通道的内存对齐的步长,即一行的对齐内存的宽度,此值大小等于图像宽度。
w: 要申请内存的图像宽度。
h: 要申请内存的图像高度。
pix_fmt: 要申请内存的图像的像素格式。
align: 用于内存对齐的值。
返回值:所申请的内存空间的总大小。如果是负值,表示申请失败。
/**
* Allocate an image with size w and h and pixel format pix_fmt, and
* fill pointers and linesizes accordingly.
* The allocated image buffer has to be freed by using
* av_freep(&pointers[0]).
*
* @param align the value to use for buffer size alignment
* @return the size in bytes required for the image buffer, a negative
* error code in case of failure
*/
int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
int w, int h, enum AVPixelFormat pix_fmt, int align);
(1)调用实例
参见本地工程 \vs2010cProjects\ffmpeg_yuv_file_show_sdl2\ffmpeg_yuv_file_show_sdl2。
具体代码:
ret= av_image_alloc(src_data, src_linesize,src_w, src_h, src_pixfmt, 1); //按照长、宽、像素格式分配各个通道的内存大小以及步长(linesize),内存地址保存到src_data的指针数组中
if (ret< 0) {
printf( "Could not allocate source image\n");
return -1;
}
二、另一种同样功能的函数调用方法
int image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1); //计算指定像素格式、图像宽、高所需要的对齐的内存大小
out_buffer = (unsigned char *)av_malloc(image_buf_size); //分配指定大小的内存空间
av_image_get_buffer_size()函数的作用是通过指定像素格式、图像宽、图像高来计算所需的内存大小。
ffmpeg中关于av_image_get_buffer_size()的定义如下:
/**
* Return the size in bytes of the amount of data required to store an
* image with the given parameters.
*
* @param pix_fmt the pixel format of the image
* @param width the width of the image in pixels
* @param height the height of the image in pixels
* @param align the assumed linesize alignment
* @return the buffer size in bytes, a negative error code in case of failure
*/
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);
重点说明一个参数align:此参数是设定内存对齐的对齐数,也就是按多大的字节进行内存对齐。比如设置为1,表示按1字节对齐,那么得到的结果就是与实际的内存大小一样。再比如设置为4,表示按4字节对齐。也就是内存的起始地址必须是4的整倍数。
ffmpeg中关于av_image_fill_array()函数的定义:
/**
* Setup the data pointers and linesizes based on the specified image
* parameters and the provided array.
*
* The fields of the given image are filled in by using the src
* address which points to the image data buffer. Depending on the
* specified pixel format, one or multiple image data pointers and
* line sizes will be set. If a planar format is specified, several
* pointers will be set pointing to the different picture planes and
* the line sizes of the different planes will be stored in the
* lines_sizes array. Call with src == NULL to get the required
* size for the src buffer.
*
* To allocate the buffer and fill in the dst_data and dst_linesize in
* one call, use av_image_alloc().
*
* @param dst_data data pointers to be filled in
* @param dst_linesize linesizes for the image in dst_data to be filled in
* @param src buffer which will contain or contains the actual image data, can be NULL
* @param pix_fmt the pixel format of the image
* @param width the width of the image in pixels
* @param height the height of the image in pixels
* @param align the value used in src for linesize alignment
* @return the size in bytes required for src, a negative error code
* in case of failure
*/
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);
av_image_fill_arrays()函数自身不具备内存申请的功能,此函数类似于格式化已经申请的内存,即通过av_malloc()函数申请的内存空间。
再者,av_image_fill_arrays()中参数具体说明:
dst_data[4]: [out]对申请的内存格式化为三个通道后,分别保存其地址
dst_linesize[4]: [out]格式化的内存的步长(即内存对齐后的宽度)
*src: [in]av_alloc()函数申请的内存地址。
pix_fmt: [in] 申请 src内存时的像素格式
width: [in]申请src内存时指定的宽度
height: [in]申请scr内存时指定的高度
align: [in]申请src内存时指定的对齐字节数。
(1)调用实例1
image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 11, 5, 1); //按1字节进行内存对齐,得到的内存大小最接近实际大小
printf("image_buf_size:%d\n",image_buf_size);
image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 11, 5, 0); //按0字节进行内存对齐,得到的内存大小是0
printf("image_buf_size:%d\n",image_buf_size);
image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 11, 5, 4); //按4字节进行内存对齐,得到的内存大小稍微大一些
printf("image_buf_size:%d\n",image_buf_size);
(2)调用实例2
img_convert_out_buffer = (unsigned char *)av_malloc(av_image_get_buffer_size(dst_pixfmt, dst_w, dst_h, 1));
av_image_fill_arrays(pFrameYUV->data,pFrameYUV->linesize, img_convert_out_buffer,dst_pixfmt, dst_w, dst_h, 1);
img_convert_ctx = sws_getContext(src_w, src_h, src_pixfmt,
dst_w, dst_h, dst_pixfmt,
SWS_BICUBIC, NULL, NULL, NULL);
(3)调用方法总结
通过以上实例可以看到,(a)计算所需内存大小av_image_get_bufferz_size() --> (b) 按计算的内存大小申请所需内存 av_malloc() --> (c) 对申请的内存进行格式化 av_image_fill_arrays();