1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-12 01:49:33 +00:00

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.
This commit is contained in:
Uoti Urpala 2009-03-16 23:30:48 +02:00
parent 4b33422c7b
commit 3279403611
3 changed files with 92 additions and 3 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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