X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Fes_out.c;h=bbcbcd7222b279ff26b19a53ccf91bd7f4826b66;hb=959554209ac3b6cb996a9b66fd717957dcfbd032;hp=b76e27626a5028c284627d8f4374dc9e699dad05;hpb=57882e0f55c854615251b67e9a8ae90faa86fa55;p=vlc diff --git a/src/input/es_out.c b/src/input/es_out.c index b76e27626a..bbcbcd7222 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -44,6 +44,7 @@ #include "decoder.h" #include "es_out.h" #include "event.h" +#include "info.h" #include "../stream_output/stream_output.h" @@ -147,6 +148,7 @@ struct es_out_sys_t /* Clock configuration */ mtime_t i_pts_delay; + mtime_t i_pts_jitter; int i_cr_average; int i_rate; @@ -189,7 +191,7 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced ); static char *LanguageGetName( const char *psz_code ); static char *LanguageGetCode( const char *psz_lang ); -static char **LanguageSplit( const char *psz_langs ); +static char **LanguageSplit( const char *psz_langs, bool b_default_any ); static int LanguageArrayIndex( char **ppsz_langs, char *psz_lang ); static char *EsOutProgramGetMetaName( es_out_pgrm_t *p_pgrm ); @@ -237,8 +239,6 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) out->pf_control = EsOutControl; out->pf_destroy = EsOutDelete; out->p_sys = p_sys; - out->b_sout = false; /* It has no meaning here, and p_input->p->p_sout is not yet valid */ - vlc_mutex_init_recursive( &p_sys->lock ); p_sys->p_input = p_input; @@ -270,7 +270,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) char *psz_string; psz_string = var_GetString( p_input, "audio-language" ); - p_sys->ppsz_audio_language = LanguageSplit( psz_string ); + p_sys->ppsz_audio_language = LanguageSplit( psz_string, true ); if( p_sys->ppsz_audio_language ) { for( int i = 0; p_sys->ppsz_audio_language[i]; i++ ) @@ -280,7 +280,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) free( psz_string ); psz_string = var_GetString( p_input, "sub-language" ); - p_sys->ppsz_sub_language = LanguageSplit( psz_string ); + p_sys->ppsz_sub_language = LanguageSplit( psz_string, false ); if( p_sys->ppsz_sub_language ) { for( int i = 0; p_sys->ppsz_sub_language[i]; i++ ) @@ -311,6 +311,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) p_sys->i_rate = i_rate; p_sys->i_pts_delay = 0; + p_sys->i_pts_jitter = 0; p_sys->i_cr_average = 0; p_sys->b_buffering = true; @@ -647,7 +648,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) ); @@ -735,13 +736,13 @@ static bool EsOutIsExtraBufferingAllowed( es_out_t *out ) if( p_es->p_dec_record ) i_size += input_DecoderGetFifoSize( p_es->p_dec_record ); } - //fprintf( stderr, "----- EsOutIsExtraBufferingAllowed =% 5d kbytes -- ", i_size / 1024 ); + //msg_Info( out, "----- EsOutIsExtraBufferingAllowed =% 5d KiB -- ", i_size / 1024 ); /* TODO maybe we want to be able to tune it ? */ #if defined(OPTIMIZE_MEMORY) - const size_t i_level_high = 500000; /* 0.5 Mbytes */ + const size_t i_level_high = 512*1024; /* 0.5 MiB */ #else - const size_t i_level_high = 10000000; /* 10 Mbytes */ + const size_t i_level_high = 10*1024*1024; /* 10 MiB */ #endif return i_size < i_level_high; } @@ -1168,7 +1169,6 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, const vlc_meta_t *p_me es_out_sys_t *p_sys = out->p_sys; es_out_pgrm_t *p_pgrm; input_thread_t *p_input = p_sys->p_input; - char *psz_cat; const char *psz_title = NULL; const char *psz_provider = NULL; int i; @@ -1230,27 +1230,40 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, const vlc_meta_t *p_me } } - psz_cat = EsOutProgramGetMetaName( p_pgrm ); - if( psz_provider ) + /* */ + char **ppsz_all_keys = vlc_meta_CopyExtraNames(p_meta ); + + info_category_t *p_cat = NULL; + if( psz_provider || *ppsz_all_keys[0] ) { - if( p_sys->p_pgrm == p_pgrm ) - { - input_item_SetPublisher( p_input->p->p_item, psz_provider ); - input_SendEventMeta( p_input ); - } - input_Control( p_input, INPUT_ADD_INFO, psz_cat, vlc_meta_TypeToLocalizedString(vlc_meta_Publisher), psz_provider ); + char *psz_cat = EsOutProgramGetMetaName( p_pgrm ); + if( psz_cat ) + p_cat = info_category_New( psz_cat ); + free( psz_cat ); } - char ** ppsz_all_keys = vlc_meta_CopyExtraNames(p_meta ); + for( i = 0; ppsz_all_keys[i]; i++ ) { - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - vlc_gettext(ppsz_all_keys[i]), - vlc_meta_GetExtra( p_meta, ppsz_all_keys[i] ) ); + if( p_cat ) + info_category_AddInfo( p_cat, vlc_gettext(ppsz_all_keys[i]), "%s", + vlc_meta_GetExtra( p_meta, ppsz_all_keys[i] ) ); free( ppsz_all_keys[i] ); } free( ppsz_all_keys ); - free( psz_cat ); + if( psz_provider ) + { + if( p_sys->p_pgrm == p_pgrm ) + { + input_item_SetPublisher( p_input->p->p_item, psz_provider ); + input_SendEventMeta( p_input ); + } + if( p_cat ) + info_category_AddInfo( p_cat, vlc_meta_TypeToLocalizedString(vlc_meta_Publisher), + "%s",psz_provider ); + } + if( p_cat ) + input_Control( p_input, INPUT_MERGE_INFOS, p_cat ); } static void EsOutProgramEpg( es_out_t *out, int i_group, const vlc_epg_t *p_epg ) @@ -2092,16 +2105,13 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es ) static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) { es_out_sys_t *p_sys = out->p_sys; - bool b, *pb; - int i; - - es_out_id_t *es; switch( i_query ) { case ES_OUT_SET_ES_STATE: - es = (es_out_id_t*) va_arg( args, es_out_id_t * ); - b = (bool) va_arg( args, int ); + { + es_out_id_t *es = va_arg( args, es_out_id_t * ); + bool b = va_arg( args, int ); if( b && !EsIsSelected( es ) ) { EsSelect( out, es ); @@ -2113,13 +2123,16 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_SUCCESS; } return VLC_SUCCESS; + } case ES_OUT_GET_ES_STATE: - es = (es_out_id_t*) va_arg( args, es_out_id_t * ); - pb = (bool*) va_arg( args, bool * ); + { + es_out_id_t *es = va_arg( args, es_out_id_t * ); + bool *pb = va_arg( args, bool * ); *pb = EsIsSelected( es ); return VLC_SUCCESS; + } case ES_OUT_SET_MODE: { @@ -2133,6 +2146,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) /* XXX Terminate vout if there are tracks but no video one. * This one is not mandatory but is he earliest place where it * can be done */ + int i; for( i = 0; i < p_sys->i_es; i++ ) { es_out_id_t *p_es = p_sys->es[i]; @@ -2146,13 +2160,13 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) p_sys->i_mode = i_mode; /* Reapply policy mode */ - for( i = 0; i < p_sys->i_es; i++ ) + for( int i = 0; i < p_sys->i_es; i++ ) { if( EsIsSelected( p_sys->es[i] ) ) EsUnselect( out, p_sys->es[i], p_sys->es[i]->p_pgrm == p_sys->p_pgrm ); } - for( i = 0; i < p_sys->i_es; i++ ) + for( int i = 0; i < p_sys->i_es; i++ ) EsOutSelect( out, p_sys->es[i], false ); if( i_mode == ES_OUT_MODE_END ) EsOutTerminate( out ); @@ -2162,10 +2176,9 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) case ES_OUT_SET_ES: case ES_OUT_RESTART_ES: { - int i_cat; - - es = (es_out_id_t*) va_arg( args, es_out_id_t * ); + es_out_id_t *es = va_arg( args, es_out_id_t * ); + int i_cat; if( es == NULL ) i_cat = UNKNOWN_ES; else if( es == (es_out_id_t*)((uint8_t*)NULL+AUDIO_ES) ) @@ -2177,7 +2190,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) else i_cat = -1; - for( i = 0; i < p_sys->i_es; i++ ) + for( int i = 0; i < p_sys->i_es; i++ ) { if( i_cat == -1 ) { @@ -2215,7 +2228,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) case ES_OUT_SET_ES_DEFAULT: { - es = (es_out_id_t*) va_arg( args, es_out_id_t * ); + es_out_id_t *es = va_arg( args, es_out_id_t * ); if( es == NULL ) { @@ -2296,23 +2309,32 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) else if( b_late && ( !p_sys->p_input->p->p_sout || !p_sys->p_input->p->b_out_pace_control ) ) { + const mtime_t i_pts_delay_base = p_sys->i_pts_delay - p_sys->i_pts_jitter; mtime_t i_pts_delay = input_clock_GetJitter( p_pgrm->p_clock ); /* Avoid dangerously high value */ - const mtime_t i_pts_delay_max = 30000000; - if( i_pts_delay > i_pts_delay_max ) - i_pts_delay = __MAX( i_pts_delay_max, p_sys->i_pts_delay ); + const mtime_t i_jitter_max = INT64_C(1000) * var_InheritInteger( p_sys->p_input, "clock-jitter" ); + if( i_pts_delay > __MIN( i_pts_delay_base + i_jitter_max, INPUT_PTS_DELAY_MAX ) ) + { + msg_Err( p_sys->p_input, + "ES_OUT_SET_(GROUP_)PCR is called too late (jitter of %d ms ignored)", + (int)(i_pts_delay - i_pts_delay_base) / 1000 ); + i_pts_delay = p_sys->i_pts_delay; + } + else + { + msg_Err( p_sys->p_input, + "ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to %d ms)", + (int)(i_pts_delay/1000) ); + } /* Force a rebufferization when we are too late */ - msg_Err( p_sys->p_input, - "ES_OUT_SET_(GROUP_)PCR is called too late, increasing pts_delay to %d ms", - (int)(i_pts_delay/1000) ); /* It is not really good, as we throw away already buffered data * TODO have a mean to correctly reenter bufferization */ es_out_Control( out, ES_OUT_RESET_PCR ); - es_out_Control( out, ES_OUT_SET_JITTER, i_pts_delay, p_sys->i_cr_average ); + es_out_SetJitter( out, i_pts_delay_base, i_pts_delay - i_pts_delay_base, p_sys->i_cr_average ); } } return VLC_SUCCESS; @@ -2325,9 +2347,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) case ES_OUT_SET_GROUP: { - int j; - i = (int) va_arg( args, int ); - for( j = 0; j < p_sys->i_pgrm; j++ ) + int i = va_arg( args, int ); + for( int j = 0; j < p_sys->i_pgrm; j++ ) { es_out_pgrm_t *p_pgrm = p_sys->pgrm[j]; if( p_pgrm->i_id == i ) @@ -2343,9 +2364,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) { /* This ain't pretty but is need by some demuxers (eg. Ogg ) * to update the p_extra data */ - es_format_t *p_fmt; - es = (es_out_id_t*) va_arg( args, es_out_id_t * ); - p_fmt = (es_format_t*) va_arg( args, es_format_t * ); + es_out_id_t *es = va_arg( args, es_out_id_t * ); + es_format_t *p_fmt = va_arg( args, es_format_t * ); if( es == NULL ) return VLC_EGENERIC; @@ -2375,7 +2395,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) case ES_OUT_SET_ES_SCRAMBLED_STATE: { - es = (es_out_id_t*) va_arg( args, es_out_id_t * ); + es_out_id_t *es = va_arg( args, es_out_id_t * ); bool b_scrambled = (bool)va_arg( args, int ); if( !es->b_scrambled != !b_scrambled ) @@ -2472,14 +2492,16 @@ 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 ** ); - if( es->p_dec ) + if( p_es->p_dec ) { if( pp_decoder ) - *pp_decoder = vlc_object_hold( es->p_dec ); - input_DecoderGetObjects( es->p_dec, pp_vout, pp_aout ); + *pp_decoder = vlc_object_hold( p_es->p_dec ); + input_DecoderGetObjects( p_es->p_dec, pp_vout, pp_aout ); } else { + if( pp_decoder ) + *pp_decoder = NULL; if( pp_vout ) *pp_vout = NULL; if( pp_aout ) @@ -2489,14 +2511,18 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) } case ES_OUT_GET_BUFFERING: - pb = (bool *)va_arg( args, bool* ); + { + bool *pb = va_arg( args, bool* ); *pb = p_sys->b_buffering; return VLC_SUCCESS; + } case ES_OUT_GET_EMPTY: - pb = (bool *)va_arg( args, bool* ); + { + bool *pb = va_arg( args, bool* ); *pb = EsOutDecodersIsEmpty( out ); return VLC_SUCCESS; + } case ES_OUT_SET_DELAY: { @@ -2507,8 +2533,10 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) } case ES_OUT_SET_RECORD_STATE: - b = (bool) va_arg( args, int ); + { + bool b = va_arg( args, int ); return EsOutSetRecord( out, b ); + } case ES_OUT_SET_PAUSE_STATE: { @@ -2581,19 +2609,22 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) } case ES_OUT_SET_JITTER: { - mtime_t i_pts_delay = (mtime_t)va_arg( args, mtime_t ); + mtime_t i_pts_delay = (mtime_t)va_arg( args, mtime_t ); + mtime_t i_pts_jitter = (mtime_t)va_arg( args, mtime_t ); int i_cr_average = (int)va_arg( args, int ); - if( i_pts_delay == p_sys->i_pts_delay && - i_cr_average == p_sys->i_cr_average ) - return VLC_SUCCESS; + bool b_change_clock = + i_pts_delay + i_pts_jitter != p_sys->i_pts_delay || + i_cr_average != p_sys->i_cr_average; - p_sys->i_pts_delay = i_pts_delay; + assert( i_pts_jitter >= 0 ); + p_sys->i_pts_delay = i_pts_delay + i_pts_jitter; + p_sys->i_pts_jitter = i_pts_jitter; p_sys->i_cr_average = i_cr_average; - for( int i = 0; i < p_sys->i_pgrm; i++ ) + for( int i = 0; i < p_sys->i_pgrm && b_change_clock; i++ ) input_clock_SetJitter( p_sys->pgrm[i]->p_clock, - i_pts_delay, i_cr_average ); + i_pts_delay + i_pts_jitter, i_cr_average ); return VLC_SUCCESS; } @@ -2607,7 +2638,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_EGENERIC; mtime_t *pi_system = va_arg( args, mtime_t *); - *pi_system = input_clock_GetSystemOrigin( p_pgrm->p_clock ); + mtime_t *pi_delay = va_arg( args, mtime_t *); + input_clock_GetSystemOrigin( p_pgrm->p_clock, pi_system, pi_delay ); return VLC_SUCCESS; } @@ -2710,7 +2742,7 @@ static char *LanguageGetCode( const char *psz_lang ) return strdup("??"); } -static char **LanguageSplit( const char *psz_langs ) +static char **LanguageSplit( const char *psz_langs, bool b_default_any ) { char *psz_dup; char *psz_parser; @@ -2733,6 +2765,10 @@ static char **LanguageSplit( const char *psz_langs ) { TAB_APPEND( i_psz, ppsz, strdup("any") ); } + else if( !strcmp( psz_parser, "none" ) ) + { + TAB_APPEND( i_psz, ppsz, strdup("none") ); + } else { psz_code = LanguageGetCode( psz_parser ); @@ -2751,6 +2787,8 @@ static char **LanguageSplit( const char *psz_langs ) if( i_psz ) { + if( b_default_any && strcmp( ppsz[i_psz - 1], "none" ) ) + TAB_APPEND( i_psz, ppsz, strdup("any") ); TAB_APPEND( i_psz, ppsz, NULL ); } @@ -2768,9 +2806,9 @@ static int LanguageArrayIndex( char **ppsz_langs, char *psz_lang ) { if( !strcasecmp( ppsz_langs[i], psz_lang ) || !strcasecmp( ppsz_langs[i], "any" ) ) - { return i; - } + if( !strcasecmp( ppsz_langs[i], "none" ) ) + break; } return -1; @@ -2785,16 +2823,15 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; const es_format_t *p_fmt_es = &es->fmt; - char *psz_cat; lldiv_t div; - /* Create category name */ - if( asprintf( &psz_cat, _("Stream %d"), es->i_meta_id ) == -1 ) + /* Create category */ + char psz_cat[128]; + snprintf( psz_cat, sizeof(psz_cat),_("Stream %d"), es->i_meta_id ); + info_category_t *p_cat = info_category_New( psz_cat ); + if( !p_cat ) return; - /* Remove previous information */ - input_Control( p_input, INPUT_DEL_INFO, psz_cat, NULL ); - /* Add informations */ const char *psz_type; switch( fmt->i_cat ) @@ -2814,46 +2851,45 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * } if( psz_type ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Type"), psz_type ); + info_category_AddInfo( p_cat, _("Type"), "%s", psz_type ); if( es->i_meta_id != es->i_id ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Original ID"), + info_category_AddInfo( p_cat, _("Original ID"), "%d", es->i_id ); 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; if( psz_codec_description ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Codec"), - "%s (%.4s)", psz_codec_description, (char*)&i_codec_fourcc ); + info_category_AddInfo( p_cat, _("Codec"), "%s (%.4s)", + psz_codec_description, (char*)&i_codec_fourcc ); else - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Codec"), - "%.4s", (char*)&i_codec_fourcc ); + info_category_AddInfo( p_cat, _("Codec"), "%.4s", + (char*)&i_codec_fourcc ); if( es->psz_language && *es->psz_language ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Language"), - "%s", es->psz_language ); + info_category_AddInfo( p_cat, _("Language"), "%s", + es->psz_language ); if( fmt->psz_description && *fmt->psz_description ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Description"), - "%s", fmt->psz_description ); + info_category_AddInfo( p_cat, _("Description"), "%s", + fmt->psz_description ); switch( fmt->i_cat ) { case AUDIO_ES: - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Type"), _("Audio") ); + info_category_AddInfo( p_cat, _("Type"), _("Audio") ); if( fmt->audio.i_physical_channels & AOUT_CHAN_PHYSMASK ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Channels"), - "%s", _( aout_FormatPrintChannels( &fmt->audio ) ) ); + info_category_AddInfo( p_cat, _("Channels"), "%s", + _( aout_FormatPrintChannels( &fmt->audio ) ) ); else if( fmt->audio.i_channels > 0 ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Channels"), - "%u", fmt->audio.i_channels ); + info_category_AddInfo( p_cat, _("Channels"), "%u", + fmt->audio.i_channels ); if( fmt->audio.i_rate > 0 ) { - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Sample rate"), - _("%u Hz"), fmt->audio.i_rate ); + info_category_AddInfo( p_cat, _("Sample rate"), _("%u Hz"), + fmt->audio.i_rate ); /* FIXME that should be removed or improved ! (used by text/strings.c) */ var_SetInteger( p_input, "sample-rate", fmt->audio.i_rate ); } @@ -2862,14 +2898,13 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * if( i_bitspersample <= 0 ) i_bitspersample = aout_BitsPerSample( p_fmt_es->i_codec ); if( i_bitspersample > 0 ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Bits per sample"), "%u", - i_bitspersample ); + info_category_AddInfo( p_cat, _("Bits per sample"), "%u", + i_bitspersample ); if( fmt->i_bitrate > 0 ) { - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Bitrate"), - _("%u kb/s"), fmt->i_bitrate / 1000 ); + info_category_AddInfo( p_cat, _("Bitrate"), _("%u kb/s"), + fmt->i_bitrate / 1000 ); /* FIXME that should be removed or improved ! (used by text/strings.c) */ var_SetInteger( p_input, "bit-rate", fmt->i_bitrate ); } @@ -2883,26 +2918,23 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * psz_name = _("Track replay gain"); else psz_name = _("Album replay gain"); - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - psz_name, _("%.2f dB"), p_rg->pf_gain[i] ); + info_category_AddInfo( p_cat, psz_name, _("%.2f dB"), + p_rg->pf_gain[i] ); } break; case VIDEO_ES: - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Type"), _("Video") ); + info_category_AddInfo( p_cat, _("Type"), _("Video") ); if( fmt->video.i_width > 0 && fmt->video.i_height > 0 ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Resolution"), "%ux%u", - fmt->video.i_width, fmt->video.i_height ); + info_category_AddInfo( p_cat, _("Resolution"), "%ux%u", + fmt->video.i_width, fmt->video.i_height ); if( fmt->video.i_visible_width > 0 && fmt->video.i_visible_height > 0 ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Display resolution"), "%ux%u", - fmt->video.i_visible_width, - fmt->video.i_visible_height); + info_category_AddInfo( p_cat, _("Display resolution"), "%ux%u", + fmt->video.i_visible_width, + fmt->video.i_visible_height); if( fmt->video.i_frame_rate > 0 && fmt->video.i_frame_rate_base > 0 ) { @@ -2910,18 +2942,16 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * fmt->video.i_frame_rate_base * 1000000, 1000000 ); if( div.rem > 0 ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Frame rate"), "%"PRId64".%06u", - div.quot, (unsigned int )div.rem ); + info_category_AddInfo( p_cat, _("Frame rate"), "%"PRId64".%06u", + div.quot, (unsigned int )div.rem ); else - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Frame rate"), "%"PRId64, div.quot ); + info_category_AddInfo( p_cat, _("Frame rate"), "%"PRId64, + div.quot ); } break; case SPU_ES: - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - _("Type"), _("Subtitle") ); + info_category_AddInfo( p_cat, _("Type"), _("Subtitle") ); break; default: @@ -2938,12 +2968,13 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * const char *psz_value = vlc_meta_GetExtra( p_meta, psz_key ); if( psz_value ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, - vlc_gettext(psz_key), vlc_gettext(psz_value) ); + info_category_AddInfo( p_cat, vlc_gettext(psz_key), "%s", + vlc_gettext(psz_value) ); free( psz_key ); } free( ppsz_all_keys ); } - - free( psz_cat ); + /* */ + input_Control( p_input, INPUT_REPLACE_INFOS, p_cat ); } +