Mercurial > libavformat.hg
changeset 3639:74787fc857be libavformat
matroskadec: use generic parser to parse chapters
author | aurel |
---|---|
date | Tue, 05 Aug 2008 00:40:21 +0000 |
parents | 5897e0c8a1eb |
children | 122a7c807f80 |
files | matroskadec.c |
diffstat | 1 files changed, 51 insertions(+), 150 deletions(-) [+] |
line wrap: on
line diff
--- a/matroskadec.c Tue Aug 05 00:40:18 2008 +0000 +++ b/matroskadec.c Tue Aug 05 00:40:21 2008 +0000 @@ -159,6 +159,13 @@ sizeof(MatroskaSubtitleTrack))) typedef struct { + uint64_t start; + uint64_t end; + uint64_t uid; + char *title; +} MatroskaChapter; + +typedef struct { uint64_t track; uint64_t pos; } MatroskaIndexPos; @@ -183,6 +190,7 @@ /* timescale in the file */ int64_t time_scale; + EbmlList chapters; EbmlList index; /* num_streams is the number of streams that av_new_stream() was called @@ -230,6 +238,37 @@ { 0 } }; +static EbmlSyntax matroska_chapter_display[] = { + { MATROSKA_ID_CHAPSTRING, EBML_UTF8, 0, offsetof(MatroskaChapter,title) }, + { EBML_ID_VOID, EBML_NONE }, + { 0 } +}; + +static EbmlSyntax matroska_chapter_entry[] = { + { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, offsetof(MatroskaChapter,start), {.u=AV_NOPTS_VALUE} }, + { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, offsetof(MatroskaChapter,end), {.u=AV_NOPTS_VALUE} }, + { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaChapter,uid) }, + { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, {.n=matroska_chapter_display} }, + { MATROSKA_ID_CHAPTERFLAGHIDDEN, EBML_NONE }, + { EBML_ID_VOID, EBML_NONE }, + { 0 } +}; + +static EbmlSyntax matroska_chapter[] = { + { MATROSKA_ID_CHAPTERATOM, EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext,chapters), {.n=matroska_chapter_entry} }, + { MATROSKA_ID_EDITIONUID, EBML_NONE }, + { MATROSKA_ID_EDITIONFLAGHIDDEN, EBML_NONE }, + { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE }, + { EBML_ID_VOID, EBML_NONE }, + { 0 } +}; + +static EbmlSyntax matroska_chapters[] = { + { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, {.n=matroska_chapter} }, + { EBML_ID_VOID, EBML_NONE }, + { 0 } +}; + static EbmlSyntax matroska_index_pos[] = { { MATROSKA_ID_CUETRACK, EBML_UINT, 0, offsetof(MatroskaIndexPos,track) }, { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos,pos) }, @@ -2063,154 +2102,18 @@ matroska_parse_chapters(AVFormatContext *s) { MatroskaDemuxContext *matroska = s->priv_data; - int res = 0; - uint32_t id; - - av_log(s, AV_LOG_DEBUG, "parsing chapters...\n"); - - 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) { - case MATROSKA_ID_EDITIONENTRY: { - uint64_t end = AV_NOPTS_VALUE, start = AV_NOPTS_VALUE; - int64_t uid= -1; - char* title = NULL; - /* if there is more than one chapter edition - we take only the first one */ - if(s->chapters) { - ebml_read_skip(matroska); - break; - } - - if ((res = ebml_read_master(matroska, &id)) < 0) - break; - - 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) { - case MATROSKA_ID_CHAPTERATOM: - if ((res = ebml_read_master(matroska, &id)) < 0) - break; - - 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) { - case MATROSKA_ID_CHAPTERTIMEEND: - res = ebml_read_uint(matroska, &id, &end); - break; - - case MATROSKA_ID_CHAPTERTIMESTART: - res = ebml_read_uint(matroska, &id, &start); - break; - - case MATROSKA_ID_CHAPTERDISPLAY: - if ((res = ebml_read_master(matroska, &id)) < 0) - break; - - 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) { - case MATROSKA_ID_CHAPSTRING: - res = ebml_read_utf8(matroska, &id, &title); - break; - - default: - av_log(s, AV_LOG_INFO, "Ignoring unknown Chapter display ID 0x%x\n", id); - case EBML_ID_VOID: - res = ebml_read_skip(matroska); - break; - } - - if (matroska->level_up) { - matroska->level_up--; - break; - } - } - break; - - case MATROSKA_ID_CHAPTERUID: - res = ebml_read_uint(matroska, &id, &uid); - break; - default: - av_log(s, AV_LOG_INFO, "Ignoring unknown Chapter atom ID 0x%x\n", id); - case MATROSKA_ID_CHAPTERFLAGHIDDEN: - case EBML_ID_VOID: - res = ebml_read_skip(matroska); - break; - } - - if (matroska->level_up) { - matroska->level_up--; - break; - } - } - - if (start != AV_NOPTS_VALUE && uid != -1) { - if(!ff_new_chapter(s, uid, (AVRational){1, 1000000000}, start, end, title)) - res= AVERROR(ENOMEM); - } - av_free(title); - break; - - default: - av_log(s, AV_LOG_INFO, "Ignoring unknown Edition entry ID 0x%x\n", id); - case MATROSKA_ID_EDITIONUID: - case MATROSKA_ID_EDITIONFLAGHIDDEN: - case MATROSKA_ID_EDITIONFLAGDEFAULT: - case EBML_ID_VOID: - res = ebml_read_skip(matroska); - break; - } - - - if (matroska->level_up) { - matroska->level_up--; - break; - } - } - break; - } - - default: - av_log(s, AV_LOG_INFO, "Expected an Edition entry (0x%x), but found 0x%x\n", MATROSKA_ID_EDITIONENTRY, id); - case EBML_ID_VOID: - res = ebml_read_skip(matroska); - break; - } - - if (matroska->level_up) { - matroska->level_up--; - break; - } - } + EbmlList *chapters_list = &matroska->chapters; + MatroskaChapter *chapters; + int i, res; + + res = ebml_parse(matroska, matroska_chapters, matroska, MATROSKA_ID_CHAPTERS, 0); + + chapters = chapters_list->elem; + for (i=0; i<chapters_list->nb_elem; i++) + if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid) + ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000}, + chapters[i].start, chapters[i].end, + chapters[i].title); return res; } @@ -2357,8 +2260,6 @@ } case MATROSKA_ID_CHAPTERS: { - if ((res = ebml_read_master(matroska, &id)) < 0) - return res; res = matroska_parse_chapters(s); break; }