]> git.sesse.net Git - vlc/commitdiff
* all: implement more es_out_* control, audio-channel and spu-channel are
authorLaurent Aimar <fenrir@videolan.org>
Thu, 27 Nov 2003 04:11:40 +0000 (04:11 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Thu, 27 Nov 2003 04:11:40 +0000 (04:11 +0000)
 implemented.

include/ninput.h
modules/demux/avi/avi.c
modules/demux/mkv.cpp
modules/demux/ogg.c
modules/demux/rawdv.c
modules/demux/util/sub.c
src/input/es_out.c
src/input/input.c

index 942b8fd8ff1c8022b031c7ed069903bcbf3aaf53..4370960e7f8211b6c7ff3352ef4a5d0e9f57875a 100644 (file)
@@ -2,7 +2,7 @@
  * ninput.h
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ninput.h,v 1.18 2003/11/21 00:38:01 gbazin Exp $
+ * $Id: ninput.h,v 1.19 2003/11/27 04:11:40 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
 
 #include "vlc_es.h"
 
+enum es_out_mode_e
+{
+    ES_OUT_MODE_NONE,   /* don't select anything */
+    ES_OUT_MODE_ALL,    /* eg for stream output */
+    ES_OUT_MODE_AUTO    /* best audio/video or for input follow audio-channel, spu-channel */
+};
+
 enum es_out_query_e
 {
-    ES_OUT_SET_SELECT,  /* arg1= es_out_id_t* arg2=vlc_bool_t   */
-    ES_OUT_GET_SELECT   /* arg1= es_out_id_t* arg2=vlc_bool_t*  */
+    /* activate apply of mode */
+    ES_OUT_SET_ACTIVE,  /* arg1= vlc_bool_t                     */
+    /* see if mode is currently aplied or not */
+    ES_OUT_GET_ACTIVE,  /* arg1= vlc_bool_t*                    */
+
+    /* set/get mode */
+    ES_OUT_SET_MODE,    /* arg1= int                            */
+    ES_OUT_GET_MODE,    /* arg2= int*                           */
+
+    /* set es selected for the es category(audio/video/spu) */
+    ES_OUT_SET_ES,      /* arg1= es_out_id_t*                   */
+
+    /* force selection/unselection of the ES (bypass current mode)*/
+    ES_OUT_SET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t   */
+    ES_OUT_GET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t*  */
 };
 
 struct es_out_t
 {
     es_out_id_t *(*pf_add)    ( es_out_t *, es_format_t * );
     int          (*pf_send)   ( es_out_t *, es_out_id_t *, block_t * );
-    int          (*pf_send_pes)( es_out_t *, es_out_id_t *, pes_packet_t * );
     void         (*pf_del)    ( es_out_t *, es_out_id_t * );
     int          (*pf_control)( es_out_t *, int i_query, va_list );
 
@@ -52,15 +71,11 @@ static inline void es_out_Del( es_out_t *out, es_out_id_t *id )
     out->pf_del( out, id );
 }
 static inline int es_out_Send( es_out_t *out, es_out_id_t *id,
-                              block_t *p_block )
+                               block_t *p_block )
 {
     return out->pf_send( out, id, p_block );
 }
-static inline int es_out_SendPES( es_out_t *out, es_out_id_t *id,
-                                  pes_packet_t *p_pes )
-{
-    return out->pf_send_pes( out, id, p_pes );
-}
+
 static inline int es_out_vaControl( es_out_t *out, int i_query, va_list args )
 {
     return out->pf_control( out, i_query, args );
index 54c161cba0e85b3093f4fff2d09fc4916cb6d959..b2a4bbf6c26ba4d14ec82fc840d6aa59feeda4b8 100644 (file)
@@ -2,7 +2,7 @@
  * avi.c : AVI file Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.77 2003/11/26 08:18:09 gbazin Exp $
+ * $Id: avi.c,v 1.78 2003/11/27 04:11:40 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -469,7 +469,7 @@ static int Demux_Seekable( input_thread_t *p_input )
         avi_track_t *tk = p_sys->track[i_track];
         vlc_bool_t  b;
 
-        es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, tk->p_es, &b );
+        es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
         if( b && !tk->b_activated )
         {
             if( p_sys->b_seekable)
@@ -794,7 +794,7 @@ static int Demux_UnSeekable( input_thread_t *p_input )
         avi_track_t *tk = p_sys->track[i_stream];
         vlc_bool_t  b;
 
-        es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, tk->p_es, &b );
+        es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
 
         if( b && tk->i_cat == VIDEO_ES )
         {
index 072cbbf585025b2502406a7720d1c6f344fe1749..ffe95de25c5e34db7ba5baabbc9713fde16754c8 100644 (file)
@@ -2,7 +2,7 @@
  * mkv.cpp : matroska demuxer
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mkv.cpp,v 1.44 2003/11/23 13:15:27 gbazin Exp $
+ * $Id: mkv.cpp,v 1.45 2003/11/27 04:11:40 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -1401,7 +1401,7 @@ static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts
         return;
     }
 
-    es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, tk.p_es, &b );
+    es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, tk.p_es, &b );
     if( !b )
     {
         tk.b_inited = VLC_FALSE;
index 9f5283dbf8eb7fde3291caf438aabac20b3f1748..a2629a59662c0ea6e1bea539a3bc1396dc752de9 100644 (file)
@@ -2,7 +2,7 @@
  * ogg.c : ogg stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001-2003 VideoLAN
- * $Id: ogg.c,v 1.47 2003/11/26 08:18:09 gbazin Exp $
+ * $Id: ogg.c,v 1.48 2003/11/27 04:11:40 fenrir Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -359,7 +359,7 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
     }
 
     /* Check the ES is selected */
-    es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT,
+    es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE,
                     p_stream->p_es, &b_selected );
 
     if( b_selected && !p_stream->b_activated )
index fe1a46bd4d92d581197a50beb1674576b00778d1..df600749c850a414e555812c237f3fd3222f00e2 100644 (file)
@@ -2,7 +2,7 @@
  * rawdv.c : raw dv input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: rawdv.c,v 1.12 2003/11/24 19:19:02 fenrir Exp $
+ * $Id: rawdv.c,v 1.13 2003/11/27 04:11:40 fenrir Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -297,9 +297,9 @@ static int Demux( input_thread_t * p_input )
         return 0;
     }
 
-    es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT,
+    es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE,
                     p_sys->p_es_audio, &b_audio );
-    es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT,
+    es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE,
                     p_sys->p_es_video, &b_video );
 
     p_block->i_dts =
index 96b030e64ebc9d0e1b10ee1dfb392c002dfcaf8b..d7cedc67319559fee4add08ec8470e76641e9328 100644 (file)
@@ -2,7 +2,7 @@
  * sub.c
  *****************************************************************************
  * Copyright (C) 1999-2003 VideoLAN
- * $Id: sub.c,v 1.38 2003/11/21 00:38:01 gbazin Exp $
+ * $Id: sub.c,v 1.39 2003/11/27 04:11:40 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -502,7 +502,7 @@ static int  sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
     input_thread_t *p_input = p_sub->p_input;
     vlc_bool_t     b;
 
-    es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT, p_sub->p_es, &b );
+    es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, p_sub->p_es, &b );
     if( b && !p_sub->i_previously_selected )
     {
         p_sub->i_previously_selected = 1;
index 7cddd82a65117f6631c0a3bac5d15b509c5a43b7..8e4e76a10c1f5dc84cc0bc1ed4b1f366f29c03d4 100644 (file)
@@ -2,7 +2,7 @@
  * es_out.c: Es Out handler for input.
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: es_out.c,v 1.1 2003/11/24 20:50:45 fenrir Exp $
+ * $Id: es_out.c,v 1.2 2003/11/27 04:11:40 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
+struct es_out_id_t
+{
+    int             i_channel;
+    es_descriptor_t *p_es;
+};
+
 struct es_out_sys_t
 {
     input_thread_t *p_input;
 
+    /* all es */
     int         i_id;
-    es_out_id_t **id;
 
-    vlc_bool_t  i_audio;
-    vlc_bool_t  i_video;
-};
+    int         i_es;
+    es_out_id_t **es;
 
-struct es_out_id_t
-{
-    es_descriptor_t *p_es;
+    /* mode gestion */
+    vlc_bool_t  b_active;
+    int         i_mode;
+
+    /* es count */
+    int         i_audio;
+    int         i_video;
+    int         i_sub;
+
+    /* es to select */
+    int         i_audio_last;
+    int         i_sub_last;
+
+    /* current main es */
+    es_out_id_t *p_es_audio;
+    es_out_id_t *p_es_video;
+    es_out_id_t *p_es_sub;
 };
 
 static es_out_id_t *EsOutAdd    ( es_out_t *, es_format_t * );
 static int          EsOutSend   ( es_out_t *, es_out_id_t *, block_t * );
-static int          EsOutSendPES( es_out_t *, es_out_id_t *, pes_packet_t * );
 static void         EsOutDel    ( es_out_t *, es_out_id_t * );
 static int          EsOutControl( es_out_t *, int i_query, va_list );
 
@@ -63,20 +81,40 @@ static int          EsOutControl( es_out_t *, int i_query, va_list );
  *****************************************************************************/
 es_out_t *input_EsOutNew( input_thread_t *p_input )
 {
-    es_out_t *out = malloc( sizeof( es_out_t ) );
+    es_out_t     *out = malloc( sizeof( es_out_t ) );
+    es_out_sys_t *p_sys = malloc( sizeof( es_out_sys_t ) );
+    vlc_value_t  val;
 
     out->pf_add     = EsOutAdd;
     out->pf_send    = EsOutSend;
-    out->pf_send_pes= EsOutSendPES;
     out->pf_del     = EsOutDel;
     out->pf_control = EsOutControl;
+    out->p_sys      = p_sys;
+
+    p_sys->p_input = p_input;
+
+    p_sys->b_active = VLC_FALSE;
+    p_sys->i_mode   = ES_OUT_MODE_AUTO;
+
+    p_sys->i_id    = 1;
+
+    p_sys->i_es    = 0;
+    p_sys->es      = NULL;
+
+    p_sys->i_audio = 0;
+    p_sys->i_video = 0;
+    p_sys->i_sub   = 0;
+
+    var_Get( p_input, "audio-channel", &val );
+    p_sys->i_audio_last = val.i_int;
+
+    var_Get( p_input, "spu-channel", &val );
+    p_sys->i_sub_last = val.i_int;
+
+    p_sys->p_es_audio = NULL;
+    p_sys->p_es_video = NULL;
+    p_sys->p_es_sub   = NULL;
 
-    out->p_sys = malloc( sizeof( es_out_sys_t ) );
-    out->p_sys->p_input = p_input;
-    out->p_sys->i_id    = 0;
-    out->p_sys->id      = NULL;
-    out->p_sys->i_audio = -1;
-    out->p_sys->i_video = -1;
     return out;
 }
 
@@ -88,18 +126,97 @@ void input_EsOutDelete( es_out_t *out )
     es_out_sys_t *p_sys = out->p_sys;
     int i;
 
-    for( i = 0; i < p_sys->i_id; i++ )
+    for( i = 0; i < p_sys->i_es; i++ )
     {
-        free( p_sys->id[i] );
+        free( p_sys->es[i] );
     }
-    if( p_sys->id )
+    if( p_sys->es )
     {
-        free( p_sys->id );
+        free( p_sys->es );
     }
     free( p_sys );
     free( out );
 }
 
+/*****************************************************************************
+ * EsOutSelect: Select an ES given the current mode
+ * XXX: you need to take a the lock before (stream.stream_lock)
+ *****************************************************************************/
+static void EsOutSelect( es_out_t *out, es_out_id_t *es, vlc_bool_t b_force )
+{
+    es_out_sys_t      *p_sys = out->p_sys;
+    input_thread_t    *p_input = p_sys->p_input;
+
+    int i_cat = es->p_es->i_cat;
+
+    if( !p_sys->b_active || ( !b_force && es->p_es->fmt.i_priority < 0 ) )
+    {
+        return;
+    }
+
+    if( p_sys->i_mode == ES_OUT_MODE_ALL || b_force )
+    {
+        input_SelectES( p_input, es->p_es );
+    }
+    else if( p_sys->i_mode == ES_OUT_MODE_AUTO )
+    {
+        int i_wanted  = -1;
+
+        if( i_cat == AUDIO_ES )
+        {
+            if( p_sys->p_es_audio && p_sys->p_es_audio->p_es->fmt.i_priority >= es->p_es->fmt.i_priority )
+            {
+                return;
+            }
+            i_wanted  = p_sys->i_audio_last >= 0 ? p_sys->i_audio_last : es->i_channel;
+        }
+        else if( i_cat == SPU_ES )
+        {
+            if( p_sys->p_es_sub && p_sys->p_es_sub->p_es->fmt.i_priority >= es->p_es->fmt.i_priority )
+            {
+                return;
+            }
+            i_wanted  = p_sys->i_sub_last;
+        }
+        else if( i_cat == VIDEO_ES )
+        {
+            i_wanted  = es->i_channel;
+        }
+
+        if( i_wanted == es->i_channel )
+        {
+            input_SelectES( p_input, es->p_es );
+        }
+    }
+
+    /* FIXME TODO handle priority here */
+    if( es->p_es->p_dec )
+    {
+        if( i_cat == AUDIO_ES )
+        {
+            if( p_sys->i_mode == ES_OUT_MODE_AUTO &&
+                p_sys->p_es_audio && p_sys->p_es_audio->p_es->p_dec )
+            {
+                input_UnselectES( p_input, p_sys->p_es_audio->p_es );
+            }
+            p_sys->p_es_audio = es;
+        }
+        else if( i_cat == SPU_ES )
+        {
+            if( p_sys->i_mode == ES_OUT_MODE_AUTO &&
+                p_sys->p_es_sub && p_sys->p_es_sub->p_es->p_dec )
+            {
+                input_UnselectES( p_input, p_sys->p_es_sub->p_es );
+            }
+            p_sys->p_es_sub = es;
+        }
+        else if( i_cat == VIDEO_ES )
+        {
+            p_sys->p_es_video = es;
+        }
+    }
+}
+
 /*****************************************************************************
  * EsOutAdd:
  *****************************************************************************/
@@ -107,7 +224,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
 {
     es_out_sys_t      *p_sys = out->p_sys;
     input_thread_t    *p_input = p_sys->p_input;
-    es_out_id_t       *id = malloc( sizeof( es_out_id_t ) );
+    es_out_id_t       *es = malloc( sizeof( es_out_id_t ) );
     pgrm_descriptor_t *p_prgm = NULL;
     char              psz_cat[strlen( "Stream " ) + 10];
     input_info_category_t *p_cat;
@@ -131,13 +248,13 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
         }
     }
 
-    id->p_es = input_AddES( p_input,
+    es->p_es = input_AddES( p_input,
                             p_prgm,
-                            1 + out->p_sys->i_id,
+                            out->p_sys->i_id,
                             fmt->i_cat,
                             fmt->psz_description, 0 );
-    id->p_es->i_stream_id = 1 + out->p_sys->i_id;
-    id->p_es->i_fourcc = fmt->i_codec;
+    es->p_es->i_stream_id = out->p_sys->i_id;
+    es->p_es->i_fourcc = fmt->i_codec;
 
     switch( fmt->i_cat )
     {
@@ -157,7 +274,9 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
             {
                 memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
             }
-            id->p_es->p_waveformatex = p_wf;
+            es->p_es->p_waveformatex = p_wf;
+
+            es->i_channel = p_sys->i_audio;
             break;
         }
         case VIDEO_ES:
@@ -181,7 +300,9 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
             {
                 memcpy( &p_bih[1], fmt->p_extra, fmt->i_extra );
             }
-            id->p_es->p_bitmapinfoheader = p_bih;
+            es->p_es->p_bitmapinfoheader = p_bih;
+
+            es->i_channel = p_sys->i_video;
             break;
         }
         case SPU_ES:
@@ -190,43 +311,24 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
             memset( p_sub, 0, sizeof( subtitle_data_t ) );
             if( fmt->i_extra > 0 )
             {
-                p_sub->psz_header = malloc( fmt->i_extra  );
+                p_sub->psz_header = malloc( fmt->i_extra  + 1 );
                 memcpy( p_sub->psz_header, fmt->p_extra , fmt->i_extra );
+                /* just to be sure */
+                ((uint8_t*)fmt->p_extra)[fmt->i_extra] = '\0';
             }
             /* FIXME beuuuuuurk */
-            id->p_es->p_demux_data = p_sub;
+            es->p_es->p_demux_data = p_sub;
+
+            es->i_channel = p_sys->i_sub;
             break;
         }
+
         default:
+            es->i_channel = 0;
             break;
     }
 
-    if( fmt->i_cat == AUDIO_ES && fmt->i_priority > out->p_sys->i_audio )
-    {
-        if( out->p_sys->i_audio >= 0 )
-        {
-            msg_Err( p_input, "FIXME unselect es in es_out_Add" );
-        }
-        input_SelectES( p_input, id->p_es );
-        if( id->p_es->p_dec )
-        {
-            out->p_sys->i_audio = fmt->i_priority;
-        }
-    }
-    else if( fmt->i_cat == VIDEO_ES && fmt->i_priority > out->p_sys->i_video )
-    {
-        if( out->p_sys->i_video >= 0 )
-        {
-            msg_Err( p_input, "FIXME unselect es in es_out_Add" );
-        }
-        input_SelectES( p_input, id->p_es );
-        if( id->p_es->p_dec )
-        {
-            out->p_sys->i_video = fmt->i_priority;
-        }
-    }
-
-    sprintf( psz_cat, _("Stream %d"), out->p_sys->i_id );
+    sprintf( psz_cat, _("Stream %d"), out->p_sys->i_id - 1 );
     if( ( p_cat = input_InfoCategory( p_input, psz_cat ) ) )
     {
         /* Add information */
@@ -284,74 +386,99 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
                 break;
         }
     }
-    vlc_mutex_unlock( &p_input->stream.stream_lock );
 
-    id->p_es->fmt = *fmt;
 
-    TAB_APPEND( out->p_sys->i_id, out->p_sys->id, id );
-    return id;
-}
-
-/*****************************************************************************
- * EsOutSend:
- *****************************************************************************/
-static int EsOutSend( es_out_t *out, es_out_id_t *id, block_t *p_block )
-{
-    if( id->p_es->p_dec )
+    /* Apply mode
+     * XXX change that when we do group too */
+    if( 1 )
     {
-        input_DecodeBlock( id->p_es->p_dec, p_block );
+        EsOutSelect( out, es, VLC_FALSE );
     }
-    else
+
+    vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+    es->p_es->fmt = *fmt;
+
+    TAB_APPEND( out->p_sys->i_es, out->p_sys->es, es );
+    p_sys->i_id++;  /* always incremented */
+    switch( fmt->i_cat )
     {
-        block_Release( p_block );
+        case AUDIO_ES:
+            p_sys->i_audio++;
+            break;
+        case SPU_ES:
+            p_sys->i_sub++;
+            break;
+        case VIDEO_ES:
+            p_sys->i_video++;
+            break;
     }
-    return VLC_SUCCESS;
+
+    return es;
 }
 
 /*****************************************************************************
- * EsOutSendPES:
+ * EsOutSend:
  *****************************************************************************/
-static int EsOutSendPES( es_out_t *out, es_out_id_t *id, pes_packet_t *p_pes )
+static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
 {
-    if( id->p_es->p_dec )
+    vlc_mutex_lock( &out->p_sys->p_input->stream.stream_lock );
+    if( es->p_es->p_dec )
     {
-        input_DecodePES( id->p_es->p_dec, p_pes );
+        input_DecodeBlock( es->p_es->p_dec, p_block );
     }
     else
     {
-        input_DeletePES( out->p_sys->p_input->p_method_data, p_pes );
+        block_Release( p_block );
     }
+    vlc_mutex_unlock( &out->p_sys->p_input->stream.stream_lock );
     return VLC_SUCCESS;
 }
 
 /*****************************************************************************
  * EsOutDel:
  *****************************************************************************/
-static void EsOutDel( es_out_t *out, es_out_id_t *id )
+static void EsOutDel( es_out_t *out, es_out_id_t *es )
 {
     es_out_sys_t *p_sys = out->p_sys;
 
-    TAB_REMOVE( p_sys->i_id, p_sys->id, id );
+    TAB_REMOVE( p_sys->i_es, p_sys->es, es );
+
+    switch( es->p_es->i_cat )
+    {
+        case AUDIO_ES:
+            p_sys->i_audio--;
+            break;
+        case SPU_ES:
+            p_sys->i_sub--;
+            break;
+        case VIDEO_ES:
+            p_sys->i_video--;
+            break;
+    }
 
+    /* We don't try to reselect */
     vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
-    if( id->p_es->p_dec )
+    if( es->p_es->p_dec )
     {
-        input_UnselectES( p_sys->p_input, id->p_es );
+        input_UnselectES( p_sys->p_input, es->p_es );
     }
-    if( id->p_es->p_waveformatex )
+
+    if( es->p_es->p_waveformatex )
     {
-        free( id->p_es->p_waveformatex );
-        id->p_es->p_waveformatex = NULL;
+        free( es->p_es->p_waveformatex );
+        es->p_es->p_waveformatex = NULL;
     }
-    if( id->p_es->p_bitmapinfoheader )
+    if( es->p_es->p_bitmapinfoheader )
     {
-        free( id->p_es->p_bitmapinfoheader );
-        id->p_es->p_bitmapinfoheader = NULL;
+        free( es->p_es->p_bitmapinfoheader );
+        es->p_es->p_bitmapinfoheader = NULL;
     }
-    input_DelES( p_sys->p_input, id->p_es );
+    input_DelES( p_sys->p_input, es->p_es );
+
     vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
 
-    free( id );
+    free( es );
 }
 
 /*****************************************************************************
@@ -361,30 +488,94 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
 {
     es_out_sys_t *p_sys = out->p_sys;
     vlc_bool_t  b, *pb;
-    es_out_id_t *id;
+    int         i, *pi;
+
+    es_out_id_t *es;
+
     switch( i_query )
     {
-        case ES_OUT_SET_SELECT:
+        case ES_OUT_SET_ES_STATE:
             vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
-            id = (es_out_id_t*) va_arg( args, es_out_id_t * );
+            es = (es_out_id_t*) va_arg( args, es_out_id_t * );
             b = (vlc_bool_t) va_arg( args, vlc_bool_t );
-            if( b && id->p_es->p_dec == NULL )
+            if( b && es->p_es->p_dec == NULL )
             {
-                input_SelectES( p_sys->p_input, id->p_es );
+                input_SelectES( p_sys->p_input, es->p_es );
                 vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
-                return id->p_es->p_dec ? VLC_SUCCESS : VLC_EGENERIC;
+                return es->p_es->p_dec ? VLC_SUCCESS : VLC_EGENERIC;
             }
-            else if( !b && id->p_es->p_dec )
+            else if( !b && es->p_es->p_dec )
             {
-                input_UnselectES( p_sys->p_input, id->p_es );
+                input_UnselectES( p_sys->p_input, es->p_es );
                 vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
                 return VLC_SUCCESS;
             }
-        case ES_OUT_GET_SELECT:
-            id = (es_out_id_t*) va_arg( args, es_out_id_t * );
+        case ES_OUT_GET_ES_STATE:
+            es = (es_out_id_t*) va_arg( args, es_out_id_t * );
             pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * );
 
-            *pb = id->p_es->p_dec ? VLC_TRUE : VLC_FALSE;
+            *pb = es->p_es->p_dec ? VLC_TRUE : VLC_FALSE;
+            return VLC_SUCCESS;
+
+        case ES_OUT_SET_ACTIVE:
+            b = (vlc_bool_t) va_arg( args, vlc_bool_t );
+            p_sys->b_active = b;
+            return VLC_SUCCESS;
+
+        case ES_OUT_GET_ACTIVE:
+            pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * );
+            *pb = p_sys->b_active;
+            return VLC_SUCCESS;
+
+        case ES_OUT_SET_MODE:
+            i = (int) va_arg( args, int );
+            if( i == ES_OUT_MODE_NONE || i == ES_OUT_MODE_ALL || i == ES_OUT_MODE_AUTO )
+            {
+                p_sys->i_mode = i;
+
+                /* Reapply policy mode */
+                vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
+                for( i = 0; i < p_sys->i_es; i++ )
+                {
+                    if( p_sys->es[i]->p_es->p_dec )
+                    {
+                        input_UnselectES( p_sys->p_input, p_sys->es[i]->p_es );
+                    }
+                }
+                for( i = 0; i < p_sys->i_es; i++ )
+                {
+                    EsOutSelect( out, p_sys->es[i], VLC_FALSE );
+                }
+                vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
+                return VLC_SUCCESS;
+            }
+            return VLC_EGENERIC;
+
+        case ES_OUT_GET_MODE:
+            pi = (int*) va_arg( args, int* );
+            *pi = p_sys->i_mode;
+            return VLC_SUCCESS;
+
+        case ES_OUT_SET_ES:
+            es = (es_out_id_t*) va_arg( args, es_out_id_t * );
+            if( es == NULL )
+            {
+                for( i = 0; i < p_sys->i_es; i++ )
+                {
+                    vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
+                    if( p_sys->es[i]->p_es->p_dec )
+                    {
+                        input_UnselectES( p_sys->p_input, p_sys->es[i]->p_es );
+                    }
+                    vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
+                }
+            }
+            else
+            {
+                vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
+                EsOutSelect( out, es, VLC_TRUE );
+                vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
+            }
             return VLC_SUCCESS;
 
         default:
@@ -393,3 +584,6 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
     }
 }
 
+
+
+
index 3cb7b4a1cefaa0966d2278bbff8a781011edca46..01ebcca8cc8da446938222daf5c9ce5a2848d287 100644 (file)
@@ -4,7 +4,7 @@
  * decoders.
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: input.c,v 1.264 2003/11/26 18:48:24 gbazin Exp $
+ * $Id: input.c,v 1.265 2003/11/27 04:11:40 fenrir Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -622,6 +622,8 @@ static int InitThread( input_thread_t * p_input )
     }
 
     p_input->p_es_out = input_EsOutNew( p_input );
+    es_out_Control( p_input->p_es_out, ES_OUT_SET_ACTIVE, VLC_FALSE );
+    es_out_Control( p_input->p_es_out, ES_OUT_SET_MODE, ES_OUT_MODE_NONE );
 
     /* Find and open appropriate access module */
     p_input->p_access = module_Need( p_input, "access",
@@ -744,7 +746,7 @@ static int InitThread( input_thread_t * p_input )
         if( ( p_sub = subtitle_New( p_input, strdup(val.psz_string), i_microsecondperframe, 0 ) ) )
         {
             /* Select this ES by default */
-            es_out_Control( p_input->p_es_out, ES_OUT_SET_SELECT, p_sub->p_es, VLC_TRUE );
+            es_out_Control( p_input->p_es_out, ES_OUT_SET_ES_STATE, p_sub->p_es, VLC_TRUE );
 
             TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
         }
@@ -767,6 +769,9 @@ static int InitThread( input_thread_t * p_input )
         free(tmp);
     }
 
+    es_out_Control( p_input->p_es_out, ES_OUT_SET_ACTIVE, VLC_TRUE );
+    es_out_Control( p_input->p_es_out, ES_OUT_SET_MODE, ES_OUT_MODE_AUTO );
+
     return VLC_SUCCESS;
 }