diff options
author | wm4 <wm4@nowhere> | 2012-11-05 17:02:04 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2012-11-12 20:06:14 +0100 |
commit | d4bdd0473d6f43132257c9fb3848d829755167a3 (patch) | |
tree | 8021c2f7da1841393c8c832105e20cd527826d6c /libmpdemux/demux_mkv.c | |
parent | bd48deba77bd5582c5829d6fe73a7d2571088aba (diff) | |
download | mpv-d4bdd0473d6f43132257c9fb3848d829755167a3.tar.bz2 mpv-d4bdd0473d6f43132257c9fb3848d829755167a3.tar.xz |
Rename directories, move files (step 1 of 2) (does not compile)
Tis drops the silly lib prefixes, and attempts to organize the tree in
a more logical way. Make the top-level directory less cluttered as
well.
Renames the following directories:
libaf -> audio/filter
libao2 -> audio/out
libvo -> video/out
libmpdemux -> demux
Split libmpcodecs:
vf* -> video/filter
vd*, dec_video.* -> video/decode
mp_image*, img_format*, ... -> video/
ad*, dec_audio.* -> audio/decode
libaf/format.* is moved to audio/ - this is similar to how mp_image.*
is located in video/.
Move most top-level .c/.h files to core. (talloc.c/.h is left on top-
level, because it's external.) Park some of the more annoying files
in compat/. Some of these are relicts from the time mplayer used
ffmpeg internals.
sub/ is not split, because it's too much of a mess (subtitle code is
mixed with OSD display and rendering).
Maybe the organization of core is not ideal: it mixes playback core
(like mplayer.c) and utility helpers (like bstr.c/h). Should the need
arise, the playback core will be moved somewhere else, while core
contains all helper and common code.
Diffstat (limited to 'libmpdemux/demux_mkv.c')
-rw-r--r-- | libmpdemux/demux_mkv.c | 2558 |
1 files changed, 0 insertions, 2558 deletions
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c deleted file mode 100644 index 3093fcae0f..0000000000 --- a/libmpdemux/demux_mkv.c +++ /dev/null @@ -1,2558 +0,0 @@ -/* - * Matroska demuxer - * Copyright (C) 2004 Aurelien Jacobs <aurel@gnuage.org> - * Based on the one written by Ronald Bultje for gstreamer - * and on demux_mkv.cpp from Moritz Bunkus. - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include <inttypes.h> -#include <stdbool.h> - -#include <libavutil/common.h> -#include <libavutil/lzo.h> -#include <libavutil/intreadwrite.h> -#include <libavutil/avstring.h> - -#include "config.h" - -#if CONFIG_ZLIB -#include <zlib.h> -#endif - -#include "talloc.h" -#include "options.h" -#include "bstr.h" -#include "stream/stream.h" -#include "demuxer.h" -#include "stheader.h" -#include "ebml.h" -#include "matroska.h" -//#include "demux_real.h" - -#include "mp_msg.h" - -static const unsigned char sipr_swaps[38][2] = { - {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68}, - {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46}, - {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56}, - {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83}, - {77,80} -}; - -// Map flavour to bytes per second -#define SIPR_FLAVORS 4 -#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 -}; - -typedef struct mkv_content_encoding { - uint64_t order, type, scope; - uint64_t comp_algo; - uint8_t *comp_settings; - int comp_settings_len; -} mkv_content_encoding_t; - -typedef struct mkv_track { - int tnum; - char *name; - int id; // -aid / -sid / -vid option value - - char *codec_id; - int ms_compat; - char *language; - - int type; - - uint32_t v_width, v_height, v_dwidth, v_dheight; - double v_frate; - - uint32_t a_formattag; - uint32_t a_channels, a_bps; - float a_sfreq; - float a_osfreq; - - double default_duration; - - int default_track; - - unsigned char *private_data; - unsigned int private_size; - - /* stuff for realmedia */ - int realmedia; - int64_t rv_kf_base; - int rv_kf_pts; - double rv_pts; /* previous video timestamp */ - double ra_pts; /* previous audio timestamp */ - - /** realaudio descrambling */ - int sub_packet_size; ///< sub packet size, per stream - int sub_packet_h; ///< number of coded frames per block - int coded_framesize; ///< coded frame size, per stream - int audiopk_size; ///< audio packet size - unsigned char *audio_buf; ///< place to store reordered audio data - 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; - double qt_last_a_pts; - - int subtitle_type; - - /* generic content encoding support */ - mkv_content_encoding_t *encodings; - int num_encodings; - - /* For VobSubs and SSA/ASS */ - sh_sub_t *sh_sub; -} mkv_track_t; - -typedef struct mkv_index { - int tnum; - uint64_t timecode, filepos; -} mkv_index_t; - -typedef struct mkv_demuxer { - off_t segment_start; - - double duration, last_pts; - uint64_t last_filepos; - - mkv_track_t **tracks; - int num_tracks; - - uint64_t tc_scale, cluster_tc; - - uint64_t cluster_start; - uint64_t cluster_size; - uint64_t blockgroup_size; - - mkv_index_t *indexes; - int num_indexes; - - off_t *parsed_pos; - int num_parsed_pos; - bool parsed_info; - bool parsed_tracks; - bool parsed_tags; - bool parsed_chapters; - bool parsed_attachments; - - struct cluster_pos { - uint64_t filepos; - uint64_t timecode; - } *cluster_positions; - int num_cluster_pos; - - uint64_t skip_to_timecode; - int v_skip_to_keyframe, a_skip_to_keyframe; - - int num_audio_tracks; - int num_video_tracks; -} mkv_demuxer_t; - -#define REALHEADER_SIZE 16 -#define RVPROPERTIES_SIZE 34 -#define RAPROPERTIES4_SIZE 56 -#define RAPROPERTIES5_SIZE 70 - -/** - * \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) -{ - if (!(nelem & 31)) - array = realloc(array, (nelem + 32) * elsize); - return array; -} - -static bool is_parsed_header(struct mkv_demuxer *mkv_d, off_t pos) -{ - int low = 0; - int high = mkv_d->num_parsed_pos; - while (high > low + 1) { - int mid = high + low >> 1; - if (mkv_d->parsed_pos[mid] > pos) - high = mid; - else - low = mid; - } - if (mkv_d->num_parsed_pos && mkv_d->parsed_pos[low] == pos) - return true; - if (!(mkv_d->num_parsed_pos & 31)) - mkv_d->parsed_pos = talloc_realloc(mkv_d, mkv_d->parsed_pos, off_t, - mkv_d->num_parsed_pos + 32); - mkv_d->num_parsed_pos++; - for (int i = mkv_d->num_parsed_pos - 1; i > low; i--) - mkv_d->parsed_pos[i] = mkv_d->parsed_pos[i - 1]; - mkv_d->parsed_pos[low] = pos; - return false; -} - -static mkv_track_t *find_track_by_num(struct mkv_demuxer *d, int n, int type) -{ - for (int i = 0; i < d->num_tracks; i++) - if (d->tracks[i] != NULL && d->tracks[i]->type == type) - if (d->tracks[i]->id == n) - return d->tracks[i]; - - return NULL; -} - -static void add_cluster_position(mkv_demuxer_t *mkv_d, uint64_t filepos, - uint64_t timecode) -{ - if (mkv_d->indexes) - return; - - int n = mkv_d->num_cluster_pos; - if (n > 0 && mkv_d->cluster_positions[n-1].filepos >= filepos) - return; - - mkv_d->cluster_positions = - grow_array(mkv_d->cluster_positions, mkv_d->num_cluster_pos, - sizeof(*mkv_d->cluster_positions)); - mkv_d->cluster_positions[mkv_d->num_cluster_pos++] = (struct cluster_pos){ - .filepos = filepos, - .timecode = timecode, - }; -} - - -#define AAC_SYNC_EXTENSION_TYPE 0x02b7 -static int aac_get_sample_rate_index(uint32_t sample_rate) -{ - static const int srates[] = { - 92017, 75132, 55426, 46009, 37566, 27713, - 23004, 18783, 13856, 11502, 9391, 0 - }; - int i = 0; - while (sample_rate < srates[i]) - i++; - return i; -} - -static void demux_mkv_decode(mkv_track_t *track, uint8_t *src, - uint8_t **dest, uint32_t *size, uint32_t type) -{ - uint8_t *orig_src = src; - - *dest = src; - - for (int i = 0; i < track->num_encodings; i++) { - struct mkv_content_encoding *enc = track->encodings + i; - if (!(enc->scope & type)) - continue; - - if (src != *dest && src != orig_src) - talloc_free(src); - src = *dest; // output from last iteration is new source - - if (enc->comp_algo == 0) { -#if CONFIG_ZLIB - /* zlib encoded track */ - - if (*size == 0) - continue; - - z_stream zstream; - - zstream.zalloc = (alloc_func) 0; - zstream.zfree = (free_func) 0; - zstream.opaque = (voidpf) 0; - if (inflateInit(&zstream) != Z_OK) { - mp_tmsg(MSGT_DEMUX, MSGL_WARN, - "[mkv] zlib initialization failed.\n"); - goto error; - } - zstream.next_in = (Bytef *) src; - zstream.avail_in = *size; - - *dest = NULL; - zstream.avail_out = *size; - int result; - do { - *size += 4000; - *dest = talloc_realloc_size(NULL, *dest, *size); - zstream.next_out = (Bytef *) (*dest + zstream.total_out); - result = inflate(&zstream, Z_NO_FLUSH); - if (result != Z_OK && result != Z_STREAM_END) { - mp_tmsg(MSGT_DEMUX, MSGL_WARN, - "[mkv] zlib decompression failed.\n"); - talloc_free(*dest); - *dest = NULL; - inflateEnd(&zstream); - goto error; - } - zstream.avail_out += 4000; - } while (zstream.avail_out == 4000 && zstream.avail_in != 0 - && result != Z_STREAM_END); - - *size = zstream.total_out; - inflateEnd(&zstream); -#endif - } else if (enc->comp_algo == 2) { - /* lzo encoded track */ - int out_avail; - int dstlen = *size * 3; - - *dest = NULL; - while (1) { - int srclen = *size; - *dest = talloc_realloc_size(NULL, *dest, - dstlen + AV_LZO_OUTPUT_PADDING); - out_avail = dstlen; - int result = av_lzo1x_decode(*dest, &out_avail, src, &srclen); - if (result == 0) - break; - if (!(result & AV_LZO_OUTPUT_FULL)) { - mp_tmsg(MSGT_DEMUX, MSGL_WARN, - "[mkv] lzo decompression failed.\n"); - talloc_free(*dest); - *dest = NULL; - goto error; - } - mp_msg(MSGT_DEMUX, MSGL_DBG2, - "[mkv] lzo decompression buffer too small.\n"); - dstlen *= 2; - } - *size = dstlen - out_avail; - } else if (enc->comp_algo == 3) { - *dest = talloc_size(NULL, *size + enc->comp_settings_len); - memcpy(*dest, enc->comp_settings, enc->comp_settings_len); - memcpy(*dest + enc->comp_settings_len, src, *size); - *size += enc->comp_settings_len; - } - } - - error: - if (src != *dest && src != orig_src) - talloc_free(src); -} - - -static int demux_mkv_read_info(demuxer_t *demuxer) -{ - mkv_demuxer_t *mkv_d = demuxer->priv; - stream_t *s = demuxer->stream; - int res = 0; - - mkv_d->tc_scale = 1000000; - mkv_d->duration = 0; - - struct ebml_info info = {}; - struct ebml_parse_ctx parse_ctx = {}; - if (ebml_read_element(s, &parse_ctx, &info, &ebml_info_desc) < 0) - return -1; - if (info.n_timecode_scale) { - mkv_d->tc_scale = info.timecode_scale; - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] | + timecode scale: %" PRIu64 "\n", mkv_d->tc_scale); - } - if (info.n_duration) { - mkv_d->duration = info.duration * mkv_d->tc_scale / 1e9; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3fs\n", - mkv_d->duration); - } - if (info.n_segment_uid) { - int len = info.segment_uid.len; - if (len != sizeof(demuxer->matroska_data.segment_uid)) { - mp_msg(MSGT_DEMUX, MSGL_INFO, - "[mkv] segment uid invalid length %d\n", len); - } else { - memcpy(demuxer->matroska_data.segment_uid, info.segment_uid.start, - len); - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + segment uid"); - for (int i = 0; i < len; i++) - mp_msg(MSGT_DEMUX, MSGL_V, " %02x", - demuxer->matroska_data.segment_uid[i]); - mp_msg(MSGT_DEMUX, MSGL_V, "\n"); - } - } - if (demuxer->params && demuxer->params->matroska_wanted_uids) { - unsigned char (*uids)[16] = demuxer->params->matroska_wanted_uids; - if (!info.n_segment_uid) - uids = NULL; - for (int i = 0; i < MP_TALLOC_ELEMS(uids); i++) { - if (!memcmp(info.segment_uid.start, uids[i], 16)) - goto out; - } - mp_tmsg(MSGT_DEMUX, MSGL_INFO, - "[mkv] This is not one of the wanted files. " - "Stopping attempt to open.\n"); - res = -2; - } - out: - talloc_free(parse_ctx.talloc_ctx); - return res; -} - -static void parse_trackencodings(struct demuxer *demuxer, - struct mkv_track *track, - struct ebml_content_encodings *encodings) -{ - // initial allocation to be a non-NULL context before realloc - mkv_content_encoding_t *ce = talloc_size(track, 1); - - for (int n_enc = 0; n_enc < encodings->n_content_encoding; n_enc++) { - struct ebml_content_encoding *enc = encodings->content_encoding + n_enc; - struct mkv_content_encoding e = {}; - e.order = enc->content_encoding_order; - if (enc->n_content_encoding_scope) - e.scope = enc->content_encoding_scope; - else - e.scope = 1; - e.type = enc->content_encoding_type; - - if (enc->n_content_compression) { - struct ebml_content_compression *z = &enc->content_compression; - e.comp_algo = z->content_comp_algo; - if (z->n_content_comp_settings) { - int sz = z->content_comp_settings.len; - e.comp_settings = talloc_size(ce, sz); - memcpy(e.comp_settings, z->content_comp_settings.start, sz); - e.comp_settings_len = sz; - } - } - - if (e.type == 1) { - 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_tmsg(MSGT_DEMUX, MSGL_WARN, - "[mkv] Unknown content encoding type for " - "track %u. Skipping track.\n", - track->tnum); - } else if (e.comp_algo != 0 && e.comp_algo != 2 && e.comp_algo != 3) { - mp_tmsg(MSGT_DEMUX, MSGL_WARN, - "[mkv] Track %u has been compressed with " - "an unknown/unsupported compression\n" - "[mkv] algorithm (%" PRIu64 "). Skipping track.\n", - track->tnum, e.comp_algo); - } -#if !CONFIG_ZLIB - else if (e.comp_algo == 0) { - mp_tmsg(MSGT_DEMUX, MSGL_WARN, - "[mkv] Track %u was compressed with zlib " - "but mpv has not been compiled\n" - "[mkv] with support for zlib compression. " - "Skipping track.\n", - track->tnum); - } -#endif - int i; - for (i = 0; i < n_enc; i++) - if (e.order >= ce[i].order) - break; - ce = talloc_realloc_size(track, ce, (n_enc + 1) * sizeof(*ce)); - memmove(ce + i + 1, ce + i, (n_enc - i) * sizeof(*ce)); - memcpy(ce + i, &e, sizeof(e)); - } - - track->encodings = ce; - track->num_encodings = encodings->n_content_encoding; -} - -static void parse_trackaudio(struct demuxer *demuxer, struct mkv_track *track, - struct ebml_audio *audio) -{ - if (audio->n_sampling_frequency) { - track->a_sfreq = audio->sampling_frequency; - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] | + Sampling frequency: %f\n", track->a_sfreq); - } else - track->a_sfreq = 8000; - if (audio->n_output_sampling_frequency) { - track->a_osfreq = audio->output_sampling_frequency; - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] | + Output sampling frequency: %f\n", track->a_osfreq); - } else - track->a_osfreq = track->a_sfreq; - if (audio->n_bit_depth) { - track->a_bps = audio->bit_depth; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Bit depth: %u\n", - track->a_bps); - } - if (audio->n_channels) { - track->a_channels = audio->channels; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Channels: %u\n", - track->a_channels); - } else - track->a_channels = 1; -} - -static void parse_trackvideo(struct demuxer *demuxer, struct mkv_track *track, - struct ebml_video *video) -{ - if (video->n_frame_rate) { - track->v_frate = video->frame_rate; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Frame rate: %f\n", - track->v_frate); - if (track->v_frate > 0) - track->default_duration = 1 / track->v_frate; - } - if (video->n_display_width) { - track->v_dwidth = video->display_width; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Display width: %u\n", - track->v_dwidth); - } - if (video->n_display_height) { - track->v_dheight = video->display_height; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Display height: %u\n", - track->v_dheight); - } - if (video->n_pixel_width) { - track->v_width = video->pixel_width; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Pixel width: %u\n", - track->v_width); - } - if (video->n_pixel_height) { - track->v_height = video->pixel_height; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Pixel height: %u\n", - track->v_height); - } -} - -/** - * \brief free any data associated with given track - * \param track track of which to free data - */ -static void demux_mkv_free_trackentry(mkv_track_t *track) -{ - free(track->audio_buf); - free(track->audio_timestamp); - talloc_free(track); -} - -static void parse_trackentry(struct demuxer *demuxer, - struct ebml_track_entry *entry) -{ - mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; - struct mkv_track *track = talloc_zero_size(NULL, sizeof(*track)); - - track->tnum = entry->track_number; - if (track->tnum) - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Track number: %u\n", - track->tnum); - else - mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Missing track number!\n"); - - if (entry->n_name) { - track->name = talloc_strndup(track, entry->name.start, - entry->name.len); - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Name: %s\n", - track->name); - } - - track->type = entry->track_type; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Track type: "); - switch (track->type) { - case MATROSKA_TRACK_AUDIO: - mp_msg(MSGT_DEMUX, MSGL_V, "Audio\n"); - break; - case MATROSKA_TRACK_VIDEO: - mp_msg(MSGT_DEMUX, MSGL_V, "Video\n"); - break; - case MATROSKA_TRACK_SUBTITLE: - mp_msg(MSGT_DEMUX, MSGL_V, "Subtitle\n"); - break; - default: - mp_msg(MSGT_DEMUX, MSGL_V, "unknown\n"); - break; - } - - if (entry->n_audio) { - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Audio track\n"); - parse_trackaudio(demuxer, track, &entry->audio); - } - - if (entry->n_video) { - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Video track\n"); - parse_trackvideo(demuxer, track, &entry->video); - } - - if (entry->n_codec_id) { - track->codec_id = talloc_strndup(track, entry->codec_id.start, - entry->codec_id.len); - if (!strcmp(track->codec_id, MKV_V_MSCOMP) - || !strcmp(track->codec_id, MKV_A_ACM)) - track->ms_compat = 1; - else if (!strcmp(track->codec_id, MKV_S_VOBSUB)) - track->subtitle_type = 'v'; - else if (!strcmp(track->codec_id, MKV_S_TEXTSSA) - || !strcmp(track->codec_id, MKV_S_TEXTASS) - || !strcmp(track->codec_id, MKV_S_SSA) - || !strcmp(track->codec_id, MKV_S_ASS)) - track->subtitle_type = 'a'; - else if (!strcmp(track->codec_id, MKV_S_TEXTASCII) - || !strcmp(track->codec_id, MKV_S_TEXTUTF8)) - track->subtitle_type = 't'; - else if (!strcmp(track->codec_id, MKV_S_PGS)) - track->subtitle_type = 'p'; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Codec ID: %s\n", - track->codec_id); - } else - mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Missing codec ID!\n"); - - if (entry->n_codec_private) { - int len = entry->codec_private.len; - track->private_data = talloc_size(track, len + AV_LZO_INPUT_PADDING); - memcpy(track->private_data, entry->codec_private.start, len); - track->private_size = len; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + CodecPrivate, length %u\n", - track->private_size); - } - - if (entry->n_language) { - track->language = talloc_strndup(track, entry->language.start, - entry->language.len); - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Language: %s\n", - track->language); - } else - track->language = talloc_strdup(track, "eng"); - - if (entry->n_flag_default) { - track->default_track = entry->flag_default; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Default flag: %u\n", - track->default_track); - } else - track->default_track = 1; - - if (entry->n_default_duration) { - track->default_duration = entry->default_duration / 1e9; - if (entry->default_duration == 0) - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Default duration: 0"); - else { - if (!track->v_frate) - track->v_frate = 1e9 / entry->default_duration; - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] | + Default duration: %.3fms ( = %.3f fps)\n", - entry->default_duration / 1000000.0, track->v_frate); - } - } - - if (entry->n_content_encodings) - parse_trackencodings(demuxer, track, &entry->content_encodings); - - mkv_d->tracks[mkv_d->num_tracks++] = track; -} - -static int demux_mkv_read_tracks(demuxer_t *demuxer) -{ - mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; - stream_t *s = demuxer->stream; - - struct ebml_tracks tracks = {}; - struct ebml_parse_ctx parse_ctx = {}; - if (ebml_read_element(s, &parse_ctx, &tracks, &ebml_tracks_desc) < 0) - return -1; - - mkv_d->tracks = talloc_size(mkv_d, - tracks.n_track_entry * sizeof(*mkv_d->tracks)); - for (int i = 0; i < tracks.n_track_entry; i++) { - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + a track...\n"); - parse_trackentry(demuxer, &tracks.track_entry[i]); - } - talloc_free(parse_ctx.talloc_ctx); - return 0; -} - -static int demux_mkv_read_cues(demuxer_t *demuxer) -{ - mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; - stream_t *s = demuxer->stream; - - if (index_mode == 0 || index_mode == 2) { - ebml_read_skip(s, NULL); - return 0; - } - - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing cues ] -----------\n"); - struct ebml_cues cues = {}; - struct ebml_parse_ctx parse_ctx = {}; - if (ebml_read_element(s, &parse_ctx, &cues, &ebml_cues_desc) < 0) - return -1; - for (int i = 0; i < cues.n_cue_point; i++) { - struct ebml_cue_point *cuepoint = &cues.cue_point[i]; - if (cuepoint->n_cue_time != 1 || !cuepoint->n_cue_track_positions) { - mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Malformed CuePoint element\n"); - continue; - } - uint64_t time = cuepoint->cue_time; - for (int i = 0; i < cuepoint->n_cue_track_positions; i++) { - struct ebml_cue_track_positions *trackpos = - &cuepoint->cue_track_positions[i]; - uint64_t track = trackpos->cue_track; - uint64_t pos = trackpos->cue_cluster_position; - 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; - mp_msg(MSGT_DEMUX, MSGL_DBG2, - "[mkv] |+ found cue point for track %" PRIu64 - ": timecode %" PRIu64 ", filepos: %" PRIu64 "\n", track, - time, mkv_d->segment_start + pos); - mkv_d->num_indexes++; - } - } - - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n"); - talloc_free(parse_ctx.talloc_ctx); - return 0; -} - -static int demux_mkv_read_chapters(struct demuxer *demuxer) -{ - struct MPOpts *opts = demuxer->opts; - stream_t *s = demuxer->stream; - - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n"); - struct ebml_chapters file_chapters = {}; - struct ebml_parse_ctx parse_ctx = {}; - if (ebml_read_element(s, &parse_ctx, &file_chapters, - &ebml_chapters_desc) < 0) - return -1; - - int selected_edition = 0; - int num_editions = file_chapters.n_edition_entry; - struct ebml_edition_entry *editions = file_chapters.edition_entry; - if (opts->edition_id >= 0 && opts->edition_id < num_editions) { - selected_edition = opts->edition_id; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] User-specified edition: %d\n", - selected_edition); - } else - for (int i = 0; i < num_editions; i++) - if (editions[i].edition_flag_default) { - selected_edition = i; - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Default edition: %d\n", i); - break; - } - struct matroska_chapter *m_chapters = NULL; - if (editions[selected_edition].edition_flag_ordered) { - int count = editions[selected_edition].n_chapter_atom; - m_chapters = talloc_array_ptrtype(demuxer, m_chapters, count); - demuxer->matroska_data.ordered_chapters = m_chapters; - demuxer->matroska_data.num_ordered_chapters = count; - } - - for (int idx = 0; idx < num_editions; idx++) { - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] New edition %d\n", idx); - int warn_level = idx == selected_edition ? MSGL_WARN : MSGL_V; - if (editions[idx].n_edition_flag_default) - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Default edition flag: %"PRIu64 - "\n", editions[idx].edition_flag_default); - if (editions[idx].n_edition_flag_ordered) - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Ordered chapter flag: %"PRIu64 - "\n", editions[idx].edition_flag_ordered); - for (int i = 0; i < editions[idx].n_chapter_atom; i++) { - struct ebml_chapter_atom *ca = editions[idx].chapter_atom + i; - struct matroska_chapter chapter = { }; - struct bstr name = { "(unnamed)", 9 }; - - if (!ca->n_chapter_time_start) - mp_msg(MSGT_DEMUX, warn_level, - "[mkv] Chapter lacks start time\n"); - chapter.start = ca->chapter_time_start; - chapter.end = ca->chapter_time_end; - - if (ca->n_chapter_display) { - if (ca->n_chapter_display > 1) - mp_msg(MSGT_DEMUX, warn_level, "[mkv] Multiple chapter " - "names not supported, picking first\n"); - if (!ca->chapter_display[0].n_chap_string) - mp_msg(MSGT_DEMUX, warn_level, "[mkv] Malformed chapter " - "name entry\n"); - else - name = ca->chapter_display[0].chap_string; - } - - if (ca->n_chapter_segment_uid) { - chapter.has_segment_uid = true; - int len = ca->chapter_segment_uid.len; - if (len != sizeof(chapter.segment_uid)) - mp_msg(MSGT_DEMUX, warn_level, - "[mkv] Chapter segment uid bad length %d\n", len); - else if (ca->n_chapter_segment_edition_uid) { - mp_tmsg(MSGT_DEMUX, warn_level, "[mkv] Warning: " - "unsupported edition recursion in chapter; " - "will skip on playback!\n"); - } else { - memcpy(chapter.segment_uid, ca->chapter_segment_uid.start, - len); - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Chapter segment uid "); - for (int i = 0; i < len; i++) - mp_msg(MSGT_DEMUX, MSGL_V, "%02x ", - chapter.segment_uid[i]); - mp_msg(MSGT_DEMUX, MSGL_V, "\n"); - } - } - - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] Chapter %u from %02d:%02d:%02d.%03d " - "to %02d:%02d:%02d.%03d, %.*s\n", i, - (int) (chapter.start / 60 / 60 / 1000000000), - (int) ((chapter.start / 60 / 1000000000) % 60), - (int) ((chapter.start / 1000000000) % 60), - (int) (chapter.start % 1000000000), - (int) (chapter.end / 60 / 60 / 1000000000), - (int) ((chapter.end / 60 / 1000000000) % 60), - (int) ((chapter.end / 1000000000) % 60), - (int) (chapter.end % 1000000000), - BSTR_P(name)); - - if (idx == selected_edition){ - demuxer_add_chapter(demuxer, name, chapter.start, chapter.end); - if (editions[idx].edition_flag_ordered) { - chapter.name = talloc_strndup(m_chapters, name.start, - name.len); - m_chapters[i] = chapter; - } - } - } - } - if (num_editions > 1) - mp_msg(MSGT_DEMUX, MSGL_INFO, - "[mkv] Found %d editions, will play #%d (first is 0).\n", - num_editions, selected_edition); - - demuxer->num_editions = num_editions; - demuxer->edition = selected_edition; - - talloc_free(parse_ctx.talloc_ctx); - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] \\---- [ parsing chapters ] ---------\n"); - return 0; -} - -static int demux_mkv_read_tags(demuxer_t *demuxer) -{ - stream_t *s = demuxer->stream; - - struct ebml_parse_ctx parse_ctx = {}; - struct ebml_tags tags = {}; - if (ebml_read_element(s, &parse_ctx, &tags, &ebml_tags_desc) < 0) - return -1; - - for (int i = 0; i < tags.n_tag; i++) { - struct ebml_tag tag = tags.tag[i]; - if (tag.targets.target_track_uid || tag.targets.target_edition_uid || - tag.targets.target_chapter_uid || tag.targets.target_attachment_uid) - continue; - - for (int j = 0; j < tag.n_simple_tag; j++) - demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name, tag.simple_tag[j].tag_string); - } - - talloc_free(parse_ctx.talloc_ctx); - return 0; -} - -static int demux_mkv_read_attachments(demuxer_t *demuxer) -{ - stream_t *s = demuxer->stream; - - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] /---- [ parsing attachments ] ---------\n"); - - struct ebml_attachments attachments = {}; - struct ebml_parse_ctx parse_ctx = {}; - if (ebml_read_element(s, &parse_ctx, &attachments, - &ebml_attachments_desc) < 0) - return -1; - - for (int i = 0; i < attachments.n_attached_file; i++) { - struct ebml_attached_file *attachment = &attachments.attached_file[i]; - if (!attachment->n_file_name || !attachment->n_file_mime_type - || !attachment->n_file_data) { - mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Malformed attachment\n"); - continue; - } - struct bstr name = attachment->file_name; - struct bstr mime = attachment->file_mime_type; - demuxer_add_attachment(demuxer, name, mime, attachment->file_data); - mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Attachment: %.*s, %.*s, %zu bytes\n", - BSTR_P(name), BSTR_P(mime), attachment->file_data.len); - } - - talloc_free(parse_ctx.talloc_ctx); - mp_msg(MSGT_DEMUX, MSGL_V, - "[mkv] \\---- [ parsing attachments ] ---------\n"); - return 0; -} - -static int read_header_element(struct demuxer *demuxer, uint32_t id, - off_t at_filepos); - -static int demux_mkv_read_seekhead(demuxer_t *demuxer) -{ - struct mkv_demuxer *mkv_d = demuxer->priv; - struct stream *s = demuxer->stream; - int res = 0; - struct ebml_seek_head seekhead = {}; - struct ebml_parse_ctx parse_ctx = {}; - |