📄 demux_mkv.c
字号:
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;}static intdemux_mkv_read_trackvideo (demuxer_t *demuxer, mkv_track_t *track){ stream_t *s = demuxer->stream; uint64_t len, length, l; int il; len = length = ebml_read_length (s, &il); len += il; while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_VIDEOFRAMERATE: { long double num = ebml_read_float (s, &l); if (num == EBML_FLOAT_INVALID) return 0; track->v_frate = num; 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; break; } case MATROSKA_ID_VIDEODISPLAYWIDTH: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->v_dwidth = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Display width: %u\n", track->v_dwidth); break; } case MATROSKA_ID_VIDEODISPLAYHEIGHT: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->v_dheight = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Display height: %u\n", track->v_dheight); break; } case MATROSKA_ID_VIDEOPIXELWIDTH: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->v_width = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Pixel width: %u\n", track->v_width); break; } case MATROSKA_ID_VIDEOPIXELHEIGHT: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->v_height = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Pixel height: %u\n", track->v_height); break; } default: ebml_read_skip (s, &l); break; } length -= l + il; } return len;}static intdemux_mkv_read_trackentry (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; mkv_track_t *track; uint64_t len, length, l; int il; track = (mkv_track_t *) malloc (sizeof (*track)); memset(track, 0, sizeof(*track)); /* set default values */ track->default_track = 1; track->language = strdup("eng"); len = length = ebml_read_length (s, &il); len += il; while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_TRACKNUMBER: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->tnum = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Track number: %u\n", track->tnum); break; } case MATROSKA_ID_TRACKTYPE: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->type = num; 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; } break; } case MATROSKA_ID_TRACKAUDIO: mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Audio track\n"); l = demux_mkv_read_trackaudio (demuxer, track); if (l == 0) return 0; break; case MATROSKA_ID_TRACKVIDEO: mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Video track\n"); l = demux_mkv_read_trackvideo (demuxer, track); if (l == 0) return 0; break; case MATROSKA_ID_CODECID: track->codec_id = ebml_read_ascii (s, &l); if (track->codec_id == NULL) return 0; 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 = MATROSKA_SUBTYPE_VOBSUB; 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 = MATROSKA_SUBTYPE_SSA; } else if (!strcmp (track->codec_id, MKV_S_TEXTASCII)) track->subtitle_type = MATROSKA_SUBTYPE_TEXT; if (!strcmp (track->codec_id, MKV_S_TEXTUTF8)) { track->subtitle_type = MATROSKA_SUBTYPE_TEXT; } mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Codec ID: %s\n", track->codec_id); break; case MATROSKA_ID_CODECPRIVATE: { int x; uint64_t num = ebml_read_length (s, &x); l = x + num; track->private_data = malloc (num); if (stream_read(s, track->private_data, num) != (int) num) return 0; track->private_size = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + CodecPrivate, length " "%u\n", track->private_size); break; } case MATROSKA_ID_TRACKLANGUAGE: track->language = ebml_read_utf8 (s, &l); if (track->language == NULL) return 0; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Language: %s\n", track->language); break; case MATROSKA_ID_TRACKFLAGDEFAULT: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; track->default_track = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Default flag: %u\n", track->default_track); break; } case MATROSKA_ID_TRACKDEFAULTDURATION: { uint64_t num = ebml_read_uint (s, &l); if (num == EBML_UINT_INVALID) return 0; if (num == 0) mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Default duration: 0"); else { track->v_frate = 1000000000.0 / num; track->default_duration = num / 1000000000.0; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + Default duration: " "%.3fms ( = %.3f fps)\n",num/1000000.0,track->v_frate); } break; } case MATROSKA_ID_TRACKENCODINGS: l = demux_mkv_read_trackencodings (demuxer, track); if (l == 0) return 0; break; default: ebml_read_skip (s, &l); break; } length -= l + il; } mkv_d->tracks[mkv_d->num_tracks++] = track; return len;}static intdemux_mkv_read_tracks (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; uint64_t length, l; int il; mkv_d->tracks = (mkv_track_t **) malloc (sizeof (*mkv_d->tracks)); mkv_d->num_tracks = 0; length = ebml_read_length (s, NULL); while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_TRACKENTRY: mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + a track...\n"); mkv_d->tracks = (mkv_track_t **) realloc (mkv_d->tracks, (mkv_d->num_tracks+1) *sizeof (*mkv_d->tracks)); l = demux_mkv_read_trackentry (demuxer); if (l == 0) return 1; break; default: ebml_read_skip (s, &l); break; } length -= l + il; } return 0;}static intdemux_mkv_read_cues (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; uint64_t length, l, time, track, pos; off_t off; int i, il; off = stream_tell (s); for (i=0; i<mkv_d->parsed_cues_num; i++) if (mkv_d->parsed_cues[i] == off) { ebml_read_skip (s, NULL); return 0; } mkv_d->parsed_cues = (off_t *) realloc (mkv_d->parsed_cues, (mkv_d->parsed_cues_num+1) * sizeof (off_t)); mkv_d->parsed_cues[mkv_d->parsed_cues_num++] = off; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing cues ] -----------\n"); length = ebml_read_length (s, NULL); while (length > 0) { time = track = pos = EBML_UINT_INVALID; switch (ebml_read_id (s, &il)) { case MATROSKA_ID_POINTENTRY: { uint64_t len; len = ebml_read_length (s, &i); l = len + i; while (len > 0) { uint64_t l; int il; switch (ebml_read_id (s, &il)) { case MATROSKA_ID_CUETIME: time = ebml_read_uint (s, &l); break; case MATROSKA_ID_CUETRACKPOSITION: { 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_CUETRACK: track = ebml_read_uint (s, &l); break; case MATROSKA_ID_CUECLUSTERPOSITION: pos = ebml_read_uint (s, &l); break; default: ebml_read_skip (s, &l); break; } le -= l + il; } break; } default: ebml_read_skip (s, &l); break; } len -= l + il; } break; } default: ebml_read_skip (s, &l); break; } length -= l + il; if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID && pos != EBML_UINT_INVALID) { if (mkv_d->indexes == NULL) mkv_d->indexes = (mkv_index_t *) malloc (32*sizeof (mkv_index_t)); else if (mkv_d->num_indexes % 32 == 0) mkv_d->indexes = (mkv_index_t *) realloc (mkv_d->indexes, (mkv_d->num_indexes+32) *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 %llu: timecode %llu, filepos: %llu\n", track, time, mkv_d->segment_start + pos); mkv_d->num_indexes++; } } mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n"); return 0;}static intdemux_mkv_read_chapters (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; uint64_t length, l; int il; if (mkv_d->chapters) { ebml_read_skip (s, NULL); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -