Mercurial > mplayer.hg
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 |