mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
matroskadec: use generic parser to parse matroska from toplevel
Originally committed as revision 14571 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
9c25bafacb
commit
ce6f28bd35
@ -209,6 +209,7 @@ typedef struct MatroskaDemuxContext {
|
||||
int metadata_parsed;
|
||||
int index_parsed;
|
||||
int done;
|
||||
int has_cluster_id;
|
||||
|
||||
/* What to skip before effectively reading a packet. */
|
||||
int skip_to_keyframe;
|
||||
@ -407,6 +408,24 @@ static EbmlSyntax matroska_seekhead[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static EbmlSyntax matroska_segment[] = {
|
||||
{ MATROSKA_ID_INFO, EBML_NEST, 0, 0, {.n=matroska_info } },
|
||||
{ MATROSKA_ID_TRACKS, EBML_NEST, 0, 0, {.n=matroska_tracks } },
|
||||
{ MATROSKA_ID_ATTACHMENTS, EBML_NEST, 0, 0, {.n=matroska_attachments} },
|
||||
{ MATROSKA_ID_CHAPTERS, EBML_NEST, 0, 0, {.n=matroska_chapters } },
|
||||
{ MATROSKA_ID_CUES, EBML_NEST, 0, 0, {.n=matroska_index } },
|
||||
{ MATROSKA_ID_TAGS, EBML_NEST, 0, 0, {.n=matroska_tags } },
|
||||
{ MATROSKA_ID_SEEKHEAD, EBML_NEST, 0, 0, {.n=matroska_seekhead } },
|
||||
{ MATROSKA_ID_CLUSTER, EBML_STOP, 0, offsetof(MatroskaDemuxContext,has_cluster_id) },
|
||||
{ EBML_ID_VOID, EBML_NONE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static EbmlSyntax matroska_segments[] = {
|
||||
{ MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, {.n=matroska_segment } },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* The first few functions handle EBML file parsing. The rest
|
||||
* is the document interpretation. Matroska really just is a
|
||||
@ -1151,14 +1170,6 @@ static void ebml_free(EbmlSyntax *syntax, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_parse_info (MatroskaDemuxContext *matroska)
|
||||
{
|
||||
int res = ebml_parse(matroska, matroska_info, matroska, MATROSKA_ID_INFO, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_decode_buffer(uint8_t** buf, int* buf_size, MatroskaTrack *track)
|
||||
{
|
||||
@ -1236,16 +1247,6 @@ matroska_decode_buffer(uint8_t** buf, int* buf_size, MatroskaTrack *track)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_parse_tracks (MatroskaDemuxContext *matroska)
|
||||
{
|
||||
int i, res;
|
||||
|
||||
res = ebml_parse(matroska, matroska_tracks, matroska, MATROSKA_ID_TRACKS, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_parse_index (MatroskaDemuxContext *matroska)
|
||||
{
|
||||
@ -1258,12 +1259,6 @@ matroska_parse_metadata (MatroskaDemuxContext *matroska)
|
||||
return ebml_parse(matroska, matroska_tags, matroska, MATROSKA_ID_TAGS, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_parse_seekhead (MatroskaDemuxContext *matroska)
|
||||
{
|
||||
return ebml_parse(matroska, matroska_seekhead, matroska, MATROSKA_ID_SEEKHEAD, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
matroska_execute_seekhead(MatroskaDemuxContext *matroska)
|
||||
{
|
||||
@ -1347,28 +1342,6 @@ matroska_execute_seekhead(MatroskaDemuxContext *matroska)
|
||||
matroska->level_up = level_up;
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_parse_attachments(AVFormatContext *s)
|
||||
{
|
||||
MatroskaDemuxContext *matroska = s->priv_data;
|
||||
int i, j, res;
|
||||
|
||||
res = ebml_parse(matroska, matroska_attachments, matroska, MATROSKA_ID_ATTACHMENTS, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_parse_chapters(AVFormatContext *s)
|
||||
{
|
||||
MatroskaDemuxContext *matroska = s->priv_data;
|
||||
int i, res;
|
||||
|
||||
res = ebml_parse(matroska, matroska_chapters, matroska, MATROSKA_ID_CHAPTERS, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
matroska_aac_profile (char *codec_id)
|
||||
{
|
||||
@ -1406,10 +1379,9 @@ matroska_read_header (AVFormatContext *s,
|
||||
MatroskaTrack *tracks;
|
||||
EbmlList *index_list;
|
||||
MatroskaIndex *index;
|
||||
int i, j, last_level, res = 0;
|
||||
Ebml ebml = { 0 };
|
||||
AVStream *st;
|
||||
uint32_t id;
|
||||
int i, j;
|
||||
|
||||
matroska->ctx = s;
|
||||
|
||||
@ -1427,107 +1399,8 @@ matroska_read_header (AVFormatContext *s,
|
||||
ebml_free(ebml_syntax, &ebml);
|
||||
|
||||
/* The next thing is a segment. */
|
||||
while (1) {
|
||||
if (!(id = ebml_peek_id(matroska, &last_level)))
|
||||
return AVERROR(EIO);
|
||||
if (id == MATROSKA_ID_SEGMENT)
|
||||
break;
|
||||
|
||||
/* oi! */
|
||||
av_log(matroska->ctx, AV_LOG_INFO,
|
||||
"Expected a Segment ID (0x%x), but received 0x%x!\n",
|
||||
MATROSKA_ID_SEGMENT, id);
|
||||
if ((res = ebml_read_skip(matroska)) < 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* We now have a Matroska segment.
|
||||
* Seeks are from the beginning of the segment,
|
||||
* after the segment ID/length. */
|
||||
if ((res = ebml_read_master(matroska, &id)) < 0)
|
||||
return res;
|
||||
matroska->segment_start = url_ftell(s->pb);
|
||||
|
||||
matroska->time_scale = 1000000;
|
||||
/* we've found our segment, start reading the different contents in here */
|
||||
while (res == 0) {
|
||||
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
|
||||
res = AVERROR(EIO);
|
||||
break;
|
||||
} else if (matroska->level_up) {
|
||||
matroska->level_up--;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
/* stream info */
|
||||
case MATROSKA_ID_INFO: {
|
||||
res = matroska_parse_info(matroska);
|
||||
break;
|
||||
}
|
||||
|
||||
/* track info headers */
|
||||
case MATROSKA_ID_TRACKS: {
|
||||
res = matroska_parse_tracks(matroska);
|
||||
break;
|
||||
}
|
||||
|
||||
/* stream index */
|
||||
case MATROSKA_ID_CUES: {
|
||||
if (!matroska->index_parsed) {
|
||||
res = matroska_parse_index(matroska);
|
||||
} else
|
||||
res = ebml_read_skip(matroska);
|
||||
break;
|
||||
}
|
||||
|
||||
/* metadata */
|
||||
case MATROSKA_ID_TAGS: {
|
||||
if (!matroska->metadata_parsed) {
|
||||
res = matroska_parse_metadata(matroska);
|
||||
} else
|
||||
res = ebml_read_skip(matroska);
|
||||
break;
|
||||
}
|
||||
|
||||
/* file index (if seekable, seek to Cues/Tags to parse it) */
|
||||
case MATROSKA_ID_SEEKHEAD: {
|
||||
res = matroska_parse_seekhead(matroska);
|
||||
break;
|
||||
}
|
||||
|
||||
case MATROSKA_ID_ATTACHMENTS: {
|
||||
res = matroska_parse_attachments(s);
|
||||
break;
|
||||
}
|
||||
|
||||
case MATROSKA_ID_CLUSTER: {
|
||||
/* Do not read the master - this will be done in the next
|
||||
* call to matroska_read_packet. */
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case MATROSKA_ID_CHAPTERS: {
|
||||
res = matroska_parse_chapters(s);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
av_log(matroska->ctx, AV_LOG_INFO,
|
||||
"Unknown matroska file header ID 0x%x\n", id);
|
||||
/* fall-through */
|
||||
|
||||
case EBML_ID_VOID:
|
||||
res = ebml_read_skip(matroska);
|
||||
break;
|
||||
}
|
||||
|
||||
if (matroska->level_up) {
|
||||
matroska->level_up--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ebml_parse(matroska, matroska_segments, matroska, 0, 1) < 0)
|
||||
return -1;
|
||||
matroska_execute_seekhead(matroska);
|
||||
|
||||
/* Have we found a cluster? */
|
||||
@ -1781,7 +1654,6 @@ matroska_read_header (AVFormatContext *s,
|
||||
|
||||
/* What do we do with private data? E.g. for Vorbis. */
|
||||
}
|
||||
res = 0;
|
||||
|
||||
attachements = attachements_list->elem;
|
||||
for (j=0; j<attachements_list->nb_elem; j++) {
|
||||
@ -1834,7 +1706,7 @@ matroska_read_header (AVFormatContext *s,
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2291,8 +2163,7 @@ matroska_read_close (AVFormatContext *s)
|
||||
for (n=0; n < matroska->tracks.nb_elem; n++)
|
||||
if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO)
|
||||
av_free(tracks[n].audio.buf);
|
||||
ebml_free(matroska_tracks, matroska);
|
||||
ebml_free(matroska_index, matroska);
|
||||
ebml_free(matroska_segment, matroska);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user