libav中帧数据是如何存储的?

How is frame data stored in libav?

我正在努力学习使用 libav。我遵循了 dranger.com 上的第一个教程,但有一点我有点困惑。

// Write pixel data
for(y=0; y<height; y++)
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);

这段代码显然可以,但是我不太明白为什么,特别是我不明白pFrame->data中的帧数据是如何存储的,是否取决于format/codec中的使用,为什么 pFrame->datapFrame->linesize 总是在索引 0 处被引用,以及为什么我们要将 y 添加到 pFrame->data[0].

教程中说

We're going to be kind of sketchy on the PPM format itself; trust us, it works.

我不确定是否将其写入 ppm 格式是导致此过程对我来说如此奇怪的原因。任何关于此代码为何如此以及 libav 如何存储帧数据的澄清都将非常有帮助。总的来说,我对媒体 encoding/decoding 不是很熟悉,因此我正在努力学习。

particularly I don't understand how the frame data in pFrame->data stored, whether or not it depends on the format/codec in use

是的,这取决于 pix_fmt 值。有些格式是平面的,有些则不是。

why pFrame->data and pFrame->linesize is always referenced at index 0,

如果你看一下结构,你会看到 data 是一个指向指针的 pointers/a 指针的数组。所以 pFrame->data[0] 是指向第一个“平面”中数据的指针。一些格式,如 RGB,有一个平面,所有数据都存储在一个缓冲区中。 YUV 等其他格式为每个平面使用单独的缓冲区。例如Y = pFrame->data[0], U = pFrame->data[1], pFrame->data[3] 音频可能每个通道使用一个平面,等等。

and why we are adding y to pFrame->data[0].

因为示例是逐行从上到下遍历图像。 要获得指向任何行的第一个像素的指针,请将行大小乘以行号,然后将其添加到指针。