void AddCommand( const KaxChapterProcessCommand & command );
- virtual bool Enter() { return true; }
- virtual bool Leave() { return true; }
+ /// \return wether the codec has seeked in the files or not
+ virtual bool Enter() { return false; }
+ virtual bool Leave() { return false; }
virtual std::string GetCodecName( bool f_for_title = false ) const { return ""; }
KaxChapterProcessPrivate m_private_data;
,i_user_start_time(-1)
,i_user_end_time(-1)
,i_seekpoint_num(-1)
+ ,i_user_chapters(0)
,b_display_seekpoint(true)
,psz_parent(NULL)
{}
}
int64_t RefreshChapters( bool b_ordered, int64_t i_prev_user_time );
- void PublishChapters( input_title_t & title, int i_level );
+ int PublishChapters( input_title_t & title, int i_level = 0 );
chapter_item_c * FindTimecode( mtime_t i_timecode );
void Append( const chapter_item_c & edition );
chapter_item_c * FindChapter( const chapter_item_c & chapter );
int64_t i_user_start_time, i_user_end_time; /* the time in the stream when an edition is ordered */
std::vector<chapter_item_c*> sub_chapters;
int i_seekpoint_num;
+ int i_user_chapters;
int64_t i_uid;
bool b_display_seekpoint;
std::string psz_name;
void RefreshChapters( );
mtime_t Duration() const;
- void PublishChapters( input_title_t & title );
std::string GetMainName() const;
bool b_ordered;
void PreloadFamily( const matroska_segment_c & of_segment );
void PreloadLinked( matroska_segment_c *p_segment );
- bool PreparePlayback( );
+ bool PreparePlayback( virtual_segment_c *p_new_segment );
matroska_stream_c *AnalyseAllSegmentsFound( EbmlStream *p_estream );
protected:
p_sys->PreloadFamily( *p_segment );
p_sys->PreloadLinked( p_segment );
- if ( !p_sys->PreparePlayback( ) )
+ if ( !p_sys->PreparePlayback( NULL ) )
{
msg_Err( p_demux, "cannot use the segment" );
goto error;
int64_t *pi64;
double *pf, f;
int i_skp;
+ size_t i_idx;
vlc_meta_t **pp_meta;
case DEMUX_SET_TITLE:
/* TODO handle editions as titles */
- if( p_sys->titles.size() && p_sys->titles[p_sys->i_current_title].i_seekpoint > 0 )
+ i_idx = (int)va_arg( args, int );
+ if( i_idx < p_sys->used_segments.size() )
{
+ p_sys->PreparePlayback( p_sys->used_segments[i_idx] );
return VLC_SUCCESS;
}
return VLC_EGENERIC;
EbmlElement *el;
int i_level;
+ if ( ep == NULL )
+ break;
+
el = ep->Get();
i_level = ep->GetLevel();
return "";
}
-void chapter_edition_c::PublishChapters( input_title_t & title )
-{
- chapter_item_c::PublishChapters( title, 0 );
-}
-
-void chapter_item_c::PublishChapters( input_title_t & title, int i_level )
+int chapter_item_c::PublishChapters( input_title_t & title, int i_level )
{
+ bool f_user_display = ( psz_name != "" );
// add support for meta-elements from codec like DVD Titles
if ( !b_display_seekpoint || psz_name == "" )
{
title.i_seekpoint++;
title.seekpoint = (seekpoint_t**)realloc( title.seekpoint, title.i_seekpoint * sizeof( seekpoint_t* ) );
title.seekpoint[title.i_seekpoint-1] = sk;
-
- i_seekpoint_num = title.i_seekpoint;
+
+ if ( f_user_display )
+ i_user_chapters++;
}
for ( size_t i=0; i<sub_chapters.size() ; i++)
{
- sub_chapters[i]->PublishChapters( title, i_level+1 );
+ i_user_chapters += sub_chapters[i]->PublishChapters( title, i_level+1 );
}
+
+ i_seekpoint_num = i_user_chapters;
+
+ return i_user_chapters;
}
void virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
if ( psz_current_chapter != NULL )
psz_current_chapter->Leave();
- if ( psz_curr_chapter->i_seekpoint_num > 0 )
+ if ( (*p_editions)[i_current_edition]->b_ordered )
{
- demux.info.i_update |= INPUT_UPDATE_SEEKPOINT;
- demux.info.i_seekpoint = psz_curr_chapter->i_seekpoint_num - 1;
+ if ( !psz_curr_chapter->Enter() )
+ {
+ // only 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 );
+ }
}
-
- if ( (*p_editions)[i_current_edition]->b_ordered )
+ else if ( psz_curr_chapter->i_seekpoint_num > 0 )
{
- psz_curr_chapter->Enter();
-
- // only 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 );
+ demux.info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
+ demux.info.i_title = sys.i_current_title = i_sys_title;
+ demux.info.i_seekpoint = psz_curr_chapter->i_seekpoint_num - 1;
}
+
+ psz_current_chapter = psz_curr_chapter;
}
- psz_current_chapter = psz_curr_chapter;
}
}
return p_result;
}
-bool demux_sys_t::PreparePlayback( )
+bool demux_sys_t::PreparePlayback( virtual_segment_c *p_new_segment )
{
+ if ( p_new_segment != NULL && p_new_segment != p_current_segment )
+ {
+ if ( p_current_segment != NULL && p_current_segment->Segment() != NULL )
+ p_current_segment->Segment()->UnSelect();
+
+ p_current_segment = p_new_segment;
+ i_current_title = p_new_segment->i_sys_title;
+ }
+
p_current_segment->LoadCues();
f_duration = p_current_segment->Duration();
{
psz_current_chapter = psz_chapter;
p_sys->i_chapter_time = i_time_offset = psz_chapter->i_user_start_time - psz_chapter->i_start_time;
- demuxer.info.i_update |= INPUT_UPDATE_SEEKPOINT;
- demuxer.info.i_seekpoint = psz_chapter->i_seekpoint_num - 1;
+ if ( psz_chapter->i_seekpoint_num > 0 )
+ {
+ demuxer.info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
+ demuxer.info.i_title = p_sys->i_current_title = i_sys_title;
+ demuxer.info.i_seekpoint = psz_chapter->i_seekpoint_num - 1;
+ }
}
// find the best matching segment
bool chapter_item_c::Enter()
{
+ bool f_result = false;
std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
while ( index != codecs.end() )
{
- (*index)->Enter();
+ f_result |= (*index)->Enter();
index++;
}
std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
while ( index_ != sub_chapters.end() )
{
- (*index_)->Enter();
+ f_result |= (*index_)->Enter();
index_++;
}
- return true;
+ return f_result;
}
bool chapter_item_c::Leave()
{
+ bool f_result = false;
std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
while ( index != codecs.end() )
{
- (*index)->Leave();
+ f_result |= (*index)->Leave();
index++;
}
std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
while ( index_ != sub_chapters.end() )
{
- (*index_)->Leave();
+ f_result |= (*index_)->Leave();
index_++;
}
- return true;
+ return f_result;
}
bool dvd_chapter_codec_c::Enter()
{
+ bool f_result = false;
std::vector<KaxChapterProcessData>::iterator index = enter_cmds.begin();
while ( index != enter_cmds.end() )
{
i_size = min( i_size, ((*index).GetSize() - 1) >> 3 );
for ( ; i_size > 0; i_size--, p_data += 8 )
{
- interpretor.Interpret( p_data );
+ f_result |= interpretor.Interpret( p_data );
}
}
index++;
}
- return true;
+ return f_result;
}
bool dvd_chapter_codec_c::Leave()
{
+ bool f_result = false;
std::vector<KaxChapterProcessData>::iterator index = leave_cmds.begin();
while ( index != leave_cmds.end() )
{
i_size = min( i_size, ((*index).GetSize() - 1) >> 3 );
for ( ; i_size > 0; i_size--, p_data += 8 )
{
- interpretor.Interpret( p_data );
+ f_result |= interpretor.Interpret( p_data );
}
}
index++;
}
- return true;
+ return f_result;
}
bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_size )
if ( i_size != 8 )
return false;
+ bool f_result = false;
uint16 i_command = ( p_command[0] << 8 ) + p_command[1];
switch ( i_command )
// if the segment is not part of the current segment, select the new one
if ( p_segment != sys.p_current_segment )
{
- sys.p_current_segment = p_segment;
- sys.i_current_title = p_segment->i_sys_title;
- sys.PreparePlayback();
+ sys.PreparePlayback( p_segment );
}
p_chapter->Enter();
// jump to the location in the found segment
p_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter );
+ f_result = true;
}
break;
}
}
- return true;
+ return f_result;
}
bool dvd_command_interpretor_c::MatchTitleNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )