demux_mkv.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,147 行 · 第 1/5 页
C
2,147 行
track->num_cached_dps = 0; track->num_allocated_dps = 0; track->max_pts = 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 = 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->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->sh_sub, start); else if (!strncasecmp(start, "palette:", 8)) things_found |= vobsub_parse_palette(t->sh_sub, start); else if (!strncasecmp(start, "custom colors:", 14)) things_found |= vobsub_parse_custom_colors(t->sh_sub, start); else if (!strncasecmp(start, "forced subs:", 12)) things_found |= vobsub_parse_forced_subs(t->sh_sub, 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, MSGTR_MPDEMUX_MKV_ZlibInitializationFailed); return modified; } zstream.next_in = (Bytef *) src; zstream.avail_in = *size; modified = 1; *dest = NULL; zstream.avail_out = *size; do { *size += 4000; *dest = 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, MSGTR_MPDEMUX_MKV_ZlibDecompressionFailed); 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; *dest = NULL; while (1) { int srclen = *size; if (dstlen > SIZE_MAX - LZO_OUTPUT_PADDING) goto lzo_fail; *dest = realloc (*dest, dstlen + LZO_OUTPUT_PADDING); result = lzo1x_decode (*dest, &dstlen, src, &srclen); if (result == 0) break; if (!(result & LZO_OUTPUT_FULL)) {lzo_fail: mp_msg (MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_LzoDecompressionFailed); free(*dest); *dest = NULL; return modified; } mp_msg (MSGT_DEMUX, MSGL_DBG2, "[mkv] lzo decompression buffer too small.\n"); dstlen *= 2; } *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; uint64_t tc_scale = 1000000; long double duration = 0.; 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; tc_scale = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + timecode scale: %"PRIu64"\n", tc_scale); break; } case MATROSKA_ID_DURATION: { long double num = ebml_read_float (s, &l); if (num == EBML_FLOAT_INVALID) return 1; duration = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3Lfs\n", duration * tc_scale / 1000000000.0); break; } default: ebml_read_skip (s, &l); break; } length -= l + il; } mkv_d->tc_scale = tc_scale; mkv_d->duration = duration * tc_scale / 1000000000.0; return 0;}/** * \brief free array of kv_content_encoding_t * \param encodings pointer to array * \param numencodings number of encodings in array */static voiddemux_mkv_free_encodings(mkv_content_encoding_t *encodings, int numencodings){ while (numencodings-- > 0) free(encodings[numencodings].comp_settings); free(encodings);}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 = 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) goto err_out; e.order = num; break; case MATROSKA_ID_CONTENTENCODINGSCOPE: num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) goto err_out; e.scope = num; break; case MATROSKA_ID_CONTENTENCODINGTYPE: num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) goto err_out; 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) goto err_out; e.comp_algo = num; break; case MATROSKA_ID_CONTENTCOMPSETTINGS: l = ebml_read_length (s, &i); e.comp_settings = 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, MSGTR_MPDEMUX_MKV_TrackEncrypted, track->tnum); } else if (e.type != 0) { mp_msg(MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownContentEncoding, track->tnum); } if (e.comp_algo != 0 && e.comp_algo != 2) { mp_msg (MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCompression, track->tnum, e.comp_algo); }#ifndef HAVE_ZLIB else if (e.comp_algo == 0) { mp_msg (MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_ZlibCompressionUnsupported, 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 = 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;err_out: demux_mkv_free_encodings(ce, n); return 0;}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; } case MATROSKA_ID_AUDIOCHANNELS: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->a_channels = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Channels: %u\n", track->a_channels); break; } default: ebml_read_skip (s, &l); break; } length -= l + il; } return len;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?