avframe保存到文件

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值