#include <vlc_es_out.h>
#include <vlc_block.h>
#include <vlc_aout.h>
+#include <vlc_fourcc.h>
#include "input_internal.h"
#include "clock.h"
}
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;
}
/*****************************************************************************
es_out_sys_t *p_sys = out->p_sys;
p_sys->i_rate = i_rate;
-
- if( !p_sys->b_paused )
- EsOutProgramsChangeRate( out );
+ EsOutProgramsChangeRate( out );
}
static void EsOutChangePosition( es_out_t *out )
free( p_pgrm );
return NULL;
}
+ if( p_sys->b_paused )
+ input_clock_ChangePause( p_pgrm->p_clock, p_sys->b_paused, p_sys->i_pause_date );
input_clock_SetJitter( p_pgrm->p_clock, p_sys->i_pts_delay, p_sys->i_cr_average );
-
/* Append it */
TAB_APPEND( p_sys->i_pgrm, p_sys->pgrm, p_pgrm );
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 );
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;
break;
}
}
- var_Change( p_sys->p_input, "programs", VLC_VAR_FREELIST, &val, NULL );
+ var_FreeList( &val, NULL );
}
else if( p_sys->i_mode == ES_OUT_MODE_AUTO )
{
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;
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 )
int i_group = 0;
int64_t i_pcr;
+ /* Search program */
if( i_query == ES_OUT_SET_PCR )
{
p_pgrm = p_sys->p_pgrm;
return VLC_EGENERIC;
i_pcr = (int64_t)va_arg( args, int64_t );
- /* search program
- * TODO do not use mdate() but proper stream acquisition date */
+ if( i_pcr <= VLC_TS_INVALID )
+ {
+ msg_Err( p_sys->p_input, "Invalid PCR value in ES_OUT_SET_(GROUP_)PCR !" );
+ return VLC_EGENERIC;
+ }
+
+ /* TODO do not use mdate() but proper stream acquisition date */
+ bool b_late;
input_clock_Update( p_pgrm->p_clock, VLC_OBJECT(p_sys->p_input),
+ &b_late,
p_sys->p_input->p->b_can_pace_control || p_sys->b_buffering, i_pcr, mdate() );
- /* Check buffering state on master clock update */
- if( p_sys->b_buffering && p_pgrm == p_sys->p_pgrm )
- EsOutDecodersStopBuffering( out, false );
+ if( p_pgrm == p_sys->p_pgrm )
+ {
+ if( p_sys->b_buffering )
+ {
+ /* Check buffering state on master clock update */
+ EsOutDecodersStopBuffering( out, false );
+ }
+ else if( b_late )
+ {
+ 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 );
+
+ /* 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 );
+ }
+ }
return VLC_SUCCESS;
}
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 );
+
+ if( !p_sys->b_buffering )
+ {
+ /* Fix for buffering delay */
+ const mtime_t i_delay = EsOutGetBuffering( out );
- i_time -= i_delay;
- if( i_time < 0 )
- i_time = 0;
+ i_time -= i_delay;
+ if( i_time < 0 )
+ i_time = 0;
- if( i_length > 0 )
- f_position -= (double)i_delay / i_length;
- if( f_position < 0 )
- f_position = 0;
+ if( i_length > 0 )
+ f_position -= (double)i_delay / i_length;
+ if( f_position < 0 )
+ f_position = 0;
- if( !p_sys->b_buffering )
- input_SendEventTimes( p_sys->p_input, f_position, i_time, i_length );
+ input_SendEventPosition( p_sys->p_input, f_position, i_time );
+ }
return VLC_SUCCESS;
}
case ES_OUT_SET_JITTER:
if( psz_lang == NULL || *psz_lang == '\0' )
return strdup("??");
- for( pl = p_languages; pl->psz_iso639_1 != NULL; pl++ )
+ for( pl = p_languages; pl->psz_eng_name != NULL; pl++ )
{
if( !strcasecmp( pl->psz_eng_name, psz_lang ) ||
!strcasecmp( pl->psz_native_name, psz_lang ) ||
break;
}
- if( pl->psz_iso639_1 != NULL )
+ if( pl->psz_eng_name != NULL )
return strdup( pl->psz_iso639_1 );
return strdup("??");
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"),
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 );