📄 demux_mkv.c
字号:
t->sh_sub.forced_subs_only = 1; else if (!strncasecmp(start, "off", 3) || (*start == '0')) t->sh_sub.forced_subs_only = 0; else return 0; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] VobSub forced subs: %d\n", t->sh_sub.forced_subs_only); return 8;}/** \brief Free cached demux packets * * Reordering the timecodes requires caching of demux packets. This function * frees all these cached packets and the memory for the cached pointers * itself. * * \param demuxer The demuxer for which the cache is to be freed. */static voidfree_cached_dps (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; mkv_track_t *track; int i, k; for (k = 0; k < mkv_d->num_tracks; k++) { track = mkv_d->tracks[k]; for (i = 0; i < track->num_cached_dps; i++) free_demux_packet (track->cached_dps[i]); free(track->cached_dps); track->cached_dps = NULL; track->num_cached_dps = 0; track->num_allocated_dps = 0; }}static intdemux_mkv_parse_idx (mkv_track_t *t){ int things_found, last; char *buf, *pos, *start; if ((t->private_data == NULL) || (t->private_size == 0)) return 0; things_found = 0; buf = (char *)malloc(t->private_size + 1); if (buf == NULL) return 0; memcpy(buf, t->private_data, t->private_size); buf[t->private_size] = 0; t->sh_sub.type = 'v'; t->sh_sub.has_palette = 0; pos = buf; start = buf; last = 0; do { if ((*pos == 0) || (*pos == '\r') || (*pos == '\n')) { if (*pos == 0) last = 1; *pos = 0; if (!strncasecmp(start, "size: ", 6)) things_found |= vobsub_parse_size(t, start); else if (!strncasecmp(start, "palette:", 8)) things_found |= vobsub_parse_palette(t, start); else if (!strncasecmp(start, "custom colors:", 14)) things_found |= vobsub_parse_custom_colors(t, start); else if (!strncasecmp(start, "forced subs:", 12)) things_found |= vobsub_parse_forced_subs(t, start); if (last) break; do { pos++; } while ((*pos == '\r') || (*pos == '\n')); start = pos; } else pos++; } while (!last && (*start != 0)); free(buf); return (things_found & 3) == 3;}static intdemux_mkv_decode (mkv_track_t *track, uint8_t *src, uint8_t **dest, uint32_t *size, uint32_t type){ int i, result; int modified = 0; *dest = src; if (track->num_encodings <= 0) return 0; for (i=0; i<track->num_encodings; i++) { if (!(track->encodings[i].scope & type)) continue;#ifdef HAVE_ZLIB if (track->encodings[i].comp_algo == 0) { /* zlib encoded track */ z_stream zstream; zstream.zalloc = (alloc_func) 0; zstream.zfree = (free_func) 0; zstream.opaque = (voidpf) 0; if (inflateInit (&zstream) != Z_OK) { mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] zlib initialization failed.\n"); return modified; } zstream.next_in = (Bytef *) src; zstream.avail_in = *size; modified = 1; *dest = (uint8_t *) malloc (*size); zstream.avail_out = *size; do { *size += 4000; *dest = (uint8_t *) realloc (*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_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] zlib decompression failed.\n"); free(*dest); *dest = NULL; inflateEnd (&zstream); return modified; } zstream.avail_out += 4000; } while (zstream.avail_out == 4000 && zstream.avail_in != 0 && result != Z_STREAM_END); *size = zstream.total_out; inflateEnd (&zstream); }#endif if (track->encodings[i].comp_algo == 2) { /* lzo encoded track */ int dstlen = *size * 3; if (lzo_init () != LZO_E_OK) { mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] lzo initialization failed.\n"); return modified; } *dest = (uint8_t *) malloc (dstlen); while (1) { result = lzo1x_decompress_safe (src, *size, *dest, &dstlen, NULL); if (result == LZO_E_OK) break; if (result != LZO_E_OUTPUT_OVERRUN) { mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] lzo decompression failed.\n"); return modified; } mp_msg (MSGT_DEMUX, MSGL_DBG2, "[mkv] lzo decompression buffer too small.\n"); dstlen *= 2; *dest = (uint8_t *) realloc (*dest, dstlen); } *size = dstlen; } } return modified;}static intdemux_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; length = ebml_read_length (s, NULL); while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_TIMECODESCALE: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 1; mkv_d->tc_scale = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + timecode scale: %llu\n", mkv_d->tc_scale); break; } case MATROSKA_ID_DURATION: { long double num = ebml_read_float (s, &l); if (num == EBML_FLOAT_INVALID) return 1; mkv_d->duration = num * mkv_d->tc_scale / 1000000000.0; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3fs\n", mkv_d->duration); break; } default: ebml_read_skip (s, &l); break; } length -= l + il; } return 0;}static intdemux_mkv_read_trackencodings (demuxer_t *demuxer, mkv_track_t *track){ stream_t *s = demuxer->stream; mkv_content_encoding_t *ce, e; uint64_t len, length, l; int il, n; ce = (mkv_content_encoding_t *) malloc (sizeof (*ce)); n = 0; len = length = ebml_read_length (s, &il); len += il; while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_CONTENTENCODING: { uint64_t len; int i; memset (&e, 0, sizeof (e)); e.scope = 1; len = ebml_read_length (s, &i); l = len + i; while (len > 0) { uint64_t num, l; int il; switch (ebml_read_id (s, &il)) { case MATROSKA_ID_CONTENTENCODINGORDER: num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; e.order = num; break; case MATROSKA_ID_CONTENTENCODINGSCOPE: num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; e.scope = num; break; case MATROSKA_ID_CONTENTENCODINGTYPE: num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; e.type = num; break; case MATROSKA_ID_CONTENTCOMPRESSION: { uint64_t le; le = ebml_read_length (s, &i); l = le + i; while (le > 0) { uint64_t l; int il; switch (ebml_read_id (s, &il)) { case MATROSKA_ID_CONTENTCOMPALGO: num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; e.comp_algo = num; break; case MATROSKA_ID_CONTENTCOMPSETTINGS: l = ebml_read_length (s, &i); e.comp_settings = (uint8_t *) malloc (l); stream_read (s, e.comp_settings, l); e.comp_settings_len = l; l += i; break; default: ebml_read_skip (s, &l); break; } le -= l + il; } if (e.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", track->tnum); } else if (e.type != 0) { mp_msg(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, "[mkv] Track %u has been compressed with an " "unknown/unsupported compression algorithm " "(%u). Skipping track.\n", track->tnum, e.comp_algo); }#ifndef HAVE_ZLIB else if (e.comp_algo == 0) { 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", track->tnum); }#endif break; } default: ebml_read_skip (s, &l); break; } len -= l + il; } for (i=0; i<n; i++) if (e.order <= ce[i].order) break; ce = (mkv_content_encoding_t *) realloc (ce, (n+1) *sizeof (*ce)); memmove (ce+i+1, ce+i, (n-i) * sizeof (*ce)); memcpy (ce+i, &e, sizeof (e)); n++; break; } default: ebml_read_skip (s, &l); break; } length -= l + il; } track->encodings = ce; track->num_encodings = n; return len;}static intdemux_mkv_read_trackaudio (demuxer_t *demuxer, mkv_track_t *track){ stream_t *s = demuxer->stream; uint64_t len, length, l; int il; track->a_sfreq = 8000.0; track->a_channels = 1; len = length = ebml_read_length (s, &il); len += il; while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_AUDIOSAMPLINGFREQ: { long double num = ebml_read_float (s, &l); if (num == EBML_FLOAT_INVALID) return 0; track->a_sfreq = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Sampling frequency: %f\n", track->a_sfreq); break; } case MATROSKA_ID_AUDIOBITDEPTH: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->a_bps = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Bit depth: %u\n", track->a_bps); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -