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