Mercurial > mplayer.hg
comparison libmpdemux/demux_mkv.c @ 19342:4e68a3881201
Add matroska chapter seeking capability.
author | eugeni |
---|---|
date | Sun, 06 Aug 2006 18:55:34 +0000 |
parents | 2895b9807ff3 |
children | de5065d3ce74 |
comparison
equal
deleted
inserted
replaced
19341:f6661e33aa60 | 19342:4e68a3881201 |
---|---|
139 { | 139 { |
140 int tnum; | 140 int tnum; |
141 uint64_t timecode, filepos; | 141 uint64_t timecode, filepos; |
142 } mkv_index_t; | 142 } mkv_index_t; |
143 | 143 |
144 typedef struct mkv_chapter | |
145 { | |
146 uint64_t start, end; | |
147 } mkv_chapter_t; | |
148 | |
149 typedef struct mkv_attachment | 144 typedef struct mkv_attachment |
150 { | 145 { |
151 char* name; | 146 char* name; |
152 char* mime; | 147 char* mime; |
153 uint64_t uid; | 148 uint64_t uid; |
186 int num_cluster_pos; | 181 int num_cluster_pos; |
187 | 182 |
188 int64_t skip_to_timecode; | 183 int64_t skip_to_timecode; |
189 int v_skip_to_keyframe, a_skip_to_keyframe; | 184 int v_skip_to_keyframe, a_skip_to_keyframe; |
190 | 185 |
191 mkv_chapter_t *chapters; | |
192 int num_chapters; | |
193 int64_t stop_timecode; | 186 int64_t stop_timecode; |
194 | 187 |
195 int last_aid; | 188 int last_aid; |
196 int audio_tracks[MAX_A_STREAMS]; | 189 int audio_tracks[MAX_A_STREAMS]; |
197 | 190 |
1326 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; | 1319 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
1327 stream_t *s = demuxer->stream; | 1320 stream_t *s = demuxer->stream; |
1328 uint64_t length, l; | 1321 uint64_t length, l; |
1329 int il; | 1322 int il; |
1330 | 1323 |
1331 if (mkv_d->chapters) | 1324 if (demuxer->chapters) |
1332 { | 1325 { |
1333 ebml_read_skip (s, NULL); | 1326 ebml_read_skip (s, NULL); |
1334 return 0; | 1327 return 0; |
1335 } | 1328 } |
1336 | 1329 |
1357 switch (ebml_read_id (s, &il)) | 1350 switch (ebml_read_id (s, &il)) |
1358 { | 1351 { |
1359 case MATROSKA_ID_CHAPTERATOM: | 1352 case MATROSKA_ID_CHAPTERATOM: |
1360 { | 1353 { |
1361 uint64_t len, start=0, end=0; | 1354 uint64_t len, start=0, end=0; |
1355 char* name = 0; | |
1362 int i; | 1356 int i; |
1357 int cid; | |
1363 | 1358 |
1364 len = ebml_read_length (s, &i); | 1359 len = ebml_read_length (s, &i); |
1365 l = len + i; | 1360 l = len + i; |
1366 | |
1367 if (mkv_d->chapters == NULL) | |
1368 mkv_d->chapters = malloc (32*sizeof(*mkv_d->chapters)); | |
1369 else if (!(mkv_d->num_chapters % 32)) | |
1370 mkv_d->chapters = realloc (mkv_d->chapters, | |
1371 (mkv_d->num_chapters + 32) | |
1372 * sizeof(*mkv_d->chapters)); | |
1373 | 1361 |
1374 while (len > 0) | 1362 while (len > 0) |
1375 { | 1363 { |
1376 uint64_t l; | 1364 uint64_t l; |
1377 int il; | 1365 int il; |
1382 start = ebml_read_uint (s, &l) / 1000000; | 1370 start = ebml_read_uint (s, &l) / 1000000; |
1383 break; | 1371 break; |
1384 | 1372 |
1385 case MATROSKA_ID_CHAPTERTIMEEND: | 1373 case MATROSKA_ID_CHAPTERTIMEEND: |
1386 end = ebml_read_uint (s, &l) / 1000000; | 1374 end = ebml_read_uint (s, &l) / 1000000; |
1375 break; | |
1376 | |
1377 case MATROSKA_ID_CHAPTERDISPLAY: | |
1378 { | |
1379 uint64_t len; | |
1380 int i; | |
1381 | |
1382 len = ebml_read_length (s, &i); | |
1383 l = len + i; | |
1384 while (len > 0) | |
1385 { | |
1386 uint64_t l; | |
1387 int il; | |
1388 | |
1389 switch (ebml_read_id (s, &il)) | |
1390 { | |
1391 case MATROSKA_ID_CHAPSTRING: | |
1392 name = ebml_read_utf8 (s, &l); | |
1393 break; | |
1394 default: | |
1395 ebml_read_skip (s, &l); | |
1396 break; | |
1397 } | |
1398 len -= l + il; | |
1399 } | |
1400 } | |
1387 break; | 1401 break; |
1388 | 1402 |
1389 default: | 1403 default: |
1390 ebml_read_skip (s, &l); | 1404 ebml_read_skip (s, &l); |
1391 break; | 1405 break; |
1392 } | 1406 } |
1393 len -= l + il; | 1407 len -= l + il; |
1394 } | 1408 } |
1395 | 1409 |
1396 mkv_d->chapters[mkv_d->num_chapters].start = start; | 1410 if (!name) |
1397 mkv_d->chapters[mkv_d->num_chapters].end = end; | 1411 name = strdup("(unnamed)"); |
1412 | |
1413 cid = demuxer_add_chapter(demuxer, name, start, end); | |
1414 | |
1398 mp_msg(MSGT_DEMUX, MSGL_V, | 1415 mp_msg(MSGT_DEMUX, MSGL_V, |
1399 "[mkv] Chapter %u from %02d:%02d:%02d." | 1416 "[mkv] Chapter %u from %02d:%02d:%02d." |
1400 "%03d to %02d:%02d:%02d.%03d\n", | 1417 "%03d to %02d:%02d:%02d.%03d, %s\n", |
1401 ++mkv_d->num_chapters, | 1418 cid, |
1402 (int) (start / 60 / 60 / 1000), | 1419 (int) (start / 60 / 60 / 1000), |
1403 (int) ((start / 60 / 1000) % 60), | 1420 (int) ((start / 60 / 1000) % 60), |
1404 (int) ((start / 1000) % 60), | 1421 (int) ((start / 1000) % 60), |
1405 (int) (start % 1000), | 1422 (int) (start % 1000), |
1406 (int) (end / 60 / 60 / 1000), | 1423 (int) (end / 60 / 60 / 1000), |
1407 (int) ((end / 60 / 1000) % 60), | 1424 (int) ((end / 60 / 1000) % 60), |
1408 (int) ((end / 1000) % 60), | 1425 (int) ((end / 1000) % 60), |
1409 (int) (end % 1000)); | 1426 (int) (end % 1000), name); |
1427 | |
1428 free(name); | |
1410 break; | 1429 break; |
1411 } | 1430 } |
1412 | 1431 |
1413 default: | 1432 default: |
1414 ebml_read_skip (s, &l); | 1433 ebml_read_skip (s, &l); |
2579 demuxer->sub->id = track->tnum; | 2598 demuxer->sub->id = track->tnum; |
2580 } | 2599 } |
2581 else | 2600 else |
2582 demuxer->sub->id = -2; | 2601 demuxer->sub->id = -2; |
2583 | 2602 |
2584 if (mkv_d->chapters) | 2603 if (demuxer->chapters) |
2585 { | 2604 { |
2586 for (i=0; i < (int)mkv_d->num_chapters; i++) | 2605 for (i=0; i < (int)demuxer->num_chapters; i++) |
2587 { | 2606 { |
2588 mkv_d->chapters[i].start -= mkv_d->first_tc; | 2607 demuxer->chapters[i].start -= mkv_d->first_tc; |
2589 mkv_d->chapters[i].end -= mkv_d->first_tc; | 2608 demuxer->chapters[i].end -= mkv_d->first_tc; |
2590 } | 2609 } |
2591 if (dvd_last_chapter > 0 && dvd_last_chapter <= mkv_d->num_chapters) | 2610 if (dvd_last_chapter > 0 && dvd_last_chapter <= demuxer->num_chapters) |
2592 { | 2611 { |
2593 if (mkv_d->chapters[dvd_last_chapter-1].end != 0) | 2612 if (demuxer->chapters[dvd_last_chapter-1].end != 0) |
2594 mkv_d->stop_timecode = mkv_d->chapters[dvd_last_chapter-1].end; | 2613 mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter-1].end; |
2595 else if (dvd_last_chapter + 1 <= mkv_d->num_chapters) | 2614 else if (dvd_last_chapter + 1 <= demuxer->num_chapters) |
2596 mkv_d->stop_timecode = mkv_d->chapters[dvd_last_chapter].start; | 2615 mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter].start; |
2597 } | 2616 } |
2598 } | 2617 } |
2599 | 2618 |
2600 if (s->end_pos == 0 || (mkv_d->indexes == NULL && index_mode < 0)) | 2619 if (s->end_pos == 0 || (mkv_d->indexes == NULL && index_mode < 0)) |
2601 demuxer->seekable = 0; | 2620 demuxer->seekable = 0; |
2602 else | 2621 else |
2603 { | 2622 { |
2604 demuxer->movi_start = s->start_pos; | 2623 demuxer->movi_start = s->start_pos; |
2605 demuxer->movi_end = s->end_pos; | 2624 demuxer->movi_end = s->end_pos; |
2606 demuxer->seekable = 1; | 2625 demuxer->seekable = 1; |
2607 if (mkv_d->chapters && dvd_chapter>1 && dvd_chapter<=mkv_d->num_chapters) | 2626 if (demuxer->chapters && dvd_chapter>1 && dvd_chapter<=demuxer->num_chapters) |
2608 { | 2627 { |
2609 if (!mkv_d->has_first_tc) | 2628 if (!mkv_d->has_first_tc) |
2610 { | 2629 { |
2611 mkv_d->first_tc = 0; | 2630 mkv_d->first_tc = 0; |
2612 mkv_d->has_first_tc = 1; | 2631 mkv_d->has_first_tc = 1; |
2613 } | 2632 } |
2614 demux_mkv_seek (demuxer, | 2633 demux_mkv_seek (demuxer, |
2615 mkv_d->chapters[dvd_chapter-1].start/1000.0, 0.0, 1); | 2634 demuxer->chapters[dvd_chapter-1].start/1000.0, 0.0, 1); |
2616 } | 2635 } |
2617 } | 2636 } |
2618 | 2637 |
2619 return DEMUXER_TYPE_MATROSKA; | 2638 return DEMUXER_TYPE_MATROSKA; |
2620 } | 2639 } |
2657 } | 2676 } |
2658 if (mkv_d->indexes) | 2677 if (mkv_d->indexes) |
2659 free (mkv_d->indexes); | 2678 free (mkv_d->indexes); |
2660 if (mkv_d->cluster_positions) | 2679 if (mkv_d->cluster_positions) |
2661 free (mkv_d->cluster_positions); | 2680 free (mkv_d->cluster_positions); |
2662 if (mkv_d->chapters) | |
2663 free (mkv_d->chapters); | |
2664 if (mkv_d->parsed_cues) | 2681 if (mkv_d->parsed_cues) |
2665 free (mkv_d->parsed_cues); | 2682 free (mkv_d->parsed_cues); |
2666 if (mkv_d->parsed_seekhead) | 2683 if (mkv_d->parsed_seekhead) |
2667 free (mkv_d->parsed_seekhead); | 2684 free (mkv_d->parsed_seekhead); |
2668 if (mkv_d->attachments) { | 2685 if (mkv_d->attachments) { |