diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-10-01 23:51:35 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-10-02 01:09:12 +0200 |
commit | 4abc411b97d72080fe9628650f5c1a1d272e7a3d (patch) | |
tree | 58c40571503b17bb7ab5d9fb327676297b7b0894 /libavformat/nutenc.c | |
parent | e3fb5bc1472c600af628df10e1472a4319781640 (diff) | |
download | ffmpeg-4abc411b97d72080fe9628650f5c1a1d272e7a3d.tar.gz |
nutenc: choose for non audio streams a timebase with finer resolution.
While a 25 fps stream can in general store frame durations in 1/25
units, this is not true for the timestamps. For example a 25fps
and a 25000/1001 fps stream when they are stored together might have
a matching 0 timestamp point but when for example a chapter from
this is cut the new start is no longer aligned. The issue gets
MUCH worse when the streams are lower fps, like 1 or 2 fps.
This commit thus makes the muxer choose a multiple of the
framerate as timebase that is at least about 20 micro seconds precise
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/nutenc.c')
-rw-r--r-- | libavformat/nutenc.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index 5133adee08..1402634442 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -156,10 +156,16 @@ static void build_frame_code(AVFormatContext *s){ int is_audio= codec->codec_type == AVMEDIA_TYPE_AUDIO; int intra_only= /*codec->intra_only || */is_audio; int pred_count; - int frame_size = av_get_audio_frame_duration(codec, 0); - - if (codec->codec_id == AV_CODEC_ID_VORBIS && !frame_size) { - frame_size = 64; + int frame_size = 0; + + if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { + frame_size = av_get_audio_frame_duration(codec, 0); + if (codec->codec_id == AV_CODEC_ID_VORBIS && !frame_size) + frame_size = 64; + } else { + AVRational f = av_div_q(codec->time_base, *nut->stream[stream_id].time_base); + if(f.den == 1 && f.num>0) + frame_size = f.num; } if(!frame_size) frame_size = 1; @@ -669,6 +675,12 @@ static int nut_write_header(AVFormatContext *s){ if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->sample_rate) { time_base = (AVRational){1, st->codec->sample_rate}; + } else { + for (j=2; j<2000; j+= 1+(j>2)) + while (time_base.den / time_base.num < 48000 && time_base.num % j == 0) + time_base.num /= j; + while (time_base.den / time_base.num < 48000 && time_base.den < (1<<24)) + time_base.den <<= 1; } avpriv_set_pts_info(st, 64, time_base.num, time_base.den); |