]> git.sesse.net Git - vlc/blobdiff - src/input/input_programs.c
* all: better handling of multiple (video) tracks.
[vlc] / src / input / input_programs.c
index 66772e36c9b4ba692422520005be8d902fbc2f38..a2467100d29c1b0045d0799b04a0683430c1e3f3 100644 (file)
@@ -2,7 +2,7 @@
  * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
  *****************************************************************************
  * Copyright (C) 1999-2002 VideoLAN
- * $Id: input_programs.c,v 1.118 2003/08/17 20:39:08 fenrir Exp $
+ * $Id: input_programs.c,v 1.125 2003/11/29 11:12:46 fenrir Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -51,6 +51,8 @@ static int NavigationCallback( vlc_object_t *, char const *,
 static int ESCallback( vlc_object_t *, char const *,
                        vlc_value_t, vlc_value_t, void * );
 
+static es_format_t null_es_format = {0};
+
 /*****************************************************************************
  * input_InitStream: init the stream descriptor of the given input
  *****************************************************************************/
@@ -291,6 +293,9 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
                  p_input->stream.i_pgrm_number,
                  i_pgrm_index );
 
+    if( p_pgrm == p_input->stream.p_selected_program )
+        p_input->stream.p_selected_program = NULL;
+
     /* Free the description of this program */
     free( p_pgrm );
 }
@@ -371,6 +376,7 @@ input_area_t * input_AddArea( input_thread_t * p_input,
         }
 
         if( text2.psz_string ) free( text2.psz_string );
+        free( val.psz_string );
     }
 
     if( p_input->stream.i_area_nb == 2 )
@@ -420,7 +426,7 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
                 i_es_index ++ )
         {
 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
-            if ( p_es->p_decoder_fifo ) /* if the ES was selected */
+            if ( p_es->p_dec ) /* if the ES was selected */
             {
                 input_UnselectES( p_input , p_es );
             }
@@ -467,7 +473,7 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
         switch( p_new_prg->pp_es[i_es_index]->i_cat )
         {
             case VIDEO_ES:
-                msg_Dbg( p_input, "selecting ES %x",
+                msg_Dbg( p_input, "selecting video ES %x",
                          p_new_prg->pp_es[i_es_index]->i_id );
                 input_SelectES( p_input, p_new_prg->pp_es[i_es_index] );
                 break;
@@ -475,7 +481,7 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
                 i_audio_es += 1;
                 if( i_audio_es <= i_required_audio_es )
                 {
-                    msg_Dbg( p_input, "selecting ES %x",
+                    msg_Dbg( p_input, "selecting audio ES %x",
                              p_new_prg->pp_es[i_es_index]->i_id );
                     input_SelectES( p_input, p_new_prg->pp_es[i_es_index]);
                 }
@@ -485,7 +491,7 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
                 i_spu_es += 1;
                 if( i_spu_es <= i_required_spu_es )
                 {
-                    msg_Dbg( p_input, "selecting ES %x",
+                    msg_Dbg( p_input, "selecting spu ES %x",
                              p_new_prg->pp_es[i_es_index]->i_id );
                     input_SelectES( p_input, p_new_prg->pp_es[i_es_index] );
                 }
@@ -498,7 +504,6 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
 
     }
 
-
     p_input->stream.p_selected_program = p_new_prg;
 
     /* Update the navigation variables without triggering a callback */
@@ -540,6 +545,8 @@ void input_DelArea( input_thread_t * p_input, input_area_t * p_area )
         sprintf( val.psz_string, "title %i", p_area->i_id );
         var_Change( p_input, "navigation", VLC_VAR_DELCHOICE, &val, NULL );
         var_Destroy( p_input, val.psz_string );
+
+        free( val.psz_string );
     }
 
     /* Remove this area from the stream's list of areas */
@@ -610,12 +617,13 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
     /* Init its values */
     p_es->i_id = i_es_id;
     p_es->p_pes = NULL;
-    p_es->p_decoder_fifo = NULL;
+    p_es->p_dec = NULL;
     p_es->i_cat = i_category;
     p_es->i_demux_fd = 0;
     p_es->c_packets = 0;
     p_es->c_invalid_packets = 0;
     p_es->b_force_decoder = VLC_FALSE;
+    p_es->fmt = null_es_format;
 
     if( i_data_len )
     {
@@ -633,6 +641,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
     }
     p_es->p_waveformatex     = NULL;
     p_es->p_bitmapinfoheader = NULL;
+    p_es->p_spuinfo = NULL;
 
     /* Add this ES to the program definition if one is given */
     if( p_pgrm )
@@ -750,7 +759,7 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
     }
 
     /* Kill associated decoder, if any. */
-    if( p_es->p_decoder_fifo != NULL )
+    if( p_es->p_dec != NULL )
     {
         input_UnselectES( p_input, p_es );
     }
@@ -785,6 +794,10 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
     {
         free( p_es->p_bitmapinfoheader );
     }
+    if( p_es->p_spuinfo )
+    {
+        free( p_es->p_spuinfo );
+    }
 
     /* Free the description string */
     if( p_es->psz_desc != NULL )
@@ -850,7 +863,7 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
 
     msg_Dbg( p_input, "selecting ES 0x%x", p_es->i_id );
 
-    if( p_es->p_decoder_fifo != NULL )
+    if( p_es->p_dec != NULL )
     {
         msg_Err( p_input, "ES 0x%x is already selected", p_es->i_id );
         return -1;
@@ -859,10 +872,10 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
     /* Release the lock, not to block the input thread during
      * the creation of the thread. */
     vlc_mutex_unlock( &p_input->stream.stream_lock );
-    p_es->p_decoder_fifo = input_RunDecoder( p_input, p_es );
+    p_es->p_dec = input_RunDecoder( p_input, p_es );
     vlc_mutex_lock( &p_input->stream.stream_lock );
 
-    if( p_es->p_decoder_fifo == NULL )
+    if( p_es->p_dec == NULL )
     {
         return -1;
     }
@@ -907,7 +920,7 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es )
 
     msg_Dbg( p_input, "unselecting ES 0x%x", p_es->i_id );
 
-    if( p_es->p_decoder_fifo == NULL )
+    if( p_es->p_dec == NULL )
     {
         msg_Err( p_input, "ES 0x%x is not selected", p_es->i_id );
         return( -1 );
@@ -937,7 +950,7 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es )
     input_EndDecoder( p_input, p_es );
     p_es->p_pes = NULL;
 
-    if( ( p_es->p_decoder_fifo == NULL ) &&
+    if( ( p_es->p_dec == NULL ) &&
         ( p_input->stream.i_selected_es_number > 0 ) )
     {
         while( ( i_index < p_input->stream.i_selected_es_number - 1 ) &&
@@ -1123,14 +1136,26 @@ static int ESCallback( vlc_object_t *p_this, char const *psz_cmd,
     input_thread_t *p_input = (input_thread_t *)p_this;
     unsigned int i;
     vlc_value_t val;
+    unsigned int i_cat = UNKNOWN_ES;
+    es_descriptor_t *p_es = NULL;
 
     vlc_mutex_lock( &p_input->stream.stream_lock );
 
-    /* Unselect old ES */
+    /* First search old es type */
+    for( i = 0 ; i < p_input->stream.i_es_number ; i++ )
+    {
+        if( p_input->stream.pp_es[i]->i_id == oldval.i_int )
+        {
+            i_cat = p_input->stream.pp_es[i]->i_cat;
+        }
+    }
+
+    /* Unselect all old ES */
     for( i = 0 ; i < p_input->stream.i_es_number ; i++ )
     {
-        if( p_input->stream.pp_es[i]->i_id == oldval.i_int &&
-            p_input->stream.pp_es[i]->p_decoder_fifo != NULL )
+        if( p_input->stream.pp_es[i]->i_cat == i_cat &&
+            p_input->stream.pp_es[i]->i_id != newval.i_int &&
+            p_input->stream.pp_es[i]->p_dec != NULL )
         {
             input_UnselectES( p_input, p_input->stream.pp_es[i] );
         }
@@ -1139,10 +1164,31 @@ static int ESCallback( vlc_object_t *p_this, char const *psz_cmd,
     /* Select new ES */
     for( i = 0 ; i < p_input->stream.i_es_number ; i++ )
     {
-        if( p_input->stream.pp_es[i]->i_id == newval.i_int &&
-            p_input->stream.pp_es[i]->p_decoder_fifo == NULL )
+        if( p_input->stream.pp_es[i]->i_id == newval.i_int )
         {
-            input_SelectES( p_input, p_input->stream.pp_es[i] );
+            p_es = p_input->stream.pp_es[i];
+            if( p_es->p_dec == NULL )
+            {
+                input_SelectES( p_input, p_es );
+            }
+        }
+    }
+
+    if( p_es )
+    {
+        /* Fix value (mainly for multiple selected ES */
+        val.i_int = p_es->i_id;
+        switch( p_es->i_cat )
+        {
+        case AUDIO_ES:
+            var_Change( p_input, "audio-es", VLC_VAR_SETVALUE, &val, NULL );
+            break;
+        case SPU_ES:
+            var_Change( p_input, "spu-es", VLC_VAR_SETVALUE, &val, NULL );
+            break;
+        case VIDEO_ES:
+            var_Change( p_input, "video-es", VLC_VAR_SETVALUE, &val, NULL );
+            break;
         }
     }