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的ffmpeg中的align
ffmpeg之所以给了这个参数让⼈设置,应该就是为了兼容各个硬件平台,因为不是所有的硬件平台都能访 问任意地址上的任意数据的, 某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
以ffmpeg的av_image_get_buffer_size为例,你能准确说出下⾯的结果吗,如果可以,那么证明你确实 理解了ffmpeg中的对⻬了。
值得注意的是yuv的计算,以w*h
的yuv420p为例,
他是分三个平⾯存储三个分量的,⽽u和v的计算是⼀致 的,
也就是说计算出了u即可得到v;
对于y来说,它有w⾏h列,因此需要计算w⾏的对⻬后字节数再乘以h;
对于u来说,它有w/2
⾏h/2
列(这是因为每4个y共享⼀组uv),
因此需要计算w/2
⾏的对⻬后字节数再乘以 h/2
;
v的计算与u的⼀模⼀样,最后将这个三个数相加即可
例如310的图⽚,每个像素点占2个字节,对⻬数align为4,那么⾏数是多少呢,从条件可知,每⾏3 个像素点,每个像素点占2字节,那么每⾏就是6字节,⽽对⻬数是4,6不是4的整数倍,因此6需要补 2个字节凑成8,8就是4的整数倍了,那么我们就知道每⾏在内存中实际占⽤了8个字节,后两个字节是 为了对⻬补上的,总共有10⾏,那么这张图⽚在实际内存中就占⽤了810=80个字节,⽽不是60个字 节了
本来这张图⽚只需要60个字节,为何要⽤80个字节来存储呢,这是因为cpu并不能从任意地址开始读 取数据,如果不对⻬,那么可能需要多次读取才能读到完整数据,因此对⻬主要是为了提升性能,典型的空间换取时间
ffmpeg的linesize
linesize其实就是我们上⽂提及到的⾏字节数,在我们解码出数据后,经常会遇到这个linesize,既然我们知 道了align的概念,就该明⽩这个linesize就是为了让你取出真实的数据的 解码后的数据中可能是经过对⻬的,既然有对⻬,那就是数据⾥加多了⼀些为了对⻬⽽多余的字节,如果 我们想最后显示视频数据,那么这些多余的数据势必要进⾏剔除掉,那么怎么剔除呢,linesize就是来帮你 ⼲这事的,有了它,你就可以一行一行⽐较,然后把每⾏最后为了对⻬⽽补的字节删除,还原出视频的真 实数据
av_image_alloc函数
/**
* Allocate an image with size w and h and pixel format pix_fmt, and
* fill pointers and linesizes accordingly.
* 分配具有大小w和h以及像素格式pix_fmt的图像,并相应地填充指针和线条大小
*
* The allocated image buffer has to be freed by using
* av_freep(&pointers[0]).
* 必须释放分配的图像缓冲区使用av_freep
*
* @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);
av_image_fill_arrays函数
/**
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.
给定图像的字段是使用指向图像数据缓冲区的src地址填充的。
根据指定的像素格式,将设置一个或多个图像数据指针和线条大小。
如果指定了平面格式,将设置多个指向不同图片平面的指针,
不同平面的线条大小将存储在lines_sizes数组中。
使用src==NULL调用以获取src缓冲区所需的大小
To allocate the buffer and fill in the dst_data and dst_linesize in
one call, use av_image_alloc().
要在一次调用中分配缓冲区并填写dst_data和dst_linesize,请使用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);
通过以上实例可以看到,(a)
计算所需内存大小av_image_get_bufferz_size()(b)
按计算的内存大小申请所需内存 av_malloc()(c)
对申请的内存进行格式化 av_image_fill_arrays()文章来源:https://www.toymoban.com/news/detail-413945.html
参考
av_image_get_buffer_size
FFmpeg简单分析系列----内存对齐简要说明文章来源地址https://www.toymoban.com/news/detail-413945.html
到了这里,关于音视频从入门到精通——FFmpeg之av_image_get_buffer_size函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!