vlc | branch: master | Denis Charmet <[email protected]> | Tue Jan 1 21:34:33 2013 +0100| [e76a28e0bce3faec88db5b021588b23bc204d97f] | committer: Denis Charmet
Reuse the decoders when possible at segment change Should fix #5906 in most cases > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e76a28e0bce3faec88db5b021588b23bc204d97f --- modules/demux/mkv/matroska_segment.cpp | 29 ++++++++++++--- modules/demux/mkv/matroska_segment.hpp | 1 + modules/demux/mkv/matroska_segment_parse.cpp | 1 + modules/demux/mkv/virtual_segment.cpp | 51 ++++++++++++++++++++++++-- modules/demux/mkv/virtual_segment.hpp | 2 + 5 files changed, 75 insertions(+), 9 deletions(-) diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp index ea0e9f7..73986a1 100644 --- a/modules/demux/mkv/matroska_segment.cpp +++ b/modules/demux/mkv/matroska_segment.cpp @@ -662,6 +662,8 @@ bool matroska_segment_c::Preload( ) msg_Dbg( &sys.demuxer, "| + Preload Unknown (%s)", typeid(*el).name() ); } + ComputeTrackPriority(); + b_preloaded = true; return true; @@ -1014,11 +1016,8 @@ int matroska_segment_c::BlockFindTrackIndex( size_t *pi_track, return VLC_SUCCESS; } -bool matroska_segment_c::Select( mtime_t i_start_time ) +void matroska_segment_c::ComputeTrackPriority() { - /* add all es */ - msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() ); - bool b_has_default_video = false; bool b_has_default_audio = false; /* check for default */ @@ -1067,8 +1066,28 @@ bool matroska_segment_c::Select( mtime_t i_start_time ) /* Avoid multivideo tracks when unnecessary */ if( p_tk->fmt.i_cat == VIDEO_ES ) p_tk->fmt.i_priority--; + } +} + +bool matroska_segment_c::Select( mtime_t i_start_time ) +{ + /* add all es */ + msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() ); + + for( size_t i_track = 0; i_track < tracks.size(); i_track++ ) + { + mkv_track_t *p_tk = tracks[i_track]; + es_format_t *p_fmt = &p_tk->fmt; + + if( unlikely( p_fmt->i_cat == UNKNOWN_ES || !p_tk->psz_codec ) ) + { + msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, p_tk->i_number ); + p_tk->p_es = NULL; + continue; + } - p_tk->p_es = es_out_Add( sys.demuxer.out, &p_tk->fmt ); + if( !p_tk->p_es ) + p_tk->p_es = es_out_Add( sys.demuxer.out, &p_tk->fmt ); /* Turn on a subtitles track if it has been flagged as default - * but only do this if no subtitles track has already been engaged, diff --git a/modules/demux/mkv/matroska_segment.hpp b/modules/demux/mkv/matroska_segment.hpp index a36a73e..afb37db 100644 --- a/modules/demux/mkv/matroska_segment.hpp +++ b/modules/demux/mkv/matroska_segment.hpp @@ -162,6 +162,7 @@ private: SimpleTag * ParseSimpleTags( KaxTagSimple *tag, int level = 50 ); void IndexAppendCluster( KaxCluster *cluster ); int32_t TrackInit( mkv_track_t * p_tk ); + void ComputeTrackPriority(); }; diff --git a/modules/demux/mkv/matroska_segment_parse.cpp b/modules/demux/mkv/matroska_segment_parse.cpp index ecdd129..697660d 100644 --- a/modules/demux/mkv/matroska_segment_parse.cpp +++ b/modules/demux/mkv/matroska_segment_parse.cpp @@ -194,6 +194,7 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m ) memset( tk, 0, sizeof( mkv_track_t ) ); es_format_Init( &tk->fmt, UNKNOWN_ES, 0 ); + tk->p_es = NULL; tk->fmt.psz_language = strdup("English"); tk->fmt.psz_description = NULL; diff --git a/modules/demux/mkv/virtual_segment.cpp b/modules/demux/mkv/virtual_segment.cpp index 0997e36..07cb975 100644 --- a/modules/demux/mkv/virtual_segment.cpp +++ b/modules/demux/mkv/virtual_segment.cpp @@ -476,10 +476,7 @@ void virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_ } if( p_current_chapter->p_segment != p_chapter->p_segment ) - { - p_chapter->p_segment->Select( i_date ); - p_current_chapter->p_segment->UnSelect(); - } + ChangeSegment( p_current_chapter->p_segment, p_chapter->p_segment, i_date ); p_current_chapter = p_chapter; p_chapter->p_segment->Seek( i_date, i_time_offset, i_global_position ); @@ -613,3 +610,49 @@ void virtual_chapter_c::print() sub_chapters[i]->print(); } #endif + +void virtual_segment_c::ChangeSegment( matroska_segment_c * p_old, matroska_segment_c * p_new, mtime_t i_start_time ) +{ + size_t i, j; + for( i = 0; i < p_new->tracks.size(); i++) + { + mkv_track_t *p_tk = p_new->tracks[i]; + es_format_t *p_nfmt = &p_tk->fmt; + + /* Let's only do that for audio and video for now */ + if( p_nfmt->i_cat == AUDIO_ES || p_nfmt->i_cat == VIDEO_ES ) + { + + /* check for a similar elementary stream */ + for( j = 0; j < p_old->tracks.size(); j++) + { + es_format_t * p_ofmt = &p_old->tracks[j]->fmt; + + if( !p_old->tracks[j]->p_es ) + continue; + + if( ( p_nfmt->i_cat == p_ofmt->i_cat ) && + ( p_nfmt->i_codec == p_ofmt->i_codec ) && + ( p_nfmt->i_priority == p_ofmt->i_priority ) && + ( p_nfmt->i_bitrate == p_ofmt->i_bitrate ) && + ( p_nfmt->i_extra == p_ofmt->i_extra ) && + ( (!p_nfmt->p_extra && !p_ofmt->p_extra) || + !memcmp( p_nfmt->p_extra, p_ofmt->p_extra, p_nfmt->i_extra ) ) && + !strcasecmp( p_nfmt->psz_language, p_ofmt->psz_language ) && + ( ( p_nfmt->i_cat == AUDIO_ES && + !memcmp( &p_nfmt->audio, &p_ofmt->audio, sizeof(audio_format_t) ) ) || + ( p_nfmt->i_cat == VIDEO_ES && + !memcmp( &p_nfmt->video, &p_ofmt->video, sizeof(video_format_t) ) ) ) ) + { + /* FIXME handle video palettes... */ + msg_Warn( &p_old->sys.demuxer, "Reusing decoder of old track %u for track %u", j, i); + p_tk->p_es = p_old->tracks[j]->p_es; + p_old->tracks[j]->p_es = NULL; + break; + } + } + } + } + p_new->Select( i_start_time ); + p_old->UnSelect(); +} diff --git a/modules/demux/mkv/virtual_segment.hpp b/modules/demux/mkv/virtual_segment.hpp index c63e34a..c901e44 100644 --- a/modules/demux/mkv/virtual_segment.hpp +++ b/modules/demux/mkv/virtual_segment.hpp @@ -157,6 +157,8 @@ public: bool UpdateCurrentToChapter( demux_t & demux ); void Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, virtual_chapter_c *p_chapter, int64_t i_global_position ); +private: + void ChangeSegment( matroska_segment_c * p_old, matroska_segment_c * p_new, mtime_t i_start_time ); }; #endif _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
