Bug 846122 - Handle split multi-track Cues in nestegg. r=padenot a=leo+
authorMatthew Gregan <kinetik@flim.org>
Wed, 10 Apr 2013 15:03:50 +1200
changeset 119128 e0bab06d5d36102508469084d265528c1374f343
parent 119127 a677aace8abbe5a987e89a1f7754fedc387227c9
child 119129 5044b1c6392283847231f9361beab291aa26a4b4
push id686
push usermgregan@mozilla.com
push dateFri, 19 Apr 2013 01:59:35 +0000
reviewerspadenot, leo
bugs846122
milestone18.0
Bug 846122 - Handle split multi-track Cues in nestegg. r=padenot a=leo+
media/libnestegg/README_MOZILLA
media/libnestegg/src/nestegg.c
--- a/media/libnestegg/README_MOZILLA
+++ b/media/libnestegg/README_MOZILLA
@@ -1,8 +1,10 @@
 The source from this directory was copied from the nestegg
 git repository using the update.sh script.  The only changes
 made were those applied by update.sh and the addition of
 Makefile.in build files for the Mozilla build system.
 
 The nestegg git repository is: git://github.com/kinetiknz/nestegg.git
 
 The git commit ID used was ef45a1c3a6b86ce3d86d179537e94c57008f07f4.
+Plus the changes from 443edc8d8cb1037275b055474256a7fa089766dc and
+7d0f6d22b5a332ce47b95bc19dc259f204d339e1.
--- a/media/libnestegg/src/nestegg.c
+++ b/media/libnestegg/src/nestegg.c
@@ -1360,33 +1360,57 @@ ne_find_seek_for_id(struct ebml_list_nod
     }
 
     seek_head = seek_head->next;
   }
 
   return NULL;
 }
 
+static struct cue_track_positions *
+ne_find_cue_position_for_track(nestegg * ctx, struct ebml_list_node * node, unsigned int track)
+{
+  struct cue_track_positions * pos = NULL;
+  uint64_t t;
+
+  while (node) {
+    assert(node->id == ID_CUE_TRACK_POSITIONS);
+    pos = node->data;
+    if (ne_get_uint(pos->track, &t) != 0)
+      return NULL;
+
+    if (t - 1 == track) {
+      return pos;
+    }
+
+    node = node->next;
+  }
+
+  return NULL;
+}
+
 static struct cue_point *
-ne_find_cue_point_for_tstamp(struct ebml_list_node * cue_point, uint64_t scale, uint64_t tstamp)
+ne_find_cue_point_for_tstamp(nestegg * ctx, struct ebml_list_node * cue_point, unsigned int track, uint64_t scale, uint64_t tstamp)
 {
   uint64_t time;
   struct cue_point * c, * prev = NULL;
 
   while (cue_point) {
     assert(cue_point->id == ID_CUE_POINT);
     c = cue_point->data;
 
     if (!prev)
       prev = c;
 
     if (ne_get_uint(c->time, &time) == 0 && time * scale > tstamp)
       break;
 
-    prev = cue_point->data;
+    if (ne_find_cue_position_for_track(ctx, c->cue_track_positions.head, track) != NULL)
+      prev = c;
+
     cue_point = cue_point->next;
   }
 
   return prev;
 }
 
 static int
 ne_is_suspend_element(uint64_t id)
@@ -1648,52 +1672,39 @@ nestegg_get_cue_point(nestegg * ctx, uns
 }
 
 int
 nestegg_track_seek(nestegg * ctx, unsigned int track, uint64_t tstamp)
 {
   int r;
   struct cue_point * cue_point;
   struct cue_track_positions * pos;
-  uint64_t seek_pos, tc_scale, t;
-  struct ebml_list_node * node = ctx->segment.cues.cue_point.head;
+  uint64_t seek_pos, tc_scale;
 
   /* If there are no cues loaded, check for cues element in the seek head
      and load it. */
-  if (!node) {
+  if (!ctx->segment.cues.cue_point.head) {
     r = ne_init_cue_points(ctx, -1);
     if (r != 0)
       return -1;
-
-    /* Check cues were loaded. */
-    node = ctx->segment.cues.cue_point.head;
-    if (!node)
-      return -1;
   }
 
   tc_scale = ne_get_timecode_scale(ctx);
 
-  cue_point = ne_find_cue_point_for_tstamp(ctx->segment.cues.cue_point.head, tc_scale, tstamp);
+  cue_point = ne_find_cue_point_for_tstamp(ctx, ctx->segment.cues.cue_point.head,
+                                           track, tc_scale, tstamp);
   if (!cue_point)
     return -1;
 
-  node = cue_point->cue_track_positions.head;
-
-  seek_pos = 0;
+  pos = ne_find_cue_position_for_track(ctx, cue_point->cue_track_positions.head, track);
+  if (pos == NULL)
+    return -1;
 
-  while (node) {
-    assert(node->id == ID_CUE_TRACK_POSITIONS);
-    pos = node->data;
-    if (ne_get_uint(pos->track, &t) == 0 && t - 1 == track) {
-      if (ne_get_uint(pos->cluster_position, &seek_pos) != 0)
-        return -1;
-      break;
-    }
-    node = node->next;
-  }
+  if (ne_get_uint(pos->cluster_position, &seek_pos) != 0)
+    return -1;
 
   /* Seek and set up parser state for segment-level element (Cluster). */
   r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET);
   if (r != 0)
     return -1;
   ctx->last_id = 0;
   ctx->last_size = 0;