]> granicus.if.org Git - handbrake/commitdiff
libav: fix mp4 edit list A/V sync properly
authorJohn Stebbins <jstebbins.hb@gmail.com>
Wed, 15 Feb 2017 19:22:48 +0000 (12:22 -0700)
committerJohn Stebbins <jstebbins.hb@gmail.com>
Wed, 15 Feb 2017 19:24:57 +0000 (12:24 -0700)
(cherry picked from commit 7196e488673c9bfa8f6a626121379885665bd886)

contrib/ffmpeg/A06-edit-list-offset.patch

index 8c1d0a66889b55d15a8e6c37f7dd274e7033936a..20debad4b59ed15f13f86eeac9061f0bee95724d 100644 (file)
@@ -1,14 +1,76 @@
+diff --git a/libavformat/isom.h b/libavformat/isom.h
+index 8cc5ab7..0050d3a 100644
+--- a/libavformat/isom.h
++++ b/libavformat/isom.h
+@@ -125,6 +125,8 @@ typedef struct MOVStreamContext {
+     int *keyframes;
+     int time_scale;
+     int64_t time_offset;  ///< time offset of the first edit list entry
++    int64_t delay;  ///< time delay of the first edit list entry
++    int64_t skip;  ///< time to skip of the first or second edit list entry
+     int current_sample;
+     unsigned int bytes_per_frame;
+     unsigned int samples_per_frame;
 diff --git a/libavformat/mov.c b/libavformat/mov.c
-index 2810960..71c37c2 100644
+index 5c9f85c..c749b46 100644
 --- a/libavformat/mov.c
 +++ b/libavformat/mov.c
-@@ -2321,6 +2321,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
-         if (sc->time_offset < 0)
-             sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);
+@@ -2323,9 +2323,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
+     uint64_t stream_size = 0;
+     /* adjust first dts according to edit list */
+-    if (sc->time_offset && mov->time_scale > 0) {
+-        if (sc->time_offset < 0)
+-            sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);
++    if (mov->time_scale > 0) {
++        sc->time_offset = sc->skip -
++                        av_rescale(sc->delay, sc->time_scale, mov->time_scale);
          current_dts = -sc->time_offset;
-+        if (sc->ctts_data && sc->ctts_count) {
-+            current_dts -= sc->ctts_data[0].duration;
+     }
+@@ -2986,6 +2986,10 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+     unsigned entries, first_sample_flags = frag->flags;
+     int flags, distance, i, err;
++    if (c->time_scale > 0) {
++        sc->time_offset = sc->skip -
++                        av_rescale(sc->delay, sc->time_scale, c->time_scale);
++    }
+     for (i = 0; i < c->fc->nb_streams; i++) {
+         if (c->fc->streams[i]->id == frag->track_id) {
+             st = c->fc->streams[i];
+@@ -3152,6 +3156,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+ {
+     MOVStreamContext *sc;
+     int i, edit_count, version;
++    int found_delay = 0;
+     if (c->fc->nb_streams < 1)
+         return 0;
+@@ -3164,7 +3169,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+     if ((uint64_t)edit_count*12+8 > atom.size)
+         return AVERROR_INVALIDDATA;
+-    for (i=0; i<edit_count; i++){
++    for (i=0; i < edit_count; i++){
+         int64_t time;
+         int64_t duration;
+         if (version == 1) {
+@@ -3175,8 +3180,15 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+             time     = (int32_t)avio_rb32(pb); /* media time */
+         }
+         avio_rb32(pb); /* Media rate */
+-        if (i == 0 && time >= -1) {
+-            sc->time_offset = time != -1 ? time : -duration;
++        if (i == 0 && time == -1) {
++            sc->delay = duration;
++            found_delay = 1;
++        }
++        else if (i == 0 && time >= 0) {
++            sc->skip = time;
 +        }
++        else if (i == 1 && found_delay && time >= 0) {
++            sc->skip = time;
+         }
      }
  
-     /* only use old uncompressed audio chunk demuxing when stts specifies it */