aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/nutenc.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-10-01 23:51:35 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-10-02 01:09:12 +0200
commit4abc411b97d72080fe9628650f5c1a1d272e7a3d (patch)
tree58c40571503b17bb7ab5d9fb327676297b7b0894 /libavformat/nutenc.c
parente3fb5bc1472c600af628df10e1472a4319781640 (diff)
downloadffmpeg-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.c20
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);