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.c559
1 files changed, 296 insertions, 263 deletions
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index 627ac7cd44..27e564578e 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"
@@ -41,8 +44,7 @@
#include "subreader.h"
#include "libvo/sub.h"
-#include "libass/ass.h"
-#include "libass/ass_mp.h"
+#include "ass_mp.h"
#include "libavutil/common.h"
@@ -55,7 +57,7 @@
#endif
#include "libavutil/lzo.h"
-#include "libavutil/intreadwrite.h"
+#include "ffmpeg_files/intreadwrite.h"
#include "libavutil/avstring.h"
static const unsigned char sipr_swaps[38][2]={
@@ -70,13 +72,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
{
@@ -98,25 +99,25 @@ typedef struct mkv_track
int type;
uint32_t v_width, v_height, v_dwidth, v_dheight;
- float v_frate;
+ double v_frate;
uint32_t a_formattag;
uint32_t a_channels, a_bps;
float a_sfreq;
- float default_duration;
+ double default_duration;
int default_track;
- void *private_data;
+ unsigned char *private_data;
unsigned int private_size;
/* stuff for realmedia */
int realmedia;
int64_t rv_kf_base;
int rv_kf_pts;
- float rv_pts; /* previous video timestamp */
- float ra_pts; /* previous audio timestamp */
+ double rv_pts; /* previous video timestamp */
+ double ra_pts; /* previous audio timestamp */
/** realaudio descrambling */
int sub_packet_size; ///< sub packet size, per stream
@@ -124,13 +125,13 @@ typedef struct mkv_track
int coded_framesize; ///< coded frame size, per stream
int audiopk_size; ///< audio packet size
unsigned char *audio_buf; ///< place to store reordered audio data
- float *audio_timestamp; ///< timestamp for each audio packet
+ double *audio_timestamp; ///< timestamp for each audio packet
int sub_packet_cnt; ///< number of subpacket already received
int audio_filepos; ///< file position of first audio packet in block
/* stuff for quicktime */
int fix_i_bps;
- float qt_last_a_pts;
+ double qt_last_a_pts;
int subtitle_type;
@@ -140,7 +141,7 @@ typedef struct mkv_track
int reorder_timecodes;
demux_packet_t **cached_dps;
int num_cached_dps, num_allocated_dps;
- float max_pts;
+ double max_pts;
/* generic content encoding support */
mkv_content_encoding_t *encodings;
@@ -160,14 +161,13 @@ typedef struct mkv_demuxer
{
off_t segment_start;
- float duration, last_pts;
+ double duration, last_pts;
uint64_t last_filepos;
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 +186,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 +195,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 +229,9 @@ add_cluster_position (mkv_demuxer_t *mkv_d, uint64_t position)
if (mkv_d->cluster_positions[i] == position)
return;
- grow_array((void **)&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 +321,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 +338,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 +370,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 +388,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 +558,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 +1089,8 @@ demux_mkv_read_cues (demuxer_t *demuxer)
if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID
&& pos != EBML_UINT_INVALID)
{
- grow_array((void **)&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 +1105,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 +1547,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 +1575,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 +1686,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;
@@ -1662,7 +1709,7 @@ demux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid)
sh_v->disp_w = track->v_width;
sh_v->disp_h = track->v_height;
if (track->v_dheight)
- sh_v->aspect = (float)track->v_dwidth / (float)track->v_dheight;
+ sh_v->aspect = (double)track->v_dwidth / track->v_dheight;
}
else
{
@@ -1757,8 +1804,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');
@@ -1778,7 +1825,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;
@@ -1882,7 +1929,7 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid)
else
{
sh_a->codecdata_len = 2;
- track->default_duration = 1024.0 / (float)sh_a->samplerate;
+ track->default_duration = 1024.0 / sh_a->samplerate;
}
}
else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) /* VORBIS */
@@ -1933,25 +1980,25 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid)
sh_a->wf->nAvgBytesPerSec = atrc_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->sub_packet_size;
track->audio_buf = malloc(track->sub_packet_h * track->audiopk_size);
- track->audio_timestamp = malloc(track->sub_packet_h * sizeof(float));
+ track->audio_timestamp = malloc(track->sub_packet_h * sizeof(double));
break;
case mmioFOURCC('c', 'o', 'o', 'k'):
sh_a->wf->nAvgBytesPerSec = cook_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->sub_packet_size;
track->audio_buf = malloc(track->sub_packet_h * track->audiopk_size);
- track->audio_timestamp = malloc(track->sub_packet_h * sizeof(float));
+ track->audio_timestamp = malloc(track->sub_packet_h * sizeof(double));
break;
case mmioFOURCC('s', 'i', 'p', 'r'):
sh_a->wf->nAvgBytesPerSec = sipr_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->coded_framesize;
track->audio_buf = malloc(track->sub_packet_h * track->audiopk_size);
- track->audio_timestamp = malloc(track->sub_packet_h * sizeof(float));
+ track->audio_timestamp = malloc(track->sub_packet_h * sizeof(double));
break;
case mmioFOURCC('2', '8', '_', '8'):
sh_a->wf->nAvgBytesPerSec = 3600;
sh_a->wf->nBlockAlign = track->coded_framesize;
track->audio_buf = malloc(track->sub_packet_h * track->audiopk_size);
- track->audio_timestamp = malloc(track->sub_packet_h * sizeof(float));
+ track->audio_timestamp = malloc(track->sub_packet_h * sizeof(double));
break;
}
@@ -1967,13 +2014,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);
}
@@ -2036,7 +2083,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;
}
@@ -2044,8 +2091,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)
{
@@ -2135,8 +2180,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;
@@ -2182,14 +2225,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;
}
@@ -2222,7 +2265,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;
}
@@ -2240,22 +2283,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
@@ -2265,6 +2292,8 @@ demux_mkv_open (demuxer_t *demuxer)
demuxer->seekable = 1;
}
+ demuxer->accurate_seek = true;
+
return DEMUXER_TYPE_MATROSKA;
}
@@ -2386,15 +2415,15 @@ 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;
}
sub_utf8 = 1;
dp = new_demux_packet(size);
memcpy(dp->buffer, block, size);
- dp->pts = timecode / 1000.0f;
- dp->endpts = (timecode + block_duration) / 1000.0f;
+ dp->pts = timecode / 1000.0;
+ dp->endpts = (timecode + block_duration) / 1000.0;
ds_add_packet(demuxer->sub, dp);
}
@@ -2553,7 +2582,7 @@ flush_cached_dps (demuxer_t *demuxer, mkv_track_t *track)
ok = 1;
for (i = 1; i < track->num_cached_dps; i++)
if (track->cached_dps[i - 1]->pts > track->cached_dps[i]->pts) {
- float tmp_pts = track->cached_dps[i - 1]->pts;
+ double tmp_pts = track->cached_dps[i - 1]->pts;
track->cached_dps[i - 1]->pts = track->cached_dps[i]->pts;
track->cached_dps[i]->pts = tmp_pts;
ok = 0;
@@ -2627,7 +2656,7 @@ handle_block (demuxer_t *demuxer, uint8_t *block, uint64_t length,
uint32_t *lace_size;
uint8_t laces, flags;
int i, num, tmp, use_this_block = 1;
- float current_pts;
+ double current_pts;
int16_t time;
/* first byte(s): track num */
@@ -2643,13 +2672,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 + 0.5;
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++)
@@ -2872,11 +2897,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;
}
@@ -2932,9 +2952,20 @@ 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.005 : 0.005;
+
free_cached_dps (demuxer);
if (!(flags & SEEK_FACTOR)) /* time in secs */
{
+ mkv_index_t *index = NULL;
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
stream_t *s = demuxer->stream;
int64_t target_timecode = 0, diff, min_diff=0xFFFFFFFFFFFFFFFLL;
@@ -2986,12 +3017,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