]> git.sesse.net Git - vlc/commitdiff
* src/video_output/video_output.c : do not use FIND_ANYWHERE to catch
authorLaurent Aimar <fenrir@videolan.org>
Sat, 13 Sep 2003 17:42:16 +0000 (17:42 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Sat, 13 Sep 2003 17:42:16 +0000 (17:42 +0000)
 the playlist.  but use FIND_PARENT. vlc_object_find  with FIND_ANYWHERE
 use p_obj->p_vlc as a starting point  and that doesn't work as playlist
 is  detach from  vlc before  vout is  destroyed by  the decoders  (when
 shutting down)  Perhaps vlc_object_find  should be  fixing to  find the
 root object, but I'm not sure.

 * src/input/*  : move  subtitle handling  from avi  to input.  Now subs
 should works with all file types _BUT_ won't be in synch if the demuxer
 doesn't implement a _precise_ DEMUX_GET_TIME.  So only .avi, .mp4 will
 be ok. Others could works if perfectly cbr.
  Now  Subtitle  track is  only  selected  when specified  by  sub-file
 option.(auto-dectected file is always added but not selected by default)
  Btw, the code could support multiple  subs files, but I don't know how
 to pass multiple filenames, any ideas ?

 * demux/mpeg/mpga.c : play with es_out_t. I'm investigating for now so
 don't use that elsewhere.

include/input_ext-intf.h
include/ninput.h
include/vlc_common.h
modules/demux/avi/avi.c
modules/demux/avi/avi.h
modules/demux/mp4/mp4.c
modules/demux/mpeg/mpga.c
src/input/demux.c
src/input/input.c
src/playlist/playlist.c
src/video_output/video_output.c

index b4c22de8a15cbfdfda0abb5333b6fe63695c7a67..4d3e3cf4bd2fba9b269b3f4ef1e3db9fd543b8e9 100644 (file)
@@ -4,7 +4,7 @@
  * control the pace of reading.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.95 2003/09/12 18:34:44 fenrir Exp $
+ * $Id: input_ext-intf.h,v 1.96 2003/09/13 17:42:15 fenrir Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -346,6 +346,9 @@ struct input_thread_t
     char *  psz_name;
 
     count_t c_loops;
+
+    /* private, do not touch it */
+    input_thread_sys_t  *p_sys;
 };
 
 /* Input methods */
index 6a30ec526f3eca2a83c6603e7f41a92e98466062..91817a869b6d6f67e03db01e1ee903084d220d8e 100644 (file)
@@ -2,7 +2,7 @@
  * ninput.h
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ninput.h,v 1.10 2003/09/12 18:34:44 fenrir Exp $
+ * $Id: ninput.h,v 1.11 2003/09/13 17:42:15 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -36,9 +36,9 @@ typedef struct
     int             i_cat;
     vlc_fourcc_t    i_codec;
 
-    int             i_group;    /* eg -1. if >= 0 then a "group" (program) is
-                                   created for each value */
-
+    int             i_group;    /* -1 : standalone
+                                   >= 0 then a "group" (program) is created
+                                        for each value */
     int             i_priority; /*  -2 : mean not selectable by the users
                                     -1 : mean not selected by default even
                                         when no other stream
@@ -78,7 +78,7 @@ static inline void es_format_Init( es_format_t *fmt,
 {
     fmt->i_cat                  = i_cat;
     fmt->i_codec                = i_codec;
-    fmt->i_group                = -1;
+    fmt->i_group                = 0;
     fmt->i_priority             = 0;
     fmt->psz_language           = NULL;
     fmt->psz_description        = NULL;
@@ -213,7 +213,9 @@ enum demux_query_e
     DEMUX_GET_TIME,             /* arg1= int64_t *      res=    */
     DEMUX_SET_TIME,             /* arg1= int64_t        res=can fail    */
 
-    DEMUX_GET_LENGTH            /* arg1= int64_t *      res=can fail    */
+    DEMUX_GET_LENGTH,           /* arg1= int64_t *      res=can fail    */
+
+    DEMUX_GET_FPS               /* arg1= float *        res=can fail    */
 };
 
 
index d0b33762e7a4ae0cfc6de683a3dfb1457dea9803..b667e0ec7b7bb9fe0989c3f7a33dbaeab6cf3641 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.77 2003/09/12 18:34:44 fenrir Exp $
+ * $Id: vlc_common.h,v 1.78 2003/09/13 17:42:15 fenrir Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -211,6 +211,7 @@ typedef struct intf_channel_t intf_channel_t;
 
 /* Input */
 typedef struct input_thread_t input_thread_t;
+typedef struct input_thread_sys_t input_thread_sys_t;
 typedef struct input_channel_t input_channel_t;
 typedef struct input_area_t input_area_t;
 typedef struct input_buffers_t input_buffers_t;
index 9070a157ee022ee5a08e98853a57299fb89f2090..aa07b8bfcb9624b4e3f3ec2e1a71c4311974a299 100644 (file)
@@ -2,7 +2,7 @@
  * avi.c : AVI file Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.61 2003/09/12 16:26:40 fenrir Exp $
+ * $Id: avi.c,v 1.62 2003/09/13 17:42:15 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -29,8 +29,6 @@
 #include <vlc/input.h>
 #include "codecs.h"
 
-#include "../util/sub.h"
-
 #include "libavi.h"
 #include "avi.h"
 
@@ -123,7 +121,6 @@ static int Open( vlc_object_t * p_this )
     demux_sys_t *p_avi;
     es_descriptor_t *p_es = NULL; /* avoid warning */
     unsigned int i;
-    mtime_t i_microsecperframe = 0; // for some subtitle format
 
     vlc_bool_t b_stream_audio, b_stream_video;
     uint8_t  *p_peek;
@@ -377,12 +374,6 @@ static int Open( vlc_object_t * p_this )
                     input_AddInfo( p_cat, _("Bits Per Pixel"), "%d",
                                    p_avi_strf_vids->p_bih->biBitCount );
                 }
-                if( i_microsecperframe == 0 )
-                {
-                    i_microsecperframe = (mtime_t)1000000 *
-                                         (mtime_t)p_info->i_scale /
-                                         (mtime_t)p_info->i_rate;
-                }
                 break;
             default:
                 msg_Warn( p_input, "stream[%d] unknown type", i );
@@ -424,11 +415,6 @@ static int Open( vlc_object_t * p_this )
 #undef p_info
     }
 
-    if( ( p_avi->p_sub = subtitle_New( p_input, NULL, i_microsecperframe ) ) )
-    {
-        subtitle_Select( p_avi->p_sub );
-    }
-
     if( config_GetInt( p_input, "avi-index" ) )
     {
         if( p_avi->b_seekable )
@@ -572,10 +558,6 @@ static void Close ( vlc_object_t * p_this )
         }
     }
     FREE( p_avi->pp_info );
-    if( p_avi->p_sub )
-    {
-        subtitle_Close( p_avi->p_sub );
-    }
     AVI_ChunkFreeRoot( p_input->s, &p_avi->ck_root );
 
     free( p_avi );
@@ -658,11 +640,6 @@ static int Demux_Seekable( input_thread_t *p_input )
 
     p_avi->i_time += 25*1000;  /* read 25ms */
 
-    if( p_avi->p_sub )
-    {
-        subtitle_Demux( p_avi->p_sub, p_avi->i_time );
-    }
-
     /* Check if we need to send the audio data to decoder */
     b_play_audio = !p_input->stream.control.b_mute;
 
@@ -1227,6 +1204,7 @@ static int Seek( input_thread_t *p_input, mtime_t i_date, int i_percent )
 static int    Control( input_thread_t *p_input, int i_query, va_list args )
 {
     demux_sys_t *p_sys = p_input->p_demux_data;
+    int i;
     double   f, *pf;
     int64_t i64, *pi64;
 
@@ -1276,10 +1254,6 @@ static int    Control( input_thread_t *p_input, int i_query, va_list args )
                 f = (double)va_arg( args, double );
                 i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );
                 i_ret = Seek( p_input, i64, (int)(f * 100) );
-                if( p_sys->p_sub )
-                {
-                    subtitle_Seek( p_sys->p_sub, p_sys->i_time );
-                }
                 return i_ret;
             }
             else
@@ -1301,6 +1275,21 @@ static int    Control( input_thread_t *p_input, int i_query, va_list args )
             *pi64 = p_sys->i_length * (mtime_t)1000000;
             return VLC_SUCCESS;
 
+        case DEMUX_GET_FPS:
+            pf = (double*)va_arg( args, double * );
+            *pf = 0.0;
+            for( i = 0; i < (int)p_sys->i_streams; i++ )
+            {
+#define tk p_sys->pp_info[i]
+                if( tk->i_cat == VIDEO_ES && tk->i_scale > 0)
+                {
+                    *pf = (float)tk->i_rate / (float)tk->i_scale;
+                    break;
+                }
+#undef tk
+            }
+            return VLC_SUCCESS;
+
         default:
             return demux_vaControlDefault( p_input, i_query, args );
     }
index 52ecbf7f34a60b4b5f1a668c4370da676289802e..1e66e5b52f0a655cf65f8cb418d187758ab4fa4b 100644 (file)
@@ -2,7 +2,7 @@
  * avi.h : AVI file Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: avi.h,v 1.14 2003/09/12 16:26:40 fenrir Exp $
+ * $Id: avi.h,v 1.15 2003/09/13 17:42:15 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -85,7 +85,5 @@ struct demux_sys_t
     /* number of streams and information */
     unsigned int i_streams;
     avi_stream_t  **pp_info;
-
-    subtitle_demux_t    *p_sub;
 };
 
index 9c15dd117255a9cc6d572cc5e4ecc563892a9242..7626f36b388fc816a6095bda36ea0762b14185e7 100644 (file)
@@ -2,7 +2,7 @@
  * mp4.c : MP4 file input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mp4.c,v 1.37 2003/09/12 16:26:40 fenrir Exp $
+ * $Id: mp4.c,v 1.38 2003/09/13 17:42:16 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -618,7 +618,9 @@ static int   Control  ( input_thread_t *p_input, int i_query, va_list args )
                     (mtime_t)p_sys->i_duration /
                     (mtime_t)p_sys->i_timescale;
             return VLC_SUCCESS;
-
+        case DEMUX_GET_FPS:
+            msg_Warn( p_input, "DEMUX_GET_FPS unimplemented !!" );
+            return VLC_EGENERIC;
         default:
             msg_Err( p_input, "control query unimplemented !!!" );
             return demux_vaControlDefault( p_input, i_query, args );
index 067fb413a23bb715f670bac3c9d6bbba587b2ea0..25719c4269814ca804a1326a0d436e8c134b7238 100644 (file)
@@ -2,7 +2,7 @@
  * mpga.c : MPEG-I/II Audio input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mpga.c,v 1.5 2003/09/12 16:26:40 fenrir Exp $
+ * $Id: mpga.c,v 1.6 2003/09/13 17:42:16 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -57,7 +57,9 @@ struct demux_sys_t
     mtime_t         i_time;
 
     int             i_bitrate_avg;  /* extracted from Xing header */
-    es_descriptor_t *p_es;
+    es_out_id_t     *p_es;
+
+    //es_descriptor_t *p_es;
 };
 
 static int HeaderCheck( uint32_t h )
@@ -173,6 +175,8 @@ static int Open( vlc_object_t * p_this )
 
     module_t       *p_id3;
 
+    es_format_t    fmt;
+
 
     if( p_input->psz_demux &&
         ( !strncmp( p_input->psz_demux, "mpga", 4 ) ||
@@ -334,28 +338,11 @@ static int Open( vlc_object_t * p_this )
         msg_Err( p_input, "cannot init stream" );
         goto error;
     }
-    if( input_AddProgram( p_input, 0, 0) == NULL )
-    {
-        vlc_mutex_unlock( &p_input->stream.stream_lock );
-        msg_Err( p_input, "cannot add program" );
-        goto error;
-    }
-    p_input->stream.pp_programs[0]->b_is_ok = 0;
-    p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
-
     p_input->stream.i_mux_rate = p_sys->i_bitrate_avg / 8 / 50;
-
-    p_sys->p_es = input_AddES( p_input,
-                               p_input->stream.p_selected_program,
-                               1 , AUDIO_ES, NULL, 0 );
-
-    p_sys->p_es->i_stream_id = 1;
-    p_sys->p_es->i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'a' );
-    input_SelectES( p_input, p_sys->p_es );
-
-    p_input->stream.p_selected_program->b_is_ok = 1;
     vlc_mutex_unlock( &p_input->stream.stream_lock );
 
+    es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
+    p_sys->p_es = es_out_Add( p_input->p_es_out, &fmt );
     return VLC_SUCCESS;
 
 error:
@@ -431,14 +418,8 @@ static int Demux( input_thread_t * p_input )
                                      p_input->stream.p_selected_program,
                                      p_sys->i_time * 9 / 100 );
 
-    if( !p_sys->p_es->p_decoder_fifo )
-    {
-        msg_Err( p_input, "no audio decoder" );
-        input_DeletePES( p_input->p_method_data, p_pes );
-        return( -1 );
-    }
+    es_out_Send( p_input->p_es_out, p_sys->p_es, p_pes );
 
-    input_DecodePES( p_sys->p_es->p_decoder_fifo, p_pes );
     p_sys->i_time += (mtime_t)1000000 *
                      (mtime_t)mpga_frame_samples( header ) /
                      (mtime_t)MPGA_SAMPLE_RATE( header );
index c900394418e6941861bf74654bf42b8b233f3dd4..c0bdccb0b6bdf7e19a85e6098de47f77b37412e5 100644 (file)
@@ -2,7 +2,7 @@
  * demux.c
  *****************************************************************************
  * Copyright (C) 1999-2003 VideoLAN
- * $Id: demux.c,v 1.2 2003/09/07 22:51:11 fenrir Exp $
+ * $Id: demux.c,v 1.3 2003/09/13 17:42:16 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -133,6 +133,9 @@ int  demux_vaControlDefault( input_thread_t *p_input, int i_query, va_list args
                 i_ret = VLC_EGENERIC;
             }
             break;
+        case DEMUX_GET_FPS:
+            i_ret = VLC_EGENERIC;
+            break;
 
         default:
             msg_Err( p_input, "unknown query in demux_vaControlDefault !!!" );
index c40a7010d1f8afebb4688df4b150e028cd7b06bf..f2efb1e9ba78be398247c43ac6a51628d6a2e32a 100644 (file)
@@ -4,7 +4,7 @@
  * decoders.
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: input.c,v 1.239 2003/09/12 18:34:45 fenrir Exp $
+ * $Id: input.c,v 1.240 2003/09/13 17:42:16 fenrir Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
 #include "stream_output.h"
 
 #include "vlc_interface.h"
+#include "codecs.h"
+#include "modules/demux/util/sub.h"
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
+struct input_thread_sys_t
+{
+    /* subtitles */
+    int              i_sub;
+    subtitle_demux_t **sub;
+};
+
 static  int RunThread       ( input_thread_t *p_input );
 static  int InitThread      ( input_thread_t *p_input );
 static void ErrorThread     ( input_thread_t *p_input );
@@ -145,6 +154,7 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
 
     /* Initialize thread properties */
     p_input->b_eof      = 0;
+    p_input->p_sys      = NULL;
 
     /* Set target */
     p_input->psz_source = strdup( p_item->psz_uri );
@@ -367,6 +377,7 @@ static int RunThread( input_thread_t *p_input )
             if( p_input->stream.p_selected_area->i_size > 0 )
             {
                 unsigned int i;
+                mtime_t      i_time;
                 double f = (double)p_input->stream.p_selected_area->i_seek /
                            (double)p_input->stream.p_selected_area->i_size;
 
@@ -385,6 +396,22 @@ static int RunThread( input_thread_t *p_input )
                     /* Reinitialize synchro. */
                     p_pgrm->i_synchro_state = SYNCHRO_REINIT;
                 }
+
+                if( !demux_Control( p_input, DEMUX_GET_TIME, &i_time ) )
+                {
+                    int i;
+                    vlc_value_t val;
+
+                    /* Help in bar display */
+                    val.i_time = i_time;
+                    var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
+
+                    /* Seek subs */
+                    for( i = 0; i < p_input->p_sys->i_sub; i++ )
+                    {
+                        subtitle_Seek( p_input->p_sys->sub[i], i_time );
+                    }
+                }
             }
             p_input->stream.p_selected_area->i_seek = NO_SEEK;
         }
@@ -434,24 +461,35 @@ static int RunThread( input_thread_t *p_input )
 
         if( !p_input->b_error && !p_input->b_eof && i_update_next < mdate() )
         {
-            double d;
+            int i;
+            mtime_t i_time;
+            mtime_t i_length;
+            double  d_pos;
 
             /* update input status variables */
-            if( !demux_Control( p_input, DEMUX_GET_POSITION, &d ) )
+            if( !demux_Control( p_input, DEMUX_GET_POSITION, &d_pos ) )
             {
-                val.f_float = (float)d;
+                val.f_float = (float)d_pos;
                 var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
             }
-            if( !demux_Control( p_input, DEMUX_GET_TIME, &val.i_time ) )
+            if( !demux_Control( p_input, DEMUX_GET_TIME, &i_time ) )
             {
+                val.i_time = i_time;
                 var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
             }
-            if( !demux_Control( p_input, DEMUX_GET_LENGTH, &val.i_time ) )
+            if( !demux_Control( p_input, DEMUX_GET_LENGTH, &i_length ) )
             {
+                val.i_time = i_length;
                 var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
             }
 
-            i_update_next = mdate() + 200000LL;
+            /* update subs */
+            for( i = 0; i < p_input->p_sys->i_sub; i++ )
+            {
+                subtitle_Demux( p_input->p_sys->sub[i], i_time );
+            }
+
+            i_update_next = mdate() + 150000LL;
         }
     }
 
@@ -470,9 +508,12 @@ static int RunThread( input_thread_t *p_input )
  *****************************************************************************/
 static int InitThread( input_thread_t * p_input )
 {
+    float f_fps;
     /* Parse source string. Syntax : [[<access>][/<demux>]:][<source>] */
     char * psz_parser = p_input->psz_dupsource = strdup(p_input->psz_source);
     vlc_value_t val;
+    subtitle_demux_t *p_sub;
+    int64_t i_microsecondperframe;
 
     /* Skip the plug-in names */
     while( *psz_parser && *psz_parser != ':' )
@@ -663,6 +704,34 @@ static int InitThread( input_thread_t * p_input )
         return VLC_EGENERIC;
     }
 
+    /* Init input_thread_sys_t */
+    p_input->p_sys = malloc( sizeof( input_thread_sys_t ) );
+    p_input->p_sys->i_sub = 0;
+    p_input->p_sys->sub   = NULL;
+
+    /* get fps */
+    if( demux_Control( p_input, DEMUX_GET_FPS, &f_fps ) || f_fps < 0.1 )
+    {
+        i_microsecondperframe = 0;
+    }
+    else
+    {
+        i_microsecondperframe = (int64_t)( (double)1000000.0 / (double)f_fps );
+    }
+
+    /* Now add subtitles (for now only one) */
+    if( ( p_sub = subtitle_New( p_input, NULL, i_microsecondperframe ) ) )
+    {
+        TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
+
+        /* see if it should be selected */
+        var_Get( p_sub, "sub-file", &val );
+        if( val.psz_string && *val.psz_string )
+        {
+            subtitle_Select( p_sub );
+        }
+    }
+
     return VLC_SUCCESS;
 }
 
@@ -685,6 +754,7 @@ static void ErrorThread( input_thread_t *p_input )
  *****************************************************************************/
 static void EndThread( input_thread_t * p_input )
 {
+    int i;
 #ifdef HAVE_SYS_TIMES_H
     /* Display statistics */
     struct tms  cpu_usage;
@@ -704,7 +774,8 @@ static void EndThread( input_thread_t * p_input )
     /* Close optional stream output instance */
     if ( p_input->stream.p_sout != NULL )
     {
-        vlc_object_t *p_pl = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+        vlc_object_t *p_pl =
+            vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
         vlc_value_t keep;
 
         if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool && p_pl )
@@ -725,6 +796,19 @@ static void EndThread( input_thread_t * p_input )
         }
     }
 
+    /* Destroy subtitles demuxers */
+    for( i = 0; i < p_input->p_sys->i_sub; i++ )
+    {
+        subtitle_Close( p_input->p_sys->sub[i] );
+    }
+    if( p_input->p_sys->i_sub > 0 )
+    {
+        free( p_input->p_sys->sub );
+    }
+
+    /* Free input_thread_sys_t */
+    free( p_input->p_sys );
+
     /* Free demultiplexer's data */
     module_Unneed( p_input, p_input->p_demux );
 
@@ -855,6 +939,9 @@ struct es_out_sys_t
 
     int         i_id;
     es_out_id_t **id;
+
+    vlc_bool_t  i_audio;
+    vlc_bool_t  i_video;
 };
 struct es_out_id_t
 {
@@ -879,32 +966,218 @@ static es_out_t *EsOutCreate( input_thread_t *p_input )
     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;
 }
 static void      EsOutRelease( es_out_t *out )
 {
-    free( out->p_sys );
+    es_out_sys_t *p_sys = out->p_sys;
+    int i;
+
+    for( i = 0; i < p_sys->i_id; i++ )
+    {
+        free( p_sys->id[i] );
+    }
+    if( p_sys->id )
+    {
+        free( p_sys->id );
+    }
+    free( p_sys );
     free( out );
 }
 
 static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
 {
-    es_out_id_t *id = malloc( sizeof( es_out_id_t ) );
+    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 ) );
+    pgrm_descriptor_t *p_prgm = NULL;
+
+    vlc_mutex_lock( &p_input->stream.stream_lock );
+    if( fmt->i_group >= 0 )
+    {
+        /* search program */
+        p_prgm = input_FindProgram( p_input, fmt->i_group );
+
+        if( p_prgm == NULL )
+        {
+            /* create it */
+            p_prgm = input_AddProgram( p_input, fmt->i_group, 0 );
+
+            /* Select the first by default */
+            if( p_input->stream.p_selected_program == NULL )
+            {
+                p_input->stream.p_selected_program = p_prgm;
+            }
+        }
+    }
+
+    id->p_es = input_AddES( p_input,
+                            p_prgm,
+                            1 + 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;
+
+    switch( fmt->i_cat )
+    {
+        case AUDIO_ES:
+        {
+            WAVEFORMATEX *p_wf = malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
+
+            p_wf->wFormatTag        = WAVE_FORMAT_UNKNOWN;
+            p_wf->nChannels         = fmt->audio.i_channels;
+            p_wf->nSamplesPerSec    = fmt->audio.i_samplerate;
+            p_wf->nAvgBytesPerSec   = fmt->audio.i_bitrate / 8;
+            p_wf->nBlockAlign       = fmt->audio.i_blockalign;
+            p_wf->wBitsPerSample    = fmt->audio.i_bitspersample;
+            p_wf->cbSize            = fmt->i_extra;
+            if( fmt->i_extra > 0 )
+            {
+                if( fmt->i_extra_type != ES_EXTRA_TYPE_WAVEFORMATEX )
+                {
+                    msg_Warn( p_input, "extra type != WAVEFORMATEX for audio" );
+                }
+                memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
+            }
+            id->p_es->p_waveformatex = p_wf;
+            break;
+        }
+        case VIDEO_ES:
+        {
+            BITMAPINFOHEADER *p_bih = malloc( sizeof( BITMAPINFOHEADER ) +
+                                              fmt->i_extra );
+            p_bih->biSize           = sizeof(BITMAPINFOHEADER) + fmt->i_extra;
+            p_bih->biWidth          = fmt->video.i_width;
+            p_bih->biHeight         = fmt->video.i_height;
+            p_bih->biPlanes         = 1;
+            p_bih->biBitCount       = 24;
+            p_bih->biCompression    = fmt->i_codec;
+            p_bih->biSizeImage      = fmt->video.i_width * fmt->video.i_height;
+            p_bih->biXPelsPerMeter  = 0;
+            p_bih->biYPelsPerMeter  = 0;
+            p_bih->biClrUsed        = 0;
+            p_bih->biClrImportant   = 0;
+
+            if( fmt->i_extra > 0 )
+            {
+                if( fmt->i_extra_type != ES_EXTRA_TYPE_BITMAPINFOHEADER )
+                {
+                    msg_Warn( p_input,
+                              "extra type != BITMAPINFOHEADER for video" );
+                }
+                memcpy( &p_bih[1], fmt->p_extra, fmt->i_extra );
+            }
+            id->p_es->p_bitmapinfoheader = p_bih;
+            break;
+        }
+        default:
+            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_decoder_fifo )
+        {
+            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_decoder_fifo )
+        {
+            out->p_sys->i_video = fmt->i_priority;
+        }
+    }
+    vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+
+    TAB_APPEND( out->p_sys->i_id, out->p_sys->id, id );
 
     return id;
 }
 static int EsOutSend( es_out_t *out, es_out_id_t *id, pes_packet_t *p_pes )
 {
+    if( id->p_es->p_decoder_fifo )
+    {
+        input_DecodePES( id->p_es->p_decoder_fifo, p_pes );
+    }
+    else
+    {
+        input_DeletePES( out->p_sys->p_input->p_method_data, p_pes );
+    }
     return VLC_SUCCESS;
 }
 static void EsOutDel( es_out_t *out, es_out_id_t *id )
 {
+    es_out_sys_t *p_sys = out->p_sys;
+
+    TAB_REMOVE( p_sys->i_id, p_sys->id, id );
+
+    vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
+    if( id->p_es->p_decoder_fifo )
+    {
+        input_UnselectES( p_sys->p_input, id->p_es );
+    }
+    if( id->p_es->p_waveformatex )
+    {
+        free( id->p_es->p_waveformatex );
+        id->p_es->p_waveformatex = NULL;
+    }
+    if( id->p_es->p_bitmapinfoheader )
+    {
+        free( id->p_es->p_bitmapinfoheader );
+        id->p_es->p_bitmapinfoheader = NULL;
+    }
+    input_DelES( p_sys->p_input, id->p_es );
+    vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
+
     free( id );
 }
 static int EsOutControl( es_out_t *out, int i_query, va_list args )
 {
-    return VLC_EGENERIC;
+    es_out_sys_t *p_sys = out->p_sys;
+    vlc_bool_t  b, *pb;
+    es_out_id_t *id;
+    switch( i_query )
+    {
+        case ES_OUT_SET_SELECT:
+            id = (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_decoder_fifo == NULL )
+            {
+                input_SelectES( p_sys->p_input, id->p_es );
+                return id->p_es->p_decoder_fifo ? VLC_SUCCESS : VLC_EGENERIC;
+            }
+            else if( !b && id->p_es->p_decoder_fifo )
+            {
+                input_UnselectES( p_sys->p_input, id->p_es );
+            }
+            return VLC_SUCCESS;
+
+        case ES_OUT_GET_SELECT:
+            id = (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_decoder_fifo ? VLC_TRUE : VLC_FALSE;
+            return VLC_SUCCESS;
+
+        default:
+            msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
+            return VLC_EGENERIC;
+    }
 }
 
 /*****************************************************************************
index 3afae4f3860abfef6cff967a4499e10bf69f29cf..dfe485f7a41e2dfd2601f97c0ed7cd6031a17263 100644 (file)
@@ -2,7 +2,7 @@
  * playlist.c : Playlist management functions
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: playlist.c,v 1.50 2003/09/10 11:37:53 fenrir Exp $
+ * $Id: playlist.c,v 1.51 2003/09/13 17:42:16 fenrir Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -692,11 +692,10 @@ static void RunThread ( playlist_t *p_playlist )
         }
         else if( p_playlist->i_status == PLAYLIST_STOPPED )
         {
-            ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
-                                    &b_vout_destroyed, &i_vout_destroyed_date );
-
             ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT,
                                     &b_sout_destroyed, &i_sout_destroyed_date );
+            ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
+                                    &b_vout_destroyed, &i_vout_destroyed_date );
         }
         vlc_mutex_unlock( &p_playlist->object_lock );
 
@@ -721,11 +720,15 @@ static void RunThread ( playlist_t *p_playlist )
             /* Unlink current input */
             p_input = p_playlist->p_input;
             p_playlist->p_input = NULL;
-            vlc_object_detach( p_input );
             vlc_mutex_unlock( &p_playlist->object_lock );
 
             /* Destroy input */
             input_DestroyThread( p_input );
+            /* Unlink current input (_after_ input_DestroyThread for vout
+             * garbage collector)*/
+            vlc_object_detach( p_input );
+
+            /* Destroy object */
             vlc_object_destroy( p_input );
             continue;
         }
@@ -750,20 +753,21 @@ static void RunThread ( playlist_t *p_playlist )
         msleep( INTF_IDLE_SLEEP );
     }
 
-    /* close all remaining vout */
+    /* close all remaining sout */
     while( ( p_obj = vlc_object_find( p_playlist,
-                                      VLC_OBJECT_VOUT, FIND_CHILD ) ) )
+                                      VLC_OBJECT_SOUT, FIND_CHILD ) ) )
     {
-        vlc_object_detach( p_obj );
         vlc_object_release( p_obj );
-        vout_Destroy( (vout_thread_t *)p_obj );
+        sout_DeleteInstance( (sout_instance_t*)p_obj );
     }
-    /* close all remaining sout */
+
+    /* close all remaining vout */
     while( ( p_obj = vlc_object_find( p_playlist,
-                                      VLC_OBJECT_SOUT, FIND_CHILD ) ) )
+                                      VLC_OBJECT_VOUT, FIND_CHILD ) ) )
     {
+        vlc_object_detach( p_obj );
         vlc_object_release( p_obj );
-        sout_DeleteInstance( (sout_instance_t*)p_obj );
+        vout_Destroy( (vout_thread_t *)p_obj );
     }
 }
 
index d89ea9b2aec63ec703e5d8e019c6b35e2e70fb51..3b09225fb18fe96002e35583e70100ee7cf681d0 100644 (file)
@@ -5,7 +5,7 @@
  * thread, and destroy a previously oppened video output thread.
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: video_output.c,v 1.233 2003/09/07 22:43:17 fenrir Exp $
+ * $Id: video_output.c,v 1.234 2003/09/13 17:42:16 fenrir Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -80,7 +80,8 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout,
         {
             vlc_object_t *p_playlist;
 
-            p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+            p_playlist = vlc_object_find( p_this,
+                                          VLC_OBJECT_PLAYLIST, FIND_PARENT );
 
             if( p_playlist )
             {