summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authormosu <mosu@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-08-04 18:38:27 +0000
committermosu <mosu@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-08-04 18:38:27 +0000
commit26ef3a9fdc9d41364bde77b76c048cddc426a127 (patch)
treeba0173d6816960ada2b06f6df407d926244f11ce /libmpdemux
parent9ad07633e55d9514b0cb67614a7d382e0e1c33a1 (diff)
downloadmpv-26ef3a9fdc9d41364bde77b76c048cddc426a127.tar.bz2
mpv-26ef3a9fdc9d41364bde77b76c048cddc426a127.tar.xz
Removed the old Matroska demuxer.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12959 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/Makefile5
-rw-r--r--libmpdemux/demux_mkv_old.cpp3182
2 files changed, 1 insertions, 3186 deletions
diff --git a/libmpdemux/Makefile b/libmpdemux/Makefile
index 3d41529b0d..53d091f732 100644
--- a/libmpdemux/Makefile
+++ b/libmpdemux/Makefile
@@ -24,12 +24,9 @@ SRCS += dvbin.c
SRCS += dvb_tune.c
endif
-ifeq ($(MATROSKA_INTERNAL),yes)
+ifeq ($(MATROSKA),yes)
SRCS += demux_mkv.c ebml.c
endif
-ifeq ($(MATROSKA_EXTERNAL),yes)
-CPLUSPLUSSRCS += demux_mkv_old.cpp
-endif
ifeq ($(CONFIG_LIBAVFORMAT),yes)
LIBAV_INC = -I../libavcodec -I../libavformat
diff --git a/libmpdemux/demux_mkv_old.cpp b/libmpdemux/demux_mkv_old.cpp
deleted file mode 100644
index 10f8c57443..0000000000
--- a/libmpdemux/demux_mkv_old.cpp
+++ /dev/null
@@ -1,3182 +0,0 @@
-// Matroska demuxer
-// written by Moritz Bunkus <moritz@bunkus.org>
-// License: GPL of course ;)
-
-// $Id$
-
-extern "C" {
-#include "config.h"
-}
-
-#ifdef HAVE_MATROSKA
-
-#include <vector>
-
-#include <ebml/EbmlHead.h>
-#include <ebml/EbmlSubHead.h>
-#include <ebml/EbmlStream.h>
-#include <ebml/EbmlContexts.h>
-#include <ebml/EbmlVersion.h>
-#include <ebml/StdIOCallback.h>
-
-#include <matroska/KaxVersion.h>
-
-#include <matroska/KaxAttachments.h>
-#include <matroska/KaxBlock.h>
-#include <matroska/KaxBlockData.h>
-#include <matroska/KaxChapters.h>
-#include <matroska/KaxCluster.h>
-#include <matroska/KaxClusterData.h>
-#if LIBMATROSKA_VERSION >= 000503
-#include <matroska/KaxContentEncoding.h>
-#endif
-#include <matroska/KaxContexts.h>
-#include <matroska/KaxCues.h>
-#include <matroska/KaxCuesData.h>
-#include <matroska/KaxInfo.h>
-#include <matroska/KaxInfoData.h>
-#include <matroska/KaxSeekHead.h>
-#include <matroska/KaxSegment.h>
-#include <matroska/KaxTracks.h>
-#include <matroska/KaxTrackAudio.h>
-#include <matroska/KaxTrackVideo.h>
-#include <matroska/KaxTrackEntryData.h>
-#include <matroska/FileKax.h>
-
-extern "C" {
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_ZLIB
-#include <zlib.h>
-#endif
-
-#include "../mp_msg.h"
-#include "../help_mp.h"
-#include "stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-
-#include "../subreader.h"
-#include "../libvo/sub.h"
-
-}
-
-#include "matroska.h"
-
-using namespace libebml;
-using namespace libmatroska;
-using namespace std;
-
-#if LIBEBML_VERSION < 000500
-#error libebml version too old - need at least 0.5.0
-#endif
-
-// for e.g. "-slang ger"
-extern char *dvdsub_lang;
-extern char *audio_lang;
-// for "-chapter x-y"
-extern int dvd_chapter;
-extern int dvd_last_chapter;
-
-// default values for Matroska elements
-#define MKVD_TIMECODESCALE 1000000 // 1000000 = 1ms
-
-#define MKV_SUBTYPE_TEXT 1
-#define MKV_SUBTYPE_SSA 2
-#define MKV_SUBTYPE_VOBSUB 3
-
-#define MKV_SUBCOMPRESSION_NONE 0
-#define MKV_SUBCOMPRESSION_ZLIB 1
-
-#define safefree(m) { if (m != NULL) free(m); }
-void *safemalloc(int bytes) {
- void *dst;
-
- dst = malloc(bytes);
- if (dst == NULL) {
- mp_msg(MSGT_DEMUX, MSGL_FATAL, "[mkv] Could not allocate %d bytes of "
- "memory.\n", bytes);
- exit(1);
- }
-
- return dst;
-}
-
-void *safememdup(const void *src, int bytes) {
- void *dst;
-
- dst = safemalloc(bytes);
- memcpy(dst, src, bytes);
-
- return dst;
-}
-
-class mpstream_io_callback: public IOCallback {
- private:
- stream_t *s;
- public:
- mpstream_io_callback(stream_t *stream);
-
- virtual uint32 read(void *buffer, size_t size);
- virtual void setFilePointer(int64 offset, seek_mode mode = seek_beginning);
- virtual size_t write(const void *buffer, size_t size);
- virtual uint64 getFilePointer();
- virtual void close();
-};
-
-mpstream_io_callback::mpstream_io_callback(stream_t *stream) {
- s = stream;
-}
-
-uint32 mpstream_io_callback::read(void *buffer, size_t size) {
- uint32_t result;
-
- result = stream_read(s, (char *)buffer, size);
-
- return result;
-}
-
-void mpstream_io_callback::setFilePointer(int64 offset, seek_mode mode) {
- int64 new_pos;
-
- if (mode == seek_beginning)
- new_pos = offset + s->start_pos;
- else if (mode == seek_end)
- new_pos = s->end_pos - offset;
- else
- new_pos = s->pos + offset;
-
- if (new_pos > s->end_pos) {
- mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] seek warning: new_pos %lld > end_pos "
- "%lld\n", new_pos, s->end_pos);
- return;
- }
-
- stream_seek(s, new_pos);
-}
-
-size_t mpstream_io_callback::write(const void */*buffer*/, size_t /*size*/) {
- return 0;
-}
-
-uint64 mpstream_io_callback::getFilePointer() {
- return s->pos - s->buf_len + s->buf_pos;
-}
-
-void mpstream_io_callback::close() {
-}
-
-typedef struct mkv_index_entry {
- uint64_t timecode, filepos;
- int is_key;
-} mkv_index_entry_t;
-
-typedef struct mkv_track_index {
- uint32_t tnum;
- int num_entries;
- mkv_index_entry_t *entries;
-} mkv_track_index_t;
-
-typedef struct {
- uint32_t order, type, scope;
- uint32_t comp_algo;
- unsigned char *comp_settings;
- uint32_t comp_settings_len;
- uint32_t enc_algo, sig_algo, sig_hash_algo;
- unsigned char *enc_keyid, *sig_keyid, *signature;
- uint32_t enc_keyid_len, sig_keyid_len, signature_len;
-} mkv_content_encoding_t;
-
-typedef struct {
- int64_t start, end;
-} mkv_chapter_t;
-
-typedef struct mkv_track {
- uint32_t tnum, xid;
-
- char *codec_id;
- int ms_compat;
- char *language;
-
- char type; // 'v' = video, 'a' = audio, 's' = subs
-
- char v_fourcc[5];
- uint32_t v_width, v_height, v_dwidth, v_dheight;
- float v_frate;
-
- uint32_t a_formattag;
- uint32_t a_channels, a_bps;
- float a_sfreq;
-
- float default_duration;
-
- int default_track;
-
- void *private_data;
- unsigned int private_size;
-
- // For Vorbis audio
- unsigned char *headers[3];
- uint32_t header_sizes[3];
-
- int ok;
-
- // Stuff for RealMedia
- bool realmedia;
- demux_packet_t *rm_dp;
- int rm_seqnum, rv_kf_base, rv_kf_pts;
- float rv_pts; // previous video timestamp
- float ra_pts; // previous audio timestamp
-
- // Stuff for QuickTime
- bool fix_i_bps;
- float qt_last_a_pts;
-
- // Stuff for VobSubs
- mkv_sh_sub_t sh_sub;
-
- // Generic content encoding support.
- vector<mkv_content_encoding_t> *c_encodings;
-} mkv_track_t;
-
-typedef struct mkv_demuxer {
- float duration, last_pts;
- uint64_t last_filepos;
-
- mkv_track_t **tracks;
- int num_tracks;
- mkv_track_t *video, *audio, *subs_track;
-
- uint64_t tc_scale, cluster_tc, first_tc;
-
- mpstream_io_callback *in;
-
- uint64_t clear_subs_at[SUB_MAX_TEXT];
-
- subtitle subs;
- int subtitle_type;
-
- EbmlStream *es;
- EbmlElement *saved_l1, *saved_l2;
- KaxSegment *segment;
- KaxCluster *cluster;
-
- mkv_track_index_t *index;
- int num_indexes, cues_found, cues_searched;
- int64_t *cluster_positions;
- int num_cluster_pos;
- vector<uint64_t> *parsed_seekheads;
- vector<uint64_t> *parsed_cues;
-
- int64_t skip_to_timecode;
- bool v_skip_to_keyframe, a_skip_to_keyframe;
-
- vector<mkv_chapter_t> *chapters; // No support for nested chapters atm.
- uint64_t stop_timecode;
-} mkv_demuxer_t;
-
-typedef struct {
- uint32_t chunks; // number of chunks
- uint32_t timestamp; // timestamp from packet header
- uint32_t len; // length of actual data
- uint32_t chunktab; // offset to chunk offset array
-} dp_hdr_t;
-
-#if __GNUC__ == 2
-#pragma pack(2)
-#else
-#pragma pack(push,2)
-#endif
-
-typedef struct {
- uint32_t size;
- uint32_t fourcc1;
- uint32_t fourcc2;
- uint16_t width;
- uint16_t height;
- uint16_t bpp;
- uint32_t unknown1;
- uint32_t fps;
- uint32_t type1;
- uint32_t type2;
-} real_video_props_t;
-
-typedef struct {
- uint32_t fourcc1; // '.', 'r', 'a', 0xfd
- uint16_t version1; // 4 or 5
- uint16_t unknown1; // 00 000
- uint32_t fourcc2; // .ra4 or .ra5
- uint32_t unknown2; // ???
- uint16_t version2; // 4 or 5
- uint32_t header_size; // == 0x4e
- uint16_t flavor; // codec flavor id
- uint32_t coded_frame_size; // coded frame size
- uint32_t unknown3; // big number
- uint32_t unknown4; // bigger number
- uint32_t unknown5; // yet another number
- uint16_t sub_packet_h;
- uint16_t frame_size;
- uint16_t sub_packet_size;
- uint16_t unknown6; // 00 00
- uint16_t sample_rate;
- uint16_t unknown8; // 0
- uint16_t sample_size;
- uint16_t channels;
-} real_audio_v4_props_t;
-
-typedef struct {
- uint32_t fourcc1; // '.', 'r', 'a', 0xfd
- uint16_t version1; // 4 or 5
- uint16_t unknown1; // 00 000
- uint32_t fourcc2; // .ra4 or .ra5
- uint32_t unknown2; // ???
- uint16_t version2; // 4 or 5
- uint32_t header_size; // == 0x4e
- uint16_t flavor; // codec flavor id
- uint32_t coded_frame_size; // coded frame size
- uint32_t unknown3; // big number
- uint32_t unknown4; // bigger number
- uint32_t unknown5; // yet another number
- uint16_t sub_packet_h;
- uint16_t frame_size;
- uint16_t sub_packet_size;
- uint16_t unknown6; // 00 00
- uint8_t unknown7[6]; // 0, srate, 0
- uint16_t sample_rate;
- uint16_t unknown8; // 0
- uint16_t sample_size;
- uint16_t channels;
- uint32_t genr; // "genr"
- uint32_t fourcc3; // fourcc
-} real_audio_v5_props_t;
-
-// I have to (re)define this struct here because g++ will not compile
-// components.h from the qtsdk if I include it.
-typedef struct {
- uint32_t id_size;
- uint32_t codec_type;
- uint32_t reserved1;
- uint16_t reserved2;
- uint16_t data_reference_index;
- uint16_t version;
- uint16_t revision;
- uint32_t vendor;
- uint32_t temporal_quality;
- uint32_t spatial_quality;
- uint16_t width;
- uint16_t height;
- uint32_t horizontal_resolution; // 32bit fixed-point number
- uint32_t vertical_resolution; // 32bit fixed-point number
- uint32_t data_size;
- uint16_t frame_count;
- char compressor_name[32];
- uint16_t depth;
- uint16_t color_table_id;
-} qt_image_description_t;
-
-#if __GNUC__ == 2
-#pragma pack()
-#else
-#pragma pack(pop)
-#endif
-
-static uint16_t get_uint16(const void *buf) {
- uint16_t ret;
- unsigned char *tmp;
-
- tmp = (unsigned char *) buf;
-
- ret = tmp[1] & 0xff;
- ret = (ret << 8) + (tmp[0] & 0xff);
-
- return ret;
-}
-
-static uint32_t get_uint32(const void *buf) {
- uint32_t ret;
- unsigned char *tmp;
-
- tmp = (unsigned char *) buf;
-
- ret = tmp[3] & 0xff;
- ret = (ret << 8) + (tmp[2] & 0xff);
- ret = (ret << 8) + (tmp[1] & 0xff);
- ret = (ret << 8) + (tmp[0] & 0xff);
-
- return ret;
-}
-
-static uint16_t get_uint16_be(const void *buf) {
- uint16_t ret;
- unsigned char *tmp;
-
- tmp = (unsigned char *) buf;
-
- ret = tmp[0] & 0xff;
- ret = (ret << 8) + (tmp[1] & 0xff);
-
- return ret;
-}
-
-static uint32_t get_uint32_be(const void *buf) {
- uint32_t ret;
- unsigned char *tmp;
-
- tmp = (unsigned char *) buf;
-
- ret = tmp[0] & 0xff;
- ret = (ret << 8) + (tmp[1] & 0xff);
- ret = (ret << 8) + (tmp[2] & 0xff);
- ret = (ret << 8) + (tmp[3] & 0xff);
-
- return ret;
-}
-
-unsigned char read_char(unsigned char *p, int &pos, int size) {
- if ((pos + 1) > size)
- throw exception();
- pos++;
- return p[pos - 1];
-}
-
-unsigned short read_word(unsigned char *p, int &pos, int size) {
- unsigned short v;
-
- if ((pos + 2) > size)
- throw exception();
- v = p[pos];
- v = (v << 8) | (p[pos + 1] & 0xff);
- pos += 2;
- return v;
-}
-
-unsigned int read_dword(unsigned char *p, int &pos, int size) {
- unsigned int v;
-
- if ((pos + 4) > size)
- throw exception();
- v = p[pos];
- v = (v << 8) | (p[pos + 1] & 0xff);
- v = (v << 8) | (p[pos + 2] & 0xff);
- v = (v << 8) | (p[pos + 3] & 0xff);
- pos += 4;
- return v;
-}
-
-static void
-finish_text_sub_handling(mkv_demuxer_t *mkv_d, KaxBlock *block,
- int64_t duration, int first_line) {
- int i;
-
-#ifdef USE_ICONV
- subcp_recode1(&mkv_d->subs);
-#endif
-
- vo_sub = &mkv_d->subs;
- vo_osd_changed(OSDTYPE_SUBTITLE);
-
- for (i = first_line; i <= (mkv_d->subs.lines - 1); i++)
- mkv_d->clear_subs_at[i] = block->GlobalTimecode() / 1000000 -
- mkv_d->first_tc + duration;
-}
-
-static void handle_subtitles(demuxer_t *d, KaxBlock *block, int64_t duration) {
- mkv_demuxer_t *mkv_d = (mkv_demuxer_t *)d->priv;
- int len, line, state, i, first_line;
- char *s1, *s2, *buffer;
-
- if (duration == -1) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Warning: No KaxBlockDuration "
- "element for subtitle track found.\n");
- return;
- }
-
- DataBuffer &data = block->GetBuffer(0);
- len = data.Size();
-
- buffer = (char *)data.Buffer();
- s1 = buffer;
-
- while (((*s1 == '\n') || (*s1 == '\r')) &&
- ((unsigned int)(s1 - buffer) <= data.Size()))
- s1++;
-
- line = 0;
- mkv_d->subs.lines++;
- if (mkv_d->subs.lines > SUB_MAX_TEXT) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Warning: too many sublines to "
- "render, skipping\n");
- mkv_d->subs.lines = SUB_MAX_TEXT;
- return;
- }
- first_line = mkv_d->subs.lines - 1;
- s2 = mkv_d->subs.text[mkv_d->subs.lines - 1];
- state = 0;
-
- if (mkv_d->subtitle_type == MKV_SUBTYPE_SSA) {
- /* Matroska's SSA format does not have timecodes embedded into
- the SAA line. Timescodes are encoded into the blocks timecode
- and duration. */
-
- /* Find text section. */
- for (i = 0; (i < 8) && (*s1 != 0); s1++)
- if (*s1 == ',')
- i++;
-
- if (*s1 == 0) { // Broken line?
- mkv_d->subs.lines--;
- return;
- }
-
- /* Load text. */
- while ((unsigned int)(s1 - buffer) < data.Size()) {
- if (*s1 == '{')
- state = 1;
- else if ((*s1 == '}') && (state == 1))
- state = 2;
-
- if (state == 0) {
- *s2 = *s1;
- s2++;
- if ((s2 - mkv_d->subs.text[mkv_d->subs.lines - 1]) >= 255)
- break;
- }
- s1++;
-
- /* Newline */
- if ((*s1 == '\\') && ((unsigned int)(s1 + 1 - buffer) < data.Size()) &&
- ((*(s1 + 1) == 'N') || (*(s1 + 1) == 'n'))) {
- *s2 = 0;
- mkv_d->subs.lines++;
- if (mkv_d->subs.lines > SUB_MAX_TEXT) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Warning: too many sublines to "
- "render, skipping\n");
- mkv_d->subs.lines = SUB_MAX_TEXT;
- finish_text_sub_handling(mkv_d, block, duration, first_line);
- return;
- }
- s2 = mkv_d->subs.text[mkv_d->subs.lines - 1];
- s1 += 2;
- }
-
- if (state == 2)
- state = 0;
- }
- *s2 = 0;
-
- } else {
- while ((unsigned int)(s1 - buffer) != data.Size()) {
- if ((*s1 == '\n') || (*s1 == '\r')) {
- if (state == 0) { // normal char --> newline
- if (mkv_d->subs.lines == SUB_MAX_TEXT)
- break;
- *s2 = 0;
- mkv_d->clear_subs_at[mkv_d->subs.lines - 1]=
- block->GlobalTimecode() / 1000000 - mkv_d->first_tc + duration;
- s2 = mkv_d->subs.text[mkv_d->subs.lines];
- mkv_d->subs.lines++;
- state = 1;
- }
- } else if (*s1 == '<') // skip HTML tags
- state = 2;
- else if (*s1 == '>')
- state = 0;
- else if (state != 2) { // normal character
- state = 0;
- if ((s2 - mkv_d->subs.text[mkv_d->subs.lines - 1]) < 255) {
- *s2 = *s1;
- s2++;
- }
- }
- s1++;
- }
-
- *s2 = 0;
- }
-
- finish_text_sub_handling(mkv_d, block, duration, first_line);
-}
-
-static mkv_track_t *new_mkv_track(mkv_demuxer_t *d) {
- mkv_track_t *t;
-
- t = (mkv_track_t *)safemalloc(sizeof(mkv_track_t));
- memset(t, 0, sizeof(mkv_track_t));
- d->tracks = (mkv_track_t **)realloc(d->tracks, (d->num_tracks + 1) *
- sizeof(mkv_track_t *));
- if (d->tracks == NULL)
- return NULL;
- d->tracks[d->num_tracks] = t;
- d->num_tracks++;
-
- // Set default values.
- t->default_track = 1;
- t->a_sfreq = 8000.0;
- t->a_channels = 1;
- t->language = strdup("eng");
-
- t->c_encodings = new vector<mkv_content_encoding_t>;
-
- return t;
-}
-
-static mkv_track_t *find_track_by_num(mkv_demuxer_t *d, uint32_t n,
- char track_type) {
- int i;
-
- for (i = 0; i < d->num_tracks; i++)
- if ((d->tracks[i] != NULL) && (d->tracks[i]->type == track_type) &&
- (d->tracks[i]->xid == n))
- return d->tracks[i];
-
- return NULL;
-}
-
-static mkv_track_t *find_duplicate_track_by_num(mkv_demuxer_t *d, uint32_t n,
- mkv_track_t *c) {
- int i;
-
- for (i = 0; i < d->num_tracks; i++)
- if ((d->tracks[i] != NULL) && (d->tracks[i]->tnum == n) &&
- (d->tracks[i] != c))
- return d->tracks[i];
-
- return NULL;
-}
-
-static mkv_track_t *find_track_by_language(mkv_demuxer_t *d, char *language,
- mkv_track_t *c, char type = 's') {
- int i;
-
- for (i = 0; i < d->num_tracks; i++)
- if ((d->tracks[i] != NULL) && (d->tracks[i] != c) &&
- (d->tracks[i]->language != NULL) &&
- !strcmp(d->tracks[i]->language, language) &&
- (d->tracks[i]->type == type))
- return d->tracks[i];
-
- return NULL;
-}
-
-static bool mkv_parse_idx(mkv_track_t *t) {
- uint32_t i, p, things_found;
- int idx;
- string line, s1, s2;
- char *src;
-
- if ((t->private_data == NULL) || (t->private_size < 1))
- return false;
-
- things_found = 0;
- i = 0;
- src = (char *)t->private_data;
- do {
- line = "";
- while ((i < t->private_size) && (src[i] != '\n') && (src[i] != '\r')) {
- if (!isspace(src[i]))
- line += src[i];
- i++;
- }
- while ((i < t->private_size) && ((src[i] == '\n') || (src[i] == '\r')))
- i++;
-
- if (!strncasecmp(line.c_str(), "size:", 5)) {
- s1 = line.substr(5);
- idx = s1.find('x');
- if (idx >= 0) {
- s2 = s1.substr(idx + 1);
- s1.erase(idx);
- t->sh_sub.width = strtol(s1.c_str(), NULL, 10);
- t->sh_sub.height = strtol(s2.c_str(), NULL, 10);
- things_found |= 1;
- mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] VobSub IDX parser: size: %d x %d\n",
- t->sh_sub.width, t->sh_sub.height);
- }
-
- } else if (!strncasecmp(line.c_str(), "palette:", 8)) {
- s1 = line.substr(8);
- for (p = 0; p < 15; p++) {
- idx = s1.find(',');
- if (idx < 0)
- break;
- s2 = s1.substr(0, idx);
- s1.erase(0, idx + 1);
- t->sh_sub.palette[p] = (unsigned int)strtol(s2.c_str(), NULL, 16);
- }
- if (idx >= 0) {
- t->sh_sub.palette[15] = (unsigned int)strtol(s1.c_str(), NULL, 16);
- things_found |= 2;
- mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] VobSub IDX parser: palette: 0x%06x "
- "0x%06x 0x%06x 0x%06x 0x%06x 0x%06x 0x%06x 0x%06x 0x%06x "
- "0x%06x 0x%06x 0x%06x 0x%06x 0x%06x 0x%06x 0x%06x\n",
- t->sh_sub.palette[0], t->sh_sub.palette[1],
- t->sh_sub.palette[2], t->sh_sub.palette[3],
- t->sh_sub.palette[4], t->sh_sub.palette[5],
- t->sh_sub.palette[6], t->sh_sub.palette[7],
- t->sh_sub.palette[8], t->sh_sub.palette[9],
- t->sh_sub.palette[10], t->sh_sub.palette[11],
- t->sh_sub.palette[12], t->sh_sub.palette[13],
- t->sh_sub.palette[14], t->sh_sub.palette[15]);
- }
- }
-
- } while ((i != t->private_size) && (things_found != 3));
- t->sh_sub.type = 'v';
-
- return (things_found == 3);
-}
-
-static bool reverse_encodings(mkv_track_t *track, unsigned char *&data,
- uint32_t &size, uint32_t type) {
- int new_size, n;
- unsigned char *new_data, *old_data;
- bool modified;
- vector<mkv_content_encoding_t>::iterator ce;
-
- if (track->c_encodings->size() == 0)
- return false;
-
- new_data = data;
- new_size = size;
- modified = false;
- for (ce = track->c_encodings->begin(); ce < track->c_encodings->end();
- ce++) {
- if ((ce->scope & type) == 0)
- continue;
-
-#ifdef HAVE_ZLIB
- if (ce->comp_algo == 0) {
- int result;
- z_stream zstream;
-
- old_data = new_data;
-
- zstream.zalloc = (alloc_func)0;
- zstream.zfree = (free_func)0;
- zstream.opaque = (voidpf)0;
- result = inflateInit(&zstream);
- if (result != Z_OK) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Zlib initialization failed. "
- "Result: %d\n", result);
- safefree(new_data);
- data = old_data;
- size = new_size;
- return modified;
- }
- zstream.next_in = (Bytef *)old_data;
- zstream.avail_in = new_size;
-
- n = 0;
- new_data = NULL;
- do {
- n++;
- new_data = (unsigned char *)realloc(new_data, n * 4000);
- zstream.next_out = (Bytef *)&new_data[(n - 1) * 4000];
- zstream.avail_out = 4000;
- result = inflate(&zstream, Z_NO_FLUSH);
- if ((result != Z_OK) && (result != Z_STREAM_END)) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Zlib decompression failed. "
- "Result: %d \n", result);
- safefree(new_data);
- data = old_data;
- size = new_size;
- inflateEnd(&zstream);
- return modified;
- }
- } while ((zstream.avail_out == 0) &&
- (zstream.avail_in != 0) && (result != Z_STREAM_END));
-
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] zlib decompression: from %d to "
- "%d \n", (int)new_size, (int)zstream.total_out);
- new_size = zstream.total_out;
- inflateEnd(&zstream);
-
- if (modified)
- safefree(old_data);
- modified = true;
- }
-#endif
- }
-
- data = new_data;
- size = new_size;
-
- return modified;
-}
-
-static int check_track_information(mkv_demuxer_t *d) {
- int i, track_num;
- unsigned char *c;
- uint32_t u, offset, length;
- mkv_track_t *t;
- mkv_content_encoding_t *ce;
- BITMAPINFOHEADER *bih;
- WAVEFORMATEX *wfe;
-
- for (track_num = 0; track_num < d->num_tracks; track_num++) {
- t = d->tracks[track_num];
-
- t->ok = 1;
- for (i = 0; i < (int)t->c_encodings->size(); i++) {
- ce = &(*t->c_encodings)[i];
-
- if (ce->type == 1) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Track number %u has been "
- "encrypted and decryption has not yet been implemented. "
- "Skipping track.\n", t->tnum);
- t->ok = 0;
- break;
- }
-
- if (ce->type != 0) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown content encoding type %u "
- "for track %u. Skipping track.\n", ce->type, t->tnum);
- t->ok = 0;
- break;
- }
-
- if (ce->comp_algo == 0) {
-#if !defined(HAVE_ZLIB)
- mp_msg(MSGT_DEMUX, MSGL_WARN, "Track %u was compressed with zlib but "
- "mplayer has not been compiled with support for zlib "
- "compression. Skipping track.\n", t->tnum);
- t->ok = 0;
- break;
-#endif
- } else {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Track %u has been compressed "
- "with an unknown/unsupported compression algorithm (%u). "
- "Skipping track.\n", t->tnum, ce->comp_algo);
- t->ok = 0;
- break;
- }
- }
-
- if (!t->ok)
- continue;
- t->ok = 0;
-
- if (t->private_data != NULL) {
- c = (unsigned char *)t->private_data;
- length = t->private_size;
- if (reverse_encodings(t, c, length, 2)) {
- safefree(t->private_data);
- t->private_data = c;
- t->private_size = length;
- }
- }
-
- switch (t->type) {
- case 'v': // video track
- if (t->codec_id == NULL)
- continue;
- if (!strcmp(t->codec_id, MKV_V_MSCOMP)) {
- if ((t->private_data == NULL) ||
- (t->private_size < sizeof(BITMAPINFOHEADER))) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: CodecID for track "
- "%u is '" MKV_V_MSCOMP "', but there was no "
- "BITMAPINFOHEADER struct present. Therefore we don't have "
- "a FourCC to identify the video codec used.\n", t->tnum);
- continue;
- } else {
- t->ms_compat = 1;
-
- bih = (BITMAPINFOHEADER *)t->private_data;
-
- u = get_uint32(&bih->biWidth);
- if (t->v_width != u) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: (MS "
- "compatibility mode, track %u) "
- "Matrosa says video width is %u, but the "
- "BITMAPINFOHEADER says %u.\n", t->tnum, t->v_width, u);
- if (t->v_width == 0)
- t->v_width = u;
- }
-
- u = get_uint32(&bih->biHeight);
- if (t->v_height != u) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: (MS compatibility "
- "mode, track %u) "
- "Matrosa video height is %u, but the BITMAPINFOHEADER "
- "says %u.\n", t->tnum, t->v_height, u);
- if (t->v_height == 0)
- t->v_height = u;
- }
-
- memcpy(t->v_fourcc, &bih->biCompression, 4);
- }
- }
-
- if (t->v_width == 0) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] The width for track %u was "
- "not set.\n", t->tnum);
- continue;
- }
- if (t->v_height == 0) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] The height for track %u was "
- "not set.\n", t->tnum);
- continue;
- }
-
- if (t->v_dwidth == 0)
- t->v_dwidth = t->v_width;
- if (t->v_dheight == 0)
- t->v_dheight = t->v_height;
-
- // This track seems to be ok.
- t->ok = 1;
- mp_msg(MSGT_DEMUX, MSGL_INFO, "[mkv] Track ID %u: video (%s), "
- "-vid %u\n", t->tnum, t->codec_id, t->xid);
-
- break;
-
- case 'a': // audio track
- if (t->codec_id == NULL)
- continue;
- if (!strcmp(t->codec_id, MKV_A_ACM)) {
- if ((t->private_data == NULL) ||
- (t->private_size < sizeof(WAVEFORMATEX))) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: CodecID for track "
- "%u is '" MKV_A_ACM "', "
- "but there was no WAVEFORMATEX struct present. "
- "Therefore we don't have a format ID to identify the audio "
- "codec used.\n", t->tnum);
- continue;
- } else {
- t->ms_compat = 1;
-
- wfe = (WAVEFORMATEX *)t->private_data;
- u = get_uint32(&wfe->nSamplesPerSec);
- if (((uint32_t)t->a_sfreq) != u) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: (MS compatibility "
- "mode for track %u) "
- "Matroska says that there are %u samples per second, "
- "but WAVEFORMATEX says that there are %u.\n", t->tnum,
- (uint32_t)t->a_sfreq, u);
- if (t->a_sfreq == 0.0)
- t->a_sfreq = (float)u;
- }
-
- u = get_uint16(&wfe->nChannels);
- if (t->a_channels != u) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: (MS "
- "compatibility mode for track %u) "
- "Matroska says that there are %u channels, but the "
- "WAVEFORMATEX says that there are %u.\n", t->tnum,
- t->a_channels, u);
- if (t->a_channels == 0)
- t->a_channels = u;
- }
-
- u = get_uint16(&wfe->wBitsPerSample);
- if (t->a_bps != u) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: (MS "
- "compatibility mode for track %u) "
- "Matroska says that there are %u bits per sample, "
- "but the WAVEFORMATEX says that there are %u.\n", t->tnum,
- t->a_bps, u);
- if (t->a_bps == 0)
- t->a_bps = u;
- }
-
- t->a_formattag = get_uint16(&wfe->wFormatTag);
- }
- } else {
- if (!strcmp(t->codec_id, MKV_A_MP3) ||
- !strcmp(t->codec_id, MKV_A_MP2))
- t->a_formattag = 0x0055;
- else if (!strncmp(t->codec_id, MKV_A_AC3, strlen(MKV_A_AC3)))
- t->a_formattag = 0x2000;
- else if (!strcmp(t->codec_id, MKV_A_DTS))
- // uses same format tag as AC3, only supported with -hwac3
- t->a_formattag = 0x2000;
- else if (!strcmp(t->codec_id, MKV_A_PCM) ||
- !strcmp(t->codec_id, MKV_A_PCM_BE))
- t->a_formattag = 0x0001;
- else if (!strcmp(t->codec_id, MKV_A_AAC_2MAIN) ||
- !strncmp(t->codec_id, MKV_A_AAC_2LC,
- strlen(MKV_A_AAC_2LC)) ||
- !strcmp(t->codec_id, MKV_A_AAC_2SSR) ||
- !strcmp(t->codec_id, MKV_A_AAC_4MAIN) ||
- !strncmp(t->codec_id, MKV_A_AAC_4LC,
- strlen(MKV_A_AAC_4LC)) ||
- !strcmp(t->codec_id, MKV_A_AAC_4SSR) ||
- !strcmp(t->codec_id, MKV_A_AAC_4LTP))
- t->a_formattag = mmioFOURCC('M', 'P', '4', 'A');
- else if (!strcmp(t->codec_id, MKV_A_VORBIS)) {
- if (t->private_data == NULL) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] WARNING: CodecID for "
- "track %u is '" MKV_A_VORBIS
- "', but there are no header packets present.", t->tnum);
- continue;
- }
-
- c = (unsigned char *)t->private_data;
- if (c[0] != 2) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Vorbis track does not "
- "contain valid headers.\n");
- continue;
- }
-
- offset = 1;
- for (i = 0; i < 2; i++) {
- length = 0;
- while ((c[offset] == (unsigned char )255) &&
- (length < t->private_size)) {
- length += 255;
- offset++;
- }
- if (offset >= (t->private_size - 1)) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Vorbis track does not "
- "contain valid headers.\n");
- continue;
- }
- length += c[offset];
- offset++;
- t->header_sizes[i] = length;
- }
-
- t->headers[0] = &c[offset];
- t->headers[1] = &c[offset + t->header_sizes[0]];
- t->headers[2] = &c[offset + t->header_sizes[0] +
- t->header_sizes[1]];
- t->header_sizes[2] = t->private_size - offset -
- t->header_sizes[0] - t->header_sizes[1];
-
- t->a_formattag = 0xFFFE;
- } else if (!strcmp(t->codec_id, MKV_A_QDMC) ||
- !strcmp(t->codec_id, MK