aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorGael Chardon <gael.ffmpeg@4now.net>2005-01-23 10:34:10 +0000
committerFrançois Revol <revol@free.fr>2005-01-23 10:34:10 +0000
commit7fe5a3c0c7d26c11a8377c6f14b486a3d3131a06 (patch)
tree9abd832d16ba9e78057c02619fe341ae47c61a1f /libavformat
parent7dbab4a9b4997d401993688968220b6e8260296f (diff)
downloadffmpeg-7fe5a3c0c7d26c11a8377c6f14b486a3d3131a06.tar.gz
Timestamp patch by Gael Chardon <gael DOT ffmpeg AT 4now DOT net>
Originally committed as revision 3865 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/mov.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index cd87fa6540..5cf5cabac5 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -231,6 +231,9 @@ typedef struct MOVStreamContext {
long sample_to_chunk_sz;
MOV_sample_to_chunk_tbl *sample_to_chunk;
long sample_to_chunk_index;
+ int sample_to_time_index;
+ long sample_to_time_sample;
+ uint64_t sample_to_time_time;
long sample_size;
long sample_count;
long *sample_sizes;
@@ -1895,6 +1898,40 @@ readchunk:
#endif
mov->next_chunk_offset = offset + size;
+
+ /* find the corresponding dts */
+ if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
+ uint32_t count;
+ uint64_t dts;
+ uint32_t duration = (uint32_t)(sc->stts_data[sc->sample_to_time_index]&0xffff);
+ count = (uint32_t)(sc->stts_data[sc->sample_to_time_index]>>32);
+ if ((sc->sample_to_time_sample + count) < sc->current_sample) {
+ sc->sample_to_time_sample += count;
+ sc->sample_to_time_time += count*duration;
+ sc->sample_to_time_index ++;
+ duration = (uint32_t)(sc->stts_data[sc->sample_to_time_index]&0xffff);
+ }
+ dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * duration;
+ dts = av_rescale( dts,
+ (int64_t)s->streams[sc->ffindex]->time_base.den,
+ (int64_t)sc->time_scale * (int64_t)s->streams[sc->ffindex]->time_base.num );
+ pkt->dts = dts;
+ // audio pts = dts, true for video only in low_latency mode (FIXME a good way to know if we are in a low latency stream ?)
+ if (s->streams[sc->ffindex]->codec.codec_type == CODEC_TYPE_AUDIO)
+ pkt->pts = dts;
+ else
+ pkt->pts = AV_NOPTS_VALUE;
+#ifdef DEBUG
+/* av_log(NULL, AV_LOG_DEBUG, "stream #%d smp #%ld dts = %ld (smp:%ld time:%ld idx:%ld ent:%d count:%ld dur:%ld)\n"
+ , pkt->stream_index, sc->current_sample-1, (long)pkt->dts
+ , (long)sc->sample_to_time_sample
+ , (long)sc->sample_to_time_time
+ , (long)sc->sample_to_time_index
+ , (long)sc->stts_count
+ , count
+ , duration);*/
+#endif
+ }
return 0;
}
@@ -1919,6 +1956,9 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
int64_t sample_file_offset;
int32_t first_chunk_sample;
int32_t sample_to_chunk_idx;
+ int sample_to_time_index;
+ long sample_to_time_sample = 0;
+ uint64_t sample_to_time_time = 0;
int mov_idx;
// Find the corresponding mov stream
@@ -1957,12 +1997,17 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
//av_log(s, AV_LOG_DEBUG, "> sample_time %lli \n", (long)sample_time);
//av_log(s, AV_LOG_DEBUG, "> count=%i duration=%i\n", count, duration);
if ((start_time + count*duration) > sample_time) {
+ sample_to_time_time = start_time;
+ sample_to_time_index = i;
+ sample_to_time_sample = sample;
sample += (sample_time - start_time) / duration;
break;
}
sample += count;
start_time += count * duration;
}
+ sample_to_time_time = start_time;
+ sample_to_time_index = i;
/* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
@@ -1989,6 +2034,8 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
// av_log(s, AV_LOG_DEBUG, "a=%i (%i) b=%i (%i) m=%i (%i) stream #%i\n", a, sc->keyframes[a], b, sc->keyframes[b], m, sc->keyframes[m], mov_idx);
#endif
}
+ // for low latency prob: always use the previous keyframe, just uncomment the next line
+ // if (a) a--;
seek_sample = sc->keyframes[a];
}
else
@@ -2084,6 +2131,20 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
}
msc->current_sample += (msc->next_chunk - (msc->sample_to_chunk[msc->sample_to_chunk_index].first - 1)) * sc->sample_to_chunk[msc->sample_to_chunk_index].count;
msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
+ // Find corresponding position in stts (used later to compute dts)
+ sample = 0;
+ start_time = 0;
+ for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
+ count = (uint32_t)(msc->stts_data[msc->sample_to_time_index]>>32);
+ duration = (uint32_t)(msc->stts_data[msc->sample_to_time_index]&0xffff);
+ if ((sample + count - 1) > msc->current_sample) {
+ msc->sample_to_time_time = start_time;
+ msc->sample_to_time_sample = sample;
+ break;
+ }
+ sample += count;
+ start_time += count * duration;
+ }
#ifdef DEBUG
av_log(s, AV_LOG_DEBUG, "Next Sample for stream #%i is #%i @%i\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
#endif