【问题标题】:AVFrame confusion between width, height and linesize宽度、高度和线大小之间的 AVFrame 混淆
【发布时间】:2019-12-29 18:27:04
【问题描述】:

我正在尝试理解 AVFrame,特别是 linesize 属性。

这是我解码的 AVFrame 属性:

width = 640 
height= 360

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

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

我正在阅读this code,这是处理 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,widthRationalheightRational1/11/1 对于 i=01/21/2 对于 i = 1,2。而yuvInternalformatyuvGlFormat 总是GL_RED

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

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

那么linesize是什么,widthheight应该如何计算才能使用glTexImage2D

【问题讨论】:

    标签: c++ opengl ffmpeg


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 如果linesize必须>=宽度,我的width=640,但是linesize[1]=320怎么办?那是什么意思?您所说的“1920x1088 线条大小”是什么意思?据我了解, linesize 是一个略大于宽度的数字。你说的 1920x1088 是什么数字?
    • 请重新阅读我的回复。我通过描述色度子采样具体解释了这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    相关资源
    最近更新 更多