+
+void virtual_segment_c::ChangeSegment( matroska_segment_c * p_old, matroska_segment_c * p_new, mtime_t i_start_time )
+{
+ size_t i, j;
+ char *sub_lang = NULL, *aud_lang = NULL;
+ for( i = 0; i < p_old->tracks.size(); i++)
+ {
+ mkv_track_t *p_tk = p_old->tracks[i];
+ es_format_t *p_ofmt = &p_tk->fmt;
+ if( p_tk->p_es )
+ {
+ bool state = false;
+ es_out_Control( p_old->sys.demuxer.out, ES_OUT_GET_ES_STATE, p_tk->p_es, &state );
+ if( state )
+ {
+ if( p_ofmt->i_cat == AUDIO_ES )
+ aud_lang = p_tk->fmt.psz_language;
+ else if( p_ofmt->i_cat == SPU_ES )
+ sub_lang = p_tk->fmt.psz_language;
+ }
+ }
+ }
+ 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->i_extra == 0 ||
+ !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 %zu for track %zu", j, i);
+ p_tk->p_es = p_old->tracks[j]->p_es;
+ p_old->tracks[j]->p_es = NULL;
+ break;
+ }
+ }
+ }
+ p_tk->fmt.i_priority &= ~(0x10);
+ if( ( sub_lang && p_nfmt->i_cat == SPU_ES && !strcasecmp(sub_lang, p_nfmt->psz_language) ) ||
+ ( aud_lang && p_nfmt->i_cat == AUDIO_ES && !strcasecmp(aud_lang, p_nfmt->psz_language) ) )
+ {
+ msg_Warn( &p_old->sys.demuxer, "Since previous segment used lang %s forcing track %zu",
+ p_nfmt->psz_language, i);
+ p_tk->fmt.i_priority |= 0x10;
+ p_tk->b_forced = true;
+ }
+ }
+ p_new->Select( i_start_time );
+ p_old->UnSelect();
+}