使用FFmpeg将解码的YUV420P数据写入文件?

时间:2016-03-04 13:57:30

标签: ffmpeg yuv

我读取了用H264编码的帧,对其进行解码,并将其转换为YUV420P,数据存储在frameYUV420->data中,(帧的类型为AVFrame)。我想将该数据保存到一个可以用GIMP显示的文件中。

我知道如何保存RGB25像素格式,但我不太清楚如何做YUV420P。虽然我知道Y分量将采用宽度x高度,而Cb / Cr将采用(宽度/ 2)x(高度/ 2)所需的空间量来保存数据。所以我猜我需要先写Y数据,之后我需要写Cb和Cr数据。有没有人完成了我可以看一下的代码?

2 个答案:

答案 0 :(得分:3)

void SaveAvFrame(AVFrame *avFrame)
{
    FILE *fDump = fopen("...", "ab");

    uint32_t pitchY = avFrame->linesize[0];
    uint32_t pitchU = avFrame->linesize[1];
    uint32_t pitchV = avFrame->linesize[2];

    uint8_t *avY = avFrame->data[0];
    uint8_t *avU = avFrame->data[1];
    uint8_t *avV = avFrame->data[2];

    for (uint32_t i = 0; i < avFrame->height; i++) {
        fwrite(avY, avFrame->width, 1, fDump);
        avY += pitchY;
    }

    for (uint32_t i = 0; i < avFrame->height/2; i++) {
        fwrite(avU, avFrame->width/2, 1, fDump);
        avU += pitchU;
    }

    for (uint32_t i = 0; i < avFrame->height/2; i++) {
        fwrite(avV, avFrame->width/2, 1, fDump);
        avV += pitchV;
    }

    fclose(fDump);
}

答案 1 :(得分:0)

int saveYUVFrameToFile(AVFrame* frame, int width, int height)
{
    FILE* fileHandle;
    int y, writeError;
    char filename[32];
    static int frameNumber = 0;

    sprintf(filename, "frame%d.yuv", frameNumber);

    fileHandle = fopen(filename, "wb");
    if (fileHandle == NULL)
    {
        printf("Unable to open %s...\n", filename);
        return ERROR;
    }

    /*Writing Y plane data to file.*/
    for (y = 0; y < height; y++)
    {
        writeError = fwrite(frame->data[0] + y*frame->linesize[0], 1, width, fileHandle);
        if (writeError != width)
        {
            printf("Unable to write Y plane data!\n");
            return ERROR;
        }
    }

    /*Dividing by 2.*/
    height >>= 1;
    width >>= 1;

    /*Writing U plane data to file.*/
    for (y = 0; y < height; y++)
    {
        writeError = fwrite(frame->data[1] + y*frame->linesize[1], 1, width, fileHandle);
        if (writeError != width)
        {
            printf("Unable to write U plane data!\n");
            return ERROR;
        }
    }

    /*Writing V plane data to file.*/
    for (y = 0; y < height; y++)
    {
        writeError = fwrite(frame->data[2] + y*frame->linesize[2], 1, width, fileHandle);
        if (writeError != width)
        {
            printf("Unable to write V plane data!\n");
            return ERROR;
        }
    }

    fclose(fileHandle);
    frameNumber++;

    return NO_ERROR;

基本上,这是我使用FFmpeg和stackoverflow用户提供的几个示例提出的。