Bug 938315 - Update nestegg to support Opus elements. r=kinetik

Merge upstream changes to the WebM parser needed to properly support Opus.
This commit is contained in:
Jan Gerber 2013-11-19 03:45:00 +13:00
Родитель e96dc3e87f
Коммит b2be7a3862
3 изменённых файлов: 98 добавлений и 21 удалений

Просмотреть файл

@ -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 git commit ID used was 26d262114af191b6654cbd5d24ec02e4b6bdb1cd.
The git commit ID used was 0851279ab11f5b2e9e8154ce7880b687b564c760.

Просмотреть файл

@ -140,6 +140,8 @@ typedef struct {
double rate; /**< Sampling rate in Hz. */
unsigned int channels; /**< Number of audio channels. */
unsigned int depth; /**< Bits per sample. */
uint64_t codec_delay; /**< Nanoseconds that must be discarded from the start. */
uint64_t seek_preroll;/**< Nanoseconds that must be discarded after a seek. */
} nestegg_audio_params;
/** Logging callback function pointer. */
@ -321,6 +323,14 @@ int nestegg_packet_count(nestegg_packet * packet, unsigned int * count);
int nestegg_packet_data(nestegg_packet * packet, unsigned int item,
unsigned char ** data, size_t * length);
/** Returns discard_padding for given packet
@param packet Packet initialized by #nestegg_read_packet.
@param discard_padding pointer to store discard padding in.
@retval 0 Success.
@retval -1 Error. */
int nestegg_packet_discard_padding(nestegg_packet * packet,
int64_t * discard_padding);
/** Query the presence of cues.
@param context Stream context initialized by #nestegg_init.
@retval 0 The media has no cues.

Просмотреть файл

@ -49,6 +49,7 @@
#define ID_BLOCK 0xa1
#define ID_BLOCK_DURATION 0x9b
#define ID_REFERENCE_BLOCK 0xfb
#define ID_DISCARD_PADDING 0x75a2
/* Tracks Elements */
#define ID_TRACKS 0x1654ae6b
@ -63,6 +64,8 @@
#define ID_LANGUAGE 0x22b59c
#define ID_CODEC_ID 0x86
#define ID_CODEC_PRIVATE 0x63a2
#define ID_CODEC_DELAY 0x56aa
#define ID_SEEK_PREROLL 0x56bb
/* Video Elements */
#define ID_VIDEO 0xe0
@ -194,6 +197,7 @@ struct info {
struct block_group {
struct ebml_type duration;
struct ebml_type reference_block;
struct ebml_type discard_padding;
};
struct cluster {
@ -230,6 +234,8 @@ struct track_entry {
struct ebml_type language;
struct ebml_type codec_id;
struct ebml_type codec_private;
struct ebml_type codec_delay;
struct ebml_type seek_preroll;
struct video video;
struct audio audio;
};
@ -305,6 +311,7 @@ struct nestegg_packet {
uint64_t track;
uint64_t timecode;
struct frame * frame;
int64_t discard_padding;
};
/* Element Descriptor */
@ -368,6 +375,7 @@ static struct ebml_element_desc ne_block_group_elements[] = {
E_SUSPEND(ID_BLOCK, TYPE_BINARY),
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_DISCARD_PADDING, TYPE_INT, struct block_group, discard_padding),
E_LAST
};
@ -409,6 +417,8 @@ static struct ebml_element_desc ne_track_entry_elements[] = {
E_FIELD(ID_LANGUAGE, TYPE_STRING, struct track_entry, language),
E_FIELD(ID_CODEC_ID, TYPE_STRING, struct track_entry, codec_id),
E_FIELD(ID_CODEC_PRIVATE, TYPE_BINARY, struct track_entry, codec_private),
E_FIELD(ID_CODEC_DELAY, TYPE_UINT, struct track_entry, codec_delay),
E_FIELD(ID_SEEK_PREROLL, TYPE_UINT, struct track_entry, seek_preroll),
E_SINGLE_MASTER(ID_VIDEO, TYPE_MASTER, struct track_entry, video),
E_SINGLE_MASTER(ID_AUDIO, TYPE_MASTER, struct track_entry, audio),
E_LAST
@ -1365,6 +1375,35 @@ ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_pac
return 1;
}
static int
ne_read_discard_padding(nestegg * ctx, nestegg_packet * pkt)
{
int r;
uint64_t id, size;
struct ebml_element_desc * element;
struct ebml_type * storage;
r = ne_peek_element(ctx, &id, &size);
if (r != 1)
return r;
if (id != ID_DISCARD_PADDING)
return 1;
element = ne_find_element(id, ctx->ancestor->node);
if (!element)
return 1;
r = ne_read_simple(ctx, element, size);
if (r != 1)
return r;
storage = (struct ebml_type *) (ctx->ancestor->data + element->offset);
pkt->discard_padding = storage->v.i;
return 1;
}
static uint64_t
ne_buf_read_id(unsigned char const * p, size_t length)
{
@ -1994,34 +2033,40 @@ nestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item,
if (!entry)
return -1;
if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS)
if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS
&& nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS)
return -1;
if (ne_get_binary(entry->codec_private, &codec_private) != 0)
return -1;
p = codec_private.data;
count = *p++ + 1;
if (nestegg_track_codec_id(ctx, track) == NESTEGG_CODEC_VORBIS) {
p = codec_private.data;
count = *p++ + 1;
if (count > 3)
return -1;
if (count > 3)
return -1;
i = 0;
total = 0;
while (--count) {
sizes[i] = ne_xiph_lace_value(&p);
total += sizes[i];
i += 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];
} else {
*data = codec_private.data;
*length = codec_private.length;
}
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];
return 0;
}
@ -2110,6 +2155,14 @@ nestegg_track_audio_params(nestegg * ctx, unsigned int track,
ne_get_uint(entry->audio.bit_depth, &value);
params->depth = value;
value = 0;
ne_get_uint(entry->codec_delay, &value);
params->codec_delay = value;
value = 0;
ne_get_uint(entry->seek_preroll, &value);
params->seek_preroll = value;
return 0;
}
@ -2135,6 +2188,13 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
/* The only DESC_FLAG_SUSPEND fields are Blocks and SimpleBlocks, which we
handle directly. */
r = ne_read_block(ctx, id, size, pkt);
if (r != 1)
return r;
r = ne_read_discard_padding(ctx, *pkt);
if (r != 1)
return r;
return r;
}
@ -2175,6 +2235,13 @@ nestegg_packet_tstamp(nestegg_packet * pkt, uint64_t * tstamp)
return 0;
}
int
nestegg_packet_discard_padding(nestegg_packet * pkt, int64_t * discard_padding)
{
*discard_padding = pkt->discard_padding;
return 0;
}
int
nestegg_packet_count(nestegg_packet * pkt, unsigned int * count)
{