]> git.sesse.net Git - vlc/blobdiff - src/input/input_programs.c
* input_dec.c : handle SPU_ES (and not as VIDEO_ES ....) so subtitle
[vlc] / src / input / input_programs.c
index b9cad54cbe9d93430c46544af77855d4fb80f12b..bb260f454687abbf54c97988be54efa4d367e01b 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.111 2003/05/15 21:31:53 gbazin Exp $
+ * $Id: input_programs.c,v 1.121 2003/11/16 21:07:31 gbazin 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
  *****************************************************************************/
@@ -84,7 +86,7 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len )
     {
         p_input->stream.p_demux_data = NULL;
     }
-    
+
     var_Create( p_input, "intf-change", VLC_VAR_BOOL );
     val.b_bool = VLC_TRUE;
     var_Set( p_input, "intf-change", val );
@@ -97,22 +99,10 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len )
     var_Create( p_input, "title", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
     text.psz_string = _("Title");
     var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL );
-    var_Create( p_input, "next-title", VLC_VAR_VOID );
-    text.psz_string = _("Next title");
-    var_Change( p_input, "next-title", VLC_VAR_SETTEXT, &text, NULL );
-    var_Create( p_input, "prev-title", VLC_VAR_VOID );
-    text.psz_string = _("Previous title");
-    var_Change( p_input, "prev-title", VLC_VAR_SETTEXT, &text, NULL );
 
     var_Create( p_input, "chapter", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
     text.psz_string = _("Chapter");
     var_Change( p_input, "chapter", VLC_VAR_SETTEXT, &text, NULL );
-    var_Create( p_input, "next-chapter", VLC_VAR_VOID );
-    text.psz_string = _("Next Chapter");
-    var_Change( p_input, "next-chapter", VLC_VAR_SETTEXT, &text, NULL );
-    var_Create( p_input, "prev-chapter", VLC_VAR_VOID );
-    text.psz_string = _("Previous Chapter");
-    var_Change( p_input, "prev-chapter", VLC_VAR_SETTEXT, &text, NULL );
 
     var_Create( p_input, "navigation", VLC_VAR_VARIABLE | VLC_VAR_HASCHOICE );
     text.psz_string = _("Navigation");
@@ -130,11 +120,7 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len )
 
     var_AddCallback( p_input, "program", ProgramCallback, NULL );
     var_AddCallback( p_input, "title", TitleCallback, NULL );
-    var_AddCallback( p_input, "next-title", TitleCallback, NULL );
-    var_AddCallback( p_input, "prev-title", TitleCallback, NULL );
     var_AddCallback( p_input, "chapter", ChapterCallback, NULL );
-    var_AddCallback( p_input, "next-chapter", ChapterCallback, NULL );
-    var_AddCallback( p_input, "prev-chapter", ChapterCallback, NULL );
     var_AddCallback( p_input, "video-es", ESCallback, NULL );
     var_AddCallback( p_input, "audio-es", ESCallback, NULL );
     var_AddCallback( p_input, "spu-es", ESCallback, NULL );
@@ -211,7 +197,7 @@ pgrm_descriptor_t * input_FindProgram( input_thread_t * p_input,
  * This program descriptor will be referenced in the given stream descriptor
  *****************************************************************************/
 pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
-                                      u16 i_pgrm_id, size_t i_data_len )
+                                      uint16_t i_pgrm_id, size_t i_data_len )
 {
     /* Where to add the pgrm */
     pgrm_descriptor_t * p_pgrm = malloc( sizeof(pgrm_descriptor_t) );
@@ -287,7 +273,7 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
         return;
     }
 
-    val.i_int = i_pgrm_index;
+    val.i_int = p_input->stream.pp_programs[i_pgrm_index]->i_number;
     var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
 
     /* Free the structures that describe the es that belongs to that program */
@@ -307,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 );
 }
@@ -356,7 +345,7 @@ input_area_t * input_AddArea( input_thread_t * p_input,
     val.psz_string = malloc( sizeof("title ") + 5 );
     if( val.psz_string )
     {
-        vlc_value_t val2;
+        vlc_value_t val2, text, text2;
 
         sprintf( val.psz_string, "title %2i", i_area_id );
         var_Destroy( p_input, val.psz_string );
@@ -365,14 +354,52 @@ input_area_t * input_AddArea( input_thread_t * p_input,
         var_AddCallback( p_input, val.psz_string, NavigationCallback,
                          (void *)(int)i_area_id );
 
-        var_Change( p_input, "navigation", VLC_VAR_ADDCHOICE, &val, NULL );
+        text.psz_string = malloc( strlen( _("Title %i") ) + 20 );
+        if( text.psz_string )
+            sprintf( text.psz_string, _("Title %i"), i_area_id );
+
+        var_Change( p_input, "navigation", VLC_VAR_ADDCHOICE, &val, &text );
+
+        if( text.psz_string ) free( text.psz_string );
+
+        text2.psz_string = malloc( strlen( _("Chapter %i") ) + 20 );
 
         for( i = 1; i <= i_part_nb; i++ )
         {
             val2.i_int = i;
+
+            if( text2.psz_string )
+                sprintf( text2.psz_string, _("Chapter %i"), i );
+
             var_Change( p_input, val.psz_string,
-                        VLC_VAR_ADDCHOICE, &val2, NULL );
+                        VLC_VAR_ADDCHOICE, &val2, &text2 );
         }
+
+        if( text2.psz_string ) free( text2.psz_string );
+    }
+
+    if( p_input->stream.i_area_nb == 2 )
+    {
+        vlc_value_t text;
+
+        /* Add another bunch of navigation object variables */
+        var_Create( p_input, "next-title", VLC_VAR_VOID );
+        text.psz_string = _("Next title");
+        var_Change( p_input, "next-title", VLC_VAR_SETTEXT, &text, NULL );
+        var_Create( p_input, "prev-title", VLC_VAR_VOID );
+        text.psz_string = _("Previous title");
+        var_Change( p_input, "prev-title", VLC_VAR_SETTEXT, &text, NULL );
+        var_AddCallback( p_input, "next-title", TitleCallback, NULL );
+        var_AddCallback( p_input, "prev-title", TitleCallback, NULL );
+
+        var_Create( p_input, "next-chapter", VLC_VAR_VOID );
+        text.psz_string = _("Next Chapter");
+        var_Change( p_input, "next-chapter", VLC_VAR_SETTEXT, &text, NULL );
+        var_Create( p_input, "prev-chapter", VLC_VAR_VOID );
+        text.psz_string = _("Previous Chapter");
+        var_Change( p_input, "prev-chapter", VLC_VAR_SETTEXT, &text, NULL );
+        var_AddCallback( p_input, "next-chapter", ChapterCallback, NULL );
+        var_AddCallback( p_input, "prev-chapter", ChapterCallback, NULL );
     }
 
     return p_area;
@@ -405,11 +432,14 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
 #undef p_es
         }
     }
+
     /* Get the number of the required audio stream */
-    if( config_GetInt( p_input, "audio" ) )
+    var_Get( p_input, "audio", &val );
+    if( val.b_bool )
     {
         /* Default is the first one */
-        i_required_audio_es = config_GetInt( p_input, "audio-channel" );
+        var_Get( p_input, "audio-channel", &val );
+        i_required_audio_es = val.i_int;
         if( i_required_audio_es < 0 )
         {
             i_required_audio_es = 1;
@@ -421,10 +451,12 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
     }
 
     /* Same thing for subtitles */
-    if( config_GetInt( p_input, "video" ) )
+    var_Get( p_input, "video", &val );
+    if( val.b_bool )
     {
         /* for spu, default is none */
-        i_required_spu_es = config_GetInt( p_input, "spu-channel" );
+        var_Get( p_input, "spu-channel", &val );
+        i_required_spu_es = val.i_int;
         if( i_required_spu_es < 0 )
         {
             i_required_spu_es = 0;
@@ -471,7 +503,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 */
@@ -522,6 +553,15 @@ void input_DelArea( input_thread_t * p_input, input_area_t * p_area )
 
     /* Free the description of this area */
     free( p_area );
+
+    if( p_input->stream.i_area_nb == 1 )
+    {
+        /* Del unneeded navigation object variables */
+        var_Destroy( p_input, "next-title" );
+        var_Destroy( p_input, "prev-title" );
+        var_Destroy( p_input, "next-chapter" );
+        var_Destroy( p_input, "prev-chapter" );
+    }
 }
 
 
@@ -551,7 +591,7 @@ es_descriptor_t * input_FindES( input_thread_t * p_input, uint16_t i_es_id )
  * alone (PSI ?)
  *****************************************************************************/
 es_descriptor_t * input_AddES( input_thread_t * p_input,
-                               pgrm_descriptor_t * p_pgrm, u16 i_es_id,
+                               pgrm_descriptor_t * p_pgrm, uint16_t i_es_id,
                                int i_category, char const *psz_desc,
                                size_t i_data_len )
 {
@@ -580,6 +620,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
     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 )
     {
@@ -597,6 +638,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 )
@@ -640,7 +682,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
         }
 
         /* Take care of the ES description */
-        if( psz_desc )
+        if( psz_desc && *psz_desc )
         {
             p_es->psz_desc = strdup( psz_desc );
         }
@@ -716,7 +758,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 )
     {
-        input_EndDecoder( p_input, p_es );
+        input_UnselectES( p_input, p_es );
     }
 
     /* Remove this ES from the description of the program if it is associated
@@ -749,6 +791,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 )
@@ -790,19 +836,26 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
         return -1;
     }
 
-    if( ((p_es->i_cat == VIDEO_ES) || (p_es->i_cat == SPU_ES))
-        && !config_GetInt( p_input, "video" ) )
+    if( p_es->i_cat == VIDEO_ES || p_es->i_cat == SPU_ES )
     {
-        msg_Dbg( p_input,
-                 "video is disabled, not selecting ES 0x%x", p_es->i_id );
-        return -1;
+        var_Get( p_input, "video", &val );
+        if( !val.b_bool )
+        {
+            msg_Dbg( p_input, "video is disabled, not selecting ES 0x%x",
+                     p_es->i_id );
+            return -1;
+        }
     }
 
-    if( (p_es->i_cat == AUDIO_ES) && !config_GetInt( p_input, "audio" ) )
+    if( p_es->i_cat == AUDIO_ES )
     {
-        msg_Dbg( p_input,
-                 "audio is disabled, not selecting ES 0x%x", p_es->i_id );
-        return -1;
+        var_Get( p_input, "audio", &val );
+        if( !val.b_bool )
+        {
+            msg_Dbg( p_input, "audio is disabled, not selecting ES 0x%x",
+                     p_es->i_id );
+            return -1;
+        }
     }
 
     msg_Dbg( p_input, "selecting ES 0x%x", p_es->i_id );
@@ -967,15 +1020,15 @@ static int TitleCallback( vlc_object_t *p_this, char const *psz_cmd,
     {
         var_Get( p_this, "title", &newval );
         var_Change( p_this, "title", VLC_VAR_GETCHOICES, &val_list, NULL );
-       for( i = 0; i < val_list.p_list->i_count; i++ )
-       {
-           if( val_list.p_list->p_values[i].i_int == newval.i_int &&
-               i + i_step >= 0 && i + i_step < val_list.p_list->i_count )
-           {
-               newval.i_int = val_list.p_list->p_values[i + i_step].i_int;
-               break;
-           }
-       }
+        for( i = 0; i < val_list.p_list->i_count; i++ )
+        {
+            if( val_list.p_list->p_values[i].i_int == newval.i_int &&
+                i + i_step >= 0 && i + i_step < val_list.p_list->i_count )
+            {
+                newval.i_int = val_list.p_list->p_values[i + i_step].i_int;
+                break;
+            }
+        }
         var_Change( p_this, "title", VLC_VAR_FREELIST, &val_list, NULL );
     }
 
@@ -1013,15 +1066,15 @@ static int ChapterCallback( vlc_object_t *p_this, char const *psz_cmd,
     {
         var_Get( p_this, "chapter", &newval );
         var_Change( p_this, "chapter", VLC_VAR_GETCHOICES, &val_list, NULL );
-       for( i = 0; i < val_list.p_list->i_count; i++ )
-       {
-           if( val_list.p_list->p_values[i].i_int == newval.i_int &&
-               i + i_step >= 0 && i + i_step < val_list.p_list->i_count )
-           {
-               newval.i_int = val_list.p_list->p_values[i + i_step].i_int;
-               break;
-           }
-       }
+        for( i = 0; i < val_list.p_list->i_count; i++ )
+        {
+            if( val_list.p_list->p_values[i].i_int == newval.i_int &&
+                i + i_step >= 0 && i + i_step < val_list.p_list->i_count )
+            {
+                newval.i_int = val_list.p_list->p_values[i + i_step].i_int;
+                break;
+            }
+        }
         var_Change( p_this, "chapter", VLC_VAR_FREELIST, &val_list, NULL );
     }
 
@@ -1060,7 +1113,7 @@ static int NavigationCallback( vlc_object_t *p_this, char const *psz_cmd,
           p_input->stream.pp_areas[i_area_id]->i_part_nb ) )
     {
         input_area_t *p_area = p_input->stream.pp_areas[i_area_id];
-        p_input->stream.p_selected_area->i_part = newval.i_int;
+        p_area->i_part = newval.i_int;
         vlc_mutex_unlock( &p_input->stream.stream_lock );
         input_ChangeArea( p_input, p_area );
         input_SetStatus( p_input, INPUT_STATUS_PLAY );