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:
parent
4b33422c7b
commit
3279403611
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user