保存原始 YUV420P 帧 FFmpeg/Libav

Saving raw YUV420P frame FFmpeg/Libav

之前我成功打开、解码并保存了 .mp4 文件中的帧。原始帧采用 YUV420P 格式,我使用 sws_scale() 函数将其转换为 RGB24 并将它们保存到 .ppm 文件中。我现在要做的是将原始解码帧保留在 YUV420P 中,或者将我得到的帧转换为 YUV420P 以确保它们在 YUV420P 中。但问题是我不知道应该使用哪种类型的文件,我猜 .yuv?另一个问题是我也不知道如何保存 YUV420P 数据。

我曾经像这样在 .ppm 中保存 RGB24

for (y = 0; y < height; y++)
{
fwrite(frame->data[0] + y*frame->linesize[0], 1, width * 3, pf);
}

因为我只使用了一架飞机所以效果很好。但是 YUV420P 使用 3 个平面 (Y,Cb,Cr)。我试图做的是先保存 Y 分量,然后 Cb/Cr。

for (y = 0; y < height; y++)
{
    fwrite(frame->data[0] + y*frame->linesize[0], 1, width, pf);
}

for (y = 0; y < height / 2; y++)
{
    fwrite(frame->data[1] + y*frame->linesize[1], 1, width, pf);
    fwrite(frame->data[2] + y*frame->linesize[2], 1, width, pf);
}

但是您可以猜到这根本不起作用。实际上它确实如此,但它只保存了 Y 分量。谁能指导我正确的方向?

编辑 我已经像你说的那样更改了我的 saveFrame() 函数,但我使用的不是交错色度书写,而是平面。但是,我仍然只得到 Y 分量图片(黑白)。

fprintf(pf, "P5\n%d %d\n255\n", width, height);

for (y = 0; y < height; y++)
{
    fwrite(frame->data[0] + y*frame->linesize[0], 1, width, pf);
}

for (y = 0; y < height / 2; y++)
{
    fwrite(frame->data[1] + y*frame->linesize[1], 1, width / 2, pf);
}

for (y = 0; y < height / 2; y++)
{
    fwrite(frame->data[2] + y*frame->linesize[2], 1, width / 2, pf);
}

您的色度代码错误:

for (y = 0; y < height / 2; y++)
{
    fwrite(frame->data[1] + y*frame->linesize[1], 1, width / 2, pf);
    fwrite(frame->data[2] + y*frame->linesize[2], 1, width / 2, pf);
}

我还声称 height / 2width / 2 是错误的,因为你应该向上取整,而不是向下取整,但这相对较小。