summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_mkv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpdemux/demux_mkv.c')
-rw-r--r--libmpdemux/demux_mkv.c513
1 files changed, 273 insertions, 240 deletions
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index cb4d971755..4f44646b56 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -27,7 +27,10 @@
#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"
#include "stheader.h"
@@ -70,13 +73,12 @@ static const unsigned char sipr_swaps[38][2]={
#define ATRC_FLAVORS 8
#define COOK_FLAVORS 34
static const int sipr_fl2bps[SIPR_FLAVORS] = {813, 1062, 625, 2000};
-static const int atrc_fl2bps[ATRC_FLAVORS] =
- {8269, 11714, 13092, 16538, 18260, 22050, 33075, 44100};
-static const int cook_fl2bps[COOK_FLAVORS] =
- { 1000, 1378, 2024, 2584, 4005, 5513, 8010, 4005, 750, 2498,
- 4048, 5513, 8010, 11973, 8010, 2584, 4005, 2067, 2584, 2584,
- 4005, 4005, 5513, 5513, 8010, 12059, 1550, 8010, 12059, 5513,
- 12016, 16408, 22911, 33506};
+static const int atrc_fl2bps[ATRC_FLAVORS] = {8269, 11714, 13092, 16538, 18260, 22050, 33075, 44100};
+static const int cook_fl2bps[COOK_FLAVORS] = {
+ 1000, 1378, 2024, 2584, 4005, 5513, 8010, 4005, 750, 2498,
+ 4048, 5513, 8010, 11973, 8010, 2584, 4005, 2067, 2584, 2584,
+ 4005, 4005, 5513, 5513, 8010, 12059, 1550, 8010, 12059, 5513,
+ 12016, 16408, 22911, 33506};
typedef struct
{
@@ -108,7 +110,7 @@ typedef struct mkv_track
int default_track;
- void *private_data;
+ unsigned char *private_data;
unsigned int private_size;
/* stuff for realmedia */
@@ -166,8 +168,7 @@ typedef struct mkv_demuxer
mkv_track_t **tracks;
int num_tracks;
- uint64_t tc_scale, cluster_tc, first_tc;
- int has_first_tc;
+ uint64_t tc_scale, cluster_tc;
uint64_t cluster_size;
uint64_t blockgroup_size;
@@ -186,8 +187,6 @@ typedef struct mkv_demuxer
int64_t skip_to_timecode;
int v_skip_to_keyframe, a_skip_to_keyframe;
- int64_t stop_timecode;
-
int last_aid;
int audio_tracks[MAX_A_STREAMS];
} mkv_demuxer_t;
@@ -197,20 +196,16 @@ typedef struct mkv_demuxer
#define RAPROPERTIES4_SIZE 56
#define RAPROPERTIES5_SIZE 70
-/* for e.g. "-slang ger" */
-extern char *dvdsub_lang;
-extern char *audio_lang;
-extern int dvdsub_id;
-
/**
* \brief ensures there is space for at least one additional element
* \param array array to grow
* \param nelem current number of elements in array
* \param elsize size of one array element
*/
-static void grow_array(void **array, int nelem, size_t elsize) {
+static void *grow_array(void *array, int nelem, size_t elsize) {
if (!(nelem & 31))
- *array = realloc(*array, (nelem + 32) * elsize);
+ array = realloc(array, (nelem + 32) * elsize);
+ return array;
}
static mkv_track_t *
@@ -235,8 +230,9 @@ add_cluster_position (mkv_demuxer_t *mkv_d, uint64_t position)
if (mkv_d->cluster_positions[i] == position)
return;
- grow_array(&mkv_d->cluster_positions, mkv_d->num_cluster_pos,
- sizeof(uint64_t));
+ mkv_d->cluster_positions = grow_array(mkv_d->cluster_positions,
+ mkv_d->num_cluster_pos,
+ sizeof(uint64_t));
mkv_d->cluster_positions[mkv_d->num_cluster_pos++] = position;
}
@@ -326,8 +322,8 @@ demux_mkv_decode (mkv_track_t *track, uint8_t *src, uint8_t **dest,
zstream.opaque = (voidpf) 0;
if (inflateInit (&zstream) != Z_OK)
{
- mp_msg (MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_ZlibInitializationFailed);
+ mp_tmsg (MSGT_DEMUX, MSGL_WARN,
+ "[mkv] zlib initialization failed.\n");
return modified;
}
zstream.next_in = (Bytef *) src;
@@ -343,8 +339,8 @@ demux_mkv_decode (mkv_track_t *track, uint8_t *src, uint8_t **dest,
result = inflate (&zstream, Z_NO_FLUSH);
if (result != Z_OK && result != Z_STREAM_END)
{
- mp_msg (MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_ZlibDecompressionFailed);
+ mp_tmsg (MSGT_DEMUX, MSGL_WARN,
+ "[mkv] zlib decompression failed.\n");
free(*dest);
*dest = NULL;
inflateEnd (&zstream);
@@ -375,8 +371,8 @@ demux_mkv_decode (mkv_track_t *track, uint8_t *src, uint8_t **dest,
if (!(result & AV_LZO_OUTPUT_FULL))
{
lzo_fail:
- mp_msg (MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_LzoDecompressionFailed);
+ mp_tmsg (MSGT_DEMUX, MSGL_WARN,
+ "[mkv] lzo decompression failed.\n");
free(*dest);
*dest = NULL;
return modified;
@@ -393,52 +389,67 @@ lzo_fail:
}
-static int
-demux_mkv_read_info (demuxer_t *demuxer)
+static int demux_mkv_read_info(demuxer_t *demuxer)
{
- mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
- stream_t *s = demuxer->stream;
- uint64_t length, l;
- int il;
- uint64_t tc_scale = 1000000;
- long double duration = 0.;
-
- length = ebml_read_length (s, NULL);
- while (length > 0)
- {
- switch (ebml_read_id (s, &il))
- {
+ mkv_demuxer_t *mkv_d = demuxer->priv;
+ stream_t *s = demuxer->stream;
+ uint64_t length, l;
+ int i;
+ uint64_t tc_scale = 1000000;
+ long double duration = 0.;
+
+ length = ebml_read_length(s, NULL);
+ while (length > 0) {
+ uint32_t id = ebml_read_id(s, &i);
+ length -= i;
+ switch (id) {
case MATROSKA_ID_TIMECODESCALE:
- {
- uint64_t num = ebml_read_uint (s, &l);
- if (num == EBML_UINT_INVALID)
- return 1;
- tc_scale = num;
- mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + timecode scale: %"PRIu64"\n",
+ tc_scale = ebml_read_uint(s, &l);
+ length -= l;
+ if (tc_scale == EBML_UINT_INVALID)
+ return 1;
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + timecode scale: %"PRIu64"\n",
tc_scale);
break;
- }
case MATROSKA_ID_DURATION:
- {
- long double num = ebml_read_float (s, &l);
- if (num == EBML_FLOAT_INVALID)
- return 1;
- duration = num;
- mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3Lfs\n",
- duration * tc_scale / 1000000000.0);
+ duration = ebml_read_float(s, &l);
+ length -= l;
+ if (duration == EBML_FLOAT_INVALID)
+ 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);
- break;
+ ebml_read_skip(s, &l);
+ length -= l;
+ break;
}
- length -= l + il;
}
- mkv_d->tc_scale = tc_scale;
- mkv_d->duration = duration * tc_scale / 1000000000.0;
- return 0;
+ mkv_d->tc_scale = tc_scale;
+ mkv_d->duration = duration * tc_scale / 1000000000.0;
+ if (duration)
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3fs\n",
+ mkv_d->duration);
+
+ return 0;
}
/**
@@ -548,26 +559,26 @@ demux_mkv_read_trackencodings (demuxer_t *demuxer, mkv_track_t *track)
if (e.type == 1)
{
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_TrackEncrypted, track->tnum);
+ mp_tmsg(MSGT_DEMUX, MSGL_WARN,
+ "[mkv] Track number %u has been encrypted and decryption has not yet been\n[mkv] implemented. Skipping track.\n", track->tnum);
}
else if (e.type != 0)
{
- mp_msg(MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_UnknownContentEncoding, track->tnum);
+ mp_tmsg(MSGT_DEMUX, MSGL_WARN,
+ "[mkv] Unknown content encoding type for track %u. Skipping track.\n", track->tnum);
}
if (e.comp_algo != 0 && e.comp_algo != 2)
{
- mp_msg (MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_UnknownCompression,
+ mp_tmsg (MSGT_DEMUX, MSGL_WARN,
+ "[mkv] Track %u has been compressed with an unknown/unsupported compression\n[mkv] algorithm (%u). Skipping track.\n",
track->tnum, e.comp_algo);
}
#if !CONFIG_ZLIB
else if (e.comp_algo == 0)
{
- mp_msg (MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_ZlibCompressionUnsupported,
+ mp_tmsg (MSGT_DEMUX, MSGL_WARN,
+ "[mkv] Track %u was compressed with zlib but mplayer has not been compiled\n[mkv] with support for zlib compression. Skipping track.\n",
track->tnum);
}
#endif
@@ -1079,7 +1090,8 @@ demux_mkv_read_cues (demuxer_t *demuxer)
if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID
&& pos != EBML_UINT_INVALID)
{
- grow_array(&mkv_d->indexes, mkv_d->num_indexes, sizeof(mkv_index_t));
+ mkv_d->indexes = grow_array(mkv_d->indexes, mkv_d->num_indexes,
+ sizeof(mkv_index_t));
mkv_d->indexes[mkv_d->num_indexes].tnum = track;
mkv_d->indexes[mkv_d->num_indexes].timecode = time;
mkv_d->indexes[mkv_d->num_indexes].filepos =mkv_d->segment_start+pos;
@@ -1094,140 +1106,175 @@ demux_mkv_read_cues (demuxer_t *demuxer)
return 0;
}
-static int
-demux_mkv_read_chapters (demuxer_t *demuxer)
+static uint64_t read_one_chapter(struct demuxer *demuxer, stream_t *s)
{
- stream_t *s = demuxer->stream;
- uint64_t length, l;
- int il;
-
- if (demuxer->chapters)
- {
- ebml_read_skip (s, NULL);
- return 0;
- }
-
- mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n");
- length = ebml_read_length (s, NULL);
-
- while (length > 0)
- {
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_EDITIONENTRY:
- {
- uint64_t len;
- int i;
-
- len = ebml_read_length (s, &i);
- l = len + i;
+ uint64_t len, l;
+ uint64_t start = 0, end = 0;
+ struct matroska_chapter chapter = {};
+ char *name = 0;
+ int i;
+ uint32_t id;
+
+ len = ebml_read_length(s, &i);
+ uint64_t bytes_read = len + i;
+
+ while (len > 0) {
+ id = ebml_read_id(s, &i);
+ len -= i;
+ switch (id) {
+ case MATROSKA_ID_CHAPTERTIMESTART:
+ start = ebml_read_uint(s, &l) / 1000000;
+ len -= l;
+ break;
- while (len > 0)
- {
- uint64_t l;
- int il;
+ case MATROSKA_ID_CHAPTERTIMEEND:
+ end = ebml_read_uint(s, &l) / 1000000;
+ len -= l;
+ break;
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_CHAPTERATOM:
- {
- uint64_t len, start=0, end=0;
- char* name = 0;
- int i;
- int cid;
+ case MATROSKA_ID_CHAPTERDISPLAY:;
+ uint64_t displaylen = ebml_read_length(s, &i);
+ len -= displaylen + i;
+ while (displaylen > 0) {
+ id = ebml_read_id(s, &i);
+ displaylen -= i;
+ switch (id) {
+ case MATROSKA_ID_CHAPSTRING:
+ name = ebml_read_utf8(s, &l);
+ break;
+ default:
+ ebml_read_skip(s, &l);
+ break;
+ }
+ displaylen -= l;
+ }
+ break;
- len = ebml_read_length (s, &i);
- l = len + i;
+ 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;
- while (len > 0)
- {
- uint64_t l;
- int il;
+ default:
+ ebml_read_skip(s, &l);
+ len -= l;
+ break;
+ }
+ }
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_CHAPTERTIMESTART:
- start = ebml_read_uint (s, &l) / 1000000;
- break;
+ if (!name)
+ 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;
+ chapter.name = talloc_strdup(m->ordered_chapters, name);
+ // 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",
+ cid,
+ (int) (start / 60 / 60 / 1000),
+ (int) ((start / 60 / 1000) % 60),
+ (int) ((start / 1000) % 60),
+ (int) (start % 1000),
+ (int) (end / 60 / 60 / 1000),
+ (int) ((end / 60 / 1000) % 60),
+ (int) ((end / 1000) % 60),
+ (int) (end % 1000), name);
+
+ free(name);
+ return bytes_read;
+}
- case MATROSKA_ID_CHAPTERTIMEEND:
- end = ebml_read_uint (s, &l) / 1000000;
- break;
+static int demux_mkv_read_chapters(struct demuxer *demuxer)
+{
+ stream_t *s = demuxer->stream;
+ uint64_t length, l;
+ int i;
+ uint32_t id;
- case MATROSKA_ID_CHAPTERDISPLAY:
- {
- uint64_t len;
- int i;
-
- len = ebml_read_length (s, &i);
- l = len + i;
- while (len > 0)
- {
- uint64_t l;
- int il;
-
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_CHAPSTRING:
- name = ebml_read_utf8 (s, &l);
- break;
- default:
- ebml_read_skip (s, &l);
- break;
- }
- len -= l + il;
- }
- }
- break;
+ if (demuxer->chapters) {
+ ebml_read_skip(s, NULL);
+ return 0;
+ }
- default:
- ebml_read_skip (s, &l);
- break;
- }
- len -= l + il;
- }
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n");
+ length = ebml_read_length(s, NULL);
- if (!name)
- name = strdup("(unnamed)");
-
- cid = demuxer_add_chapter(demuxer, name, start, end);
-
- mp_msg(MSGT_DEMUX, MSGL_V,
- "[mkv] Chapter %u from %02d:%02d:%02d."
- "%03d to %02d:%02d:%02d.%03d, %s\n",
- cid,
- (int) (start / 60 / 60 / 1000),
- (int) ((start / 60 / 1000) % 60),
- (int) ((start / 1000) % 60),
- (int) (start % 1000),
- (int) (end / 60 / 60 / 1000),
- (int) ((end / 60 / 1000) % 60),
- (int) ((end / 1000) % 60),
- (int) (end % 1000), name);
-
- free(name);
- break;
- }
+ bool have_edition = false;
+ while (length > 0) {
+ id = ebml_read_id(s, &i);
+ length -= i;
+ switch (id) {
+ 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;
+ switch (id) {
+ 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);
+ default:
+ ebml_read_skip(s, &l);
break;
- }
- len -= l + il;
- }
+ }
+ 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:
- ebml_read_skip (s, &l);
- break;
+ ebml_read_skip(s, &l);
+ length -= l;
+ break;
}
-
- length -= l + il;
}
- mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing chapters ] ---------\n");
- return 0;
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing chapters ] ---------\n");
+ return 0;
}
static int
@@ -1501,10 +1548,10 @@ display_create_tracks (demuxer_t *demuxer)
break;
}
if (mkv_d->tracks[i]->name)
- mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_TrackIDName,
+ mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] Track ID %u: %s (%s) \"%s\", %s\n",
mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id, mkv_d->tracks[i]->name, str);
else
- mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_TrackID,
+ mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] Track ID %u: %s (%s), %s\n",
mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id, str);
}
}
@@ -1529,6 +1576,7 @@ static const videocodec_info_t vinfo[] = {
static int
demux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid)
{
+ struct MPOpts *opts = demuxer->opts;
BITMAPINFOHEADER *bih;
void *ImageDesc = NULL;
sh_video_t *sh_v;
@@ -1639,9 +1687,9 @@ demux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid)
bih = realloc (bih, bih->biSize);
memcpy (bih + 1, track->private_data, track->private_size);
}
- track->reorder_timecodes = user_correct_pts == 0;
+ track->reorder_timecodes = opts->user_correct_pts == 0;
if (!vi->id) {
- mp_msg (MSGT_DEMUX,MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCodecID,
+ mp_tmsg (MSGT_DEMUX,MSGL_WARN, "[mkv] Unknown/unsupported CodecID (%s) or missing/bad CodecPrivate\n[mkv] data (track %u).\n",
track->codec_id, track->tnum);
free(bih);
return 1;
@@ -1755,8 +1803,8 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid)
{
if (track->private_data == NULL || track->private_size == 0)
{
- mp_msg (MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_FlacTrackDoesNotContainValidHeaders);
+ mp_tmsg (MSGT_DEMUX, MSGL_WARN,
+ "[mkv] FLAC track does not contain valid headers.\n");
return 1;
}
track->a_formattag = mmioFOURCC ('f', 'L', 'a', 'C');
@@ -1776,7 +1824,7 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid)
}
else
{
- mp_msg (MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownAudioCodec,
+ mp_tmsg (MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported audio codec ID '%s' for track %u or missing/faulty\n[mkv] private codec data.\n",
track->codec_id, track->tnum);
free_sh_audio(demuxer, track->tnum);
return 1;
@@ -1965,13 +2013,13 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid)
if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C'))
{
- ptr = (unsigned char *)track->private_data;
+ ptr = track->private_data;
size = track->private_size;
}
else
{
sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
- ptr = (unsigned char *) track->private_data
+ ptr = track->private_data
+ sizeof (WAVEFORMATEX);
size = track->private_size - sizeof (WAVEFORMATEX);
}
@@ -2033,7 +2081,7 @@ demux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track, int sid)
}
else
{
- mp_msg (MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_MKV_SubtitleTypeNotSupported,
+ mp_tmsg (MSGT_DEMUX, MSGL_ERR, "[mkv] Subtitle type '%s' is not supported.\n",
track->codec_id);
return 1;
}
@@ -2041,8 +2089,6 @@ demux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track, int sid)
return 0;
}
-static void demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags);
-
static int
demux_mkv_open (demuxer_t *demuxer)
{
@@ -2132,8 +2178,6 @@ demux_mkv_open (demuxer_t *demuxer)
uint64_t num = ebml_read_uint (s, NULL);
if (num == EBML_UINT_INVALID)
return 0;
- mkv_d->first_tc = num * mkv_d->tc_scale / 1000000.0;
- mkv_d->has_first_tc = 1;
}
stream_seek (s, p - 4);
cont = 1;
@@ -2179,14 +2223,14 @@ demux_mkv_open (demuxer_t *demuxer)
if (track && demuxer->v_streams[track->tnum])
{
- mp_msg (MSGT_DEMUX, MSGL_INFO,
- MSGTR_MPDEMUX_MKV_WillPlayVideoTrack, track->tnum);
+ mp_tmsg (MSGT_DEMUX, MSGL_INFO,
+ "[mkv] Will play video track %u.\n", track->tnum);
demuxer->video->id = track->tnum;
demuxer->video->sh = demuxer->v_streams[track->tnum];
}
else
{
- mp_msg (MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_NoVideoTrackFound);
+ mp_tmsg (MSGT_DEMUX, MSGL_INFO, "[mkv] No video track found/wanted.\n");
demuxer->video->id = -2;
}
@@ -2219,7 +2263,7 @@ demux_mkv_open (demuxer_t *demuxer)
}
else
{
- mp_msg (MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_NoAudioTrackFound);
+ mp_tmsg (MSGT_DEMUX, MSGL_INFO, "[mkv] No audio track found/wanted.\n");
demuxer->audio->id = -2;
}
@@ -2237,22 +2281,6 @@ demux_mkv_open (demuxer_t *demuxer)
}
}
- if (demuxer->chapters)
- {
- for (i=0; i < (int)demuxer->num_chapters; i++)
- {
- demuxer->chapters[i].start -= mkv_d->first_tc;
- demuxer->chapters[i].end -= mkv_d->first_tc;
- }
- if (dvd_last_chapter > 0 && dvd_last_chapter <= demuxer->num_chapters)
- {
- if (demuxer->chapters[dvd_last_chapter-1].end != 0)
- mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter-1].end;
- else if (dvd_last_chapter + 1 <= demuxer->num_chapters)
- mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter].start;
- }
- }
-
if (s->end_pos == 0 || (mkv_d->indexes == NULL && index_mode < 0))
demuxer->seekable = 0;
else
@@ -2262,6 +2290,8 @@ demux_mkv_open (demuxer_t *demuxer)
demuxer->seekable = 1;
}
+ demuxer->accurate_seek = true;
+
return DEMUXER_TYPE_MATROSKA;
}
@@ -2383,7 +2413,7 @@ handle_subtitles(demuxer_t *demuxer, mkv_track_t *track, char *block,
if (block_duration == 0)
{
mp_msg (MSGT_DEMUX, MSGL_WARN,
- MSGTR_MPDEMUX_MKV_NoBlockDurationForSubtitleTrackFound);
+ "[mkv] Warning: No BlockDuration for subtitle track found.\n");
return;
}
@@ -2640,13 +2670,9 @@ handle_block (demuxer_t *demuxer, uint8_t *block, uint64_t length,
return 0;
block += old_length - length;
- tc = ((time*mkv_d->tc_scale+mkv_d->cluster_tc) /1000000.0 - mkv_d->first_tc);
+ tc = ((time*mkv_d->tc_scale+mkv_d->cluster_tc) /1000000.0);
if (tc < 0)
tc = 0;
- if (mkv_d->stop_timecode > 0 && tc > mkv_d->stop_timecode) {
- free(lace_size);
- return -1;
- }
current_pts = tc / 1000.0;
for (i=0; i<mkv_d->num_tracks; i++)
@@ -2869,11 +2895,6 @@ demux_mkv_fill_buffer (demuxer_t *demuxer, demux_stream_t *ds)
uint64_t num = ebml_read_uint (s, &l);
if (num == EBML_UINT_INVALID)
return 0;
- if (!mkv_d->has_first_tc)
- {
- mkv_d->first_tc = num * mkv_d->tc_scale / 1000000.0;
- mkv_d->has_first_tc = 1;
- }
mkv_d->cluster_tc = num * mkv_d->tc_scale;
break;
}
@@ -2929,6 +2950,16 @@ demux_mkv_fill_buffer (demuxer_t *demuxer, demux_stream_t *ds)
static void
demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
{
+ if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
+ if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0)
+ flags |= SEEK_BACKWARD;
+ else
+ flags |= SEEK_FORWARD;
+ }
+ // Adjust the target a little bit to catch cases where the target position
+ // specifies a keyframe with high, but not perfect, precision.
+ rel_seek_secs += flags & SEEK_FORWARD ? -0.001 : 0.001;
+
free_cached_dps (demuxer);
if (!(flags & SEEK_FACTOR)) /* time in secs */
{
@@ -2983,12 +3014,12 @@ demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int
for (i=0; i < mkv_d->num_cluster_pos; i++)
{
diff = mkv_d->cluster_positions[i] - target_filepos;
- if (rel_seek_secs < 0 && diff < 0 && -diff < min_diff)
+ if (flags & SEEK_BACKWARD && diff < 0 && -diff < min_diff)
{
cluster_pos = mkv_d->cluster_positions[i];
min_diff = -diff;
}
- else if (rel_seek_secs > 0
+ else if (flags & SEEK_FORWARD
&& (diff < 0 ? -1 * diff : diff) < min_diff)
{
cluster_pos = mkv_d->cluster_positions[i];
@@ -3009,17 +3040,17 @@ demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int
for (i=0; i < mkv_d->num_indexes; i++)
if (mkv_d->indexes[i].tnum == seek_id)
{
- diff = target_timecode + mkv_d->first_tc -
+ diff = target_timecode -
(int64_t) mkv_d->indexes[i].timecode * mkv_d->tc_scale / 1000000.0;
- if ((flags & SEEK_ABSOLUTE || target_timecode <= mkv_d->last_pts*1000)) {
- // Absolute seek or seek backward: find the last index
- // position before target time
+ if (flags & SEEK_BACKWARD) {
+ // Seek backward: find the last index position
+ // before target time
if (diff < 0 || diff >= min_diff)
continue;
}
else {
- // Relative seek forward: find the first index position
+ // Seek forward: find the first index position
// after target time. If no such index exists, find last
// position between current position and target time.
if (diff <= 0) {
@@ -3043,8 +3074,10 @@ demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int
if (demuxer->video->id >= 0)
mkv_d->v_skip_to_keyframe = 1;
- if (rel_seek_secs > 0.0)
+ if (flags & SEEK_FORWARD)
mkv_d->skip_to_timecode = target_timecode;
+ else
+ mkv_d->skip_to_timecode = 0;
mkv_d->a_skip_to_keyframe = 1;
demux_mkv_fill_buffer(demuxer, NULL);