зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1064705 - Don't treat EOS as fatal when reading optional block subelements in nestegg_read_packet. r=cajbir
This commit is contained in:
Родитель
6393ec70b5
Коммит
ba4e7fa834
|
@ -72,8 +72,9 @@ runWithMSE(function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
v.addEventListener("ended", function () {
|
v.addEventListener("ended", function () {
|
||||||
is(v.duration, 4, "Video has correct duration");
|
// XXX: Duration should be exactly 4.0, see bug 1065207.
|
||||||
is(v.currentTime, 4, "Video has played to end");
|
is(v.duration, 4.001, "Video has correct duration");
|
||||||
|
is(v.currentTime, 4.001, "Video has played to end");
|
||||||
v.parentNode.removeChild(v);
|
v.parentNode.removeChild(v);
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,8 +32,9 @@ runWithMSE(function (ms, v) {
|
||||||
});
|
});
|
||||||
|
|
||||||
v.addEventListener("ended", function () {
|
v.addEventListener("ended", function () {
|
||||||
is(v.duration, 4, "Video has correct duration");
|
// XXX: Duration should be exactly 4.0, see bug 1065207.
|
||||||
is(v.currentTime, 4, "Video has played to end");
|
is(v.duration, 4.001, "Video has correct duration");
|
||||||
|
is(v.currentTime, 4.001, "Video has played to end");
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,8 +34,9 @@ runWithMSE(function (ms, v) {
|
||||||
});
|
});
|
||||||
|
|
||||||
v.addEventListener("ended", function () {
|
v.addEventListener("ended", function () {
|
||||||
is(v.duration, 4, "Video has correct duration");
|
// XXX: Duration should be exactly 4.0, see bug 1065207.
|
||||||
is(v.currentTime, 4, "Video has played to end");
|
is(v.duration, 4.001, "Video has correct duration");
|
||||||
|
is(v.currentTime, 4.001, "Video has played to end");
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
|
||||||
|
|
||||||
The nestegg git repository is: git://github.com/kinetiknz/nestegg.git
|
The nestegg git repository is: git://github.com/kinetiknz/nestegg.git
|
||||||
|
|
||||||
The git commit ID used was 276ccd80e723b0edaf0ef42dbacb5a3a42e02d5c.
|
The git commit ID used was 46ab96bcc8b099704cc8a15993f80fe0269a5284.
|
||||||
|
|
|
@ -133,6 +133,7 @@ typedef struct {
|
||||||
unsigned int crop_top; /**< Pixels to crop from the top of the frame. */
|
unsigned int crop_top; /**< Pixels to crop from the top of the frame. */
|
||||||
unsigned int crop_left; /**< Pixels to crop from the left of the frame. */
|
unsigned int crop_left; /**< Pixels to crop from the left of the frame. */
|
||||||
unsigned int crop_right; /**< Pixels to crop from the right of the frame. */
|
unsigned int crop_right; /**< Pixels to crop from the right of the frame. */
|
||||||
|
unsigned int alpha_mode; /**< 1 if an additional opacity stream is available, otherwise 0. */
|
||||||
} nestegg_video_params;
|
} nestegg_video_params;
|
||||||
|
|
||||||
/** Parameters specific to an audio track. */
|
/** Parameters specific to an audio track. */
|
||||||
|
@ -340,6 +341,19 @@ int nestegg_packet_count(nestegg_packet * packet, unsigned int * count);
|
||||||
int nestegg_packet_data(nestegg_packet * packet, unsigned int item,
|
int nestegg_packet_data(nestegg_packet * packet, unsigned int item,
|
||||||
unsigned char ** data, size_t * length);
|
unsigned char ** data, size_t * length);
|
||||||
|
|
||||||
|
/** Get a pointer to additional data with identifier @a id of additional packet
|
||||||
|
data. If @a id isn't present in the packet, returns -1.
|
||||||
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
|
@param id Codec specific identifer. For VP8, use 1 to get a VP8 encoded
|
||||||
|
frame containing an alpha channel in its Y plane.
|
||||||
|
@param data Storage for the queried data pointer.
|
||||||
|
The data is owned by the #nestegg_packet packet.
|
||||||
|
@param length Storage for the queried data size.
|
||||||
|
@retval 0 Success.
|
||||||
|
@retval -1 Error. */
|
||||||
|
int nestegg_packet_additional_data(nestegg_packet * packet, unsigned int id,
|
||||||
|
unsigned char ** data, size_t * length);
|
||||||
|
|
||||||
/** Returns discard_padding for given packet
|
/** Returns discard_padding for given packet
|
||||||
@param packet Packet initialized by #nestegg_read_packet.
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
@param discard_padding pointer to store discard padding in.
|
@param discard_padding pointer to store discard padding in.
|
||||||
|
|
|
@ -47,10 +47,18 @@
|
||||||
|
|
||||||
/* BlockGroup Elements */
|
/* BlockGroup Elements */
|
||||||
#define ID_BLOCK 0xa1
|
#define ID_BLOCK 0xa1
|
||||||
|
#define ID_BLOCK_ADDITIONS 0x75a1
|
||||||
#define ID_BLOCK_DURATION 0x9b
|
#define ID_BLOCK_DURATION 0x9b
|
||||||
#define ID_REFERENCE_BLOCK 0xfb
|
#define ID_REFERENCE_BLOCK 0xfb
|
||||||
#define ID_DISCARD_PADDING 0x75a2
|
#define ID_DISCARD_PADDING 0x75a2
|
||||||
|
|
||||||
|
/* BlockAdditions Elements */
|
||||||
|
#define ID_BLOCK_MORE 0xa6
|
||||||
|
|
||||||
|
/* BlockMore Elements */
|
||||||
|
#define ID_BLOCK_ADD_ID 0xee
|
||||||
|
#define ID_BLOCK_ADDITIONAL 0xa5
|
||||||
|
|
||||||
/* Tracks Elements */
|
/* Tracks Elements */
|
||||||
#define ID_TRACKS 0x1654ae6b
|
#define ID_TRACKS 0x1654ae6b
|
||||||
#define ID_TRACK_ENTRY 0xae
|
#define ID_TRACK_ENTRY 0xae
|
||||||
|
@ -71,6 +79,7 @@
|
||||||
/* Video Elements */
|
/* Video Elements */
|
||||||
#define ID_VIDEO 0xe0
|
#define ID_VIDEO 0xe0
|
||||||
#define ID_STEREO_MODE 0x53b8
|
#define ID_STEREO_MODE 0x53b8
|
||||||
|
#define ID_ALPHA_MODE 0x53c0
|
||||||
#define ID_PIXEL_WIDTH 0xb0
|
#define ID_PIXEL_WIDTH 0xb0
|
||||||
#define ID_PIXEL_HEIGHT 0xba
|
#define ID_PIXEL_HEIGHT 0xba
|
||||||
#define ID_PIXEL_CROP_BOTTOM 0x54aa
|
#define ID_PIXEL_CROP_BOTTOM 0x54aa
|
||||||
|
@ -195,7 +204,17 @@ struct info {
|
||||||
struct ebml_type duration;
|
struct ebml_type duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct block_more {
|
||||||
|
struct ebml_type block_add_id;
|
||||||
|
struct ebml_type block_additional;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct block_additions {
|
||||||
|
struct ebml_list block_more;
|
||||||
|
};
|
||||||
|
|
||||||
struct block_group {
|
struct block_group {
|
||||||
|
struct ebml_type block_additions;
|
||||||
struct ebml_type duration;
|
struct ebml_type duration;
|
||||||
struct ebml_type reference_block;
|
struct ebml_type reference_block;
|
||||||
struct ebml_type discard_padding;
|
struct ebml_type discard_padding;
|
||||||
|
@ -208,6 +227,7 @@ struct cluster {
|
||||||
|
|
||||||
struct video {
|
struct video {
|
||||||
struct ebml_type stereo_mode;
|
struct ebml_type stereo_mode;
|
||||||
|
struct ebml_type alpha_mode;
|
||||||
struct ebml_type pixel_width;
|
struct ebml_type pixel_width;
|
||||||
struct ebml_type pixel_height;
|
struct ebml_type pixel_height;
|
||||||
struct ebml_type pixel_crop_bottom;
|
struct ebml_type pixel_crop_bottom;
|
||||||
|
@ -294,6 +314,13 @@ struct frame {
|
||||||
struct frame * next;
|
struct frame * next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct block_additional {
|
||||||
|
unsigned int id;
|
||||||
|
unsigned char * data;
|
||||||
|
size_t length;
|
||||||
|
struct block_additional * next;
|
||||||
|
};
|
||||||
|
|
||||||
/* Public (opaque) Structures */
|
/* Public (opaque) Structures */
|
||||||
struct nestegg {
|
struct nestegg {
|
||||||
nestegg_io * io;
|
nestegg_io * io;
|
||||||
|
@ -314,6 +341,7 @@ struct nestegg_packet {
|
||||||
uint64_t timecode;
|
uint64_t timecode;
|
||||||
uint64_t duration;
|
uint64_t duration;
|
||||||
struct frame * frame;
|
struct frame * frame;
|
||||||
|
struct block_additional * block_additional;
|
||||||
int64_t discard_padding;
|
int64_t discard_padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -374,11 +402,23 @@ static struct ebml_element_desc ne_info_elements[] = {
|
||||||
E_LAST
|
E_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ebml_element_desc ne_block_more_elements[] = {
|
||||||
|
E_FIELD(ID_BLOCK_ADD_ID, TYPE_UINT, struct block_more, block_add_id),
|
||||||
|
E_FIELD(ID_BLOCK_ADDITIONAL, TYPE_BINARY, struct block_more, block_additional),
|
||||||
|
E_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ebml_element_desc ne_block_additions_elements[] = {
|
||||||
|
E_MASTER(ID_BLOCK_MORE, TYPE_MASTER, struct block_additions, block_more),
|
||||||
|
E_LAST
|
||||||
|
};
|
||||||
|
|
||||||
static struct ebml_element_desc ne_block_group_elements[] = {
|
static struct ebml_element_desc ne_block_group_elements[] = {
|
||||||
E_SUSPEND(ID_BLOCK, TYPE_BINARY),
|
E_SUSPEND(ID_BLOCK, TYPE_BINARY),
|
||||||
E_FIELD(ID_BLOCK_DURATION, TYPE_UINT, struct block_group, duration),
|
E_FIELD(ID_BLOCK_DURATION, TYPE_UINT, struct block_group, duration),
|
||||||
E_FIELD(ID_REFERENCE_BLOCK, TYPE_INT, struct block_group, reference_block),
|
E_FIELD(ID_REFERENCE_BLOCK, TYPE_INT, struct block_group, reference_block),
|
||||||
E_FIELD(ID_DISCARD_PADDING, TYPE_INT, struct block_group, discard_padding),
|
E_FIELD(ID_DISCARD_PADDING, TYPE_INT, struct block_group, discard_padding),
|
||||||
|
E_SINGLE_MASTER(ID_BLOCK_ADDITIONS, TYPE_MASTER, struct block_group, block_additions),
|
||||||
E_LAST
|
E_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -391,6 +431,7 @@ static struct ebml_element_desc ne_cluster_elements[] = {
|
||||||
|
|
||||||
static struct ebml_element_desc ne_video_elements[] = {
|
static struct ebml_element_desc ne_video_elements[] = {
|
||||||
E_FIELD(ID_STEREO_MODE, TYPE_UINT, struct video, stereo_mode),
|
E_FIELD(ID_STEREO_MODE, TYPE_UINT, struct video, stereo_mode),
|
||||||
|
E_FIELD(ID_ALPHA_MODE, TYPE_UINT, struct video, alpha_mode),
|
||||||
E_FIELD(ID_PIXEL_WIDTH, TYPE_UINT, struct video, pixel_width),
|
E_FIELD(ID_PIXEL_WIDTH, TYPE_UINT, struct video, pixel_width),
|
||||||
E_FIELD(ID_PIXEL_HEIGHT, TYPE_UINT, struct video, pixel_height),
|
E_FIELD(ID_PIXEL_HEIGHT, TYPE_UINT, struct video, pixel_height),
|
||||||
E_FIELD(ID_PIXEL_CROP_BOTTOM, TYPE_UINT, struct video, pixel_crop_bottom),
|
E_FIELD(ID_PIXEL_CROP_BOTTOM, TYPE_UINT, struct video, pixel_crop_bottom),
|
||||||
|
@ -689,14 +730,16 @@ ne_read_string(nestegg * ctx, char ** val, uint64_t length)
|
||||||
char * str;
|
char * str;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (length == 0 || length > LIMIT_STRING)
|
if (length > LIMIT_STRING)
|
||||||
return -1;
|
return -1;
|
||||||
str = ne_pool_alloc(length + 1, ctx->alloc_pool);
|
str = ne_pool_alloc(length + 1, ctx->alloc_pool);
|
||||||
if (!str)
|
if (!str)
|
||||||
return -1;
|
return -1;
|
||||||
r = ne_io_read(ctx->io, (unsigned char *) str, length);
|
if (length) {
|
||||||
if (r != 1)
|
r = ne_io_read(ctx->io, (unsigned char *) str, length);
|
||||||
return r;
|
if (r != 1)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
str[length] = '\0';
|
str[length] = '\0';
|
||||||
*val = str;
|
*val = str;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1420,6 +1463,7 @@ ne_read_block_duration(nestegg * ctx, nestegg_packet * pkt)
|
||||||
r = ne_read_simple(ctx, element, size);
|
r = ne_read_simple(ctx, element, size);
|
||||||
if (r != 1)
|
if (r != 1)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
storage = (struct ebml_type *) (ctx->ancestor->data + element->offset);
|
storage = (struct ebml_type *) (ctx->ancestor->data + element->offset);
|
||||||
pkt->duration = storage->v.i * ne_get_timecode_scale(ctx);
|
pkt->duration = storage->v.i * ne_get_timecode_scale(ctx);
|
||||||
|
|
||||||
|
@ -1448,12 +1492,123 @@ ne_read_discard_padding(nestegg * ctx, nestegg_packet * pkt)
|
||||||
r = ne_read_simple(ctx, element, size);
|
r = ne_read_simple(ctx, element, size);
|
||||||
if (r != 1)
|
if (r != 1)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
storage = (struct ebml_type *) (ctx->ancestor->data + element->offset);
|
storage = (struct ebml_type *) (ctx->ancestor->data + element->offset);
|
||||||
pkt->discard_padding = storage->v.i;
|
pkt->discard_padding = storage->v.i;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ne_read_block_additions(nestegg * ctx, nestegg_packet * pkt)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
uint64_t id, size, data_size;
|
||||||
|
int64_t block_additions_end, block_more_end;
|
||||||
|
void * data;
|
||||||
|
int has_data;
|
||||||
|
struct block_additional * block_additional;
|
||||||
|
uint64_t add_id;
|
||||||
|
|
||||||
|
assert(pkt != NULL);
|
||||||
|
assert(pkt->block_additional == NULL);
|
||||||
|
|
||||||
|
r = ne_peek_element(ctx, &id, &size);
|
||||||
|
if (r != 1)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (id != ID_BLOCK_ADDITIONS)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* This makes ne_read_element read the next element instead of returning
|
||||||
|
information about the already "peeked" one. */
|
||||||
|
ctx->last_valid = 0;
|
||||||
|
|
||||||
|
block_additions_end = ne_io_tell(ctx->io) + size;
|
||||||
|
|
||||||
|
while (ne_io_tell(ctx->io) < block_additions_end) {
|
||||||
|
add_id = 1;
|
||||||
|
data = NULL;
|
||||||
|
has_data = 0;
|
||||||
|
r = ne_read_element(ctx, &id, &size);
|
||||||
|
if (r != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (id != ID_BLOCK_MORE) {
|
||||||
|
/* We don't know what this element is, so skip over it */
|
||||||
|
if (id != ID_VOID && id != ID_CRC32)
|
||||||
|
ctx->log(ctx, NESTEGG_LOG_DEBUG,
|
||||||
|
"unknown element %llx in BlockAdditions", id);
|
||||||
|
ne_io_read_skip(ctx->io, size);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_more_end = ne_io_tell(ctx->io) + size;
|
||||||
|
|
||||||
|
while (ne_io_tell(ctx->io) < block_more_end) {
|
||||||
|
r = ne_read_element(ctx, &id, &size);
|
||||||
|
if (r != 1) {
|
||||||
|
free(data);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == ID_BLOCK_ADD_ID) {
|
||||||
|
r = ne_read_uint(ctx->io, &add_id, size);
|
||||||
|
if (r != 1) {
|
||||||
|
free(data);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_id == 0) {
|
||||||
|
ctx->log(ctx, NESTEGG_LOG_ERROR, "Disallowed BlockAddId 0 used");
|
||||||
|
free(data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (id == ID_BLOCK_ADDITIONAL) {
|
||||||
|
if (has_data) {
|
||||||
|
/* BlockAdditional is supposed to only occur once in a
|
||||||
|
BlockMore. */
|
||||||
|
ctx->log(ctx, NESTEGG_LOG_ERROR,
|
||||||
|
"Multiple BlockAdditional elements in a BlockMore");
|
||||||
|
free(data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
has_data = 1;
|
||||||
|
data_size = size;
|
||||||
|
if (size != 0) {
|
||||||
|
data = ne_alloc(size);
|
||||||
|
r = ne_io_read(ctx->io, data, size);
|
||||||
|
if (r != 1) {
|
||||||
|
free(data);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* We don't know what this element is, so skip over it */
|
||||||
|
if (id != ID_VOID && id != ID_CRC32)
|
||||||
|
ctx->log(ctx, NESTEGG_LOG_DEBUG,
|
||||||
|
"unknown element %llx in BlockMore", id);
|
||||||
|
ne_io_read_skip(ctx->io, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_data == 0) {
|
||||||
|
ctx->log(ctx, NESTEGG_LOG_ERROR,
|
||||||
|
"No BlockAdditional element in a BlockMore");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_additional = ne_alloc(sizeof(*block_additional));
|
||||||
|
block_additional->next = pkt->block_additional;
|
||||||
|
block_additional->id = add_id;
|
||||||
|
block_additional->data = data;
|
||||||
|
block_additional->length = data_size;
|
||||||
|
pkt->block_additional = block_additional;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
ne_buf_read_id(unsigned char const * p, size_t length)
|
ne_buf_read_id(unsigned char const * p, size_t length)
|
||||||
|
@ -1727,8 +1882,8 @@ ne_match_webm(nestegg_io io, int64_t max_offset)
|
||||||
ne_ctx_push(ctx, ne_top_level_elements, ctx);
|
ne_ctx_push(ctx, ne_top_level_elements, ctx);
|
||||||
|
|
||||||
/* we don't check the return value of ne_parse, that might fail because
|
/* we don't check the return value of ne_parse, that might fail because
|
||||||
* max_offset is not on a valid element end point. We only want to check
|
max_offset is not on a valid element end point. We only want to check
|
||||||
* the EBML ID and that the doctype is "webm". */
|
the EBML ID and that the doctype is "webm". */
|
||||||
ne_parse(ctx, NULL, max_offset);
|
ne_parse(ctx, NULL, max_offset);
|
||||||
|
|
||||||
if (ne_get_string(ctx->ebml.doctype, &doctype) != 0 ||
|
if (ne_get_string(ctx->ebml.doctype, &doctype) != 0 ||
|
||||||
|
@ -2168,6 +2323,10 @@ nestegg_track_video_params(nestegg * ctx, unsigned int track,
|
||||||
value == NESTEGG_VIDEO_STEREO_RIGHT_LEFT)
|
value == NESTEGG_VIDEO_STEREO_RIGHT_LEFT)
|
||||||
params->stereo_mode = value;
|
params->stereo_mode = value;
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
ne_get_uint(entry->video.alpha_mode, &value);
|
||||||
|
params->alpha_mode = value;
|
||||||
|
|
||||||
if (ne_get_uint(entry->video.pixel_width, &value) != 0)
|
if (ne_get_uint(entry->video.pixel_width, &value) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
params->width = value;
|
params->width = value;
|
||||||
|
@ -2262,7 +2421,7 @@ nestegg_track_default_duration(nestegg * ctx, unsigned int track,
|
||||||
int
|
int
|
||||||
nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
|
nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
|
||||||
{
|
{
|
||||||
int r;
|
int r, read_block = 0;
|
||||||
uint64_t id, size;
|
uint64_t id, size;
|
||||||
|
|
||||||
*pkt = NULL;
|
*pkt = NULL;
|
||||||
|
@ -2284,15 +2443,27 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
|
||||||
if (r != 1)
|
if (r != 1)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = ne_read_block_duration(ctx, *pkt);
|
read_block = 1;
|
||||||
if (r != 1)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = ne_read_discard_padding(ctx, *pkt);
|
/* These are not valid elements of a SimpleBlock, only a full-blown
|
||||||
if (r != 1)
|
Block. */
|
||||||
return r;
|
if (id != ID_SIMPLE_BLOCK) {
|
||||||
|
r = ne_read_block_duration(ctx, *pkt);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
return r;
|
r = ne_read_discard_padding(ctx, *pkt);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = ne_read_block_additions(ctx, *pkt);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have read a block and hit EOS when reading optional block
|
||||||
|
subelements, don't report EOS until the next call. */
|
||||||
|
return read_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = ne_parse(ctx, NULL, -1);
|
r = ne_parse(ctx, NULL, -1);
|
||||||
|
@ -2307,6 +2478,7 @@ void
|
||||||
nestegg_free_packet(nestegg_packet * pkt)
|
nestegg_free_packet(nestegg_packet * pkt)
|
||||||
{
|
{
|
||||||
struct frame * frame;
|
struct frame * frame;
|
||||||
|
struct block_additional * block_additional;
|
||||||
|
|
||||||
while (pkt->frame) {
|
while (pkt->frame) {
|
||||||
frame = pkt->frame;
|
frame = pkt->frame;
|
||||||
|
@ -2315,6 +2487,13 @@ nestegg_free_packet(nestegg_packet * pkt)
|
||||||
free(frame);
|
free(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2384,6 +2563,27 @@ nestegg_packet_data(nestegg_packet * pkt, unsigned int item,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nestegg_packet_additional_data(nestegg_packet * pkt, unsigned int id,
|
||||||
|
unsigned char ** data, size_t * length)
|
||||||
|
{
|
||||||
|
struct block_additional * a = pkt->block_additional;
|
||||||
|
|
||||||
|
*data = NULL;
|
||||||
|
*length = 0;
|
||||||
|
|
||||||
|
while (a) {
|
||||||
|
if (a->id == id) {
|
||||||
|
*data = a->data;
|
||||||
|
*length = a->length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nestegg_has_cues(nestegg * ctx)
|
nestegg_has_cues(nestegg * ctx)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче