return true;
}
+void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position )
+{
+ KaxBlock *block;
+ 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;
+
+ if( i_global_position >= 0 )
+ {
+ /* Special case for seeking in files with no cues */
+ EbmlElement *el = NULL;
+ es.I_O().setFilePointer( i_start_pos, seek_beginning );
+ delete ep;
+ ep = new EbmlParser( &es, segment, &sys.demuxer );
+ cluster = NULL;
+
+ while( ( el = ep->Get() ) != NULL )
+ {
+ if( MKV_IS_ID( el, KaxCluster ) )
+ {
+ cluster = (KaxCluster *)el;
+ i_cluster_pos = cluster->GetElementPosition();
+ if( i_index == 0 ||
+ ( i_index > 0 && p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
+ {
+ IndexAppendCluster( cluster );
+ }
+ if( es.I_O().getFilePointer() >= i_global_position )
+ {
+ ParseCluster();
+ msg_Dbg( &sys.demuxer, "we found a cluster that is in the neighbourhood" );
+ return;
+ }
+ }
+ }
+ msg_Err( &sys.demuxer, "This file has no cues, and we were unable to seek to the requested position by parsing." );
+ return;
+ }
+
+ if ( i_index > 0 )
+ {
+ int i_idx = 0;
+
+ for( ; i_idx < i_index; i_idx++ )
+ {
+ if( p_indexes[i_idx].i_time + i_time_offset > i_date )
+ {
+ break;
+ }
+ }
+
+ if( i_idx > 0 )
+ {
+ i_idx--;
+ }
+
+ i_seek_position = p_indexes[i_idx].i_position;
+ i_seek_time = p_indexes[i_idx].i_time;
+ }
+
+ msg_Dbg( &sys.demuxer, "seek got %"PRId64" (%d%%)",
+ i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
+
+ es.I_O().setFilePointer( i_seek_position, seek_beginning );
+
+ delete ep;
+ ep = new EbmlParser( &es, segment, &sys.demuxer );
+ cluster = NULL;
+
+ sys.i_start_pts = i_date;
+
+ /* now parse until key frame */
+ i_track_skipping = 0;
+ for( i_track = 0; i_track < tracks.size(); i_track++ )
+ {
+ if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
+ {
+ tracks[i_track]->b_search_keyframe = true;
+ i_track_skipping++;
+ }
+ }
+ es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
+
+ while( i_track_skipping > 0 )
+ {
+ if( BlockGet( block, simpleblock, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
+ {
+ msg_Warn( &sys.demuxer, "cannot get block EOF?" );
+
+ return;
+ }
+
+ for( i_track = 0; i_track < tracks.size(); i_track++ )
+ {
+ if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) ||
+ (block && tracks[i_track]->i_number == block->TrackNum()) )
+ {
+ break;
+ }
+ }
+
+ if( simpleblock )
+ sys.i_pts = (sys.i_chapter_time + simpleblock->GlobalTimecode()) / (mtime_t) 1000;
+ else
+ sys.i_pts = (sys.i_chapter_time + block->GlobalTimecode()) / (mtime_t) 1000;
+
+ if( i_track < tracks.size() )
+ {
+ if( sys.i_pts > sys.i_start_pts )
+ {
+ cluster = static_cast<KaxCluster*>(ep->UnGet( i_block_pos, i_cluster_pos ));
+ i_track_skipping = 0;
+ }
+ else if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
+ {
+ if( i_block_ref1 == 0 && 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 );
+ }
+ }
+ }
+
+ delete block;
+ }
+
+ /* FIXME current ES_OUT_SET_NEXT_DISPLAY_TIME does not work that well if
+ * the delay is too high. */
+ if( sys.i_pts + 500*1000 < sys.i_start_pts )
+ {
+ sys.i_start_pts = sys.i_pts;
+
+ es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, sys.i_start_pts );
+ }
+}
+
+
int matroska_segment_c::BlockFindTrackIndex( size_t *pi_track,
const KaxBlock *p_block, const KaxSimpleBlock *p_simpleblock )
{
return p_block;
}
-/* Needed by matroska_segment::Seek() */
-static void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock,
+/* Needed by matroska_segment::Seek() and Seek */
+void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock,
mtime_t i_pts, mtime_t i_duration, bool f_mandatory )
{
demux_sys_t *p_sys = p_demux->p_sys;
}
}
-
-void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position )
-{
- KaxBlock *block;
- 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;
-
- if( i_global_position >= 0 )
- {
- /* Special case for seeking in files with no cues */
- EbmlElement *el = NULL;
- es.I_O().setFilePointer( i_start_pos, seek_beginning );
- delete ep;
- ep = new EbmlParser( &es, segment, &sys.demuxer );
- cluster = NULL;
-
- while( ( el = ep->Get() ) != NULL )
- {
- if( MKV_IS_ID( el, KaxCluster ) )
- {
- cluster = (KaxCluster *)el;
- i_cluster_pos = cluster->GetElementPosition();
- if( i_index == 0 ||
- ( i_index > 0 && p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
- {
- IndexAppendCluster( cluster );
- }
- if( es.I_O().getFilePointer() >= i_global_position )
- {
- ParseCluster();
- msg_Dbg( &sys.demuxer, "we found a cluster that is in the neighbourhood" );
- return;
- }
- }
- }
- msg_Err( &sys.demuxer, "This file has no cues, and we were unable to seek to the requested position by parsing." );
- return;
- }
-
- if ( i_index > 0 )
- {
- int i_idx = 0;
-
- for( ; i_idx < i_index; i_idx++ )
- {
- if( p_indexes[i_idx].i_time + i_time_offset > i_date )
- {
- break;
- }
- }
-
- if( i_idx > 0 )
- {
- i_idx--;
- }
-
- i_seek_position = p_indexes[i_idx].i_position;
- i_seek_time = p_indexes[i_idx].i_time;
- }
-
- msg_Dbg( &sys.demuxer, "seek got %"PRId64" (%d%%)",
- i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
-
- es.I_O().setFilePointer( i_seek_position, seek_beginning );
-
- delete ep;
- ep = new EbmlParser( &es, segment, &sys.demuxer );
- cluster = NULL;
-
- sys.i_start_pts = i_date;
-
- /* now parse until key frame */
- i_track_skipping = 0;
- for( i_track = 0; i_track < tracks.size(); i_track++ )
- {
- if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
- {
- tracks[i_track]->b_search_keyframe = true;
- i_track_skipping++;
- }
- }
- es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
-
- while( i_track_skipping > 0 )
- {
- if( BlockGet( block, simpleblock, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
- {
- msg_Warn( &sys.demuxer, "cannot get block EOF?" );
-
- return;
- }
-
- for( i_track = 0; i_track < tracks.size(); i_track++ )
- {
- if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) ||
- (block && tracks[i_track]->i_number == block->TrackNum()) )
- {
- break;
- }
- }
-
- if( simpleblock )
- sys.i_pts = (sys.i_chapter_time + simpleblock->GlobalTimecode()) / (mtime_t) 1000;
- else
- sys.i_pts = (sys.i_chapter_time + block->GlobalTimecode()) / (mtime_t) 1000;
-
- if( i_track < tracks.size() )
- {
- if( sys.i_pts > sys.i_start_pts )
- {
- cluster = static_cast<KaxCluster*>(ep->UnGet( i_block_pos, i_cluster_pos ));
- i_track_skipping = 0;
- }
- else if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
- {
- if( i_block_ref1 == 0 && 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 );
- }
- }
- }
-
- delete block;
- }
-
- /* FIXME current ES_OUT_SET_NEXT_DISPLAY_TIME does not work that well if
- * the delay is too high. */
- if( sys.i_pts + 500*1000 < sys.i_start_pts )
- {
- sys.i_start_pts = sys.i_pts;
-
- es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, sys.i_start_pts );
- }
-}
-
-
/*****************************************************************************
* Demux: reads and demuxes data packets
*****************************************************************************