]> git.sesse.net Git - vlc/blobdiff - src/input/es_out.c
Simplification (make_path always returns an absolute path)
[vlc] / src / input / es_out.c
index c596ae6dd7de279bb17c90121728f6e6a9052c62..8d644a1822560b30bc9bda02c9c7eea6bd0cf76b 100644 (file)
@@ -148,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;
 
@@ -190,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 );
@@ -269,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++ )
@@ -279,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++ )
@@ -310,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;
@@ -646,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) );
@@ -734,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;
 }
@@ -1232,7 +1234,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 )
@@ -1451,7 +1453,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;
@@ -2307,23 +2314,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;
@@ -2598,19 +2614,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;
         }
 
@@ -2624,7 +2643,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;
         }
 
@@ -2727,7 +2747,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;
@@ -2750,6 +2770,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 );
@@ -2768,6 +2792,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 );
     }
 
@@ -2785,9 +2811,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;