c++ - 将 FFMPEG 帧写入 png/jpeg 文件

标签 c++ c ffmpeg

我有 AV_PIX_FMT_YUV420P AVFrame,我想把它写成 PNG 或 JPEG 文件,不管里面是什么格式(BGR、BGRA、RGB 或 RGBA)。我尝试将其保存为 AV_PIX_FMT_YUV420P,但我得到了 3 张图片,所以我需要先将其转换为 RGB24。我通过以下方式进行:

        int destW = decCtx->width;
        int destH = decCtx->height;

        AVFrame * resFrame = av_frame_alloc();
        resFrame->linesize[0] = destW * 3;
        resFrame->data[0] = (uint8_t*)malloc(resFrame->linesize[0] * destH);

        SwsContext * ctx = sws_getContext(decCtx->width,
                                          decCtx->height,
                                          AV_PIX_FMT_YUV420P,
                                          decCtx->width,
                                          decCtx->height,
                                          AV_PIX_FMT_RGB24,
                                          SWS_FAST_BILINEAR, 0, 0, 0);
        sws_scale(ctx, frame->data, frame->linesize, 0,
                  decCtx->height, resFrame->data, resFrame->linesize);
        sws_freeContext(ctx);
        int64_t pts = frame->pts;

        resFrame->format = AV_PIX_FMT_RGB24;
        resFrame->pts = pts;

看起来我有正确的转换帧,但现在编码器返回给我一个大小为 86 的数据包,所以我的图像实际上是空白或接近它。我通过以下方式进行编码:
    encCodec = avcodec_find_encoder(AV_CODEC_ID_PNG);

    if (!encCodec) {
        return false;
    }

    encCtx = avcodec_alloc_context3(encCodec);
    if (!encCtx) {
        return false;
    }

    encCtx->bit_rate = decCtx->bit_rate;
    encCtx->codec_type = AVMEDIA_TYPE_VIDEO;
    encCtx->thread_count = 1;
    encCtx->width = decCtx->width;
    encCtx->height = decCtx->height;

    int fps = fmtc->streams[iVideoStream]->r_frame_rate.num / fmtc->streams[iVideoStream]->r_frame_rate.den;
    encCtx->time_base = (AVRational){1, fps};
    encCtx->framerate = (AVRational){fps, 1};

    encCtx->gop_size = decCtx->gop_size;
    encCtx->max_b_frames = decCtx->max_b_frames;
    encCtx->pix_fmt = AV_PIX_FMT_RGB24;

    int ret = avcodec_parameters_from_context(fmtc->streams[iVideoStream]->codecpar, encCtx);
    if (ret < 0) {
        return false;
    }

    ret = avcodec_open2(encCtx, encCodec,  nullptr);
    if (ret < 0) {
        return false;
    }

    ret = avcodec_send_frame(encCtx, source);
    if (ret < 0) {
        return false;
    }

    av_packet_unref(pkt);
    av_init_packet(pkt);

    ret = avcodec_receive_packet(encCtx, pkt);
    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
        return false;
    else if (ret < 0) {
        return false;
    }

    if (ret >= 0)
    {
        FILE * outPng = fopen("./sample.png", "wb");
        fwrite(pkt->data, pkt->size, 1, outPng);
        fclose(outPng);
    }

将图像转换为 RGB24 或对其进行编码时我做错了什么?

最佳答案

@parthlr 在上述讨论中提供了可接受的解决方案。但是,您也可以在他的介词下阅读我的评论。

关于c++ - 将 FFMPEG 帧写入 png/jpeg 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62026613/

相关文章:

c - 负值转换为其对应的正值

FFmpeg 将 .mov 转换为 .ogv

bash - ffmpeg 从大型视频 bash 中选择子剪辑并创建输出文件名

c++ - 如何使用 pair 遍历所有可能的字符对?

c++ - 在 C++ 中未检测到相机,但在 QML 中检测到

c++ - extern "C"函数访问代码

c - 在递归函数中使用 readdir 时出现段错误

php - FFMPEG 与 PHP 将视频转换为 mp4 和快照

c++ - 将功能添加到窗口顶部的主菜单

c++ - 如何在 OpenCV 中编辑/更新 YAML 文件?