comparison libmpdemux/demux_mkv.cpp @ 10283:21972de8631d

Support for files whose first timecode is not 0 (which is the case for splitted/linked files).
author mosu
date Thu, 12 Jun 2003 19:12:00 +0000
parents 02c2c05b7da6
children c2fc1c310699
comparison
equal deleted inserted replaced
10282:12552a460f20 10283:21972de8631d
165 165
166 mkv_track_t **tracks; 166 mkv_track_t **tracks;
167 int num_tracks; 167 int num_tracks;
168 mkv_track_t *video, *audio, *subs_track; 168 mkv_track_t *video, *audio, *subs_track;
169 169
170 uint64_t tc_scale, cluster_tc; 170 uint64_t tc_scale, cluster_tc, first_tc;
171 171
172 mpstream_io_callback *in; 172 mpstream_io_callback *in;
173 173
174 uint64_t clear_subs_at; 174 uint64_t clear_subs_at;
175 175
271 #endif 271 #endif
272 272
273 vo_sub = &mkv_d->subs; 273 vo_sub = &mkv_d->subs;
274 vo_osd_changed(OSDTYPE_SUBTITLE); 274 vo_osd_changed(OSDTYPE_SUBTITLE);
275 275
276 mkv_d->clear_subs_at = block->GlobalTimecode() / 1000000 + duration; 276 mkv_d->clear_subs_at = block->GlobalTimecode() / 1000000 - mkv_d->first_tc +
277 duration;
277 } 278 }
278 279
279 static mkv_track_t *new_mkv_track(mkv_demuxer_t *d) { 280 static mkv_track_t *new_mkv_track(mkv_demuxer_t *d) {
280 mkv_track_t *t; 281 mkv_track_t *t;
281 282
690 break; 691 break;
691 692
692 if (EbmlId(*l3) == KaxCueTime::ClassInfos.GlobalId) { 693 if (EbmlId(*l3) == KaxCueTime::ClassInfos.GlobalId) {
693 KaxCueTime &cue_time = *static_cast<KaxCueTime *>(l3); 694 KaxCueTime &cue_time = *static_cast<KaxCueTime *>(l3);
694 cue_time.ReadData(es->I_O()); 695 cue_time.ReadData(es->I_O());
696 timecode = uint64(cue_time) * tc_scale / 1000000 - mkv_d->first_tc;
695 mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] | + found cue time: %.3fs\n", 697 mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] | + found cue time: %.3fs\n",
696 ((float)uint64(cue_time)) * tc_scale / 1000000000.0); 698 (float)timecode / 1000.0);
697
698 timecode = uint64(cue_time) * tc_scale / 1000000;
699 elements_found |= 1; 699 elements_found |= 1;
700 700
701 } else if (EbmlId(*l3) == 701 } else if (EbmlId(*l3) ==
702 KaxCueTrackPositions::ClassInfos.GlobalId) { 702 KaxCueTrackPositions::ClassInfos.GlobalId) {
703 mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] | + found cue track " 703 mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] | + found cue track "
1063 KaxTrackDefaultDuration::ClassInfos.GlobalId) { 1063 KaxTrackDefaultDuration::ClassInfos.GlobalId) {
1064 KaxTrackDefaultDuration &def_duration = 1064 KaxTrackDefaultDuration &def_duration =
1065 *static_cast<KaxTrackDefaultDuration *>(l3); 1065 *static_cast<KaxTrackDefaultDuration *>(l3);
1066 def_duration.ReadData(es->I_O()); 1066 def_duration.ReadData(es->I_O());
1067 track->v_frate = 1000000000.0 / (float)uint64(def_duration); 1067 track->v_frate = 1000000000.0 / (float)uint64(def_duration);
1068 fprintf(stdout, "[mkv] | + Default duration: %.3fms ( = %.3f " 1068 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Default duration: "
1069 "fps)\n", (float)uint64(def_duration) / 1000000.0, 1069 "%.3fms ( = %.3f fps)\n", (float)uint64(def_duration) /
1070 track->v_frate); 1070 1000000.0, track->v_frate);
1071 #endif // LIBEBML_VERSION 1071 #endif // LIBEBML_VERSION
1072 1072
1073 } else if (EbmlId(*l3) == KaxTrackType::ClassInfos.GlobalId) { 1073 } else if (EbmlId(*l3) == KaxTrackType::ClassInfos.GlobalId) {
1074 KaxTrackType &ttype = *static_cast<KaxTrackType *>(l3); 1074 KaxTrackType &ttype = *static_cast<KaxTrackType *>(l3);
1075 ttype.ReadData(es->I_O()); 1075 ttype.ReadData(es->I_O());
1428 if (!exit_loop) { 1428 if (!exit_loop) {
1429 free_mkv_demuxer(mkv_d); 1429 free_mkv_demuxer(mkv_d);
1430 return 0; 1430 return 0;
1431 } 1431 }
1432 1432
1433 // Try to find the very first timecode (cluster timecode).
1434 l2 = es->FindNextElement(l1->Generic().Context, upper_lvl_el,
1435 0xFFFFFFFFL, true, 1);
1436 if ((l2 != NULL) && !upper_lvl_el &&
1437 (EbmlId(*l2) == KaxClusterTimecode::ClassInfos.GlobalId)) {
1438 KaxClusterTimecode &ctc = *static_cast<KaxClusterTimecode *>(l2);
1439 ctc.ReadData(es->I_O());
1440 mkv_d->first_tc = uint64(ctc) * mkv_d->tc_scale / 1000000;
1441 delete l2;
1442 } else
1443 mkv_d->first_tc = 0;
1444 stream_seek(s, l1->GetElementPosition());
1445
1446 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] First tc: %lld\n", mkv_d->first_tc);
1447
1433 // If we have found an entry for the cues in the meta seek data but no 1448 // If we have found an entry for the cues in the meta seek data but no
1434 // cues at the front of the file then read them now. This way the 1449 // cues at the front of the file then read them now. This way the
1435 // timecode scale will have been initialized correctly. 1450 // timecode scale will have been initialized correctly.
1436 if (cues_pos && !mkv_d->cues_found) { 1451 if (cues_pos && !mkv_d->cues_found) {
1437 current_pos = io.getFilePointer(); 1452 current_pos = io.getFilePointer();
1439 mkv_d->cues_found = parse_cues(mkv_d); 1454 mkv_d->cues_found = parse_cues(mkv_d);
1440 if (s->eof) 1455 if (s->eof)
1441 stream_reset(s); 1456 stream_reset(s);
1442 io.setFilePointer(current_pos); 1457 io.setFilePointer(current_pos);
1443 } 1458 }
1444
1445 1459
1446 } catch (exception &ex) { 1460 } catch (exception &ex) {
1447 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] caught exception\n"); 1461 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] caught exception\n");
1448 return 0; 1462 return 0;
1449 } 1463 }
1822 1836
1823 if (block != NULL) { 1837 if (block != NULL) {
1824 // Clear the subtitles if they're obsolete now. 1838 // Clear the subtitles if they're obsolete now.
1825 if ((mkv_d->clear_subs_at > 0) && 1839 if ((mkv_d->clear_subs_at > 0) &&
1826 (mkv_d->clear_subs_at <= 1840 (mkv_d->clear_subs_at <=
1827 (block->GlobalTimecode() / 1000000))) { 1841 (block->GlobalTimecode() / 1000000 - mkv_d->first_tc))) {
1828 mkv_d->subs.lines = 0; 1842 mkv_d->subs.lines = 0;
1829 vo_sub = &mkv_d->subs; 1843 vo_sub = &mkv_d->subs;
1830 vo_osd_changed(OSDTYPE_SUBTITLE); 1844 vo_osd_changed(OSDTYPE_SUBTITLE);
1831 mkv_d->clear_subs_at = 0; 1845 mkv_d->clear_subs_at = 0;
1832 } 1846 }
1841 1855
1842 if (!mkv_d->skip_to_keyframe || // Not skipping is ok. 1856 if (!mkv_d->skip_to_keyframe || // Not skipping is ok.
1843 (((elements_found & 4) == 0) && // It's a key frame. 1857 (((elements_found & 4) == 0) && // It's a key frame.
1844 (ds != NULL) && // Corresponding track found 1858 (ds != NULL) && // Corresponding track found
1845 (ds == d->video))) { // track is our video track 1859 (ds == d->video))) { // track is our video track
1846 if ((ds != NULL) && ((block->GlobalTimecode() / 1000000) >= 1860 if ((ds != NULL) && ((block->GlobalTimecode() / 1000000 -
1861 mkv_d->first_tc) >=
1847 (uint64_t)mkv_d->skip_to_timecode)) { 1862 (uint64_t)mkv_d->skip_to_timecode)) {
1848 for (i = 0; i < (int)block->NumberFrames(); i++) { 1863 for (i = 0; i < (int)block->NumberFrames(); i++) {
1849 DataBuffer &data = block->GetBuffer(i); 1864 DataBuffer &data = block->GetBuffer(i);
1850 dp = new_demux_packet(data.Size()); 1865 dp = new_demux_packet(data.Size());
1851 memcpy(dp->buffer, data.Buffer(), data.Size()); 1866 memcpy(dp->buffer, data.Buffer(), data.Size());
1859 } else if ((mkv_d->subs_track != NULL) && 1874 } else if ((mkv_d->subs_track != NULL) &&
1860 (mkv_d->subs_track->tnum == block->TrackNum())) 1875 (mkv_d->subs_track->tnum == block->TrackNum()))
1861 handle_subtitles(d, block, block_duration); 1876 handle_subtitles(d, block, block_duration);
1862 1877
1863 d->filepos = mkv_d->in->getFilePointer(); 1878 d->filepos = mkv_d->in->getFilePointer();
1864 mkv_d->last_pts = (float)block->GlobalTimecode() / 1879 mkv_d->last_pts = (float)(block->GlobalTimecode() / 1000000.0 -
1865 1000000000.0; 1880 mkv_d->first_tc) / 1000.0;
1866 mkv_d->last_filepos = d->filepos; 1881 mkv_d->last_filepos = d->filepos;
1867 } 1882 }
1868 1883
1869 delete block; 1884 delete block;
1870 } // block != NULL 1885 } // block != NULL