avframe保存到文件

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 08:15   39   0

https://stackoverflow.com/questions/35797904/writing-decoded-yuv420p-data-into-a-file-with-ffmpeg

1 down vote favorite

2

I've read frame which is encoded with H264, decoded it, and converted it to YUV420P and the data is stored in frameYUV420->data, (type of frame is AVFrame). I want to save that data into a file that can be displayed with GIMP for example.

I know how to save RGB25 pixel format but i'm not quite sure how to do YUV420P. Though i know that Y component will take width x height , and Cb/Cr will take (width/2) x (height/2) amount of space needed to save the data. So i'm guessing i need to first write Y data, and after that i need to write Cb and Cr data. Does anyone have finished code that i could take a look at?

ffmpeg yuv

shareimprove this question

asked Mar 4 '16 at 13:57

Sir DrinksCoffeeALot

149416

add a comment

2 Answers

active oldest votes

up vote 3 down vote

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);
}

shareimprove this answer

answered May 7 '16 at 14:39

fandyushin

1,283924

add a comment

up vote 0 down vote

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;

Basicly this is what i came up with using several examples provided by FFmpeg and stackoverflow user

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);
}

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;

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP