summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-03-16 23:30:48 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-03-22 04:42:25 +0200
commit327940361170a4d830bc7c120503cdd0396a125a (patch)
tree725c912fe7452f679f650c00e6f39af6b308f960
parent4b33422c7b004f31eb8fb1962231f69ab6f18445 (diff)
downloadmpv-327940361170a4d830bc7c120503cdd0396a125a.tar.bz2
mpv-327940361170a4d830bc7c120503cdd0396a125a.tar.xz
demux_mkv: Parse ordered chapter information
Parse the ordered chapter structure if present and place the information in the public demuxer structure. Nothing uses the information yet.
-rw-r--r--libmpdemux/demux_mkv.c75
-rw-r--r--libmpdemux/demuxer.h17
-rw-r--r--libmpdemux/ebml.h3
3 files changed, 92 insertions, 3 deletions
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index 9c17751e2e..8f8a53e6da 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -12,7 +12,9 @@
#include <stdio.h>
#include <ctype.h>
#include <inttypes.h>
+#include <stdbool.h>
+#include "talloc.h"
#include "options.h"
#include "stream/stream.h"
#include "demuxer.h"
@@ -405,6 +407,24 @@ static int demux_mkv_read_info(demuxer_t *demuxer)
return 1;
break;
+ case MATROSKA_ID_SEGMENTUID:;
+ l = ebml_read_length(s, &i);
+ length -= i;
+ if (l != sizeof(demuxer->matroska_data.segment_uid)) {
+ mp_msg(MSGT_DEMUX, MSGL_INFO,
+ "[mkv] segment uid invalid length %"PRIu64"\n", l);
+ stream_skip(s, l);
+ } else {
+ stream_read(s, demuxer->matroska_data.segment_uid, l);
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + segment uid");
+ for (int i = 0; i < l; i++)
+ mp_msg(MSGT_DEMUX, MSGL_V, " %02x",
+ demuxer->matroska_data.segment_uid[i]);
+ mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+ }
+ length -= l;
+ break;
+
default:
ebml_read_skip(s, &l);
length -= l;
@@ -1074,10 +1094,11 @@ demux_mkv_read_cues (demuxer_t *demuxer)
return 0;
}
-static uint64_t read_one_chapter(demuxer_t *demuxer, stream_t *s)
+static uint64_t read_one_chapter(struct demuxer *demuxer, stream_t *s)
{
uint64_t len, l;
uint64_t start = 0, end = 0;
+ struct matroska_chapter chapter = {};
char *name = 0;
int i;
uint32_t id;
@@ -1117,6 +1138,24 @@ static uint64_t read_one_chapter(demuxer_t *demuxer, stream_t *s)
}
break;
+ case MATROSKA_ID_CHAPTERSEGMENTUID:
+ l = ebml_read_length(s, &i);
+ len -= l + i;
+ if (l != sizeof(chapter.segment_uid)) {
+ mp_msg(MSGT_DEMUX, MSGL_INFO,
+ "[mkv] chapter segment uid invalid length %"PRIu64"\n",
+ l);
+ stream_skip(s, l);
+ } else {
+ stream_read(s, chapter.segment_uid, l);
+ chapter.has_segment_uid = true;
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Chapter segment uid ");
+ for (int i = 0; i < l; i++)
+ mp_msg(MSGT_DEMUX, MSGL_V, "%02x ", chapter.segment_uid[i]);
+ mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+ }
+ break;
+
default:
ebml_read_skip(s, &l);
len -= l;
@@ -1128,6 +1167,15 @@ static uint64_t read_one_chapter(demuxer_t *demuxer, stream_t *s)
name = strdup("(unnamed)");
int cid = demuxer_add_chapter(demuxer, name, start, end);
+ struct matroska_data *m = &demuxer->matroska_data;
+ m->ordered_chapters = talloc_realloc(demuxer, m->ordered_chapters,
+ struct matroska_chapter,
+ m->num_ordered_chapters + 1);
+ chapter.start = start;
+ chapter.end = end;
+ // Will be undone later if this is a normal chapter rather than ordered
+ m->ordered_chapters[m->num_ordered_chapters] = chapter;
+ m->num_ordered_chapters++;
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Chapter %u from %02d:%02d:%02d."
"%03d to %02d:%02d:%02d.%03d, %s\n",
@@ -1160,13 +1208,23 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n");
length = ebml_read_length(s, NULL);
+ bool have_edition = false;
while (length > 0) {
id = ebml_read_id(s, &i);
length -= i;
switch (id) {
- case MATROSKA_ID_EDITIONENTRY:;
+ case MATROSKA_ID_EDITIONENTRY:
+ if (have_edition) {
+ mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Multiple edition entries"
+ " - ignoring all but first!\n");
+ ebml_read_skip(s, &l);
+ length -= l;
+ break;
+ }
+ have_edition = true;
uint64_t editionlen = ebml_read_length(s, &i);
length -= editionlen + i;
+ bool ordered = false;
while (editionlen > 0) {
id = ebml_read_id(s, &i);
editionlen -= i;
@@ -1174,12 +1232,25 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
case MATROSKA_ID_CHAPTERATOM:
l = read_one_chapter(demuxer, s);
break;
+ case MATROSKA_ID_EDITIONFLAGORDERED:
+ ordered = ebml_read_uint(s, &l);
+ mp_msg(MSGT_DEMUX, MSGL_V,
+ "[mkv] Ordered chapter flag: %d\n", ordered);
+ break;
+
default:
ebml_read_skip(s, &l);
break;
}
editionlen -= l;
}
+ if (!ordered) {
+ // The chapters should be interpreted as normal ones,
+ // so undo the addition of this information.
+ talloc_free(demuxer->matroska_data.ordered_chapters);
+ demuxer->matroska_data.ordered_chapters = NULL;
+ demuxer->matroska_data.num_ordered_chapters = 0;
+ }
break;
default:
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index 4815c8b7d9..8d1f1d0b88 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include "stream/stream.h"
@@ -187,6 +188,18 @@ typedef struct demux_chapter
char* name;
} demux_chapter_t;
+struct matroska_data {
+ unsigned char segment_uid[16];
+ // Ordered chapter information if any
+ struct matroska_chapter {
+ uint64_t start;
+ uint64_t end;
+ bool has_segment_uid;
+ unsigned char segment_uid[16];
+ } *ordered_chapters;
+ int num_ordered_chapters;
+};
+
typedef struct demux_attachment
{
char* name;
@@ -220,10 +233,12 @@ typedef struct demuxer {
demux_chapter_t* chapters;
int num_chapters;
-
+
demux_attachment_t* attachments;
int num_attachments;
+ struct matroska_data matroska_data;
+
void* priv; // fileformat-dependent data
char** info;
struct MPOpts *opts;
diff --git a/libmpdemux/ebml.h b/libmpdemux/ebml.h
index c4d7256d91..345f08b46a 100644
--- a/libmpdemux/ebml.h
+++ b/libmpdemux/ebml.h
@@ -54,6 +54,7 @@
#define MATROSKA_ID_WRITINGAPP 0x5741
#define MATROSKA_ID_MUXINGAPP 0x4D80
#define MATROSKA_ID_DATEUTC 0x4461
+#define MATROSKA_ID_SEGMENTUID 0x73A4
/* ID in the tracks master */
#define MATROSKA_ID_TRACKENTRY 0xAE
@@ -126,11 +127,13 @@
/* IDs in the chapters master */
#define MATROSKA_ID_EDITIONENTRY 0x45B9
+#define MATROSKA_ID_EDITIONFLAGORDERED 0x45DD
#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_CHAPTERSEGMENTUID 0x6E67
/* IDs in the cluster master */
#define MATROSKA_ID_CLUSTERTIMECODE 0xE7