QVideoFrame::planeCount() 和 QVideoFrame::bytesPerLine 的含义

Meaning of QVideoFrame::planeCount() and QVideoFrame::bytesPerLine

QVideoFrame::planeCount

Returns the number of planes in the video frame. This value is only valid while the frame data is mapped

QVideoFrame::bytesPerLine

Returns the number of bytes in a scan line.

我不太理解这些说法,谁能详细解释一下?

在使用 QVideoFrame::map

后,我从网络摄像头获得了以下数据
width=640
height=480
pixelFormat=Format_RGB32
bytesPerLine=2560
mappedBytes=122880
planeCount=1

一条扫描线就是视频图像的一行。 (术语“扫描线”是在阴极射线逐行扫描屏幕管表面的常用技术时代创造的 – Scan line。)

如果 bytesPerLine 除以 width (bytesPerLine / width = 2560 / 640 = 4),它产生每个像素的字节数。

如果计算出的每像素字节数不是整数值,则该行对齐到某个倍数(通常为4)。一个复杂的例子来说明这一点:

width=458
pixelFormat=Format_RGB24
bytesPerLine=1376 (a multiple of 4)

1376 / 458 = 3.0043668122270742358078602620087(根据我的 Windows 计算器)

458 * 3 = 1374 → 有 2 个字节来填充行到下一个 4 的倍数(未使用的字节,应忽略)。

在 OP 的示例中,这不是问题 - 像素格式本身具有与行对齐匹配的大小。

所以,这 4 个字节与 pixelFormat 相匹配,其中说明 Format_RGB32 意思是:

The frame stored using a 32-bit RGB format (0xffRRGGBB). This is equivalent to QImage::Format_RGB32.

作为 32 位 = 4 字节。

飞机的数量有点棘手。我用谷歌搜索自己,发现 Single- and multi-planar APIs:

Some devices require data for each input or output video frame to be placed in discontiguous memory buffers. In such cases, one video frame has to be addressed using more than one memory address, i.e. one pointer per “plane”. A plane is a sub-buffer of the current frame.

在 OP 的情况下,有 1 个平面 - 像素的颜色分量连续存储(打包)。

另一个示例,其中平面数 > 1:QVideoFrame::Format_YUV420P

The frame is stored using an 8-bit per component planar YUV format with the U and V planes horizontally and vertically sub-sampled, i.e. the height and width of the U and V planes are half that of the Y plane.

这意味着像素的颜色分量没有打包在一起(如 Format_RGB32),但每个平面仅存储一个像素的一种颜色分量。要重建像素,必须从每个平面读取相应的颜色分量并分别组合。

在有多个平面的情况下,应使用 bytesPerLine() 的第 2nd 种风格:

int QVideoFrame::bytesPerLine(int plane) const

Returns the number of bytes in a scan line of a plane.

在上述QVideoFrame::Format_YUV420P的情况下:U和V分量被水平和垂直子采样。 IE。要获得 (x, y) = (123, 72) 处的像素,必须读取组件:

  • 偏移处的 Y 分量 72 * getBytesPerLine(0) + 123
  • 偏移处的 U 分量 72 / 2 * getBytesPerLine(1) + 123 / 2
  • 偏移量 72 / 2 * getBytesPerLine(2) + 123 / 2 处的 V 分量。