changeset 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 12552a460f20
children fbe033f27a14
files libmpdemux/demux_mkv.cpp
diffstat 1 files changed, 28 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_mkv.cpp	Wed Jun 11 22:27:50 2003 +0000
+++ b/libmpdemux/demux_mkv.cpp	Thu Jun 12 19:12:00 2003 +0000
@@ -167,7 +167,7 @@
   int num_tracks;
   mkv_track_t *video, *audio, *subs_track;
 
-  uint64_t tc_scale, cluster_tc;
+  uint64_t tc_scale, cluster_tc, first_tc;
 
   mpstream_io_callback *in;
 
@@ -273,7 +273,8 @@
   vo_sub = &mkv_d->subs;
   vo_osd_changed(OSDTYPE_SUBTITLE);
 
-  mkv_d->clear_subs_at = block->GlobalTimecode() / 1000000 + duration;
+  mkv_d->clear_subs_at = block->GlobalTimecode() / 1000000 - mkv_d->first_tc +
+    duration;
 }
 
 static mkv_track_t *new_mkv_track(mkv_demuxer_t *d) {
@@ -692,10 +693,9 @@
         if (EbmlId(*l3) == KaxCueTime::ClassInfos.GlobalId) {
           KaxCueTime &cue_time = *static_cast<KaxCueTime *>(l3);
           cue_time.ReadData(es->I_O());
+          timecode = uint64(cue_time) * tc_scale / 1000000 - mkv_d->first_tc;
           mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] |  + found cue time: %.3fs\n",
-                 ((float)uint64(cue_time)) * tc_scale / 1000000000.0);
-
-          timecode = uint64(cue_time) * tc_scale / 1000000;
+                 (float)timecode / 1000.0);
           elements_found |= 1;
 
         } else if (EbmlId(*l3) ==
@@ -1065,9 +1065,9 @@
                   *static_cast<KaxTrackDefaultDuration *>(l3);
                 def_duration.ReadData(es->I_O());
                 track->v_frate = 1000000000.0 / (float)uint64(def_duration);
-                fprintf(stdout, "[mkv] |  + Default duration: %.3fms ( = %.3f "
-                        "fps)\n", (float)uint64(def_duration) / 1000000.0,
-                        track->v_frate);
+                mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] |  + Default duration: "
+                       "%.3fms ( = %.3f fps)\n", (float)uint64(def_duration) /
+                       1000000.0, track->v_frate);
 #endif // LIBEBML_VERSION
 
               } else if (EbmlId(*l3) == KaxTrackType::ClassInfos.GlobalId) {
@@ -1430,6 +1430,21 @@
       return 0;
     }
 
+    // Try to find the very first timecode (cluster timecode).
+    l2 = es->FindNextElement(l1->Generic().Context, upper_lvl_el,
+                             0xFFFFFFFFL, true, 1);
+    if ((l2 != NULL) && !upper_lvl_el &&
+        (EbmlId(*l2) == KaxClusterTimecode::ClassInfos.GlobalId)) {
+      KaxClusterTimecode &ctc = *static_cast<KaxClusterTimecode *>(l2);
+      ctc.ReadData(es->I_O());
+      mkv_d->first_tc = uint64(ctc) * mkv_d->tc_scale / 1000000;
+      delete l2;
+    } else
+      mkv_d->first_tc = 0;
+    stream_seek(s, l1->GetElementPosition());
+    
+    mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] First tc: %lld\n", mkv_d->first_tc);
+
     // If we have found an entry for the cues in the meta seek data but no
     // cues at the front of the file then read them now. This way the
     // timecode scale will have been initialized correctly.
@@ -1442,7 +1457,6 @@
       io.setFilePointer(current_pos);
     }
 
-
   } catch (exception &ex) {
     mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] caught exception\n");
     return 0;
@@ -1824,7 +1838,7 @@
               // Clear the subtitles if they're obsolete now.
               if ((mkv_d->clear_subs_at > 0) &&
                   (mkv_d->clear_subs_at <=
-                   (block->GlobalTimecode() / 1000000))) {
+                   (block->GlobalTimecode() / 1000000 - mkv_d->first_tc))) {
                 mkv_d->subs.lines = 0;
                 vo_sub = &mkv_d->subs;
                 vo_osd_changed(OSDTYPE_SUBTITLE);
@@ -1843,7 +1857,8 @@
                   (((elements_found & 4) == 0) && // It's a key frame.
                    (ds != NULL) &&                // Corresponding track found
                    (ds == d->video))) {           // track is our video track
-                if ((ds != NULL) && ((block->GlobalTimecode() / 1000000) >=
+                if ((ds != NULL) && ((block->GlobalTimecode() / 1000000 -
+                                       mkv_d->first_tc) >=
                                      (uint64_t)mkv_d->skip_to_timecode)) {
                   for (i = 0; i < (int)block->NumberFrames(); i++) {
                     DataBuffer &data = block->GetBuffer(i);
@@ -1861,8 +1876,8 @@
                   handle_subtitles(d, block, block_duration);
 
                 d->filepos = mkv_d->in->getFilePointer();
-                mkv_d->last_pts = (float)block->GlobalTimecode() /
-                  1000000000.0;
+                mkv_d->last_pts = (float)(block->GlobalTimecode() / 1000000.0 -
+                                          mkv_d->first_tc) / 1000.0;
                 mkv_d->last_filepos = d->filepos;
               }