void LoadCues( KaxCues *cues );
void LoadTags( KaxTags *tags );
void InformationCreate( );
- void Seek( mtime_t i_date, mtime_t i_time_offset );
+ void Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position );
#if LIBMATROSKA_VERSION >= 0x000800
int BlockGet( KaxBlock * &, KaxSimpleBlock * &, int64_t *, int64_t *, int64_t *);
#else
size_t AddSegment( matroska_segment_c *p_segment );
void PreloadLinked( );
mtime_t Duration( ) const;
- void Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, chapter_item_c *psz_chapter );
+ void Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, chapter_item_c *psz_chapter, int64_t i_global_position );
inline chapter_edition_c *Edition()
{
{
// only physically seek if necessary
if ( psz_current_chapter == NULL || (psz_current_chapter->i_end_time != psz_curr_chapter->i_start_time) )
- Seek( demux, sys.i_pts, 0, psz_curr_chapter );
+ Seek( demux, sys.i_pts, 0, psz_curr_chapter, -1 );
}
}
virtual_segment_c *p_vsegment = p_sys->p_current_segment;
matroska_segment_c *p_segment = p_vsegment->Segment();
mtime_t i_time_offset = 0;
+ int64_t i_global_position = -1;
int i_index;
{
int64_t i_pos = int64_t( f_percent * stream_Size( p_demux->s ) );
- msg_Dbg( p_demux, "inacurate way of seeking" );
+ msg_Dbg( p_demux, "inaccurate way of seeking for pos:%"PRId64, i_pos );
for( i_index = 0; i_index < p_segment->i_index; i_index++ )
{
- if( p_segment->p_indexes[i_index].i_position >= i_pos)
- {
+ if( p_segment->b_cues && p_segment->p_indexes[i_index].i_position < i_pos )
+ break;
+ if( !p_segment->b_cues && p_segment->p_indexes[i_index].i_position >= i_pos && p_segment->p_indexes[i_index].i_time > 0 )
break;
- }
}
if( i_index == p_segment->i_index )
{
i_date = p_segment->p_indexes[i_index].i_time;
-#if 0
- if( p_segment->p_indexes[i_index].i_position < i_pos )
+ if( !p_segment->b_cues && ( p_segment->p_indexes[i_index].i_position < i_pos || p_segment->p_indexes[i_index].i_position - i_pos > 2000000 ))
{
- EbmlElement *el;
-
- msg_Warn( p_demux, "searching for cluster, could take some time" );
-
- /* search a cluster */
- while( ( el = p_sys->ep->Get() ) != NULL )
- {
- if( MKV_IS_ID( el, KaxCluster ) )
- {
- KaxCluster *cluster = (KaxCluster*)el;
-
- /* add it to the index */
- p_segment->IndexAppendCluster( cluster );
-
- if( (int64_t)cluster->GetElementPosition() >= i_pos )
- {
- p_sys->cluster = cluster;
- p_sys->ep->Down();
- break;
- }
- }
- }
+ msg_Dbg( p_demux, "no cues, seek request to global pos: %"PRId64, i_pos );
+ i_global_position = i_pos;
}
-#endif
}
}
- p_vsegment->Seek( *p_demux, i_date, i_time_offset, psz_chapter );
+ p_vsegment->Seek( *p_demux, i_date, i_time_offset, psz_chapter, i_global_position );
}
/*****************************************************************************
if ( !p_chapter->Enter( true ) )
{
// jump to the location in the found segment
- vsegment.Seek( demuxer, p_chapter->i_user_start_time, -1, p_chapter );
+ vsegment.Seek( demuxer, p_chapter->i_user_start_time, -1, p_chapter, -1 );
}
}
linked_uids.push_back( *(KaxSegmentUID*)(p_UID) );
}
-void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset )
+void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position )
{
KaxBlock *block;
#if LIBMATROSKA_VERSION >= 0x000800
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" );
+ es_out_Control( sys.demuxer.out, ES_OUT_RESET_PCR );
+ 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;
es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, tracks[i_track]->p_es, i_date );
}
-
while( i_track_skipping > 0 )
{
#if LIBMATROSKA_VERSION >= 0x000800
}
}
-void virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, chapter_item_c *psz_chapter )
+void virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, chapter_item_c *psz_chapter, int64_t i_global_position )
{
demux_sys_t *p_sys = demuxer.p_sys;
size_t i;
i_current_segment = i;
}
- linked_segments[i]->Seek( i_date, i_time_offset );
+ linked_segments[i]->Seek( i_date, i_time_offset, i_global_position );
}
void chapter_codec_cmds_c::AddCommand( const KaxChapterProcessCommand & command )
{
if ( !p_chapter->Enter( true ) )
// jump to the location in the found segment
- sys.p_current_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter );
+ sys.p_current_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter, -1 );
f_result = true;
}
{
if ( !p_chapter->Enter( true ) )
// jump to the location in the found segment
- sys.p_current_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter );
+ sys.p_current_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter, -1 );
f_result = true;
}
else
{
if ( !p_chapter->EnterAndLeave( sys.p_current_segment->CurrentChapter() ) )
- p_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter );
+ p_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter, -1 );
b_result = true;
}
}