]> git.sesse.net Git - vlc/blobdiff - src/input/es_out.c
* src/input/demux.c: ignore STREAM_CONTROL_ACCESS control query + coding style changes.
[vlc] / src / input / es_out.c
index bc1c5ce11896aafd50208e007d5151d205001050..47887b523c270420342d5b13c83ce95337738a22 100644 (file)
@@ -109,6 +109,7 @@ static void         EsOutDel    ( es_out_t *, es_out_id_t * );
 static void         EsOutSelect( es_out_t *out, es_out_id_t *es, vlc_bool_t b_force );
 static int          EsOutControl( es_out_t *, int i_query, va_list );
 
+static void         EsOutAddInfo( es_out_t *, es_out_id_t *es );
 
 static void EsSelect( es_out_t *out, es_out_id_t *es );
 static void EsUnselect( es_out_t *out, es_out_id_t *es, vlc_bool_t b_update );
@@ -242,10 +243,26 @@ void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay )
         p_sys->i_spu_delay = i_delay;
 }
 
+vlc_bool_t input_EsOutDecodersEmpty( es_out_t *out )
+{
+    es_out_sys_t      *p_sys = out->p_sys;
+    int i;
+
+    for( i = 0; i < p_sys->i_es; i++ )
+    {
+        es_out_id_t *es = p_sys->es[i];
+
+        if( es->p_dec && !input_DecoderEmpty( es->p_dec ) )
+            return VLC_FALSE;
+    }
+    return VLC_TRUE;
+}
+
 /*****************************************************************************
  *
  *****************************************************************************/
-static void EsOutESVarUpdate( es_out_t *out, es_out_id_t *es )
+static void EsOutESVarUpdate( es_out_t *out, es_out_id_t *es,
+                              vlc_bool_t b_delete )
 {
     es_out_sys_t      *p_sys = out->p_sys;
     input_thread_t    *p_input = p_sys->p_input;
@@ -262,6 +279,14 @@ static void EsOutESVarUpdate( es_out_t *out, es_out_id_t *es )
     else
         return;
 
+    if( b_delete )
+    {
+        val.i_int = es->i_id;
+        var_Change( p_input, psz_var, VLC_VAR_DELCHOICE, &val, NULL );
+        var_SetBool( p_sys->p_input, "intf-change", VLC_TRUE );
+        return;
+    }
+
     /* Get the number of ES already added */
     var_Change( p_input, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL );
     if( val.i_int == 0 )
@@ -342,7 +367,7 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
     var_Change( p_input, "spu-es",   VLC_VAR_CLEARCHOICES, NULL, NULL );
     for( i = 0; i < p_sys->i_es; i++ )
     {
-        EsOutESVarUpdate( out, p_sys->es[i] );
+        EsOutESVarUpdate( out, p_sys->es[i], VLC_FALSE );
         EsOutSelect( out, p_sys->es[i], VLC_FALSE );
     }
 
@@ -448,75 +473,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     es->p_dec = NULL;
 
     if( es->p_pgrm == p_sys->p_pgrm )
-        EsOutESVarUpdate( out, es );
-
-#if 0
-    /* Add stream info */
-    sprintf( psz_cat, _("Stream %d"), out->p_sys->i_id - 1 );
-
-    input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Codec"),
-                   "%.4s", (char*)&fmt->i_codec );
-
-    if( *psz_description )
-        input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Language"),
-                       "%s", psz_description );
-
-    if( fmt->psz_description && *fmt->psz_description )
-        input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Description"),
-                       "%s", fmt->psz_description );
-
-    /* Add information */
-    switch( fmt->i_cat )
-    {
-    case AUDIO_ES:
-        input_Control( p_input, INPUT_ADD_INFO, psz_cat,
-                       _("Type"), _("Audio") );
-
-        if( fmt->audio.i_channels > 0 )
-            input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Channels"),
-                           "%d", fmt->audio.i_channels );
-
-        if( fmt->audio.i_rate > 0 )
-            input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Sample rate"),
-                           _("%d Hz"), fmt->audio.i_rate );
-
-        if( fmt->audio.i_bitspersample > 0 )
-            input_Control( p_input, INPUT_ADD_INFO, psz_cat,
-                           _("Bits per sample"), "%d",
-                           fmt->audio.i_bitspersample );
-
-        if( fmt->i_bitrate > 0 )
-            input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Bitrate"),
-                           _("%d bps"), fmt->i_bitrate );
-        break;
-
-    case VIDEO_ES:
-        input_Control( p_input, INPUT_ADD_INFO, psz_cat,
-                       _("Type"), _("Video") );
-
-        if( fmt->video.i_width > 0 && fmt->video.i_height > 0 )
-            input_Control( p_input, INPUT_ADD_INFO, psz_cat,
-                           _("Resolution"), "%dx%d",
-                           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"), "%dx%d",
-                           fmt->video.i_visible_width,
-                           fmt->video.i_visible_height);
-        break;
-
-    case SPU_ES:
-        input_Control( p_input, INPUT_ADD_INFO, psz_cat,
-                       _("Type"), _("Subtitle") );
-        break;
-
-    default:
-        break;
-    }
-    free( psz_description );
-#endif
+        EsOutESVarUpdate( out, es, VLC_FALSE );
 
     /* Select it if needed */
     EsOutSelect( out, es, VLC_FALSE );
@@ -537,6 +494,8 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
             break;
     }
 
+    EsOutAddInfo( out, es );
+
     return es;
 }
 
@@ -555,18 +514,22 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
 
     if( es->fmt.i_cat == VIDEO_ES || es->fmt.i_cat == SPU_ES )
     {
-        if( !var_GetBool( p_input, "video" ) || ( p_input->p_sout && !var_GetBool( p_input, "sout-video" ) ) )
+        if( !var_GetBool( p_input, "video" ) ||
+            ( p_input->p_sout && !var_GetBool( p_input, "sout-video" ) ) )
         {
-            msg_Dbg( p_input, "video is disabled, not selecting ES 0x%x", es->i_id );
+            msg_Dbg( p_input, "video is disabled, not selecting ES 0x%x",
+                     es->i_id );
             return;
         }
     }
     else if( es->fmt.i_cat == AUDIO_ES )
     {
         var_Get( p_input, "audio", &val );
-        if( !var_GetBool( p_input, "audio" ) || ( p_input->p_sout && !var_GetBool( p_input, "sout-audio" ) ) )
+        if( !var_GetBool( p_input, "audio" ) ||
+            ( p_input->p_sout && !var_GetBool( p_input, "sout-audio" ) ) )
         {
-            msg_Dbg( p_input, "audio is disabled, not selecting ES 0x%x", es->i_id );
+            msg_Dbg( p_input, "audio is disabled, not selecting ES 0x%x",
+                     es->i_id );
             return;
         }
     }
@@ -785,12 +748,16 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
     if( es->p_dec )
         EsUnselect( out, es, es->p_pgrm == p_sys->p_pgrm );
 
+    if( es->p_pgrm == p_sys->p_pgrm )
+        EsOutESVarUpdate( out, es, VLC_TRUE );
+
     TAB_REMOVE( p_sys->i_es, p_sys->es, es );
 
     es->p_pgrm->i_es--;
     if( es->p_pgrm->i_es == 0 )
     {
-        msg_Err( p_sys->p_input, "Program doesn't have es anymore, clenaing TODO ?" );
+        msg_Warn( p_sys->p_input, "Program doesn't contain anymore ES, "
+                  "TODO cleaning ?" );
     }
 
     if( p_sys->p_es_audio == es ) p_sys->p_es_audio = NULL;
@@ -885,7 +852,8 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
                 {
                     if( p_sys->es[i]->p_dec )
                     {
-                        EsUnselect( out, p_sys->es[i], p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
+                        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++ )
@@ -917,24 +885,30 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
             {
                 for( i = 0; i < p_sys->i_es; i++ )
                 {
-                    if( p_sys->es[i]->p_dec && p_sys->es[i]->fmt.i_cat == AUDIO_ES )
-                        EsUnselect( out, p_sys->es[i], p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
+                    if( p_sys->es[i]->p_dec &&
+                        p_sys->es[i]->fmt.i_cat == AUDIO_ES )
+                        EsUnselect( out, p_sys->es[i],
+                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
                 }
             }
             else if( es == (es_out_id_t*)((uint8_t*)NULL+VIDEO_ES) )
             {
                 for( i = 0; i < p_sys->i_es; i++ )
                 {
-                    if( p_sys->es[i]->p_dec && p_sys->es[i]->fmt.i_cat == VIDEO_ES )
-                        EsUnselect( out, p_sys->es[i], p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
+                    if( p_sys->es[i]->p_dec &&
+                        p_sys->es[i]->fmt.i_cat == VIDEO_ES )
+                        EsUnselect( out, p_sys->es[i],
+                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
                 }
             }
             else if( es == (es_out_id_t*)((uint8_t*)NULL+SPU_ES) )
             {
                 for( i = 0; i < p_sys->i_es; i++ )
                 {
-                    if( p_sys->es[i]->p_dec && p_sys->es[i]->fmt.i_cat == SPU_ES )
-                        EsUnselect( out, p_sys->es[i], p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
+                    if( p_sys->es[i]->p_dec &&
+                        p_sys->es[i]->fmt.i_cat == SPU_ES )
+                        EsUnselect( out, p_sys->es[i],
+                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
                 }
             }
             else
@@ -979,8 +953,9 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
 
             i_pcr = (int64_t)va_arg( args, int64_t );
             /* search program */
-                /* 11 is a vodoo trick to avoid non_pcr*9/100 to be null */
-                input_ClockSetPCR( p_sys->p_input, &p_pgrm->clock, (i_pcr + 11 ) * 9 / 100);
+            /* 11 is a vodoo trick to avoid non_pcr*9/100 to be null */
+            input_ClockSetPCR( p_sys->p_input, &p_pgrm->clock,
+                               (i_pcr + 11 ) * 9 / 100);
             return VLC_SUCCESS;
         }
 
@@ -1016,6 +991,33 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
             return VLC_EGENERIC;
         }
 
+        case ES_OUT_SET_FMT:
+        {
+            /* 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 * );
+            if( es == NULL ) return VLC_EGENERIC;
+
+            if( p_fmt->i_extra )
+            {
+                es->fmt.i_extra = p_fmt->i_extra;
+                es->fmt.p_extra = realloc( es->fmt.p_extra, p_fmt->i_extra );
+                memcpy( es->fmt.p_extra, p_fmt->p_extra, p_fmt->i_extra );
+
+                if( !es->p_dec ) return VLC_SUCCESS;
+
+                es->p_dec->fmt_in.i_extra = p_fmt->i_extra;
+                es->p_dec->fmt_in.p_extra =
+                    realloc( es->p_dec->fmt_in.p_extra, p_fmt->i_extra );
+                memcpy( es->p_dec->fmt_in.p_extra,
+                        p_fmt->p_extra, p_fmt->i_extra );
+            }
+
+            return VLC_SUCCESS;
+        }
+
         default:
             msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
             return VLC_EGENERIC;
@@ -1064,3 +1066,76 @@ static char *LanguageGetName( const char *psz_code )
         return strdup( pl->psz_eng_name );
     }
 }
+
+/****************************************************************************
+ * EsOutAddInfo:
+ * - add meta info to the playlist item
+ ****************************************************************************/
+static void EsOutAddInfo( 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;
+    es_format_t       *fmt = &es->fmt;
+
+    char psz_cat[strlen(_("Stream %d")) + 12];
+
+    /* Add stream info */
+    sprintf( psz_cat, _("Stream %d"), out->p_sys->i_id - 1 );
+
+    input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Codec"),
+                   "%.4s", (char*)&fmt->i_codec );
+
+    input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Language"),
+                   "%s", es->psz_description );
+
+    /* Add information */
+    switch( fmt->i_cat )
+    {
+    case AUDIO_ES:
+        input_Control( p_input, INPUT_ADD_INFO, psz_cat,
+                       _("Type"), _("Audio") );
+
+        if( fmt->audio.i_channels > 0 )
+            input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Channels"),
+                           "%d", fmt->audio.i_channels );
+
+        if( fmt->audio.i_rate > 0 )
+            input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Sample rate"),
+                           _("%d Hz"), fmt->audio.i_rate );
+
+        if( fmt->audio.i_bitspersample > 0 )
+            input_Control( p_input, INPUT_ADD_INFO, psz_cat,
+                           _("Bits per sample"), "%d",
+                           fmt->audio.i_bitspersample );
+
+        if( fmt->i_bitrate > 0 )
+            input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Bitrate"),
+                           _("%d kb/s"), fmt->i_bitrate / 1000 );
+        break;
+
+    case VIDEO_ES:
+        input_Control( p_input, INPUT_ADD_INFO, psz_cat,
+                       _("Type"), _("Video") );
+
+        if( fmt->video.i_width > 0 && fmt->video.i_height > 0 )
+            input_Control( p_input, INPUT_ADD_INFO, psz_cat,
+                           _("Resolution"), "%dx%d",
+                           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"), "%dx%d",
+                           fmt->video.i_visible_width,
+                           fmt->video.i_visible_height);
+        break;
+
+    case SPU_ES:
+        input_Control( p_input, INPUT_ADD_INFO, psz_cat,
+                       _("Type"), _("Subtitle") );
+        break;
+
+    default:
+        break;
+    }
+}