I am trying to write a video converting script that converts an input video file to .mp4 output. I am using ffmpeg libx264 encoder. Unfortunately, when I convert from .avi to .mp4, the output video is not smooth, a little skippy. Here is how I set up the encoder code:
AVCodecContext *Video::setupVideoEncoder(const AVCodec *encoder, AVStream *inVideoStream, AVFormatContext *outFormatCtx)
{
AVCodecContext *codecCtx = avcodec_alloc_context3(encoder);
if (!codecCtx)
{
std::cerr << "Failed to allocate the video codec context." << std::endl;
return nullptr;
}
if (avcodec_parameters_to_context(codecCtx, inVideoStream->codecpar) < 0)
{
std::cerr << "Failed to copy codec parameters to encoder context." << std::endl;
avcodec_free_context(&codecCtx);
return nullptr;
}
// Correctly assign pixel format based on encoder support
if (!check_pix_fmt(encoder, inVideoStream->codecpar->format))
{
codecCtx->pix_fmt = encoder->pix_fmts[0];
}
else
{
codecCtx->pix_fmt = static_cast<AVPixelFormat>(inVideoStream->codecpar->format);
}
codecCtx->width = inVideoStream->codecpar->width;
codecCtx->height = inVideoStream->codecpar->height;
codecCtx->bit_rate = 2000000; // 2 Mbps
codecCtx->gop_size = 12;
codecCtx->max_b_frames = 3;
// Setting frame rate and time base using guessed values
AVRational framerate = av_guess_frame_rate(outFormatCtx, inVideoStream, nullptr);
codecCtx->framerate = framerate;
codecCtx->time_base = av_inv_q(framerate);
AVDictionary *opts = nullptr;
av_dict_set(&opts, "x264-params", "keyint=25:min-keyint=25:no-scenecut=1", 0);
if (outFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
{
codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
if (avcodec_open2(codecCtx, encoder, &opts) < 0)
{
std::cerr << "Failed to open the video encoder." << std::endl;
avcodec_free_context(&codecCtx);
av_dict_free(&opts);
return nullptr;
}
av_dict_free(&opts);
return codecCtx;
}
I can only thing the configurations here are the problem, because if I converted a .mov to .mp4, I get the expected output.