机型:Intel(R)?Xeon(R)?Gold?5218
ffmpeg版本4.3-dev
解码视频分辨率?720x1280?,?解码后?AVFrame?linesize?768
解码视频分辨率?480x640,?解码后AVFrame?linesize?512
avcodec_default_get_buffer2
-->update_frame_pool()
-->video_get_buffer()
video_get_buffer()-->
for?(i = 0;?i < 4 && pool->pools[i];?i++)?{
pic->linesize[i]?= pool->linesize[i];
由上面代码可见,AVFrame的linesize源自于?pool的linesize
update_frame_pool()
case AVMEDIA_TYPE_VIDEO:?{
int linesize[4];
int w = frame->width;
int h = frame->height;
int unaligned;
ptrdiff_t linesize1[4];
size_t size[4];
avcodec_align_dimensions2(avctx,?&w,?&h,?pool->stride_align);
do?{
//?NOTE:?do?not?align?linesizes?individually,?this?breaks?e.g.?assumptions
//?that?linesize[0]?==?2*linesize[1]?in?the?MPEG-encoder?for?4:2:2
ret = av_image_fill_linesizes(linesize,?avctx->pix_fmt,?w);
if?(ret < 0)
goto fail;
//?increase?alignment?of?w?for?next?try?(rhs?gives?the?lowest?bit?set?in?w)
w += w & ~(w - 1);
unaligned = 0;
for?(i = 0;?i < 4;?i++)
unaligned |= linesize[i]?% pool->stride_align[i];
????????}?while?(unaligned);
for?(i = 0;?i < 4;?i++)
linesize1[i]?= linesize[i];
ret = av_image_fill_plane_sizes(size,?avctx->pix_fmt,?h,?linesize1);
if?(ret < 0)
goto fail;
for?(i = 0;?i < 4;?i++)?{
pool->linesize[i]?= linesize[i];?//这里赋值给pool的linesize
linesize列表?通过?av_image_fill_linesizes获取,基本就是等于?width。
循环中
w?+=?w?&?~(w?-?1);?//每次将最低有效二进制位+1,这样做的目的,比如当前是16的整数倍,调整为32的整数倍。然后64的整数倍。
直到最终对?stride_align[i]取余为0.
avcodec_align_dimensions2(avctx,?&w,?&h,?pool->stride_align);
函数获取?stride_align
for?(i = 0;?i < 4;?i++)
linesize_align[i]?= STRIDE_ALIGN;
#if?HAVE_SIMD_ALIGN_64
#???define?STRIDE_ALIGN?64?/*?AVX-512?*/
#elif?HAVE_SIMD_ALIGN_32
#???define?STRIDE_ALIGN?32
#elif?HAVE_SIMD_ALIGN_16
#???define?STRIDE_ALIGN?16
#else
#???define?STRIDE_ALIGN?8
#endif
当机器支持avx512,?STRIDE_ALIGN?64.
总结:ffmpeg的AVFrame?linesize对齐方式和机器支持的simd有关,avx512就是64字节,avx256就是32字节