X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Fes_out.c;h=760e57bab3ebc100a5b9db4cdd873cf3a7f2385c;hb=1575796ce7f14190594b9d14e27c88ae130cf8b5;hp=7c62573affa0c4c1b819a2a7dd8a4149a1f5e003;hpb=066b059ba824a8ec9155ecde84d707ba16d2a469;p=vlc diff --git a/src/input/es_out.c b/src/input/es_out.c index 7c62573aff..760e57bab3 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -45,6 +45,7 @@ #include "es_out.h" #include "event.h" #include "info.h" +#include "item.h" #include "../stream_output/stream_output.h" @@ -130,7 +131,8 @@ struct es_out_sys_t int i_video; int i_sub; - /* es to select */ + /* es/group to select */ + int i_group_id; int i_audio_last, i_audio_id; int i_sub_last, i_sub_id; int i_default_sub_id; /* As specified in container; if applicable */ @@ -259,6 +261,8 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) p_sys->i_sub = 0; /* */ + p_sys->i_group_id = var_GetInteger( p_input, "program" ); + p_sys->i_audio_last = var_GetInteger( p_input, "audio-track" ); p_sys->i_sub_last = var_GetInteger( p_input, "sub-track" ); @@ -402,7 +406,8 @@ static mtime_t EsOutGetWakeup( es_out_t *out ) /* We do not have a wake up date if the input cannot have its speed * controlled or sout is imposing its own or while buffering * - * FIXME for !p_input->p->b_can_pace_control a wkeup time is still needed to avoid too strong buffering */ + * FIXME for !p_input->p->b_can_pace_control a wake-up time is still needed + * to avoid too heavy buffering */ if( !p_input->p->b_can_pace_control || p_input->p->b_out_pace_control || p_sys->b_buffering ) @@ -648,7 +653,7 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced ) if( i_stream_duration <= i_buffering_duration && !b_forced ) { - const double f_level = (double)i_stream_duration / i_buffering_duration; + const double f_level = __MAX( (double)i_stream_duration / i_buffering_duration, 0 ); input_SendEventCache( p_sys->p_input, f_level ); msg_Dbg( p_sys->p_input, "Buffering %d%%", (int)(100 * f_level) ); @@ -764,14 +769,13 @@ static void EsOutDecoderChangeDelay( es_out_t *out, es_out_id_t *p_es ) i_delay = p_sys->i_audio_delay; else if( p_es->fmt.i_cat == SPU_ES ) i_delay = p_sys->i_spu_delay; + else + return; - if( i_delay != 0 ) - { - if( p_es->p_dec ) - input_DecoderChangeDelay( p_es->p_dec, i_delay ); - if( p_es->p_dec_record ) - input_DecoderChangeDelay( p_es->p_dec_record, i_delay ); - } + if( p_es->p_dec ) + input_DecoderChangeDelay( p_es->p_dec, i_delay ); + if( p_es->p_dec_record ) + input_DecoderChangeDelay( p_es->p_dec_record, i_delay ); } static void EsOutProgramsChangeRate( es_out_t *out ) { @@ -948,12 +952,12 @@ static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, { if( psz_language && *psz_language ) { - if( asprintf( &text.psz_string, "%s %i - [%s]", _( "Track" ), val.i_int, psz_language ) == -1 ) + if( asprintf( &text.psz_string, "%s %"PRId64" - [%s]", _( "Track" ), val.i_int, psz_language ) == -1 ) text.psz_string = NULL; } else { - if( asprintf( &text.psz_string, "%s %i", _( "Track" ), val.i_int ) == -1 ) + if( asprintf( &text.psz_string, "%s %"PRId64, _( "Track" ), val.i_int ) == -1 ) text.psz_string = NULL; } } @@ -978,6 +982,11 @@ static void EsOutESVarUpdate( es_out_t *out, es_out_id_t *es, EsOutESVarUpdateGeneric( out, es->i_id, &es->fmt, es->psz_language, b_delete ); } +static bool EsOutIsProgramVisible( es_out_t *out, int i_group ) +{ + return out->p_sys->i_group_id == 0 || out->p_sys->i_group_id == i_group; +} + /* EsOutProgramSelect: * Select a program and update the object variable */ @@ -1076,9 +1085,10 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group ) TAB_APPEND( p_sys->i_pgrm, p_sys->pgrm, p_pgrm ); /* Update "program" variable */ - input_SendEventProgramAdd( p_input, i_group, NULL ); + if( EsOutIsProgramVisible( out, i_group ) ) + input_SendEventProgramAdd( p_input, i_group, NULL ); - if( i_group == var_GetInteger( p_input, "program" ) ) + if( i_group == p_sys->i_group_id || ( !p_sys->p_pgrm && p_sys->i_group_id == 0 ) ) EsOutProgramSelect( out, p_pgrm ); return p_pgrm; @@ -1184,6 +1194,8 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, const vlc_meta_t *p_me return; } /* Find program */ + if( !EsOutIsProgramVisible( out, i_group ) ) + return; p_pgrm = EsOutProgramFind( out, i_group ); if( !p_pgrm ) return; @@ -1234,7 +1246,7 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, const vlc_meta_t *p_me char **ppsz_all_keys = vlc_meta_CopyExtraNames(p_meta ); info_category_t *p_cat = NULL; - if( psz_provider || *ppsz_all_keys[0] ) + if( psz_provider || ( ppsz_all_keys[0] && *ppsz_all_keys[0] ) ) { char *psz_cat = EsOutProgramGetMetaName( p_pgrm ); if( psz_cat ) @@ -1275,6 +1287,8 @@ static void EsOutProgramEpg( es_out_t *out, int i_group, const vlc_epg_t *p_epg char *psz_cat; /* Find program */ + if( !EsOutIsProgramVisible( out, i_group ) ) + return; p_pgrm = EsOutProgramFind( out, i_group ); if( !p_pgrm ) return; @@ -1453,7 +1467,12 @@ static es_out_id_t *EsOutAdd( es_out_t *out, const es_format_t *fmt ) es->fmt.i_id = out->p_sys->i_id; if( !es->fmt.i_original_fourcc ) es->fmt.i_original_fourcc = es->fmt.i_codec; - es->fmt.i_codec = vlc_fourcc_GetCodec( es->fmt.i_cat, es->fmt.i_codec ); + if( es->fmt.i_cat == AUDIO_ES ) + es->fmt.i_codec = vlc_fourcc_GetCodecAudio( es->fmt.i_codec, + es->fmt.audio.i_bitspersample ); + else + es->fmt.i_codec = vlc_fourcc_GetCodec( es->fmt.i_cat, + es->fmt.i_codec ); es->i_id = es->fmt.i_id; es->i_meta_id = out->p_sys->i_id; @@ -1742,19 +1761,24 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force ) } else if( p_sys->i_mode == ES_OUT_MODE_PARTIAL ) { - vlc_value_t val; - int i; - var_Get( p_sys->p_input, "programs", &val ); - for ( i = 0; i < val.p_list->i_count; i++ ) + char *prgms = var_GetNonEmptyString( p_sys->p_input, "programs" ); + if( prgms != NULL ) { - if ( val.p_list->p_values[i].i_int == es->p_pgrm->i_id || b_force ) + char *buf; + + for ( const char *prgm = strtok_r( prgms, ",", &buf ); + prgm != NULL; + prgm = strtok_r( NULL, ",", &buf ) ) { - if( !EsIsSelected( es ) ) - EsSelect( out, es ); - break; + if( atoi( prgm ) == es->p_pgrm->i_id || b_force ) + { + if( !EsIsSelected( es ) ) + EsSelect( out, es ); + break; + } } + free( prgms ); } - var_FreeList( &val, NULL ); } else if( p_sys->i_mode == ES_OUT_MODE_AUTO ) { @@ -1935,8 +1959,6 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) p_block->i_flags |= BLOCK_FLAG_PREROLL; } - p_block->i_rate = 0; - if( !es->p_dec ) { block_Release( p_block ); @@ -2134,6 +2156,13 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_SUCCESS; } + case ES_OUT_GET_GROUP_FORCED: + { + int *pi_group = va_arg( args, int * ); + *pi_group = p_sys->i_group_id; + return VLC_SUCCESS; + } + case ES_OUT_SET_MODE: { const int i_mode = va_arg( args, int ); @@ -2491,7 +2520,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) vlc_object_t **pp_decoder = va_arg( args, vlc_object_t ** ); vout_thread_t **pp_vout = va_arg( args, vout_thread_t ** ); - aout_instance_t **pp_aout = va_arg( args, aout_instance_t ** ); + audio_output_t **pp_aout = va_arg( args, audio_output_t ** ); if( p_es->p_dec ) { if( pp_decoder ) @@ -2657,6 +2686,22 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) input_clock_ChangeSystemOrigin( p_pgrm->p_clock, b_absolute, i_system ); return VLC_SUCCESS; } + case ES_OUT_SET_EOS: + { + for (int i = 0; i < p_sys->i_es; i++) { + es_out_id_t *id = p_sys->es[i]; + decoder_t *p_dec = id->p_dec; + if (!p_dec) + continue; + block_t *p_block = block_Alloc(0); + if( !p_block ) + break; + + p_block->i_flags |= BLOCK_FLAG_CORE_EOS; + input_DecoderDecode(p_dec, p_block, false); + } + return VLC_SUCCESS; + } default: msg_Err( p_sys->p_input, "unknown query in es_out_Control" ); @@ -2682,7 +2727,7 @@ static char *LanguageGetName( const char *psz_code ) { const iso639_lang_t *pl; - if( psz_code == NULL ) + if( psz_code == NULL || !strcmp( psz_code, "und" ) ) { return strdup( "" ); } @@ -2825,6 +2870,15 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * const es_format_t *p_fmt_es = &es->fmt; lldiv_t div; + if( es->fmt.i_cat == fmt->i_cat ) + { + es_format_t update = *fmt; + update.i_id = es->i_meta_id; + update.i_codec = es->fmt.i_codec; + update.i_original_fourcc = es->fmt.i_original_fourcc; + input_item_UpdateTracksInfo(input_GetItem(p_input), &update); + } + /* Create category */ char psz_cat[128]; snprintf( psz_cat, sizeof(psz_cat),_("Stream %d"), es->i_meta_id ); @@ -2832,7 +2886,7 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * if( !p_cat ) return; - /* Add informations */ + /* Add information */ const char *psz_type; switch( fmt->i_cat ) { @@ -2859,7 +2913,8 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * const char *psz_codec_description = vlc_fourcc_GetDescription( p_fmt_es->i_cat, p_fmt_es->i_codec ); - const vlc_fourcc_t i_codec_fourcc = p_fmt_es->i_original_fourcc ?: p_fmt_es->i_codec; + const vlc_fourcc_t i_codec_fourcc = ( p_fmt_es->i_original_fourcc )? + p_fmt_es->i_original_fourcc : p_fmt_es->i_codec; if( psz_codec_description ) info_category_AddInfo( p_cat, _("Codec"), "%s (%.4s)", psz_codec_description, (char*)&i_codec_fourcc ); @@ -2948,6 +3003,15 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * info_category_AddInfo( p_cat, _("Frame rate"), "%"PRId64, div.quot ); } + if( fmt->i_codec != p_fmt_es->i_codec ) + { + const char *psz_chroma_description = + vlc_fourcc_GetDescription( VIDEO_ES, fmt->i_codec ); + if( psz_chroma_description ) + info_category_AddInfo( p_cat, _("Decoded format"), "%s", + psz_chroma_description ); + } + break; case SPU_ES: @@ -2977,4 +3041,3 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * /* */ input_Control( p_input, INPUT_REPLACE_INFOS, p_cat ); } -