[vlc-commits] Reuse the decoders when possible at segment change
Denis Charmet
git at videolan.org
Mon Jan 7 22:15:59 CET 2013
vlc | branch: master | Denis Charmet <typx at dinauz.org> | 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
More information about the vlc-commits
mailing list