[FFmpeg-cvslog] r13241 - in trunk/libavformat: matroska.h matroskadec.c
aurel
subversion
Fri May 23 00:07:09 CEST 2008
Author: aurel
Date: Fri May 23 00:07:09 2008
New Revision: 13241
Log:
demux chapters out of matroska
patch by Anton Khirnov wyskas _at_ gmail _dot_ com
Modified:
trunk/libavformat/matroska.h
trunk/libavformat/matroskadec.c
Modified: trunk/libavformat/matroska.h
==============================================================================
--- trunk/libavformat/matroska.h (original)
+++ trunk/libavformat/matroska.h Fri May 23 00:07:09 2008
@@ -57,6 +57,7 @@
#define MATROSKA_ID_SEEKHEAD 0x114D9B74
#define MATROSKA_ID_ATTACHMENTS 0x1941A469
#define MATROSKA_ID_CLUSTER 0x1F43B675
+#define MATROSKA_ID_CHAPTERS 0x1043A770
/* IDs in the info master */
#define MATROSKA_ID_TIMECODESCALE 0x2AD7B1
@@ -155,6 +156,18 @@
#define MATROSKA_ID_FILEDATA 0x465C
#define MATROSKA_ID_FILEUID 0x46AE
+/* IDs in the chapters master */
+#define MATROSKA_ID_EDITIONENTRY 0x45B9
+#define MATROSKA_ID_CHAPTERATOM 0xB6
+#define MATROSKA_ID_CHAPTERTIMESTART 0x91
+#define MATROSKA_ID_CHAPTERTIMEEND 0x92
+#define MATROSKA_ID_CHAPTERDISPLAY 0x80
+#define MATROSKA_ID_CHAPSTRING 0x85
+#define MATROSKA_ID_EDITIONUID 0x45BC
+#define MATROSKA_ID_EDITIONFLAGHIDDEN 0x45BD
+#define MATROSKA_ID_CHAPTERUID 0x73C4
+#define MATROSKA_ID_CHAPTERFLAGHIDDEN 0x98
+
typedef enum {
MATROSKA_TRACK_TYPE_NONE = 0x0,
MATROSKA_TRACK_TYPE_VIDEO = 0x1,
Modified: trunk/libavformat/matroskadec.c
==============================================================================
--- trunk/libavformat/matroskadec.c (original)
+++ trunk/libavformat/matroskadec.c Fri May 23 00:07:09 2008
@@ -2139,6 +2139,156 @@ matroska_parse_attachments(AVFormatConte
return res;
}
+static int
+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;
+ 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;
+
+ default:
+ av_log(s, AV_LOG_INFO, "Ignoring unknown Chapter atom ID 0x%x\n", id);
+ case MATROSKA_ID_CHAPTERUID:
+ 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 && end != AV_NOPTS_VALUE)
+ res = ff_new_chapter(s, start * AV_TIME_BASE / 1000000000 , end * AV_TIME_BASE / 1000000000, title ? title : "(unnamed)");
+ 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 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;
+ }
+ }
+
+ return res;
+}
+
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
static int
@@ -2291,6 +2441,13 @@ matroska_read_header (AVFormatContext
break;
}
+ case MATROSKA_ID_CHAPTERS: {
+ if ((res = ebml_read_master(matroska, &id)) < 0)
+ return res;
+ res = matroska_parse_chapters(s);
+ break;
+ }
+
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown matroska file header ID 0x%x\n", id);
More information about the ffmpeg-cvslog
mailing list