diff mbox

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

Message ID 1477506663-7509-1-git-send-email-isasi@google.com
State Accepted
Commit 4abe1ff08f1fb2a909c4a99bd9e44a81e2c3cc3d
Headers show

Commit Message

Sasi Inguva Oct. 26, 2016, 6:31 p.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  | 25 ++++++++++++++++++++++---
 2 files changed, 23 insertions(+), 3 deletions(-)

Comments

Sasi Inguva Oct. 31, 2016, 5:23 p.m. UTC | #1
ping.

Thanks!

On Wed, Oct 26, 2016 at 11:31 AM, 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  | 25 ++++++++++++++++++++++---
>  2 files changed, 23 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..d9ed5a3 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -4202,7 +4202,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 +4285,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 +5864,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
>
>
Sasi Inguva Nov. 2, 2016, 10:04 p.m. UTC | #2
Ping. Sorry for the urgency on this, but this is blocking us internally.

Thanks

On Mon, Oct 31, 2016 at 10:23 AM, Sasi Inguva <isasi@google.com> wrote:

> ping.
>
> Thanks!
>
> On Wed, Oct 26, 2016 at 11:31 AM, 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  | 25 ++++++++++++++++++++++---
>>  2 files changed, 23 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..d9ed5a3 100644
>> --- a/libavformat/mov.c
>> +++ b/libavformat/mov.c
>> @@ -4202,7 +4202,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 +4285,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 +5864,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
>>
>>
>
Derek Buitenhuis Nov. 2, 2016, 10:50 p.m. UTC | #3
On 10/26/2016 7:31 PM, 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  | 25 ++++++++++++++++++++++---
>  2 files changed, 23 insertions(+), 3 deletions(-)

The idea seems to sound OK.

[...]

> st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);

Without surrounding context, this line seems a bit funky. You're intending
to set the duration/end to ... timescale? One second?

- Derek
Sasi Inguva Nov. 3, 2016, 4:56 p.m. UTC | #4
On Wed, Nov 2, 2016 at 3:50 PM, Derek Buitenhuis <derek.buitenhuis@gmail.com
> wrote:

> On 10/26/2016 7:31 PM, 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  | 25 ++++++++++++++++++++++---
> >  2 files changed, 23 insertions(+), 3 deletions(-)
>
> The idea seems to sound OK.
>
> [...]
>
> > st->duration = sc->track_end = av_rescale(ref_st->duration,
> sc->time_scale, ref_sc->time_scale);
>
> Without surrounding context, this line seems a bit funky. You're intending
> to set the duration/end to ... timescale? One second?
>
> I am just converting the *reference* stream duration from that streams'
timescale to the timescale of the stream I am setting to.


> - Derek
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Derek Buitenhuis Nov. 3, 2016, 5:02 p.m. UTC | #5
On 11/3/2016 4:56 PM, Sasi Inguva wrote:
>> I am just converting the *reference* stream duration from that streams'
> timescale to the timescale of the stream I am setting to.
> 
> 

Indeed, I misread this (midnight emails FTL; I read time_scale 3 times instead of 2).

Anyway, the rest seems OK to me.

- Derek
Michael Niedermayer Nov. 3, 2016, 6:04 p.m. UTC | #6
On Thu, Nov 03, 2016 at 05:02:50PM +0000, Derek Buitenhuis wrote:
> On 11/3/2016 4:56 PM, Sasi Inguva wrote:
> >> I am just converting the *reference* stream duration from that streams'
> > timescale to the timescale of the stream I am setting to.
> > 
> > 
> 
> Indeed, I misread this (midnight emails FTL; I read time_scale 3 times instead of 2).
> 
> Anyway, the rest seems OK to me.

ok, applied

thx

[...]
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..d9ed5a3 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4202,7 +4202,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 +4285,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 +5864,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) {