首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法将YUV框架从ffmpeg写入.yuv文件

无法将YUV框架从ffmpeg写入.yuv文件
EN

Stack Overflow用户
提问于 2016-11-28 17:43:51
回答 2查看 951关注 0票数 0

我的目标是将我解码的帧写成一个文件。我知道我很好地捕捉了它,因为它显示在我的SDL回放中,然后我对它进行编码,没有任何问题。然而,我似乎无法正确地将框架写入文件中。以下是代码:

代码语言:javascript
复制
#define PIXFMT AV_PIX_FMT_YUV420P
#define WIDTH 1280
#define HEIGHT 720
// initialize SWS context for software scaling

sws_ctx = sws_getContext(pCodecCtx->width,
    pCodecCtx->height,
    pCodecCtx->pix_fmt,
    WIDTH,
    HEIGHT,
    PIXFMT,
    SWS_LANCZOS,
    NULL,
    NULL,
    NULL
);

FfmpegEncoder enc("rtsp://127.0.0.1:1935/live/myStream", pParser);
//SetPixelArray();

i = 0;
enc.FillYuvImage(pFrameRGB, 0, this->pCodecCtx->width, this->pCodecCtx->height);
FILE *pFile;
while (av_read_frame(pFormatCtx, &packet) >= 0 && !exit) {
    if (packet.stream_index == videoindex) {
        // Decode video frame
        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

        if (frameFinished) {

            i++;
            sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
            if (i < 500)
            {
                pFile = fopen(std::string("./screenshots/screen.yuv").c_str(), "a+");
                for (int y = 0; y < pCodecCtx->height; y++)
                {
                    fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, pCodecCtx->width * pCodecCtx->height, pFile);
                    fwrite(pFrame->data[1] + y * pFrame->linesize[1], 1, pCodecCtx->width * pCodecCtx->height / 4, pFile);
                    fwrite(pFrame->data[2] + y * pFrame->linesize[2], 1, pCodecCtx->width * pCodecCtx->height / 4, pFile);
                }
                fclose(pFile);
            }
            enc.encodeFrame(pFrameRGB);
        }
    }
    // Free the packet that was allocated by av_read_frame
    av_free_packet(&packet);
}

当程序试图写入框架时,程序会崩溃。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-29 12:33:25

首先,谢谢你的评论和回答!这是固定代码:

代码语言:javascript
复制
    while (av_read_frame(pFormatCtx, &packet) >= 0 && !exit && i < 1000) {
    if (packet.stream_index == videoindex) {
        // Decode video frame
        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

        if (frameFinished) {

            i++;
            sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
            if ((pFile = fopen(std::string("./screenshots/screen.yuv").c_str(), "ab")) == NULL)
                continue;
            fwrite(pFrameRGB->data[0], 1, pCodecCtx->width * pCodecCtx->height, pFile);
            fwrite(pFrameRGB->data[1], 1, pCodecCtx->width * pCodecCtx->height / 4, pFile);
            fwrite(pFrameRGB->data[2], 1, pCodecCtx->width * pCodecCtx->height / 4, pFile);
            fclose(pFile);
            enc.encodeFrame(pFrameRGB);
        }
    }
    // Free the packet that was allocated by av_read_frame
    av_free_packet(&packet);
}

我之前使用的是错误的帧,以及错误的数据和大小。

票数 0
EN

Stack Overflow用户

发布于 2016-11-28 18:09:59

正如我在评论中提到的,您需要检查fopen是否成功。

但我认为问题是,你写的比缓冲区中的内容更多。我知道关于尤夫的有限的知识。我认为你应该做以下几件事。这是基于我对此页中的单帧YUV420图片的理解。

代码语言:javascript
复制
abcfor (int y = 0; y < pCodecCtx->height; y++) //plane 0: same width and height
{
    fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, pCodecCtx->width, pFile);
}


for (int y = 0; y < pCodecCtx->height/4; y++) //plane1: Same width and quarter height.
{
    fwrite(pFrame->data[1] + y * pFrame->linesize[1], 1, pCodecCtx->width, pFile);
}

for (int y = 0; y < pCodecCtx->height/4; y++) //plane2: Same width and quarter height.
{
    fwrite(pFrame->data[2] + y * pFrame->linesize[2], 1, pCodecCtx->width, pFile);
}

请注意,书写顺序取决于颜色的格式。我希望您将重点放在每次迭代中循环迭代的次数和fwrite()中的字节数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40850403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档