]> git.sesse.net Git - vlc/blobdiff - src/input/es_out.c
input: fix a crash when loading an invalid mrl
[vlc] / src / input / es_out.c
index afc8c47fecd1937eee46a122e01834b332ac76f8..760e57bab3ebc100a5b9db4cdd873cf3a7f2385c 100644 (file)
@@ -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 )
@@ -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;
@@ -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;
@@ -1945,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 );
@@ -2144,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 );
@@ -2501,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 )
@@ -2667,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" );
@@ -2692,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( "" );
     }
@@ -2835,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 );
@@ -2842,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 )
     {
@@ -2959,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:
@@ -2988,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 );
 }
-