Commit 3068a849 authored by Ilkka Ollakka's avatar Ilkka Ollakka

avcodec: refactor frame_rate probing into own function

if codec has list of supported framerates, select highest one
unless user has provided one. If we end up using CLOCK_FREQ in
time_base, it should be quite ok in most cases. Tested with ts/mp4/webm
and mp2v/mp4v/VP80. For some cases it can select higher fps in
mpeg-codecs (60fps) in case of input fps isn't yet known in that point
or is fubared.

Also add special case for MP4V as it doesn't like CLOCK_FREQ in
time_base/frame_rates.
parent 50f98e2a
......@@ -238,6 +238,44 @@ static const int DEFAULT_ALIGN = 0;
/*****************************************************************************
* OpenEncoder: probe the encoder
*****************************************************************************/
static void probe_video_frame_rate( encoder_t *p_enc, AVCodecContext *p_context, AVCodec *p_codec )
{
/* if we don't have i_frame_rate_base, we are probing and just checking if we can find codec
* so set fps to requested fps if asked by user or input fps is availabled */
p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base ? p_enc->fmt_in.video.i_frame_rate_base : 1;
// MP4V doesn't like CLOCK_FREQ denominator in time_base, so use 1/25 as default for that
p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate_base ? p_enc->fmt_in.video.i_frame_rate :
( p_enc->fmt_out.i_codec == VLC_CODEC_MP4V ? 25 : CLOCK_FREQ );
msg_Dbg( p_enc, "Time base for probing setted to %d/%d", p_context->time_base.num, p_context->time_base.den );
if( p_codec->supported_framerates )
{
/* We are finding fps values so 1/time_base */
AVRational target = {
.num = p_context->time_base.den,
.den = p_context->time_base.num
};
int idx = av_find_nearest_q_idx(target, p_codec->supported_framerates);
p_context->time_base.num = p_codec->supported_framerates[idx].den ?
p_codec->supported_framerates[idx].den : 1;
p_context->time_base.den = p_codec->supported_framerates[idx].den ?
p_codec->supported_framerates[idx].num : CLOCK_FREQ;
/* If we have something reasonable on supported framerates, use that*/
if( p_context->time_base.den && p_context->time_base.den < CLOCK_FREQ )
{
p_enc->fmt_out.video.i_frame_rate_base =
p_enc->fmt_in.video.i_frame_rate_base =
p_context->time_base.num;
p_enc->fmt_out.video.i_frame_rate =
p_enc->fmt_in.video.i_frame_rate =
p_context->time_base.den;
}
}
msg_Dbg( p_enc, "Time base set to %d/%d", p_context->time_base.num, p_context->time_base.den );
}
int OpenEncoder( vlc_object_t *p_this )
{
......@@ -463,22 +501,7 @@ int OpenEncoder( vlc_object_t *p_this )
p_context->width = p_enc->fmt_in.video.i_visible_width;
p_context->height = p_enc->fmt_in.video.i_visible_height;
/* if we don't have i_frame_rate_base, we are probing and just checking if we can find codec
* so set fps to 25 as some codecs (DIV3 atleast) needs time_base data */
p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base ? p_enc->fmt_in.video.i_frame_rate_base : 1;
p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate_base ? p_enc->fmt_in.video.i_frame_rate : 25 ;
if( p_codec->supported_framerates )
{
AVRational target = {
.num = p_enc->fmt_in.video.i_frame_rate,
.den = p_enc->fmt_in.video.i_frame_rate_base,
};
int idx = av_find_nearest_q_idx(target, p_codec->supported_framerates);
p_context->time_base.num = p_codec->supported_framerates[idx].den;
p_context->time_base.den = p_codec->supported_framerates[idx].num;
}
msg_Dbg( p_enc, "Time base set to %d/%d", p_context->time_base.num, p_context->time_base.den );
probe_video_frame_rate( p_enc, p_context, p_codec );
/* Defaults from ffmpeg.c */
p_context->qblur = 0.5;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment