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) {