diff options
Diffstat (limited to 'libmpdemux')
-rw-r--r-- | libmpdemux/Makefile | 5 | ||||
-rw-r--r-- | libmpdemux/demux_mkv_old.cpp | 3182 |
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, MKV_A_QDMC2)) { - ; - } else if (!strcmp(t->codec_id, MKV_A_FLAC)) { - if ((t->private_data == NULL) || (t->private_size == 0)) { - mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] FLAC track does not " - "contain valid headers.\n"); - continue; - } - t->a_formattag = mmioFOURCC('f', 'L', 'a', 'C'); - } else if (t->private_size >= sizeof(real_audio_v4_props_t)) { - if (!strcmp(t->codec_id, MKV_A_REAL28)) - t->a_formattag = mmioFOURCC('2', '8', '_', '8'); |