demux_mkv.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,147 行 · 第 1/5 页
C
2,147 行
mkv_d->num_indexes++; } } mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n"); return 0;}static intdemux_mkv_read_chapters (demuxer_t *demuxer){ stream_t *s = demuxer->stream; uint64_t length, l; int il; if (demuxer->chapters) { ebml_read_skip (s, NULL); return 0; } mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n"); length = ebml_read_length (s, NULL); while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_EDITIONENTRY: { uint64_t len; int i; 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_CHAPTERATOM: { uint64_t len, start=0, end=0; char* name = 0; int i; int cid; 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_CHAPTERTIMESTART: start = ebml_read_uint (s, &l) / 1000000; break; case MATROSKA_ID_CHAPTERTIMEEND: end = ebml_read_uint (s, &l) / 1000000; break; case MATROSKA_ID_CHAPTERDISPLAY: { uint64_t len; int i; 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_CHAPSTRING: name = ebml_read_utf8 (s, &l); break; default: ebml_read_skip (s, &l); break; } len -= l + il; } } break; default: ebml_read_skip (s, &l); break; } len -= l + il; } if (!name) name = strdup("(unnamed)"); cid = demuxer_add_chapter(demuxer, name, start, end); mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Chapter %u from %02d:%02d:%02d." "%03d to %02d:%02d:%02d.%03d, %s\n", cid, (int) (start / 60 / 60 / 1000), (int) ((start / 60 / 1000) % 60), (int) ((start / 1000) % 60), (int) (start % 1000), (int) (end / 60 / 60 / 1000), (int) ((end / 60 / 1000) % 60), (int) ((end / 1000) % 60), (int) (end % 1000), name); free(name); break; } default: ebml_read_skip (s, &l); break; } len -= l + il; } break; } default: ebml_read_skip (s, &l); break; } length -= l + il; } mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing chapters ] ---------\n"); return 0;}static intdemux_mkv_read_tags (demuxer_t *demuxer){ ebml_read_skip (demuxer->stream, NULL); return 0;}static intdemux_mkv_read_attachments (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; uint64_t length, l; int il; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing attachments ] ---------\n"); length = ebml_read_length (s, NULL); while (length > 0) { switch (ebml_read_id (s, &il)) { case MATROSKA_ID_ATTACHEDFILE: { uint64_t len; int i; char* name = NULL; char* mime = NULL; uint64_t uid = 0; char* data = NULL; int data_size = 0; len = ebml_read_length (s, &i); l = len + i; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + an attachment...\n"); grow_array(&mkv_d->attachments, mkv_d->num_attachments, sizeof(*mkv_d->attachments)); while (len > 0) { uint64_t l; int il; switch (ebml_read_id (s, &il)) { case MATROSKA_ID_FILENAME: name = ebml_read_utf8 (s, &l); if (name == NULL) return 0; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + FileName: %s\n", name); break; case MATROSKA_ID_FILEMIMETYPE: mime = ebml_read_ascii (s, &l); if (mime == NULL) return 0; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + FileMimeType: %s\n", mime); break; case MATROSKA_ID_FILEUID: uid = ebml_read_uint (s, &l); break; case MATROSKA_ID_FILEDATA: { int x; uint64_t num = ebml_read_length (s, &x); l = x + num; free(data); data = malloc (num); if (stream_read(s, data, num) != (int) num) { free(data); return 0; } data_size = num; mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + FileData, length " "%u\n", data_size); break; } default: ebml_read_skip (s, &l); break; } len -= l + il; } mkv_d->attachments[mkv_d->num_attachments].name = name; mkv_d->attachments[mkv_d->num_attachments].mime = mime; mkv_d->attachments[mkv_d->num_attachments].uid = uid; mkv_d->attachments[mkv_d->num_attachments].data = data; mkv_d->attachments[mkv_d->num_attachments].data_size = data_size; mkv_d->num_attachments ++; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Attachment: %s, %s, %u bytes\n", name, mime, data_size);#ifdef USE_ASS if (ass_library && extract_embedded_fonts && name && data && data_size && mime && (strcmp(mime, "application/x-truetype-font") == 0 || strcmp(mime, "application/x-font") == 0)) ass_add_font(ass_library, name, data, data_size);#endif break; } default: ebml_read_skip (s, &l); break; } length -= l + il; } mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing attachments ] ---------\n"); return 0;}static intdemux_mkv_read_seekhead (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; uint64_t length, l, seek_pos, saved_pos, num; uint32_t seek_id; int i, il, res = 0; off_t off; off = stream_tell (s); for (i=0; i<mkv_d->parsed_seekhead_num; i++) if (mkv_d->parsed_seekhead[i] == off) { ebml_read_skip (s, NULL); return 0; } mkv_d->parsed_seekhead = realloc (mkv_d->parsed_seekhead, (mkv_d->parsed_seekhead_num+1) * sizeof (off_t)); mkv_d->parsed_seekhead[mkv_d->parsed_seekhead_num++] = off; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing seek head ] ---------\n"); length = ebml_read_length (s, NULL); /* off now holds the position of the next element after the seek head. */ off = stream_tell (s) + length; while (length > 0 && !res) { seek_id = 0; seek_pos = EBML_UINT_INVALID; switch (ebml_read_id (s, &il)) { case MATROSKA_ID_SEEKENTRY: { 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_SEEKID: num = ebml_read_uint (s, &l); if (num != EBML_UINT_INVALID) seek_id = num; break; case MATROSKA_ID_SEEKPOSITION: seek_pos = ebml_read_uint (s, &l); break; default: ebml_read_skip (s, &l); break; } len -= l + il; } break; } default: ebml_read_skip (s, &l); break; } length -= l + il; if (seek_id == 0 || seek_id == MATROSKA_ID_CLUSTER || seek_pos == EBML_UINT_INVALID || ((mkv_d->segment_start + seek_pos) >= (uint64_t)demuxer->movi_end)) continue; saved_pos = stream_tell (s); if (!stream_seek (s, mkv_d->segment_start + seek_pos)) res = 1; else { if (ebml_read_id (s, &il) != seek_id) res = 1; else switch (seek_id) { case MATROSKA_ID_CUES: if (demux_mkv_read_cues (demuxer)) res = 1; break; case MATROSKA_ID_TAGS: if (demux_mkv_read_tags (demuxer)) res = 1; break; case MATROSKA_ID_SEEKHEAD: if (demux_mkv_read_seekhead (demuxer)) res = 1; break; case MATROSKA_ID_CHAPTERS: if (demux_mkv_read_chapters (demuxer)) res = 1; break; } } stream_seek (s, saved_pos); } if (res) { /* If there was an error then try to skip this seek head. */ if (stream_seek (s, off)) res = 0; } else if (length > 0) stream_seek (s, stream_tell (s) + length); mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing seek head ] ---------\n"); return res;}static intdemux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid);static intdemux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid);static intdemux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track, int sid);static voiddisplay_create_tracks (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *)demuxer->priv; int i, vid=0, aid=0, sid=0; for (i=0; i<mkv_d->num_tracks; i++) { char *type = "unknown", str[32]; *str = '\0'; switch (mkv_d->tracks[i]->type) { case MATROSKA_TRACK_VIDEO: type = "video"; demux_mkv_open_video(demuxer, mkv_d->tracks[i], vid); if (mkv_d->tracks[i]->name) mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", vid, mkv_d->tracks[i]->name); sprintf (str, "-vid %u", vid++); break; case MATROSKA_TRACK_AUDIO: type = "audio"; demux_mkv_open_audio(demuxer, mkv_d->tracks[i], aid); if (mkv_d->tracks[i]->name) mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", aid, mkv_d->tracks[i]->name); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n", aid, mkv_d->tracks[i]->language); sprintf (str, "-aid %u, -alang %.5s",aid++,mkv_d->tracks[i]->language); break; case MATROSKA_TRACK_SUBTITLE: type = "subtitles"; demux_mkv_open_sub(demuxer, mkv_d->tracks[i], sid); if (mkv_d->tracks[i]->name)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?