According to spec ISO_IEC_15444_12 "For any media stream for which no segment 
index is present, referred to as non‐indexed stream, the media stream 
associated with the first Segment Index box in the segment serves as a 
reference stream in a sense that it also describes the subsegments for any 
non‐indexed media stream."

Signed-off-by: Sasi Inguva <is...@google.com>
---
 libavformat/isom.h |  1 +
 libavformat/mov.c  | 26 +++++++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 9038057..d684502 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -179,6 +179,7 @@ typedef struct MOVStreamContext {
     int32_t *display_matrix;
     uint32_t format;
 
+    int has_sidx;  // If there is an sidx entry for this stream.
     struct {
         int use_subsamples;
         uint8_t* auxiliary_info;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 357d800..1b04b1a 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4189,6 +4189,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 
     frag->implicit_offset = offset;
 
+    av_log(c, AV_LOG_DEBUG, "stindex: %d duration: %d end: %d\n", st->index, 
st->duration, sc->track_end);
     sc->track_end = dts + sc->time_offset;
     if (st->duration < sc->track_end)
         st->duration = sc->track_end;
@@ -4202,7 +4203,8 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     uint8_t version;
     unsigned i, track_id;
     AVStream *st = NULL;
-    MOVStreamContext *sc;
+    AVStream *ref_st;
+    MOVStreamContext *sc, *ref_sc;
     MOVFragmentIndex *index = NULL;
     MOVFragmentIndex **tmp;
     AVRational timescale;
@@ -4284,9 +4286,26 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 
     c->fragment_index_data = tmp;
     c->fragment_index_data[c->fragment_index_count++] = index;
+    sc->has_sidx = 1;
+
+    if (offset == avio_size(pb)) {
+        for (i = 0; i < c->fc->nb_streams; i++) {
+            if (c->fc->streams[i]->id == c->fragment_index_data[0]->track_id) {
+                ref_st = c->fc->streams[i];
+                ref_sc = ref_st->priv_data;
+                break;
+            }
+        }
+        for (i = 0; i < c->fc->nb_streams; i++) {
+            st = c->fc->streams[i];
+            sc = st->priv_data;
+            if (!sc->has_sidx) {
+                st->duration = sc->track_end = av_rescale(ref_st->duration, 
sc->time_scale, ref_sc->time_scale);
+            }
+        }
 
-    if (offset == avio_size(pb))
         c->fragment_index_complete = 1;
+    }
 
     return 0;
 }
@@ -5846,13 +5865,14 @@ static int mov_read_packet(AVFormatContext *s, AVPacket 
*pkt)
 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t 
timestamp)
 {
     MOVContext *mov = s->priv_data;
+    MOVStreamContext *sc = st->priv_data;
     int i, j;
 
     if (!mov->fragment_index_complete)
         return 0;
 
     for (i = 0; i < mov->fragment_index_count; i++) {
-        if (mov->fragment_index_data[i]->track_id == st->id) {
+        if (mov->fragment_index_data[i]->track_id == st->id || !sc->has_sidx) {
             MOVFragmentIndex *index = mov->fragment_index_data[i];
             for (j = index->item_count - 1; j >= 0; j--) {
                 if (index->items[j].time <= timestamp) {
-- 
2.8.0.rc3.226.g39d4020

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to