X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Fes_out.c;h=a0b0b1cad56b171f7ff2d8ad6926b16ba1324281;hb=89b6530d8abd99b96b9f33af022022241fe97ee2;hp=1481ad18d3a866bb6ebd0a381ff1746822c47222;hpb=04ee4c9fb32a3c5c97d0aa973ebfa12ed4c625c0;p=vlc diff --git a/src/input/es_out.c b/src/input/es_out.c index 1481ad18d3..a0b0b1cad5 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "input_internal.h" #include "clock.h" @@ -211,7 +212,7 @@ static inline int EsOutGetClosedCaptionsChannel( vlc_fourcc_t fcc ) } static inline bool EsFmtIsTeletext( const es_format_t *p_fmt ) { - return p_fmt->i_cat == SPU_ES && p_fmt->i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ); + return p_fmt->i_cat == SPU_ES && p_fmt->i_codec == VLC_CODEC_TELETEXT; } /***************************************************************************** @@ -219,9 +220,6 @@ static inline bool EsFmtIsTeletext( const es_format_t *p_fmt ) *****************************************************************************/ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) { - vlc_value_t val; - int i; - es_out_t *out = malloc( sizeof( *out ) ); if( !out ) return NULL; @@ -261,35 +259,35 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) p_sys->i_sub = 0; /* */ - var_Get( p_input, "audio-track", &val ); - p_sys->i_audio_last = val.i_int; + p_sys->i_audio_last = var_GetInteger( p_input, "audio-track" ); - var_Get( p_input, "sub-track", &val ); - p_sys->i_sub_last = val.i_int; + p_sys->i_sub_last = var_GetInteger( p_input, "sub-track" ); p_sys->i_default_sub_id = -1; if( !p_input->b_preparsing ) { - var_Get( p_input, "audio-language", &val ); - p_sys->ppsz_audio_language = LanguageSplit(val.psz_string); + char *psz_string; + + psz_string = var_GetString( p_input, "audio-language" ); + p_sys->ppsz_audio_language = LanguageSplit( psz_string ); if( p_sys->ppsz_audio_language ) { - for( i = 0; p_sys->ppsz_audio_language[i]; i++ ) + for( int i = 0; p_sys->ppsz_audio_language[i]; i++ ) msg_Dbg( p_input, "selected audio language[%d] %s", i, p_sys->ppsz_audio_language[i] ); } - free( val.psz_string ); + free( psz_string ); - var_Get( p_input, "sub-language", &val ); - p_sys->ppsz_sub_language = LanguageSplit(val.psz_string); + psz_string = var_GetString( p_input, "sub-language" ); + p_sys->ppsz_sub_language = LanguageSplit( psz_string ); if( p_sys->ppsz_sub_language ) { - for( i = 0; p_sys->ppsz_sub_language[i]; i++ ) + for( int i = 0; p_sys->ppsz_sub_language[i]; i++ ) msg_Dbg( p_input, "selected subtitle language[%d] %s", i, p_sys->ppsz_sub_language[i] ); } - free( val.psz_string ); + free( psz_string ); } else { @@ -297,11 +295,9 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) p_sys->ppsz_audio_language = NULL; } - var_Get( p_input, "audio-track-id", &val ); - p_sys->i_audio_id = val.i_int; + p_sys->i_audio_id = var_GetInteger( p_input, "audio-track-id" ); - var_Get( p_input, "sub-track-id", &val ); - p_sys->i_sub_id = val.i_int; + p_sys->i_sub_id = var_GetInteger( p_input, "sub-track-id" ); p_sys->p_es_audio = NULL; p_sys->p_es_video = NULL; @@ -1210,8 +1206,10 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta ) char ** ppsz_all_keys = vlc_dictionary_all_keys( &p_meta->extra_tags ); for( i = 0; ppsz_all_keys[i]; i++ ) { - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _(ppsz_all_keys[i]), - vlc_dictionary_value_for_key( &p_meta->extra_tags, ppsz_all_keys[i] ) ); + input_Control( p_input, INPUT_ADD_INFO, psz_cat, + vlc_gettext(ppsz_all_keys[i]), + vlc_dictionary_value_for_key( &p_meta->extra_tags, + ppsz_all_keys[i] ) ); free( ppsz_all_keys[i] ); } free( ppsz_all_keys ); @@ -1271,7 +1269,6 @@ static void EsOutProgramEpg( es_out_t *out, int i_group, vlc_epg_t *p_epg ) input_thread_t *p_input = p_sys->p_input; es_out_pgrm_t *p_pgrm; char *psz_cat; - int i; /* Find program */ p_pgrm = EsOutProgramFind( out, i_group ); @@ -1284,37 +1281,17 @@ static void EsOutProgramEpg( es_out_t *out, int i_group, vlc_epg_t *p_epg ) vlc_epg_Merge( p_pgrm->p_epg, p_epg ); /* Update info */ + msg_Dbg( p_input, "EsOutProgramEpg: number=%d name=%s", i_group, p_pgrm->p_epg->psz_name ); + psz_cat = EsOutProgramGetMetaName( p_pgrm ); -#ifdef HAVE_LOCALTIME_R + char *psz_epg; - if( asprintf( &psz_epg, "EPG %s", psz_cat ) == -1 ) - psz_epg = NULL; - input_Control( p_input, INPUT_DEL_INFO, psz_epg, NULL ); - msg_Dbg( p_input, "EsOutProgramEpg: number=%d name=%s", i_group, p_pgrm->p_epg->psz_name ); - for( i = 0; i < p_pgrm->p_epg->i_event; i++ ) - { - const vlc_epg_event_t *p_evt = p_pgrm->p_epg->pp_event[i]; - time_t t_start = (time_t)p_evt->i_start; - struct tm tm_start; - char psz_start[128]; - - localtime_r( &t_start, &tm_start ); - - snprintf( psz_start, sizeof(psz_start), "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", - 1900 + tm_start.tm_year, 1 + tm_start.tm_mon, tm_start.tm_mday, - tm_start.tm_hour, tm_start.tm_min, tm_start.tm_sec ); - if( p_evt->psz_short_description || p_evt->psz_description ) - input_Control( p_input, INPUT_ADD_INFO, psz_epg, psz_start, "%s (%2.2d:%2.2d) - %s", - p_evt->psz_name, - p_evt->i_duration/60/60, (p_evt->i_duration/60)%60, - p_evt->psz_short_description ? p_evt->psz_short_description : p_evt->psz_description ); - else - input_Control( p_input, INPUT_ADD_INFO, psz_epg, psz_start, "%s (%2.2d:%2.2d)", - p_evt->psz_name, - p_evt->i_duration/60/60, (p_evt->i_duration/60)%60 ); + if( asprintf( &psz_epg, "EPG %s", psz_cat ) >= 0 ) + { + input_item_SetEpg( p_input->p->p_item, psz_epg, p_pgrm->p_epg ); + free( psz_epg ); } - free( psz_epg ); -#endif + /* Update now playing */ free( p_pgrm->psz_now_playing ); p_pgrm->psz_now_playing = NULL; @@ -1410,6 +1387,10 @@ static es_out_id_t *EsOutAdd( es_out_t *out, const es_format_t *fmt ) es_format_Copy( &es->fmt, fmt ); if( es->fmt.i_id < 0 ) 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 ); + es->i_id = es->fmt.i_id; es->i_meta_id = out->p_sys->i_id; es->b_scrambled = false; @@ -1560,7 +1541,6 @@ static void EsSelect( es_out_t *out, es_out_id_t *es ) { es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; - vlc_value_t val; if( EsIsSelected( es ) ) { @@ -1591,7 +1571,6 @@ static void EsSelect( es_out_t *out, es_out_id_t *es ) } else if( es->fmt.i_cat == AUDIO_ES ) { - var_Get( p_input, "audio", &val ); if( !var_GetBool( p_input, out->b_sout ? "sout-audio" : "audio" ) ) { msg_Dbg( p_input, "audio is disabled, not selecting ES 0x%x", @@ -1601,7 +1580,6 @@ static void EsSelect( es_out_t *out, es_out_id_t *es ) } if( es->fmt.i_cat == SPU_ES ) { - var_Get( p_input, "spu", &val ); if( !var_GetBool( p_input, out->b_sout ? "sout-spu" : "spu" ) ) { msg_Dbg( p_input, "spu is disabled, not selecting ES 0x%x", @@ -1863,6 +1841,19 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) p_block->i_buffer, &i_total ); stats_UpdateFloat( p_input , p_input->p->counters.p_demux_bitrate, (float)i_total, NULL ); + + /* Update number of corrupted data packats */ + if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) + { + stats_UpdateInteger( p_input, p_input->p->counters.p_demux_corrupted, + 1, NULL ); + } + /* Update number of discontinuities */ + if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY ) + { + stats_UpdateInteger( p_input, p_input->p->counters.p_demux_discontinuity, + 1, NULL ); + } vlc_mutex_unlock( &p_input->p->counters.counters_lock ); } @@ -1888,14 +1879,34 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) return VLC_SUCCESS; } + /* Check for sout mode */ + if( out->b_sout ) + { + /* FIXME review this, proper lock may be missing */ + if( p_input->p->p_sout->i_out_pace_nocontrol > 0 && + p_input->p->b_out_pace_control ) + { + msg_Dbg( p_input, "switching to sync mode" ); + p_input->p->b_out_pace_control = false; + } + else if( p_input->p->p_sout->i_out_pace_nocontrol <= 0 && + !p_input->p->b_out_pace_control ) + { + msg_Dbg( p_input, "switching to async mode" ); + p_input->p->b_out_pace_control = true; + } + } + /* Decode */ if( es->p_dec_record ) { block_t *p_dup = block_Duplicate( p_block ); if( p_dup ) - input_DecoderDecode( es->p_dec_record, p_dup ); + input_DecoderDecode( es->p_dec_record, p_dup, + p_input->p->b_out_pace_control ); } - input_DecoderDecode( es->p_dec, p_block ); + input_DecoderDecode( es->p_dec, p_block, + p_input->p->b_out_pace_control ); es_format_t fmt_dsc; vlc_meta_t *p_meta_dsc; @@ -1914,19 +1925,13 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) input_DecoderIsCcPresent( es->p_dec, pb_cc ); for( int i = 0; i < 4; i++ ) { - static const vlc_fourcc_t fcc[4] = { - VLC_FOURCC('c', 'c', '1', ' '), - VLC_FOURCC('c', 'c', '2', ' '), - VLC_FOURCC('c', 'c', '3', ' '), - VLC_FOURCC('c', 'c', '4', ' '), - }; es_format_t fmt; if( es->pb_cc_present[i] || !pb_cc[i] ) continue; msg_Dbg( p_input, "Adding CC track %d for es[%d]", 1+i, es->i_id ); - es_format_Init( &fmt, SPU_ES, fcc[i] ); + es_format_Init( &fmt, SPU_ES, EsOutFourccClosedCaptions[i] ); fmt.i_group = es->fmt.i_group; if( asprintf( &fmt.psz_description, _("Closed captions %u"), 1 + i ) == -1 ) @@ -2221,6 +2226,12 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_EGENERIC; i_pcr = (int64_t)va_arg( args, int64_t ); + if( i_pcr <= VLC_TS_INVALID ) + { + msg_Err( p_sys->p_input, "Invalid PCR value in ES_OUT_SET_(GROUP_)PCR !" ); + return VLC_EGENERIC; + } + /* search program * TODO do not use mdate() but proper stream acquisition date */ input_clock_Update( p_pgrm->p_clock, VLC_OBJECT(p_sys->p_input), @@ -2433,20 +2444,24 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) mtime_t i_time = (mtime_t)va_arg( args, mtime_t ); mtime_t i_length = (mtime_t)va_arg( args, mtime_t ); - /* Fix for buffering delay */ - const mtime_t i_delay = EsOutGetBuffering( out ); + input_SendEventLength( p_sys->p_input, i_length ); - i_time -= i_delay; - if( i_time < 0 ) - i_time = 0; + if( !p_sys->b_buffering ) + { + /* Fix for buffering delay */ + const mtime_t i_delay = EsOutGetBuffering( out ); - if( i_length > 0 ) - f_position -= (double)i_delay / i_length; - if( f_position < 0 ) - f_position = 0; + i_time -= i_delay; + if( i_time < 0 ) + i_time = 0; - if( !p_sys->b_buffering ) - input_SendEventTimes( p_sys->p_input, f_position, i_time, i_length ); + if( i_length > 0 ) + f_position -= (double)i_delay / i_length; + if( f_position < 0 ) + f_position = 0; + + input_SendEventPosition( p_sys->p_input, f_position, i_time ); + } return VLC_SUCCESS; } case ES_OUT_SET_JITTER: @@ -2661,8 +2676,15 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Original ID"), "%d", es->i_id ); - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Codec"), - "%.4s", (char*)&p_fmt_es->i_codec ); + 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 ); + else + input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Codec"), + "%.4s", (char*)&i_codec_fourcc ); if( es->psz_language && *es->psz_language ) input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Language"), @@ -2772,7 +2794,8 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t * char *psz_value = vlc_dictionary_value_for_key( &p_meta->extra_tags, psz_key ); if( psz_value ) - input_Control( p_input, INPUT_ADD_INFO, psz_cat, _(psz_key), _(psz_value) ); + input_Control( p_input, INPUT_ADD_INFO, psz_cat, + vlc_gettext(psz_key), vlc_gettext(psz_value) ); free( psz_key ); } free( ppsz_all_keys );