Bug 1261900: [nestegg] P10. Improve handling of resume. r?kinetik draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 27 Apr 2016 12:41:05 +1000
changeset 356747 c754903c9187ce3ea56ba0917e2b1b0500b725aa
parent 356746 1031f2fe7259daa5cc99ccaf4ae3ebc3437ffab5
child 519470 66243a14608e2e8a0c56bc0cd8ceb5a2a64369bf
push id16586
push userbmo:jyavenard@mozilla.com
push dateWed, 27 Apr 2016 02:47:40 +0000
reviewerskinetik
bugs1261900
milestone49.0a1
Bug 1261900: [nestegg] P10. Improve handling of resume. r?kinetik Following IRC discussion, also remove the temporary leak of already read ebml_binary or string if any. MozReview-Commit-ID: 1W9Uu9M1lx3
media/libnestegg/src/nestegg.c
--- a/media/libnestegg/src/nestegg.c
+++ b/media/libnestegg/src/nestegg.c
@@ -950,25 +950,19 @@ static int
 ne_read_simple(nestegg * ctx, struct ebml_element_desc * desc, size_t length)
 {
   struct ebml_type * storage;
   int r;
 
   storage = (struct ebml_type *) (ctx->ancestor->data + desc->offset);
 
   if (storage->read) {
-    ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) already read",
+    ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) already read, skipping",
              desc->id, desc->name);
-    /* We do not need to re-read the element, however we do need to move the IO
-       position back to the original offset */
-    if (storage->offset >= 0) {
-      return ne_io_seek(ctx->io, storage->offset, NESTEGG_SEEK_SET);
-    } else {
-      return 0;
-    }
+    return 0;
   }
 
   storage->type = desc->type;
 
   ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) -> %p (%u)",
            desc->id, desc->name, storage, desc->offset);
 
   switch (desc->type) {
@@ -1780,16 +1774,56 @@ ne_match_webm(nestegg_io io, int64_t max
     return 0;
   }
 
   nestegg_destroy(ctx);
 
   return 1;
 }
 
+static void
+ne_clear_element(struct ebml_element_desc * desc, unsigned char * data, int64_t stream_offset)
+{
+  struct ebml_type * storage;
+  struct ebml_element_desc * children;
+
+  if (!desc || !desc->name) {
+    return;
+  }
+
+  switch (desc->type) {
+  case TYPE_UINT:
+  case TYPE_FLOAT:
+  case TYPE_STRING:
+  case TYPE_BINARY:
+    storage = (struct ebml_type *) (data + desc->offset);
+    if (storage->offset >= stream_offset) {
+      storage->read = 0;
+      if (desc->type == TYPE_BINARY) {
+        h_free(storage->v.b.data);
+      } else if (desc->type == TYPE_STRING) {
+        h_free(storage->v.s);
+      }
+    }
+    break;
+
+  case TYPE_MASTER:
+    children = desc->children;
+    while (children->name) {
+      ne_clear_element(children, data, stream_offset);
+      children++;
+    }
+    break;
+  case TYPE_UNKNOWN:
+  default:
+    assert(0);
+    break;
+  }
+}
+
 int
 nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t max_offset)
 {
   int r;
   uint64_t id, version, docversion;
   struct ebml_list_node * track;
   char * doctype;
   nestegg * ctx;
@@ -1927,16 +1961,17 @@ nestegg_restore_state(nestegg * ctx, nes
     return;
   }
 
   while (ctx->ancestor)
     ne_ctx_pop(ctx);
 
   copy.ancestor = s->ancestor;
   while (copy.ancestor) {
+    ne_clear_element(copy.ancestor->node, copy.ancestor->data, s->stream_offset);
     ne_ctx_push(ctx, copy.ancestor->node, copy.ancestor->data);
     ne_ctx_pop(&copy);
   }
   s->ancestor = ctx->ancestor;
   ne_ctx_restore(ctx, s);
   free(s);
   return;
 }