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
--- 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(©);
}
s->ancestor = ctx->ancestor;
ne_ctx_restore(ctx, s);
free(s);
return;
}