ffmpeg使用png编码器把rgb24编码为png图像

version

#define LIBAVUTIL_VERSION_MAJOR 58

#define LIBAVUTIL_VERSION_MINOR 12

#define LIBAVUTIL_VERSION_MICRO 100

note

不使用AVOutputFormat

code

复制代码
void CFfmpegOps::EncodeRGB24ToPNG(const char *infile, const char *width_str, const char *height_str, const char *outfile)
{
    if ((!infile) || (!width_str) || (!height_str) || (!outfile))
    {
        return;
    }

    int width = 0;
    int height = 0;
    AVFrame *rgb24frame = nullptr;
    int rgb24frame_bytes = 0;
    AVPixelFormat rgb24_fmt = AV_PIX_FMT_RGB24;
    int ret = -1;
    FILE *in_fp = nullptr;
    size_t n = 0;
    AVPacket *pkt = nullptr;
    const AVCodec *png_encoder = nullptr;
    AVCodecContext *png_encoder_ctx = nullptr;
    FILE *out_fp = nullptr;

    try
    {
        width = std::stoi(width_str);
        height = std::stoi(height_str);
    }
    catch (const std::exception &e)
    {
        return;
    }

    rgb24frame = av_frame_alloc();
    if (!rgb24frame)
    {
        printf("av_frame_alloc error\n");
        goto end;
    }
    rgb24frame->format = rgb24_fmt;
    rgb24frame->width = width;
    rgb24frame->height = height;

    rgb24frame_bytes = av_image_get_buffer_size(rgb24_fmt, width, height, 1);

    ret = av_frame_get_buffer(rgb24frame, 0);
    if (ret < 0)
    {
        printf("av_frame_get_buffer error(%s)\n", GetFfmpegERR(ret));
        goto end;
    }

    in_fp = fopen(infile, "rb");
    if (!in_fp)
    {
        printf("fopen error\n");
        goto end;
    }

    n = fread(rgb24frame->data[0], sizeof(uint8_t), width * height * 3, in_fp);
    if ((int)n != (width * height * 3))
    {
        printf("n != (width * height * 3)\n");
        goto end;
    }

    pkt = av_packet_alloc();
    if (!pkt)
    {
        printf("av_packet_alloc error\n");
        goto end;
    }

    png_encoder = avcodec_find_encoder(AV_CODEC_ID_PNG);
    if (!png_encoder)
    {
        printf("avcodec_find_encoder error\n");
        goto end;
    }

    png_encoder_ctx = avcodec_alloc_context3(png_encoder);
    if (!png_encoder_ctx)
    {
        printf("avcodec_alloc_context3 error\n");
        goto end;
    }
    png_encoder_ctx->pix_fmt = rgb24_fmt;
    png_encoder_ctx->width = width;
    png_encoder_ctx->height = height;
    png_encoder_ctx->time_base.num = 1;
    png_encoder_ctx->time_base.den = 25;
    png_encoder_ctx->framerate.num = 25;
    png_encoder_ctx->framerate.den = 1;
    png_encoder_ctx->bit_rate = rgb24frame_bytes * png_encoder_ctx->framerate.num * 8;

    ret = avcodec_open2(png_encoder_ctx, png_encoder, nullptr);
    if (ret < 0)
    {
        printf("avcodec_open2 error(%s)\n", GetFfmpegERR(ret));
        goto end;
    }

    out_fp = fopen(outfile, "wb");
    if (!out_fp)
    {
        printf("fopen error\n");
        goto end;
    }

    ret = avcodec_send_frame(png_encoder_ctx, rgb24frame);
    if (ret != 0)
    {
        printf("avcodec_send_frame error(%s)\n", GetFfmpegERR(ret));
        goto end;
    }

    while (1)
    {
        ret = avcodec_receive_packet(png_encoder_ctx, pkt);
        if (ret != 0)
        {
            if (ret == AVERROR(EAGAIN))
            {
                continue;
            }

            printf("avcodec_receive_packet error(%s)\n", GetFfmpegERR(ret));
            break;
        }

        n = fwrite(pkt->data, pkt->size, sizeof(uint8_t), out_fp);

        av_packet_unref(pkt);

        break;
    }

end:
    if (out_fp)
    {
        fclose(out_fp);
        out_fp = nullptr;
    }

    if (png_encoder_ctx)
    {
        avcodec_free_context(&png_encoder_ctx);
        png_encoder_ctx = nullptr;
    }

    if (pkt)
    {
        av_packet_free(&pkt);
        pkt = nullptr;
    }

    if (in_fp)
    {
        fclose(in_fp);
        in_fp = nullptr;
    }

    if (rgb24frame)
    {
        av_frame_free(&rgb24frame);
        rgb24frame = nullptr;
    }
}

performance

相关推荐
序属秋秋秋22 分钟前
《Linux系统编程之进程基础》【进程优先级】
linux·运维·c语言·c++·笔记·进程·优先级
草莓熊Lotso23 分钟前
C++ STL map 系列全方位解析:从基础使用到实战进阶
java·开发语言·c++·人工智能·经验分享·网络协议·everything
_F_y24 分钟前
C++IO流
c++
草莓熊Lotso25 分钟前
《算法闯关指南:优选算法--模拟》--41.Z 字形变换,42.外观数列
开发语言·c++·算法
AA陈超6 小时前
ASC学习笔记0020:用于定义角色或Actor的默认属性值
c++·笔记·学习·ue5·虚幻引擎
coderxiaohan7 小时前
【C++】仿函数 + 模板进阶
开发语言·c++
思成不止于此8 小时前
深入理解 C++ 多态:从概念到实现的完整解析
开发语言·c++·笔记·学习·多态·c++40周年
小曹要微笑10 小时前
STM32各系列时钟树详解
c语言·stm32·单片机·嵌入式硬件·算法
布丁写代码10 小时前
GESP C++ 一级 2025年09月真题解析
开发语言·c++·程序人生·学习方法
inputA10 小时前
【LwIP源码学习8】netbuf源码分析
android·c语言·笔记·嵌入式硬件·学习