[vlc-commits] commit: Fixed mkv seeking when simpleblock is used for video. ( Laurent Aimar )

git at videolan.org git at videolan.org
Tue Apr 20 00:21:08 CEST 2010


vlc/vlc-1.1 | branch: master | Laurent Aimar <fenrir at videolan.org> | Sun Apr 18 22:41:19 2010 +0200| [cdf5d257320dca800836dbb1ef2c8f07262dd379] | committer: Jean-Baptiste Kempf 

Fixed mkv seeking when simpleblock is used for video.
(cherry picked from commit 2c172c179ea9054fb140b5b3e863a2e670d558b9)

This fixes the long-standing bug #3026, aka, VLC can't seek properly in most HD movies from p2p networks :)

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-1.1.git/?a=commit;h=cdf5d257320dca800836dbb1ef2c8f07262dd379
---

 modules/demux/mkv/matroska_segment.cpp |   37 +++++++++++++++++--------------
 modules/demux/mkv/matroska_segment.hpp |    2 +-
 modules/demux/mkv/mkv.cpp              |    9 +++----
 3 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
index c351b46..13271cf 100644
--- a/modules/demux/mkv/matroska_segment.cpp
+++ b/modules/demux/mkv/matroska_segment.cpp
@@ -610,8 +610,6 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
     KaxSimpleBlock *simpleblock;
     int         i_track_skipping;
     int64_t     i_block_duration;
-    int64_t     i_block_ref1;
-    int64_t     i_block_ref2;
     size_t      i_track;
     int64_t     i_seek_position = i_start_pos;
     int64_t     i_seek_time = i_start_time;
@@ -694,7 +692,9 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
 
     while( i_track_skipping > 0 )
     {
-        if( BlockGet( block, simpleblock, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
+        bool b_key_picture;
+        bool b_discardable_picture;
+        if( BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) )
         {
             msg_Warn( &sys.demuxer, "cannot get block EOF?" );
 
@@ -724,14 +724,14 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
             }
             else if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
             {
-                if( i_block_ref1 == 0 && tracks[i_track]->b_search_keyframe )
+                if( b_key_picture && tracks[i_track]->b_search_keyframe )
                 {
                     tracks[i_track]->b_search_keyframe = false;
                     i_track_skipping--;
                 }
                 if( !tracks[i_track]->b_search_keyframe )
                 {
-                    BlockDecode( &sys.demuxer, block, simpleblock, sys.i_pts, 0, i_block_ref1 >= 0 || i_block_ref2 > 0 );
+                    BlockDecode( &sys.demuxer, block, simpleblock, sys.i_pts, 0, b_key_picture || b_discardable_picture );
                 }
             }
         }
@@ -1250,12 +1250,13 @@ void matroska_segment_c::UnSelect( )
     ep = NULL;
 }
 
-int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_simpleblock, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
+int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_simpleblock, bool *pb_key_picture, bool *pb_discardable_picture, int64_t *pi_duration )
 {
     pp_simpleblock = NULL;
     pp_block = NULL;
-    *pi_ref1  = 0;
-    *pi_ref2  = 0;
+
+    *pb_key_picture         = true;
+    *pb_discardable_picture = false;
 
     for( ;; )
     {
@@ -1275,6 +1276,11 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
                 pp_block = NULL;
                 continue;
             }
+            if( pp_simpleblock != NULL )
+            {
+                *pb_key_picture         = pp_simpleblock->IsKeyframe();
+                *pb_discardable_picture = pp_simpleblock->IsDiscardable();
+            }
 
             /* update the index */
 #define idx p_indexes[i_index - 1]
@@ -1284,7 +1290,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
                     idx.i_time        = pp_simpleblock->GlobalTimecode() / (mtime_t)1000;
                 else
                     idx.i_time        = (*pp_block).GlobalTimecode() / (mtime_t)1000;
-                idx.b_key         = *pi_ref1 == 0 ? true : false;
+                idx.b_key         = *pb_key_picture;
             }
 #undef idx
             return VLC_SUCCESS;
@@ -1398,14 +1404,11 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
 
                 ref.ReadData( es.I_O() );
-                if( *pi_ref1 == 0 )
-                {
-                    *pi_ref1 = int64( ref ) * cluster->GlobalTimecodeScale();
-                }
-                else if( *pi_ref2 == 0 )
-                {
-                    *pi_ref2 = int64( ref ) * cluster->GlobalTimecodeScale();
-                }
+
+                if( int64( ref ) < 0 )
+                    *pb_key_picture = false;
+                else if( int64( ref ) > 0 )
+                    *pb_discardable_picture = true;
             }
             else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )
             {
diff --git a/modules/demux/mkv/matroska_segment.hpp b/modules/demux/mkv/matroska_segment.hpp
index 5347e75..3ac9b60 100644
--- a/modules/demux/mkv/matroska_segment.hpp
+++ b/modules/demux/mkv/matroska_segment.hpp
@@ -148,7 +148,7 @@ public:
     void LoadTags( KaxTags *tags );
     void InformationCreate( );
     void Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position );
-    int BlockGet( KaxBlock * &, KaxSimpleBlock * &, int64_t *, int64_t *, int64_t *);
+    int BlockGet( KaxBlock * &, KaxSimpleBlock * &, bool *, bool *, int64_t *);
 
     int BlockFindTrackIndex( size_t *pi_track,
                              const KaxBlock *, const KaxSimpleBlock * );
diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
index 0f5b902..d766d4f 100644
--- a/modules/demux/mkv/mkv.cpp
+++ b/modules/demux/mkv/mkv.cpp
@@ -673,10 +673,9 @@ static int Demux( demux_t *p_demux)
         KaxBlock *block;
         KaxSimpleBlock *simpleblock;
         int64_t i_block_duration = 0;
-        int64_t i_block_ref1;
-        int64_t i_block_ref2;
-
-        if( p_segment->BlockGet( block, simpleblock, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
+        bool b_key_picture;
+        bool b_discardable_picture;
+        if( p_segment->BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) )
         {
             if ( p_vsegment->Edition() && p_vsegment->Edition()->b_ordered )
             {
@@ -760,7 +759,7 @@ static int Demux( demux_t *p_demux)
             continue;
         }
 
-        BlockDecode( p_demux, block, simpleblock, p_sys->i_pts, i_block_duration, i_block_ref1 >= 0 || i_block_ref2 > 0 );
+        BlockDecode( p_demux, block, simpleblock, p_sys->i_pts, i_block_duration, b_key_picture || b_discardable_picture );
 
         delete block;
         i_block_count++;



More information about the vlc-commits mailing list