version
#define LIBAVCODEC_VERSION_MAJOR 60
#define LIBAVCODEC_VERSION_MINOR 15
#define LIBAVCODEC_VERSION_MICRO 100
node
不使用AVOutputFormat
code
void CFfmpegOps::EncodeYUVJ420pToMJPEG(const char* infile, const char* width_str, const char* height_str, const char* outfile)
{
if ((!infile) || (!outfile))
{
return;
}
int32_t width = 0;
int32_t height = 0;
FILE *in_fp = nullptr;
size_t n = 0;
AVCodecContext *encoder_ctx = nullptr;
const AVCodec *encoder = nullptr;
FILE* out_fp = nullptr;
int ret = -1;
AVFrame *avframe = nullptr;
AVPacket *avpacket = nullptr;
int frame_bytes = 0;
try
{
width = std::stoi(width_str);
height = std::stoi(height_str);
}
catch (std::exception &e)
{
return;
}
in_fp = fopen(infile, "rb");
if (!in_fp)
{
printf("fopen error\n");
goto end;
}
avframe = av_frame_alloc();
if (!avframe)
{
printf("av_frame_alloc error\n");
goto end;
}
avframe->width = width;
avframe->height = height;
avframe->format = AV_PIX_FMT_YUVJ420P;
avframe->pts = 0;
// 获取单帧yuvj420p的字节数
frame_bytes = av_image_get_buffer_size((AVPixelFormat)(avframe->format), avframe->width, avframe->height, 1);
ret = av_frame_get_buffer(avframe, 0);
if (ret < 0)
{
printf("av_frame_get_buffer error:%s\n", GetFfmpegERR(ret));
goto end;
}
// 读取y分量
n = fread(avframe->data[0], sizeof(uint8_t), avframe->width * avframe->height, in_fp);
if ((int)n != (avframe->width * avframe->height))
{
printf("n != (avframe->width * avframe->height)\n");
goto end;
}
// 读取u分量
n = fread(avframe->data[1], sizeof(uint8_t), avframe->width * avframe->height / 4, in_fp);
if ((int)n != (avframe->width * avframe->height / 4))
{
printf("n != (avframe->width * avframe->height / 4)\n");
goto end;
}
// 读取v分量
n = fread(avframe->data[2], sizeof(uint8_t), avframe->width * avframe->height / 4, in_fp);
if ((int)n != (avframe->width * avframe->height / 4))
{
printf("n != (avframe->width * avframe->height / 4)\n");
goto end;
}
avpacket = av_packet_alloc();
if (!avpacket)
{
printf("av_packet_alloc error\n");
goto end;
}
encoder = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
if (!encoder)
{
printf("avcodec_find_encoder error\n");
goto end;
}
encoder_ctx = avcodec_alloc_context3(encoder);
if (!encoder_ctx)
{
printf("avcodec_alloc_context3 error\n");
goto end;
}
// encoder_ctx->colorspace = ;
// encoder_ctx->color_range = ;
encoder_ctx->pix_fmt = AV_PIX_FMT_YUVJ420P;
encoder_ctx->width = width;
encoder_ctx->height = height;
encoder_ctx->framerate.num = 25;
encoder_ctx->framerate.den = 1;
encoder_ctx->time_base.num = 1;
encoder_ctx->time_base.den = 25;
encoder_ctx->bit_rate = frame_bytes * encoder_ctx->framerate.num * 8;
ret = avcodec_open2(encoder_ctx, encoder, nullptr);
if (ret < 0)
{
printf("avcodec_open2 error:%s\n", GetFfmpegERR(ret));
goto end;
}
out_fp = fopen(outfile, "wb");
if (!out_fp)
{
printf("avcodec_alloc_context3 error\n");
goto end;
}
ret = avcodec_send_frame(encoder_ctx, avframe);
if (ret < 0)
{
printf("avcodec_send_frame error:%s\n", GetFfmpegERR(ret));
goto end;
}
while (1)
{
ret = avcodec_receive_packet(encoder_ctx, avpacket);
if (ret < 0)
{
printf("avcodec_receive_packet error:%s\n", GetFfmpegERR(ret));
break;
}
n = fwrite(avpacket->data, sizeof(uint8_t), avpacket->size, out_fp);
}
end:
if (avpacket)
{
av_packet_free(&avpacket);
avpacket = nullptr;
}
if (avframe)
{
av_frame_free(&avframe);
avframe = nullptr;
}
if (out_fp)
{
fclose(out_fp);
out_fp = nullptr;
}
if (encoder_ctx)
{
avcodec_free_context(&encoder_ctx);
encoder_ctx = nullptr;
}
if (in_fp)
{
fclose(in_fp);
in_fp = nullptr;
}
}