diff mbox

[FFmpeg-devel] lavf/mov.c: Use the first sidx for tracks without sidx.

Message ID 1477462078-1997-1-git-send-email-isasi@google.com
State Superseded
Headers show

Commit Message

Sasi Inguva Oct. 26, 2016, 6:07 a.m. UTC
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 <isasi@google.com>
---
 libavformat/isom.h |  1 +
 libavformat/mov.c  | 26 +++++++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

Comments

Sasi Inguva Oct. 26, 2016, 6:12 a.m. UTC | #1
Fixes audio stream duration of the attached mp4f file.
Without this patch , .
/ffprobe -show_streams h264_aac_6sec.mp4
audio duration is determined as 2s. because there is no sidx for that
stream. With this patch it stream duration is 6s.

On Tue, Oct 25, 2016 at 11:07 PM, Sasi Inguva <isasi@google.com> wrote:

> 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 <isasi@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
>
>
Michael Niedermayer Oct. 26, 2016, 2:47 p.m. UTC | #2
On Tue, Oct 25, 2016 at 11:07:58PM -0700, Sasi Inguva wrote:
> 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 <isasi@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);

the types mismatch, also not sure this should be DEBUG or TRACE

[...]
Sasi Inguva Oct. 26, 2016, 6:30 p.m. UTC | #3
sorry. forgot to remove the debug printf. sending the corrected  patch.

On Wed, Oct 26, 2016 at 7:47 AM, Michael Niedermayer <michael@niedermayer.cc
> wrote:

> On Tue, Oct 25, 2016 at 11:07:58PM -0700, Sasi Inguva wrote:
> > 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 <isasi@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);
>
> the types mismatch, also not sure this should be DEBUG or TRACE
>
> [...]
>
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> When you are offended at any man's fault, turn to yourself and study your
> own failings. Then you will forget your anger. -- Epictetus
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
diff mbox

Patch

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) {