From 86d8602f626c403071ededb088a7359cd012e6b2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 21 May 2005 09:50:25 +0000 Subject: [PATCH] support non interleaved mov files Originally committed as revision 4294 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/mov.c | 58 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index b6e1d36..1bbbf7f 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -268,6 +268,7 @@ typedef struct MOVContext { int found_mdat; /* we suppose we have enough data to read the file */ int64_t mdat_size; int64_t mdat_offset; + int ni; ///< non interleaved mode int total_streams; /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio * but we need the info to be able to skip data from those streams in the 'mdat' section @@ -768,6 +769,14 @@ static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) } } else return -1; + + for(i=0; ifc->nb_streams; i++){ + MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data; + int64_t first= sc2->chunk_offsets[0]; + int64_t last= sc2->chunk_offsets[sc2->chunk_count-1]; + if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0]) + c->ni=1; + } #ifdef DEBUG /* for(i=0; ipriv_data; MOVStreamContext *sc; - int64_t offset = 0x0FFFFFFFFFFFFFFFLL; + int64_t offset = INT64_MAX; + int64_t best_dts = INT64_MAX; int i, a, b, m; int size; int idx; @@ -1833,17 +1843,44 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) again: sc = 0; + if(offset == INT64_MAX) + best_dts= INT64_MAX; for(i=0; itotal_streams; i++) { MOVStreamContext *msc = mov->streams[i]; - //av_log(NULL, AV_LOG_DEBUG, "MOCHUNK %ld %d %p pos:%Ld\n", mov->streams[i]->next_chunk, mov->total_streams, mov->streams[i], url_ftell(&s->pb)); - if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0 - && (msc->chunk_offsets[msc->next_chunk] < offset)) { - sc = msc; - offset = msc->chunk_offsets[msc->next_chunk]; - //av_log(NULL, AV_LOG_DEBUG, "SELETED %Ld i:%d\n", offset, i); + + if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){ + if (msc->sample_to_time_index < msc->stts_count && mov->ni) { + int64_t dts; + int index= msc->sample_to_time_index; + int sample= msc->sample_to_time_sample; + int time= msc->sample_to_time_time; + int duration = msc->stts_data[index].duration; + int count = msc->stts_data[index].count; + if (sample + count < msc->current_sample) { + sample += count; + time += count*duration; + index ++; + duration = msc->stts_data[index].duration; + } + dts = time + (msc->current_sample-1 - sample) * (int64_t)duration; + dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale); +// av_log(NULL, AV_LOG_DEBUG, "%d %Ld %Ld %Ld \n", i, dts, best_dts, offset); + if(dts < best_dts){ + best_dts= dts; + sc = msc; + offset = msc->chunk_offsets[msc->next_chunk]; + } + }else{ + //av_log(NULL, AV_LOG_DEBUG, "MOCHUNK %ld %d %p pos:%Ld\n", mov->streams[i]->next_chunk, mov->total_streams, mov->streams[i], url_ftell(&s->pb)); + if ((msc->chunk_offsets[msc->next_chunk] < offset)) { + sc = msc; + offset = msc->chunk_offsets[msc->next_chunk]; + //av_log(NULL, AV_LOG_DEBUG, "SELETED %Ld i:%d\n", offset, i); + } + } } } - if (!sc || offset==0x0FFFFFFFFFFFFFFFLL) + if (!sc || offset==INT64_MAX) return -1; sc->next_chunk++; @@ -1857,7 +1894,7 @@ again: if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) { url_fskip(&s->pb, (offset - mov->next_chunk_offset)); mov->next_chunk_offset = offset; - offset = 0x0FFFFFFFFFFFFFFFLL; + offset = INT64_MAX; goto again; } @@ -1866,7 +1903,8 @@ again: for(i=0; itotal_streams; i++) { MOVStreamContext *msc = mov->streams[i]; if ((msc->next_chunk < msc->chunk_count) - && ((msc->chunk_offsets[msc->next_chunk] - offset) < size)) + && msc->chunk_offsets[msc->next_chunk] - offset < size + && msc->chunk_offsets[msc->next_chunk] > offset) size = msc->chunk_offsets[msc->next_chunk] - offset; } -- 2.7.4