note
视频帧率调整
帧率(fps-frame per second)
例如:原来帧率为30,调整后为1 现象:原来是每秒有30张图像,调整后每秒1张图像,看着图像很慢
实现:在每秒的时间区间里,取一张图像
version
#define LIBAVFILTER_VERSION_MINOR 12
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_MINOR 31
#define LIBAVCODEC_VERSION_MICRO 102
code
void CFfmpegOps::ChangeVideoFPS(const char *in_mp4, const char *out_mp4)
{
AVFormatContext *in_fmt_ctx = nullptr;
const AVInputFormat *in_fmt = nullptr;
AVFormatContext *out_fmt_ctx = nullptr;
const AVOutputFormat *out_fmt = nullptr;
int ret = -1;
int video_stream_index = 0;
const AVCodec *decoder = nullptr;
AVCodecContext *decoder_ctx = nullptr;
const AVCodec* encoder = nullptr;
AVCodecContext* encoder_ctx = nullptr;
AVStream* in_avstream = nullptr;
AVStream* out_avstream = nullptr;
const AVFilter * avfilter_buffer_src = nullptr; // 源,video buffer可设置的参数有
AVFilterContext* avfilter_ctx_buffer_src = nullptr;
const AVFilter * avfilter_fps = nullptr; // 中间节点,video fps可设置的参数包含fps
AVFilterContext* avfilter_ctx_fps = nullptr;
const AVFilter* avfilter_buffer_sink = nullptr; // 终,video buffersink可设置的参数只有pixel formats
AVFilterContext* avfilter_ctx_buffer_sink = nullptr;
AVFilterGraph* avfiltergraph = nullptr;
AVPacket* avpacket_src = nullptr;
AVFrame* avframe_src = nullptr;
AVFrame* avframe_dest = nullptr;
AVPacket* avpacket_dest = nullptr;
AVRational pixel_aspect = {.num = 1, .den = 1};
ret = avformat_open_input(&in_fmt_ctx, in_mp4, nullptr, nullptr);
if (ret < 0)
{
printf("avformat_open_input error(%s)\n", GetFfmpegERR(ret));
goto END;
}
in_fmt = in_fmt_ctx->iformat;
ret = avformat_find_stream_info(in_fmt_ctx, nullptr);
if (ret < 0)
{
printf("avformat_find_stream_info error(%s)\n", GetFfmpegERR(ret));
goto END;
}
ret = av_find_best_stream(in_fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
if (ret < 0)
{
printf("av_find_best_stream error(%s)\n", GetFfmpegERR(ret));
goto END;
}
video_stream_index = ret;
in_avstream = in_fmt_ctx->streams[video_stream_index];
decoder = avcodec_find_decoder(in_avstream->codecpar->codec_id);
if (!decoder)
{
printf("avcodec_find_decoder error\n");
goto END;
}
decoder_ctx = avcodec_alloc_context3(decoder);
if (!decoder_ctx)
{
printf("avcodec_alloc_context3 error\n");
goto END;
}
ret = avcodec_parameters_to_context(decoder_ctx, in_avstream->codecpar);
if (ret < 0)
{
printf("avcodec_parameters_to_context error(%s)\n", GetFfmpegERR(ret));
goto END;
}
ret = avcodec_open2(decoder_ctx, decoder, nullptr);
if (ret < 0)
{
printf("avcodec_open2 error(%s)\n", GetFfmpegERR(ret));
goto END;
}
avfiltergraph = avfilter_graph_alloc();