author | Matthew Gregan <kinetik@flim.org> |
Mon, 29 Sep 2014 13:13:10 +1300 | |
changeset 208091 | 27bcbf49cfd7de5bf9eb356069ead2eebc4747a1 |
parent 208090 | 6122db43cad3586390bc490d2f2342a6bc4616b5 |
child 208092 | 5997c0f393ba4f67eeb35a60c3cc1370824362a4 |
push id | 27575 |
push user | cbook@mozilla.com |
push date | Wed, 01 Oct 2014 12:52:17 +0000 |
treeherder | mozilla-central@fe0afc101ad2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | giles |
bugs | 1074004 |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
media/libnestegg/README | file | annotate | diff | comparison | revisions | |
media/libnestegg/README.md | file | annotate | diff | comparison | revisions | |
media/libnestegg/README_MOZILLA | file | annotate | diff | comparison | revisions | |
media/libnestegg/include/nestegg.h | file | annotate | diff | comparison | revisions | |
media/libnestegg/src/halloc.c | file | annotate | diff | comparison | revisions | |
media/libnestegg/src/nestegg.c | file | annotate | diff | comparison | revisions | |
media/libnestegg/update.sh | file | annotate | diff | comparison | revisions |
rename from media/libnestegg/README rename to media/libnestegg/README.md --- a/media/libnestegg/README +++ b/media/libnestegg/README.md @@ -1,6 +1,8 @@ +[](https://travis-ci.org/kinetiknz/nestegg) + See INSTALL for build instructions. Licensed under an ISC-style license. See LICENSE for details. The source under the halloc/ directory is licensed under a BSD license. See halloc/halloc.h for details.
--- a/media/libnestegg/README_MOZILLA +++ b/media/libnestegg/README_MOZILLA @@ -1,8 +1,8 @@ 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 46ab96bcc8b099704cc8a15993f80fe0269a5284. +The git commit ID used was 59220ae3e801cbad0f8160129c4df315469af671.
--- a/media/libnestegg/include/nestegg.h +++ b/media/libnestegg/include/nestegg.h @@ -376,16 +376,19 @@ int nestegg_has_cues(nestegg * context); * @retval 0 The file is not a WebM file. * @retval 1 The file is a WebM file. */ int nestegg_sniff(unsigned char const * buffer, size_t length); /** * Set the underlying allocation function for library allocations. * * @param realloc_func The desired function. + * @retval 0 realloc_func(p, 0) does not act as free() + * @retval 1 realloc_func(p, 0) acts as free() + * @retval -1 malloc failed during realloc_func test */ -void nestegg_set_halloc_func(void * (* realloc_func)(void *, size_t)); +int nestegg_set_halloc_func(void * (* realloc_func)(void *, size_t)); #if defined(__cplusplus) } #endif #endif /* NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79 */
--- a/media/libnestegg/src/halloc.c +++ b/media/libnestegg/src/halloc.c @@ -41,33 +41,36 @@ typedef struct hblock */ realloc_t halloc_allocator = NULL; #define allocator halloc_allocator /* * static methods */ -static void _set_allocator(void); +int halloc_set_allocator(realloc_t realloc_func); static void * _realloc(void * ptr, size_t n); static int _relate(hblock_t * b, hblock_t * p); static void _free_children(hblock_t * p); /* * Core API */ void * halloc(void * ptr, size_t len) { hblock_t * p; /* set up default allocator */ if (! allocator) { - _set_allocator(); + if (halloc_set_allocator(realloc) == 0) + { + halloc_set_allocator(_realloc); + } assert(allocator); } /* calloc */ if (! ptr) { if (! len) return NULL; @@ -167,42 +170,42 @@ char * h_strdup(const char * str) size_t len = strlen(str); char * ptr = halloc(0, len + 1); return ptr ? (ptr[len] = 0, memcpy(ptr, str, len)) : NULL; } /* * static stuff */ -static void _set_allocator(void) +int halloc_set_allocator(realloc_t realloc_func) { void * p; assert(! allocator); /* * the purpose of the test below is to check the behaviour * of realloc(ptr, 0), which is defined in the standard * as an implementation-specific. if it returns zero, * then it's equivalent to free(). it can however return * non-zero, in which case it cannot be used for freeing * memory blocks and we'll need to supply our own version * * Thanks to Stan Tobias for pointing this tricky part out. */ - allocator = realloc; - if (! (p = malloc(1))) + if (! (p = realloc_func(NULL, 1))) /* hmm */ - return; + return -1; - if ((p = realloc(p, 0))) + if ((p = realloc_func(p, 0))) { - /* realloc cannot be used as free() */ - allocator = _realloc; - free(p); + /* realloc_func cannot be used as free() */ + return 0; } + allocator = realloc_func; + return 1; } static void * _realloc(void * ptr, size_t n) { /* * free'ing realloc() */ if (n)
--- a/media/libnestegg/src/nestegg.c +++ b/media/libnestegg/src/nestegg.c @@ -316,19 +316,28 @@ struct frame { struct block_additional { unsigned int id; unsigned char * data; size_t length; struct block_additional * next; }; +#define NE_IO_BUFSZ 16384 + +struct nestegg_io_buf { + nestegg_io io; + unsigned char buffer[NE_IO_BUFSZ]; + size_t bufsz; + int offset; +}; + /* Public (opaque) Structures */ struct nestegg { - nestegg_io * io; + struct nestegg_io_buf * io; nestegg_log log; struct pool_ctx * alloc_pool; uint64_t last_id; uint64_t last_size; int last_valid; struct list_node * ancestor; struct ebml ebml; struct segment segment; @@ -541,53 +550,127 @@ ne_pool_alloc(size_t size, struct pool_c static void * ne_alloc(size_t size) { return calloc(1, size); } static int -ne_io_read(nestegg_io * io, void * buffer, size_t length) +ne_io_read(struct nestegg_io_buf * io, void * buffer, size_t length) { - return io->read(buffer, length, io->userdata); + int64_t off; + int r; + size_t avail; + + assert(io->offset == -1 || (io->offset >= 0 && (unsigned int) io->offset < io->bufsz)); + + /* Too big to buffer, invalidate buffer and read through */ + if (length > io->bufsz) { + if (io->offset != -1) { + r = io->io.seek(-(io->bufsz - io->offset), NESTEGG_SEEK_CUR, io->io.userdata); + if (r != 0) { + return -1; + } + } + io->offset = -1; + return io->io.read(buffer, length, io->io.userdata); + } + + /* Buffer invalid */ + if (io->offset == -1) { + off = io->io.tell(io->io.userdata); + if (off == -1) { + return -1; + } + /* Refill buffer */ + r = io->io.read(io->buffer, io->bufsz, io->io.userdata); + if (r != 1) { + /* Read truncated due to being within io->bufsz of EOS, reset read + position and switch to read through mode */ + io->offset = -1; + io->bufsz = 0; + if (r == 0) { + r = io->io.seek(off, NESTEGG_SEEK_SET, io->io.userdata); + } + if (r == 0) { + return io->io.read(buffer, length, io->io.userdata); + } + return -1; + } + if (r == 1) { + io->offset = 0; + } + } + + /* Service request with what we have */ + avail = length; + if (io->bufsz - io->offset < length) { + avail = io->bufsz - io->offset; + } + memcpy(buffer, io->buffer + io->offset, avail); + io->offset += avail; + + if ((unsigned int) io->offset == io->bufsz) { + io->offset = -1; + } + + /* Still more to read, invalidate buffer and read more */ + if (length - avail > 0) { + return ne_io_read(io, (char *) buffer + avail, length - avail); + } + + return 1; } static int -ne_io_seek(nestegg_io * io, int64_t offset, int whence) +ne_io_seek(struct nestegg_io_buf * io, int64_t offset, int whence) +{ + /* Invalidate buffer */ + io->offset = -1; + + return io->io.seek(offset, whence, io->io.userdata); +} + +static int64_t +ne_io_tell(struct nestegg_io_buf * io) { - return io->seek(offset, whence, io->userdata); + int64_t off; + + off = io->io.tell(io->io.userdata); + if (off == -1) { + return -1; + } + if (io->offset == -1) { + return off; + } + assert(off >= (int64_t) io->bufsz - io->offset); + return off - io->bufsz + (unsigned int) io->offset; } static int -ne_io_read_skip(nestegg_io * io, size_t length) +ne_io_read_skip(struct nestegg_io_buf * io, size_t length) { size_t get; unsigned char buf[8192]; int r = 1; while (length > 0) { get = length < sizeof(buf) ? length : sizeof(buf); r = ne_io_read(io, buf, get); if (r != 1) break; length -= get; } return r; } -static int64_t -ne_io_tell(nestegg_io * io) -{ - return io->tell(io->userdata); -} - static int -ne_bare_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length, enum vint_mask maskflag) +ne_bare_read_vint(struct nestegg_io_buf * io, uint64_t * value, uint64_t * length, enum vint_mask maskflag) { int r; unsigned char b; size_t maxlen = 8; unsigned int count = 1, mask = 1 << 7; r = ne_io_read(io, &b, 1); if (r != 1) @@ -614,29 +697,29 @@ ne_bare_read_vint(nestegg_io * io, uint6 *value <<= 8; *value |= b; } return 1; } static int -ne_read_id(nestegg_io * io, uint64_t * value, uint64_t * length) +ne_read_id(struct nestegg_io_buf * io, uint64_t * value, uint64_t * length) { return ne_bare_read_vint(io, value, length, MASK_NONE); } static int -ne_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length) +ne_read_vint(struct nestegg_io_buf * io, uint64_t * value, uint64_t * length) { return ne_bare_read_vint(io, value, length, MASK_FIRST_BIT); } static int -ne_read_svint(nestegg_io * io, int64_t * value, uint64_t * length) +ne_read_svint(struct nestegg_io_buf * io, int64_t * value, uint64_t * length) { int r; uint64_t uvalue; uint64_t ulength; int64_t svint_subtr[] = { 0x3f, 0x1fff, 0xfffff, 0x7ffffff, 0x3ffffffffLL, 0x1ffffffffffLL, @@ -648,17 +731,17 @@ ne_read_svint(nestegg_io * io, int64_t * return r; *value = uvalue - svint_subtr[ulength - 1]; if (length) *length = ulength; return r; } static int -ne_read_uint(nestegg_io * io, uint64_t * val, uint64_t length) +ne_read_uint(struct nestegg_io_buf * io, uint64_t * val, uint64_t length) { unsigned char b; int r; if (length == 0 || length > 8) return -1; r = ne_io_read(io, &b, 1); if (r != 1) @@ -670,44 +753,44 @@ ne_read_uint(nestegg_io * io, uint64_t * return r; *val <<= 8; *val |= b; } return 1; } static int -ne_read_int(nestegg_io * io, int64_t * val, uint64_t length) +ne_read_int(struct nestegg_io_buf * io, int64_t * val, uint64_t length) { int r; uint64_t uval, base; r = ne_read_uint(io, &uval, length); if (r != 1) return r; if (length < sizeof(int64_t)) { base = 1; base <<= length * 8 - 1; if (uval >= base) { - base = 1; - base <<= length * 8; + base = 1; + base <<= length * 8; } else { base = 0; } *val = uval - base; } else { *val = (int64_t) uval; } return 1; } static int -ne_read_float(nestegg_io * io, double * val, uint64_t length) +ne_read_float(struct nestegg_io_buf * io, double * val, uint64_t length) { union { uint64_t u; float f; double d; } value; int r; @@ -731,19 +814,19 @@ ne_read_string(nestegg * ctx, char ** va int r; if (length > LIMIT_STRING) return -1; str = ne_pool_alloc(length + 1, ctx->alloc_pool); if (!str) return -1; if (length) { - r = ne_io_read(ctx->io, (unsigned char *) str, length); - if (r != 1) - return r; + r = ne_io_read(ctx->io, (unsigned char *) str, length); + if (r != 1) + return r; } str[length] = '\0'; *val = str; return 1; } static int ne_read_binary(nestegg * ctx, struct ebml_binary * val, uint64_t length) @@ -1013,18 +1096,19 @@ ne_read_simple(nestegg * ctx, struct ebm case TYPE_STRING: r = ne_read_string(ctx, &storage->v.s, length); break; case TYPE_BINARY: r = ne_read_binary(ctx, &storage->v.b, length); break; case TYPE_MASTER: case TYPE_UNKNOWN: + default: + r = 0; assert(0); - r = 0; break; } if (r == 1) storage->read = 1; return r; } @@ -1131,17 +1215,17 @@ ne_xiph_lace_value(unsigned char ** np) } *np = p; return value; } static int -ne_read_xiph_lace_value(nestegg_io * io, uint64_t * value, size_t * consumed) +ne_read_xiph_lace_value(struct nestegg_io_buf * io, uint64_t * value, size_t * consumed) { int r; uint64_t lace; r = ne_read_uint(io, &lace, 1); if (r != 1) return r; *consumed += 1; @@ -1154,17 +1238,17 @@ ne_read_xiph_lace_value(nestegg_io * io, *consumed += 1; *value += lace; } return 1; } static int -ne_read_xiph_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) +ne_read_xiph_lacing(struct nestegg_io_buf * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) { int r; size_t i = 0; uint64_t sum = 0; while (--n) { r = ne_read_xiph_lace_value(io, &sizes[i], read); if (r != 1) @@ -1177,17 +1261,17 @@ ne_read_xiph_lacing(nestegg_io * io, siz return -1; /* Last frame is the remainder of the block. */ sizes[i] = block - *read - sum; return 1; } static int -ne_read_ebml_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) +ne_read_ebml_lacing(struct nestegg_io_buf * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) { int r; uint64_t lace, sum, length; int64_t slace; size_t i = 0; r = ne_read_vint(io, &lace, &length); if (r != 1) @@ -1787,61 +1871,61 @@ ne_init_cue_points(nestegg * ctx, int64_ * sniff_buffer. */ struct sniff_buffer { unsigned char const * buffer; size_t length; int64_t offset; }; static int -ne_buffer_read(void * buffer, size_t length, void * user_data) +ne_buffer_read(void * buffer, size_t length, void * userdata) { - struct sniff_buffer * sb = user_data; + struct sniff_buffer * sb = userdata; int rv = 1; size_t available = sb->length - sb->offset; if (available < length) return 0; memcpy(buffer, sb->buffer + sb->offset, length); sb->offset += length; return rv; } static int -ne_buffer_seek(int64_t offset, int whence, void * user_data) +ne_buffer_seek(int64_t offset, int whence, void * userdata) { - struct sniff_buffer * sb = user_data; + struct sniff_buffer * sb = userdata; int64_t o = sb->offset; switch(whence) { - case NESTEGG_SEEK_SET: - o = offset; - break; - case NESTEGG_SEEK_CUR: - o += offset; - break; - case NESTEGG_SEEK_END: - o = sb->length + offset; - break; + case NESTEGG_SEEK_SET: + o = offset; + break; + case NESTEGG_SEEK_CUR: + o += offset; + break; + case NESTEGG_SEEK_END: + o = sb->length + offset; + break; } if (o < 0 || o > (int64_t) sb->length) return -1; sb->offset = o; return 0; } static int64_t -ne_buffer_tell(void * user_data) +ne_buffer_tell(void * userdata) { - struct sniff_buffer * sb = user_data; + struct sniff_buffer * sb = userdata; return sb->offset; } static int ne_match_webm(nestegg_io io, int64_t max_offset) { int r; uint64_t id; @@ -1855,17 +1939,19 @@ ne_match_webm(nestegg_io io, int64_t max if (!ctx) return -1; ctx->io = ne_alloc(sizeof(*ctx->io)); if (!ctx->io) { nestegg_destroy(ctx); return -1; } - *ctx->io = io; + ctx->io->io = io; + ctx->io->bufsz = NE_IO_BUFSZ; + ctx->io->offset = -1; ctx->alloc_pool = ne_pool_init(); if (!ctx->alloc_pool) { nestegg_destroy(ctx); return -1; } ctx->log = ne_null_log_callback; r = ne_peek_element(ctx, &id, NULL); @@ -1913,17 +1999,19 @@ nestegg_init(nestegg ** context, nestegg if (!ctx) return -1; ctx->io = ne_alloc(sizeof(*ctx->io)); if (!ctx->io) { nestegg_destroy(ctx); return -1; } - *ctx->io = io; + ctx->io->io = io; + ctx->io->bufsz = NE_IO_BUFSZ; + ctx->io->offset = -1; ctx->log = callback; ctx->alloc_pool = ne_pool_init(); if (!ctx->alloc_pool) { nestegg_destroy(ctx); return -1; } if (!ctx->log) @@ -2259,45 +2347,45 @@ nestegg_track_codec_data(nestegg * ctx, *data = NULL; *length = 0; entry = ne_find_track_entry(ctx, track); if (!entry) return -1; if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS - && nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS) + && nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS) return -1; if (ne_get_binary(entry->codec_private, &codec_private) != 0) return -1; if (nestegg_track_codec_id(ctx, track) == NESTEGG_CODEC_VORBIS) { - p = codec_private.data; - count = *p++ + 1; - - if (count > 3) + p = codec_private.data; + count = *p++ + 1; + + if (count > 3) + return -1; + + i = 0; + total = 0; + while (--count) { + sizes[i] = ne_xiph_lace_value(&p); + total += sizes[i]; + i += 1; + } + sizes[i] = codec_private.length - total - (p - codec_private.data); + + for (i = 0; i < item; ++i) { + if (sizes[i] > LIMIT_FRAME) return -1; - - i = 0; - total = 0; - while (--count) { - sizes[i] = ne_xiph_lace_value(&p); - total += sizes[i]; - i += 1; - } - sizes[i] = codec_private.length - total - (p - codec_private.data); - - for (i = 0; i < item; ++i) { - if (sizes[i] > LIMIT_FRAME) - return -1; - p += sizes[i]; - } - *data = p; - *length = sizes[item]; + p += sizes[i]; + } + *data = p; + *length = sizes[item]; } else { *data = codec_private.data; *length = codec_private.length; } return 0; } @@ -2489,17 +2577,17 @@ nestegg_free_packet(nestegg_packet * pkt while (pkt->block_additional) { block_additional = pkt->block_additional; pkt->block_additional = block_additional->next; free(block_additional->data); free(block_additional); } - free(pkt); + free(pkt); } int nestegg_packet_track(nestegg_packet * pkt, unsigned int * track) { *track = pkt->track; return 0; } @@ -2583,33 +2671,36 @@ nestegg_packet_additional_data(nestegg_p return -1; } int nestegg_has_cues(nestegg * ctx) { return ctx->segment.cues.cue_point.head || - ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES); + ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES); } int nestegg_sniff(unsigned char const * buffer, size_t length) { nestegg_io io; - struct sniff_buffer user_data; - - user_data.buffer = buffer; - user_data.length = length; - user_data.offset = 0; + struct sniff_buffer userdata; + + userdata.buffer = buffer; + userdata.length = length; + userdata.offset = 0; io.read = ne_buffer_read; io.seek = ne_buffer_seek; io.tell = ne_buffer_tell; - io.userdata = &user_data; + io.userdata = &userdata; return ne_match_webm(io, length); } -void +/* From halloc.c */ +int halloc_set_allocator(realloc_t realloc_func); + +int nestegg_set_halloc_func(void * (* realloc_func)(void *, size_t)) { - halloc_allocator = realloc_func; + return halloc_set_allocator(realloc_func); }
--- a/media/libnestegg/update.sh +++ b/media/libnestegg/update.sh @@ -2,17 +2,17 @@ cp $1/include/nestegg/nestegg.h include cp $1/src/nestegg.c src cp $1/halloc/halloc.h src cp $1/halloc/src/align.h src cp $1/halloc/src/halloc.c src cp $1/halloc/src/hlist.h src cp $1/halloc/src/macros.h src cp $1/LICENSE . -cp $1/README . +cp $1/README.md . cp $1/AUTHORS . if [ -d $1/.git ]; then rev=$(cd $1 && git rev-parse --verify HEAD) dirty=$(cd $1 && git diff-index --name-only HEAD) fi if [ -n "$rev" ]; then version=$rev