首页 > 解决方案 > 宽度,高度和线条大小之间的AVFrame混淆

问题描述

我试图了解 AVFrame,特别是 linesize 属性。

这是我解码的 AVFrame 属性:

width = 640 
height= 360

linesize[0] = 640
linesize[1] = 320
linesize[2] = 320

这是一个 YUV 420 平面图像 ( AV_PIX_FMT_YUVJ420P)

我正在阅读这段代码,这是处理 AVFrame 属性的部分:

int linesize = qAbs(m_format.renderFrame->linesize[i]);
AVRational widthRational = params.yuvwidths[i];
AVRational heightRational = params.yuvheights[i];
int width = linesize * widthRational.num / widthRational.den;
int height = m_format.renderFrame->height * heightRational.num / heightRational.den;
glTexImage2D ( GL_TEXTURE_2D, 0, params.yuvInternalformat[i],width ,height, 0, params.yuvGlFormat[i], params.dataType, NULL);
        

其中,对于 YUV420P,widthRationaland heightRationalare 1/1and 1/1for i=0,and 1/2and 1/2for i = 1,2。并且总是。yuvInternalformat_yuvGlFormatGL_RED

在这段代码中有一些我无法理解的东西:

为什么他取绝对值linesize?可以linesize是负数吗?文档中没有关于负值的内容。我理解他为什么在 中进行分数乘法height,但为什么在 中linesize?不应该是平面图像linesize的实际width情况,因此不需要乘法吗?

那么是什么,linesize应该如何计算才能使用呢?widthheightglTexImage2D

标签: c++openglffmpeg

解决方案


高度是以像素为单位的高度,没什么特别的。

宽度是显示图像的宽度(以像素为单位)。

步幅或线大小,内存中每行像素的宽度。线条大小必须等于或大于宽度。例如,1920x1080 通常具有 1088 的线条大小,以使步幅可以被 16 整除,但不显示最右边的 8 列像素。

色度二次采样是另一回事。对于某些颜色格式,例如 yuv420p,第一个平面(黑白平面)是全分辨率,但 2 个颜色平面是四分之一分辨率(半高和半宽)。在我的 1920x1080 示例中,这使得第二个和第三个平面的高度为 960,宽度为 540,步幅(最有可能)为 544(544 = ceil(1080/16)*16)。

其他颜色格式,如 RGB 或 yuv444p,第二个和第三个平面的尺寸与第一个相同。


推荐阅读