[vlc-devel] [PATCH] Reuse the decoders when possible at segment change
Rafaël Carré
funman at videolan.org
Tue Jan 1 22:30:00 CET 2013
Hello,
Le 01/01/2013 21:36, Denis Charmet a écrit :
> Should fix #5906 in most cases
I am not sure it's a good idea, it seems like a fragile heavy workaround
for a bug which will continue to exist at the start of every decoder.
Your code looks ok, but you never know..
> ---
> 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 | 49 ++++++++++++++++++++++++++
> modules/demux/mkv/virtual_segment.hpp | 2 ++
> 5 files changed, 77 insertions(+), 5 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..5dbedd8 100644
> --- a/modules/demux/mkv/virtual_segment.cpp
> +++ b/modules/demux/mkv/virtual_segment.cpp
> @@ -477,8 +477,11 @@ 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();
> + */
Do you really need to keep that code around?
You know it will always be present in git log -p
> + ChangeSegment( p_current_chapter->p_segment, p_chapter->p_segment, i_date );
> }
> p_current_chapter = p_chapter;
>
> @@ -613,3 +616,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 )
if( p_nfmt->i_cat != AUDIO_ES && p_nfmt->i_cat != VIDEO_ES )
continue;
And shift the rest of the code to the left.
> + {
> +
> + /* 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) ) ) ) )
p_nfmt->video == p_ofmt->video
> + {
> + /* 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-devel
mailing list