]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
Fix revision 12116 which broke other transcode options. The commandline for streaming...
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c: transcoding stream output module
3  *****************************************************************************
4  * Copyright (C) 2003-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl> 
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32
33 #include <vlc/vlc.h>
34 #include <vlc/input.h>
35 #include <vlc/sout.h>
36 #include <vlc/vout.h>
37 #include <vlc/decoder.h>
38 #include "vlc_filter.h"
39 #include "osd.h"
40
41 #define MASTER_SYNC_MAX_DRIFT 100000
42
43 /*****************************************************************************
44  * Module descriptor
45  *****************************************************************************/
46 #define VENC_TEXT N_("Video encoder")
47 #define VENC_LONGTEXT N_( \
48     "Allows you to specify the video encoder to use and its associated " \
49     "options." )
50 #define VCODEC_TEXT N_("Destination video codec")
51 #define VCODEC_LONGTEXT N_( \
52     "Allows you to specify the destination video codec used for the " \
53     "streaming output." )
54 #define VB_TEXT N_("Video bitrate")
55 #define VB_LONGTEXT N_( \
56     "Allows you to specify the video bitrate used for the streaming " \
57     "output." )
58 #define SCALE_TEXT N_("Video scaling")
59 #define SCALE_LONGTEXT N_( \
60     "Allows you to scale the video before encoding." )
61 #define FPS_TEXT N_("Video frame-rate")
62 #define FPS_LONGTEXT N_( \
63     "Allows you to specify an output frame rate for the video." )
64 #define DEINTERLACE_TEXT N_("Deinterlace video")
65 #define DEINTERLACE_LONGTEXT N_( \
66     "Allows you to deinterlace the video before encoding." )
67 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
68 #define DEINTERLACE_MODULE_LONGTEXT N_( \
69     "Specifies the deinterlace module to use." )
70 #define WIDTH_TEXT N_("Video width")
71 #define WIDTH_LONGTEXT N_( \
72     "Allows you to specify the output video width." )
73 #define HEIGHT_TEXT N_("Video height")
74 #define HEIGHT_LONGTEXT N_( \
75     "Allows you to specify the output video height." )
76 #define VFILTER_TEXT N_("Video filter")
77 #define VFILTER_LONGTEXT N_( \
78     "Allows you to specify video filters used after the video " \
79     "transcoding and subpictures overlaying." )
80
81 #define CROPTOP_TEXT N_("Video crop top")
82 #define CROPTOP_LONGTEXT N_( \
83     "Allows you to specify the top coordinate for the video cropping." )
84 #define CROPLEFT_TEXT N_("Video crop left")
85 #define CROPLEFT_LONGTEXT N_( \
86     "Allows you to specify the left coordinate for the video cropping." )
87 #define CROPBOTTOM_TEXT N_("Video crop bottom")
88 #define CROPBOTTOM_LONGTEXT N_( \
89     "Allows you to specify the bottom coordinate for the video cropping." )
90 #define CROPRIGHT_TEXT N_("Video crop right")
91 #define CROPRIGHT_LONGTEXT N_( \
92     "Allows you to specify the right coordinate for the video cropping." )
93
94 #define AENC_TEXT N_("Audio encoder")
95 #define AENC_LONGTEXT N_( \
96     "Allows you to specify the audio encoder to use and its associated " \
97     "options." )
98 #define ACODEC_TEXT N_("Destination audio codec")
99 #define ACODEC_LONGTEXT N_( \
100     "Allows you to specify the destination audio codec used for the " \
101     "streaming output." )
102 #define AB_TEXT N_("Audio bitrate")
103 #define AB_LONGTEXT N_( \
104     "Allows you to specify the audio bitrate used for the streaming " \
105     "output." )
106 #define ARATE_TEXT N_("Audio sample rate")
107 #define ARATE_LONGTEXT N_( \
108     "Allows you to specify the audio sample rate used for the streaming " \
109     "output." )
110 #define ACHANS_TEXT N_("Audio channels")
111 #define ACHANS_LONGTEXT N_( \
112     "Allows you to specify the number of audio channels used for the " \
113     "streaming output." )
114
115 #define SENC_TEXT N_("Subtitles encoder")
116 #define SENC_LONGTEXT N_( \
117     "Allows you to specify the subtitles encoder to use and its associated " \
118     "options." )
119 #define SCODEC_TEXT N_("Destination subtitles codec")
120 #define SCODEC_LONGTEXT N_( \
121     "Allows you to specify the destination subtitles codec used for the " \
122     "streaming output." )
123 #define SFILTER_TEXT N_("Subpictures filter")
124 #define SFILTER_LONGTEXT N_( \
125     "Allows you to specify subpictures filters used during the video " \
126     "transcoding. The subpictures produced by the filters will be overlayed " \
127     "directly onto the video." )
128
129 #define OSD_TEXT N_("OSD menu")
130 #define OSD_LONGTEXT N_(\
131     "Enable streaming of the On Screen Display. It uses the osdmenu subfilter." )
132                   
133 #define THREADS_TEXT N_("Number of threads")
134 #define THREADS_LONGTEXT N_( \
135     "Allows you to specify the number of threads used for the transcoding." )
136 #define HP_TEXT N_("High priority")
137 #define HP_LONGTEXT N_( \
138     "Runs the optional encoder thread at the OUTPUT priority instead of " \
139     "VIDEO." )
140
141 #define ASYNC_TEXT N_("Synchronise on audio track")
142 #define ASYNC_LONGTEXT N_( \
143     "This option will drop/duplicate video frames to synchronise the video " \
144     "track on the audio track." )
145
146 #define HURRYUP_TEXT N_( "Hurry up" )
147 #define HURRYUP_LONGTEXT N_( "Allows you to specify if the transcoder " \
148   "should drop frames if your CPU can't keep up with the encoding rate." )
149
150 static char *ppsz_deinterlace_type[] =
151 {
152     "deinterlace", "ffmpeg-deinterlace"
153 };
154
155 static int  Open ( vlc_object_t * );
156 static void Close( vlc_object_t * );
157
158 #define SOUT_CFG_PREFIX "sout-transcode-"
159
160 vlc_module_begin();
161     set_shortname( _("Transcode"));
162     set_description( _("Transcode stream output") );
163     set_capability( "sout stream", 50 );
164     add_shortcut( "transcode" );
165     set_callbacks( Open, Close );
166     set_category( CAT_SOUT );
167     set_subcategory( SUBCAT_SOUT_STREAM );
168     set_section( N_("Video"), NULL );
169     add_string( SOUT_CFG_PREFIX "venc", NULL, NULL, VENC_TEXT,
170                 VENC_LONGTEXT, VLC_FALSE );
171     add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
172                 VCODEC_LONGTEXT, VLC_FALSE );
173     add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT,
174                  VB_LONGTEXT, VLC_FALSE );
175     add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
176                SCALE_LONGTEXT, VLC_FALSE );
177     add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT,
178                FPS_LONGTEXT, VLC_FALSE );
179     add_bool( SOUT_CFG_PREFIX "hurry-up", VLC_TRUE, NULL, HURRYUP_TEXT,
180                HURRYUP_LONGTEXT, VLC_FALSE );
181     add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
182               DEINTERLACE_LONGTEXT, VLC_FALSE );
183     add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL,
184                 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
185                 VLC_FALSE );
186         change_string_list( ppsz_deinterlace_type, 0, 0 );
187     add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
188                  WIDTH_LONGTEXT, VLC_TRUE );
189     add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
190                  HEIGHT_LONGTEXT, VLC_TRUE );
191     add_module_list_cat( SOUT_CFG_PREFIX "vfilter", SUBCAT_VIDEO_VFILTER,
192                      NULL, NULL,
193                      VFILTER_TEXT, VFILTER_LONGTEXT, VLC_FALSE );
194
195     add_integer( SOUT_CFG_PREFIX "croptop", 0, NULL, CROPTOP_TEXT,
196                  CROPTOP_LONGTEXT, VLC_TRUE );
197     add_integer( SOUT_CFG_PREFIX "cropleft", 0, NULL, CROPLEFT_TEXT,
198                  CROPLEFT_LONGTEXT, VLC_TRUE );
199     add_integer( SOUT_CFG_PREFIX "cropbottom", 0, NULL, CROPBOTTOM_TEXT,
200                  CROPBOTTOM_LONGTEXT, VLC_TRUE );
201     add_integer( SOUT_CFG_PREFIX "cropright", 0, NULL, CROPRIGHT_TEXT,
202                  CROPRIGHT_LONGTEXT, VLC_TRUE );
203
204     set_section( N_("Audio"), NULL );
205     add_string( SOUT_CFG_PREFIX "aenc", NULL, NULL, AENC_TEXT,
206                 AENC_LONGTEXT, VLC_FALSE );
207     add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
208                 ACODEC_LONGTEXT, VLC_FALSE );
209     add_integer( SOUT_CFG_PREFIX "ab", 64000, NULL, AB_TEXT,
210                  AB_LONGTEXT, VLC_FALSE );
211     add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
212                  ACHANS_LONGTEXT, VLC_FALSE );
213     add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
214                  ARATE_LONGTEXT, VLC_TRUE );
215     add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
216               ASYNC_LONGTEXT, VLC_FALSE );
217
218     set_section( N_("Overlays/Subtitles"), NULL );
219     add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT,
220                 SENC_LONGTEXT, VLC_FALSE );
221     add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
222                 SCODEC_LONGTEXT, VLC_FALSE );
223     add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
224                SCODEC_LONGTEXT, VLC_FALSE );
225     add_module_list_cat( SOUT_CFG_PREFIX "sfilter", SUBCAT_VIDEO_SUBPIC,
226                      NULL, NULL,
227                      SFILTER_TEXT, SFILTER_LONGTEXT, VLC_FALSE );
228
229     set_section( N_("On Screen Display"), NULL );
230     add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
231               OSD_LONGTEXT, VLC_FALSE );
232     
233     set_section( N_("Miscellaneous"), NULL );
234     add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
235                  THREADS_LONGTEXT, VLC_TRUE );
236     add_bool( SOUT_CFG_PREFIX "high-priority", 0, NULL, HP_TEXT, HP_LONGTEXT,
237               VLC_TRUE );
238
239 vlc_module_end();
240
241 static const char *ppsz_sout_options[] = {
242     "venc", "vcodec", "vb", "croptop", "cropbottom", "cropleft", "cropright",
243     "scale", "fps", "width", "height", "vfilter", "deinterlace",
244     "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
245     "samplerate", "channels", "senc", "scodec", "soverlay", "sfilter",
246     "osd", "audio-sync", "high-priority", NULL
247 };
248
249 /*****************************************************************************
250  * Exported prototypes
251  *****************************************************************************/
252 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
253 static int               Del ( sout_stream_t *, sout_stream_id_t * );
254 static int               Send( sout_stream_t *, sout_stream_id_t *, block_t* );
255
256 static int  transcode_audio_new    ( sout_stream_t *, sout_stream_id_t * );
257 static void transcode_audio_close  ( sout_stream_t *, sout_stream_id_t * );
258 static int  transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
259                                      block_t *, block_t ** );
260
261 static aout_buffer_t *audio_new_buffer( decoder_t *, int );
262 static void audio_del_buffer( decoder_t *, aout_buffer_t * );
263
264 static int  transcode_video_new    ( sout_stream_t *, sout_stream_id_t * );
265 static void transcode_video_close  ( sout_stream_t *, sout_stream_id_t * );
266 static int  transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
267 static int  transcode_video_process( sout_stream_t *, sout_stream_id_t *,
268                                      block_t *, block_t ** );
269
270 static void video_del_buffer( vlc_object_t *, picture_t * );
271 static picture_t *video_new_buffer_decoder( decoder_t * );
272 static void video_del_buffer_decoder( decoder_t *, picture_t * );
273 static void video_link_picture_decoder( decoder_t *, picture_t * );
274 static void video_unlink_picture_decoder( decoder_t *, picture_t * );
275 static picture_t *video_new_buffer_filter( filter_t * );
276 static void video_del_buffer_filter( filter_t *, picture_t * );
277
278 static int  transcode_spu_new    ( sout_stream_t *, sout_stream_id_t * );
279 static void transcode_spu_close  ( sout_stream_t *, sout_stream_id_t * );
280 static int  transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
281                                    block_t *, block_t ** );
282
283 static int  transcode_osd_new    ( sout_stream_t *, sout_stream_id_t * );
284 static void transcode_osd_close  ( sout_stream_t *, sout_stream_id_t * );
285 static int  transcode_osd_process( sout_stream_t *, sout_stream_id_t *,
286                                    block_t *, block_t ** );
287                                    
288 static int  EncoderThread( struct sout_stream_sys_t * p_sys );
289
290 static int pi_channels_maps[6] =
291 {
292     0,
293     AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
294     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
295     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
296      | AOUT_CHAN_REARRIGHT,
297     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
298      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
299 };
300
301 #define PICTURE_RING_SIZE 64
302 #define SUBPICTURE_RING_SIZE 20
303
304 struct sout_stream_sys_t
305 {
306     VLC_COMMON_MEMBERS
307
308     sout_stream_t   *p_out;
309     sout_stream_id_t *id_video;
310     block_t         *p_buffers;
311     vlc_mutex_t     lock_out;
312     vlc_cond_t      cond;
313     picture_t *     pp_pics[PICTURE_RING_SIZE];
314     int             i_first_pic, i_last_pic;
315
316     /* Audio */
317     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
318     char            *psz_aenc;
319     sout_cfg_t      *p_audio_cfg;
320     int             i_sample_rate;
321     int             i_channels;
322     int             i_abitrate;
323
324     /* Video */
325     vlc_fourcc_t    i_vcodec;   /* codec video (0 if not transcode) */
326     char            *psz_venc;
327     sout_cfg_t      *p_video_cfg;
328     int             i_vbitrate;
329     double          f_scale;
330     double          f_fps;
331     int             i_width;
332     int             i_height;
333     vlc_bool_t      b_deinterlace;
334     char            *psz_deinterlace;
335     sout_cfg_t      *p_deinterlace_cfg;
336     int             i_threads;
337     vlc_bool_t      b_high_priority;
338     vlc_bool_t      b_hurry_up;
339     char            *psz_vfilters[10];
340     sout_cfg_t      *p_vfilters_cfg[10];
341     int             i_vfilters;
342
343     int             i_crop_top;
344     int             i_crop_bottom;
345     int             i_crop_right;
346     int             i_crop_left;
347
348     /* SPU */
349     vlc_fourcc_t    i_scodec;   /* codec spu (0 if not transcode) */
350     char            *psz_senc;
351     vlc_bool_t      b_soverlay;
352     sout_cfg_t      *p_spu_cfg;
353     spu_t           *p_spu;
354
355     /* OSD Menu */
356     sout_stream_id_t *id_osd;   /* extension for streaming OSD menus */
357     vlc_fourcc_t    i_osdcodec; /* codec osd menu (0 if not transcode) */
358     char            *psz_osdenc;
359     sout_cfg_t      *p_osd_cfg;
360     vlc_bool_t      b_es_osd;      /* VLC_TRUE when osd es is registered */
361     vlc_bool_t      b_sout_osd;
362         
363     /* Sync */
364     vlc_bool_t      b_master_sync;
365     mtime_t         i_master_drift;
366 };
367
368 struct decoder_owner_sys_t
369 {
370     picture_t *pp_pics[PICTURE_RING_SIZE];
371     sout_stream_sys_t *p_sys;
372 };
373 struct filter_owner_sys_t
374 {
375     picture_t *pp_pics[PICTURE_RING_SIZE];
376     sout_stream_sys_t *p_sys;
377 };
378
379 /*****************************************************************************
380  * Open:
381  *****************************************************************************/
382 static int Open( vlc_object_t *p_this )
383 {
384     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
385     sout_stream_sys_t *p_sys;
386     vlc_value_t       val;
387
388     p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
389
390     p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
391     if( !p_sys->p_out )
392     {
393         msg_Err( p_stream, "cannot create chain" );
394         vlc_object_destroy( p_sys );
395         return VLC_EGENERIC;
396     }
397
398     p_sys->i_master_drift = 0;
399
400     sout_CfgParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
401                    p_stream->p_cfg );
402
403     /* Audio transcoding parameters */
404     var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
405     p_sys->psz_aenc = NULL;
406     p_sys->p_audio_cfg = NULL;
407     if( val.psz_string && *val.psz_string )
408     {
409         char *psz_next;
410         psz_next = sout_CfgCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
411                                    val.psz_string );
412         if( psz_next ) free( psz_next );
413     }
414     if( val.psz_string ) free( val.psz_string );
415
416     var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
417     p_sys->i_acodec = 0;
418     if( val.psz_string && *val.psz_string )
419     {
420         char fcc[4] = "    ";
421         memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
422         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
423     }
424     if( val.psz_string ) free( val.psz_string );
425
426     var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
427     p_sys->i_abitrate = val.i_int;
428     if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
429
430     var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
431     p_sys->i_sample_rate = val.i_int;
432
433     var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
434     p_sys->i_channels = val.i_int;
435
436     if( p_sys->i_acodec )
437     {
438         if( (strncmp( (char *)&p_sys->i_acodec, "mp3", 3) == 0) &&
439                             (p_sys->i_channels > 2) )
440         {
441             msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
442                       p_sys->i_channels );
443             p_sys->i_channels = 2;
444         }                    
445         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
446                  (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
447                  p_sys->i_channels, p_sys->i_abitrate / 1000 );
448     }
449
450     /* Video transcoding parameters */
451     var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
452     p_sys->psz_venc = NULL;
453     p_sys->p_video_cfg = NULL;
454     if( val.psz_string && *val.psz_string )
455     {
456         char *psz_next;
457         psz_next = sout_CfgCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
458                                    val.psz_string );
459         if( psz_next ) free( psz_next );
460     }
461     if( val.psz_string ) free( val.psz_string );
462
463     var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
464     p_sys->i_vcodec = 0;
465     if( val.psz_string && *val.psz_string )
466     {
467         char fcc[4] = "    ";
468         memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
469         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
470     }
471     if( val.psz_string ) free( val.psz_string );
472
473     var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
474     p_sys->i_vbitrate = val.i_int;
475     if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
476
477     var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
478     p_sys->f_scale = val.f_float;
479
480     var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val );
481     p_sys->f_fps = val.f_float;
482
483     var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val );
484     p_sys->b_hurry_up = val.b_bool;
485
486     var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
487     p_sys->i_width = val.i_int;
488
489     var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
490     p_sys->i_height = val.i_int;
491
492     var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
493     p_sys->i_vfilters = 0;
494     if( val.psz_string && *val.psz_string )
495     {
496         char *psz_parser = val.psz_string;
497
498         while( psz_parser != NULL && *psz_parser != '\0' )
499         {
500             psz_parser = sout_CfgCreate(
501                                    &p_sys->psz_vfilters[p_sys->i_vfilters],
502                                    &p_sys->p_vfilters_cfg[p_sys->i_vfilters],
503                                    psz_parser );
504             p_sys->i_vfilters++;
505             if( psz_parser != NULL && *psz_parser != '\0' ) psz_parser++;
506         }
507     }
508     if( val.psz_string ) free( val.psz_string );
509     p_sys->psz_vfilters[p_sys->i_vfilters] = NULL;
510     p_sys->p_vfilters_cfg[p_sys->i_vfilters] = NULL;
511
512     var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
513     p_sys->b_deinterlace = val.b_bool;
514
515     var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val );
516     p_sys->psz_deinterlace = NULL;
517     p_sys->p_deinterlace_cfg = NULL;
518     if( val.psz_string && *val.psz_string )
519     {
520         char *psz_next;
521         psz_next = sout_CfgCreate( &p_sys->psz_deinterlace,
522                                    &p_sys->p_deinterlace_cfg,
523                                    val.psz_string );
524         if( psz_next ) free( psz_next );
525     }
526     if( val.psz_string ) free( val.psz_string );
527
528     var_Get( p_stream, SOUT_CFG_PREFIX "croptop", &val );
529     p_sys->i_crop_top = val.i_int;
530     var_Get( p_stream, SOUT_CFG_PREFIX "cropbottom", &val );
531     p_sys->i_crop_bottom = val.i_int;
532     var_Get( p_stream, SOUT_CFG_PREFIX "cropleft", &val );
533     p_sys->i_crop_left = val.i_int;
534     var_Get( p_stream, SOUT_CFG_PREFIX "cropright", &val );
535     p_sys->i_crop_right = val.i_int;
536
537     var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
538     p_sys->i_threads = val.i_int;
539     var_Get( p_stream, SOUT_CFG_PREFIX "high-priority", &val );
540     p_sys->b_high_priority = val.b_bool;
541
542     if( p_sys->i_vcodec )
543     {
544         msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
545                  (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
546                  p_sys->f_scale, p_sys->i_vbitrate / 1000 );
547     }
548
549     /* Subpictures transcoding parameters */
550     p_sys->p_spu = NULL;
551     p_sys->psz_senc = NULL;
552     p_sys->p_spu_cfg = NULL;
553     p_sys->i_scodec = 0;
554
555     var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
556     if( val.psz_string && *val.psz_string )
557     {
558         char *psz_next;
559         psz_next = sout_CfgCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
560                                    val.psz_string );
561         if( psz_next ) free( psz_next );
562     }
563     if( val.psz_string ) free( val.psz_string );
564
565     var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
566     if( val.psz_string && *val.psz_string )
567     {
568         char fcc[4] = "    ";
569         memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
570         p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
571     }
572     if( val.psz_string ) free( val.psz_string );
573
574     if( p_sys->i_scodec )
575     {
576         msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
577     }
578
579     var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
580     p_sys->b_soverlay = val.b_bool;
581
582     var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val );
583     if( val.psz_string && *val.psz_string )
584     {
585         p_sys->p_spu = spu_Create( p_stream );
586         var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
587         var_Set( p_sys->p_spu, "sub-filter", val );
588         spu_Init( p_sys->p_spu );
589     }
590     if( val.psz_string ) free( val.psz_string );
591
592     /* OSD menu transcoding parameters */
593     p_sys->psz_osdenc = NULL;
594     p_sys->p_osd_cfg  = NULL;
595     p_sys->i_osdcodec = 0;
596     p_sys->b_es_osd   = VLC_FALSE;
597
598     var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
599     p_sys->b_sout_osd = val.b_bool;
600     if( p_sys->b_sout_osd )
601     {
602         vlc_value_t osd_val;
603         char *psz_next;
604        
605         psz_next = sout_CfgCreate( &p_sys->psz_osdenc,
606                                    &p_sys->p_osd_cfg, strdup( "dvbsub") );
607         if( psz_next ) free( psz_next );
608         
609         p_sys->i_osdcodec = VLC_FOURCC('Y','U','V','P' );        
610
611         msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
612
613         if( !p_sys->p_spu )
614         {
615             osd_val.psz_string = strdup("osdmenu");
616             p_sys->p_spu = spu_Create( p_stream );
617             var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
618             var_Set( p_sys->p_spu, "sub-filter", osd_val );
619             spu_Init( p_sys->p_spu );
620             if( osd_val.psz_string ) free( osd_val.psz_string );
621         }
622         else
623         {
624             osd_val.psz_string = strdup("osdmenu");
625             var_Set( p_sys->p_spu, "sub-filter", osd_val );
626             if( osd_val.psz_string ) free( osd_val.psz_string );
627         }         
628     }
629
630     /* Audio settings */
631     var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );
632     p_sys->b_master_sync = val.b_bool;
633     if( p_sys->f_fps > 0 ) p_sys->b_master_sync = VLC_TRUE;
634
635     p_stream->pf_add    = Add;
636     p_stream->pf_del    = Del;
637     p_stream->pf_send   = Send;
638     p_stream->p_sys     = p_sys;
639
640     return VLC_SUCCESS;
641 }
642
643 /*****************************************************************************
644  * Close:
645  *****************************************************************************/
646 static void Close( vlc_object_t * p_this )
647 {
648     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
649     sout_stream_sys_t   *p_sys = p_stream->p_sys;
650
651     sout_StreamDelete( p_sys->p_out );
652
653     while( p_sys->p_audio_cfg != NULL )
654     {
655         sout_cfg_t *p_next = p_sys->p_audio_cfg->p_next;
656
657         if( p_sys->p_audio_cfg->psz_name )
658             free( p_sys->p_audio_cfg->psz_name );
659         if( p_sys->p_audio_cfg->psz_value )
660             free( p_sys->p_audio_cfg->psz_value );
661         free( p_sys->p_audio_cfg );
662
663         p_sys->p_audio_cfg = p_next;
664     }
665     if( p_sys->psz_aenc ) free( p_sys->psz_aenc );
666
667     while( p_sys->p_video_cfg != NULL )
668     {
669         sout_cfg_t *p_next = p_sys->p_video_cfg->p_next;
670
671         if( p_sys->p_video_cfg->psz_name )
672             free( p_sys->p_video_cfg->psz_name );
673         if( p_sys->p_video_cfg->psz_value )
674             free( p_sys->p_video_cfg->psz_value );
675         free( p_sys->p_video_cfg );
676
677         p_sys->p_video_cfg = p_next;
678     }
679     if( p_sys->psz_venc ) free( p_sys->psz_venc );
680
681     while( p_sys->p_deinterlace_cfg != NULL )
682     {
683         sout_cfg_t *p_next = p_sys->p_deinterlace_cfg->p_next;
684
685         if( p_sys->p_deinterlace_cfg->psz_name )
686             free( p_sys->p_deinterlace_cfg->psz_name );
687         if( p_sys->p_deinterlace_cfg->psz_value )
688             free( p_sys->p_deinterlace_cfg->psz_value );
689         free( p_sys->p_deinterlace_cfg );
690
691         p_sys->p_deinterlace_cfg = p_next;
692     }
693     if( p_sys->psz_deinterlace ) free( p_sys->psz_deinterlace );
694
695     while( p_sys->p_spu_cfg != NULL )
696     {
697         sout_cfg_t *p_next = p_sys->p_spu_cfg->p_next;
698
699         if( p_sys->p_spu_cfg->psz_name )
700             free( p_sys->p_spu_cfg->psz_name );
701         if( p_sys->p_spu_cfg->psz_value )
702             free( p_sys->p_spu_cfg->psz_value );
703         free( p_sys->p_spu_cfg );
704
705         p_sys->p_spu_cfg = p_next;
706     }
707     if( p_sys->psz_senc ) free( p_sys->psz_senc );
708
709     if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
710     
711     while( p_sys->p_osd_cfg != NULL )
712     {
713         sout_cfg_t *p_next = p_sys->p_osd_cfg->p_next;
714
715         if( p_sys->p_osd_cfg->psz_name )
716             free( p_sys->p_osd_cfg->psz_name );
717         if( p_sys->p_osd_cfg->psz_value )
718             free( p_sys->p_osd_cfg->psz_value );
719         free( p_sys->p_osd_cfg );
720
721         p_sys->p_osd_cfg = p_next;
722     }
723     if( p_sys->psz_osdenc ) free( p_sys->psz_osdenc );    
724
725     vlc_object_destroy( p_sys );
726 }
727
728 struct sout_stream_id_t
729 {
730     vlc_fourcc_t  b_transcode;
731
732     /* id of the out stream */
733     void *id;
734
735     /* Decoder */
736     decoder_t       *p_decoder;
737
738     /* Filters */
739     filter_t        *pp_filter[10];
740     int             i_filter;
741     filter_t        *pp_vfilter[10];
742     int             i_vfilter;
743
744     /* Encoder */
745     encoder_t       *p_encoder;
746
747     /* Sync */
748     date_t          interpolated_pts;
749 };
750
751 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
752 {
753     sout_stream_sys_t *p_sys = p_stream->p_sys;
754     sout_stream_id_t *id;
755
756     id = malloc( sizeof( sout_stream_id_t ) );
757     memset( id, 0, sizeof(sout_stream_id_t) );
758
759     id->id = NULL;
760     id->p_decoder = NULL;
761     id->p_encoder = NULL;
762
763     /* Create decoder object */
764     id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
765     if( !id->p_decoder )
766     {
767         msg_Err( p_stream, "out of memory" );
768         goto error;
769     }
770     vlc_object_attach( id->p_decoder, p_stream );
771     id->p_decoder->p_module = NULL;
772     id->p_decoder->fmt_in = *p_fmt;
773     id->p_decoder->b_pace_control = VLC_TRUE;
774
775     /* Create encoder object */
776     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
777     if( !id->p_encoder )
778     {
779         msg_Err( p_stream, "out of memory" );
780         goto error;
781     }
782     vlc_object_attach( id->p_encoder, p_stream );
783     id->p_encoder->p_module = NULL;
784
785     /* Create destination format */
786     es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
787     id->p_encoder->fmt_out.i_id    = p_fmt->i_id;
788     id->p_encoder->fmt_out.i_group = p_fmt->i_group;
789     if( p_fmt->psz_language )
790         id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
791
792     if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
793     {
794         msg_Dbg( p_stream,
795                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
796                  (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
797
798         /* Complete destination format */
799         id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
800         id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
801             p_sys->i_sample_rate : (int)p_fmt->audio.i_rate;
802         id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
803         id->p_encoder->fmt_out.audio.i_bitspersample =
804             p_fmt->audio.i_bitspersample;
805         id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
806             p_sys->i_channels : p_fmt->audio.i_channels;
807         /* Sanity check for audio channels */
808         id->p_encoder->fmt_out.audio.i_channels =
809             __MIN( id->p_encoder->fmt_out.audio.i_channels,
810                    id->p_decoder->fmt_in.audio.i_channels );
811         id->p_encoder->fmt_out.audio.i_original_channels =
812             id->p_decoder->fmt_in.audio.i_physical_channels;
813         if( id->p_decoder->fmt_in.audio.i_channels ==
814             id->p_encoder->fmt_out.audio.i_channels )
815         {
816             id->p_encoder->fmt_out.audio.i_physical_channels =
817                 id->p_decoder->fmt_in.audio.i_physical_channels;
818         }
819         else
820         {
821             id->p_encoder->fmt_out.audio.i_physical_channels =
822                 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
823         }
824
825         /* Build decoder -> filter -> encoder chain */
826         if( transcode_audio_new( p_stream, id ) )
827         {
828             msg_Err( p_stream, "cannot create audio chain" );
829             goto error;
830         }
831
832         /* Open output stream */
833         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
834         id->b_transcode = VLC_TRUE;
835
836         if( !id->id ) goto error;
837
838         date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
839     }
840     else if( p_fmt->i_cat == VIDEO_ES &&
841              (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
842     {
843         msg_Dbg( p_stream,
844                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
845                  (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
846
847         /* Complete destination format */
848         id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
849         id->p_encoder->fmt_out.video.i_width  = p_sys->i_width;
850         id->p_encoder->fmt_out.video.i_height = p_sys->i_height;
851         id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
852
853         /* Build decoder -> filter -> encoder chain */
854         if( transcode_video_new( p_stream, id ) )
855         {
856             msg_Err( p_stream, "cannot create video chain" );
857             goto error;
858         }
859
860         /* Stream will be added later on because we don't know
861          * all the characteristics of the decoded stream yet */
862         id->b_transcode = VLC_TRUE;
863
864         if( p_sys->f_fps > 0 )
865         {
866             id->p_encoder->fmt_out.video.i_frame_rate =
867                 (p_sys->f_fps * 1001) + 0.5;
868             id->p_encoder->fmt_out.video.i_frame_rate_base = 1001;
869         }
870     }
871     else if( p_fmt->i_cat == SPU_ES && (p_sys->i_scodec || p_sys->psz_senc) )
872     {
873         msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
874                  "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
875                  (char*)&p_sys->i_scodec );
876
877         /* Complete destination format */
878         id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
879
880         /* build decoder -> filter -> encoder */
881         if( transcode_spu_new( p_stream, id ) )
882         {
883             msg_Err( p_stream, "cannot create subtitles chain" );
884             goto error;
885         }
886
887         /* open output stream */
888         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
889         id->b_transcode = VLC_TRUE;
890
891         if( !id->id ) goto error;
892     }
893     else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
894     {
895         msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
896                  (char*)&p_fmt->i_codec );
897
898         id->b_transcode = VLC_TRUE;
899
900         /* Build decoder -> filter -> overlaying chain */
901         if( transcode_spu_new( p_stream, id ) )
902         {
903             msg_Err( p_stream, "cannot create subtitles chain" );
904             goto error;
905         }
906     }
907     else
908     {
909         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
910                  (char*)&p_fmt->i_codec );
911         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
912         id->b_transcode = VLC_FALSE;
913
914         if( !id->id ) goto error;
915     }
916
917     if( p_sys->b_sout_osd )
918     {
919         /* Create a fake OSD menu elementary stream */
920         if( !p_sys->b_es_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
921         {
922             if( transcode_osd_new( p_stream, p_sys->id_osd ) )
923             {
924                 msg_Err( p_stream, "cannot create osd chain" );
925                 goto error;
926             }
927             p_sys->b_es_osd = VLC_TRUE;
928         }
929     }
930     return id;
931
932  error:
933     if( id->p_decoder )
934     {
935         vlc_object_detach( id->p_decoder );
936         vlc_object_destroy( id->p_decoder );
937     }
938
939     if( id->p_encoder )
940     {
941         vlc_object_detach( id->p_encoder );
942         vlc_object_destroy( id->p_encoder );
943     }
944
945     free( id );
946     return NULL;
947 }
948
949 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
950 {
951     sout_stream_sys_t *p_sys = p_stream->p_sys;
952
953     if( p_sys->b_es_osd )
954         transcode_osd_close( p_stream, p_sys->id_osd );
955
956     if( id->b_transcode )
957     {
958         switch( id->p_decoder->fmt_in.i_cat )
959         {
960         case AUDIO_ES:
961             transcode_audio_close( p_stream, id );
962             break;
963         case VIDEO_ES:
964             transcode_video_close( p_stream, id );
965             break;
966         case SPU_ES:
967             transcode_spu_close( p_stream, id );
968             break;
969         }
970     }
971
972     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
973
974     if( id->p_decoder )
975     {
976         vlc_object_detach( id->p_decoder );
977         vlc_object_destroy( id->p_decoder );
978     }
979
980     if( id->p_encoder )
981     {
982         vlc_object_detach( id->p_encoder );
983         vlc_object_destroy( id->p_encoder );
984     }
985
986     free( id );
987
988     return VLC_SUCCESS;
989 }
990
991 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
992                  block_t *p_buffer )
993 {
994     sout_stream_sys_t *p_sys = p_stream->p_sys;
995     block_t *p_out = NULL;
996
997     if( !id->b_transcode && id->id )
998     {
999         /* Transcode OSD menu pictures. */
1000         if( p_sys->b_es_osd )
1001         {
1002             transcode_osd_process( p_stream, id, p_buffer, &p_out );                
1003         }
1004         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
1005     }
1006     else if( !id->b_transcode )
1007     {
1008         block_Release( p_buffer );
1009         return VLC_EGENERIC;
1010     }
1011
1012     switch( id->p_decoder->fmt_in.i_cat )
1013     {
1014     case AUDIO_ES:
1015         transcode_audio_process( p_stream, id, p_buffer, &p_out );
1016         break;
1017
1018     case VIDEO_ES:
1019         if( transcode_video_process( p_stream, id, p_buffer, &p_out )
1020             != VLC_SUCCESS )
1021         {
1022             return VLC_EGENERIC;
1023         }
1024         break;
1025
1026     case SPU_ES:
1027         if( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
1028             VLC_SUCCESS )
1029         {
1030             return VLC_EGENERIC;
1031         }
1032         break;
1033
1034     default:
1035         p_out = NULL;
1036         block_Release( p_buffer );
1037         break;
1038     }
1039
1040     if( p_out ) return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_out );
1041     return VLC_SUCCESS;
1042 }
1043
1044 /****************************************************************************
1045  * decoder reencoder part
1046  ****************************************************************************/
1047 int audio_BitsPerSample( vlc_fourcc_t i_format )
1048 {
1049     switch( i_format )
1050     {
1051     case VLC_FOURCC('u','8',' ',' '):
1052     case VLC_FOURCC('s','8',' ',' '):
1053         return 8;
1054
1055     case VLC_FOURCC('u','1','6','l'):
1056     case VLC_FOURCC('s','1','6','l'):
1057     case VLC_FOURCC('u','1','6','b'):
1058     case VLC_FOURCC('s','1','6','b'):
1059         return 16;
1060
1061     case VLC_FOURCC('u','2','4','l'):
1062     case VLC_FOURCC('s','2','4','l'):
1063     case VLC_FOURCC('u','2','4','b'):
1064     case VLC_FOURCC('s','2','4','b'):
1065         return 24;
1066
1067     case VLC_FOURCC('u','3','2','l'):
1068     case VLC_FOURCC('s','3','2','l'):
1069     case VLC_FOURCC('u','3','2','b'):
1070     case VLC_FOURCC('s','3','2','b'):
1071     case VLC_FOURCC('f','l','3','2'):
1072     case VLC_FOURCC('f','i','3','2'):
1073         return 32;
1074
1075     case VLC_FOURCC('f','l','6','4'):
1076         return 64;
1077     }
1078
1079     return 0;
1080 }
1081
1082 static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream,
1083                                              sout_stream_id_t *id,
1084                                              es_format_t *p_fmt_in,
1085                                              es_format_t *p_fmt_out )
1086 {
1087     filter_t *p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1088
1089     vlc_object_attach( p_filter, p_stream );
1090     p_filter->pf_audio_buffer_new = (block_t* (*) (filter_t*, int))__block_New;
1091
1092     p_filter->fmt_in = *p_fmt_in;
1093     p_filter->fmt_out = *p_fmt_out;
1094
1095     p_filter->p_module = module_Need( p_filter, "audio filter2", 0, 0 );
1096     if( p_filter->p_module )
1097     {
1098         p_filter->fmt_out.audio.i_bitspersample = 
1099             audio_BitsPerSample( p_filter->fmt_out.i_codec );
1100         *p_fmt_in = p_filter->fmt_out;
1101     }
1102     else
1103     {
1104         vlc_object_detach( p_filter );
1105         vlc_object_destroy( p_filter );
1106         p_filter = 0;
1107     }
1108
1109     return p_filter;
1110 }
1111
1112 static int transcode_audio_new( sout_stream_t *p_stream,
1113                                 sout_stream_id_t *id )
1114 {
1115     sout_stream_sys_t *p_sys = p_stream->p_sys;
1116     es_format_t fmt_last;
1117     int i_pass = 6;
1118
1119     /*
1120      * Open decoder
1121      */
1122
1123     /* Initialization of decoder structures */
1124     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1125     id->p_decoder->fmt_out.i_extra = 0;
1126     id->p_decoder->fmt_out.p_extra = 0;
1127     id->p_decoder->pf_decode_audio = 0;
1128     id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1129     id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1130     /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1131
1132     id->p_decoder->p_module =
1133         module_Need( id->p_decoder, "decoder", "$codec", 0 );
1134
1135     if( !id->p_decoder->p_module )
1136     {
1137         msg_Err( p_stream, "cannot find decoder" );
1138         return VLC_EGENERIC;
1139     }
1140     id->p_decoder->fmt_out.audio.i_bitspersample = 
1141         audio_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1142     fmt_last = id->p_decoder->fmt_out;
1143     /* FIX decoders so we don't have to do this */
1144     fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1145
1146     /*
1147      * Open encoder
1148      */
1149
1150     /* Initialization of encoder format structures */
1151     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1152                     id->p_decoder->fmt_out.i_codec );
1153     id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1154
1155     /* Initialization of encoder format structures */
1156     es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, AOUT_FMT_S16_NE );
1157     id->p_encoder->fmt_in.audio.i_format = AOUT_FMT_S16_NE;
1158     id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1159     id->p_encoder->fmt_in.audio.i_physical_channels =
1160         id->p_encoder->fmt_out.audio.i_physical_channels;
1161     id->p_encoder->fmt_in.audio.i_original_channels =
1162         id->p_encoder->fmt_out.audio.i_original_channels;
1163     id->p_encoder->fmt_in.audio.i_channels =
1164         id->p_encoder->fmt_out.audio.i_channels;
1165     id->p_encoder->fmt_in.audio.i_bitspersample =
1166         audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1167
1168     id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1169
1170     id->p_encoder->p_module =
1171         module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, VLC_TRUE );
1172     if( !id->p_encoder->p_module )
1173     {
1174         msg_Err( p_stream, "cannot find encoder" );
1175         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1176         id->p_decoder->p_module = 0;
1177         return VLC_EGENERIC;
1178     }
1179     id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1180     id->p_encoder->fmt_in.audio.i_bitspersample =
1181         audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1182
1183     /* Load conversion filters */
1184     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1185         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1186     {
1187         /* We'll have to go through fl32 first */
1188         es_format_t fmt_out = id->p_encoder->fmt_in;
1189         fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2');
1190
1191         id->pp_filter[id->i_filter] =
1192             transcode_audio_filter_new( p_stream, id, &fmt_last, &fmt_out );
1193
1194         if( id->pp_filter[id->i_filter] ) id->i_filter++;
1195     }
1196
1197     while( i_pass-- )
1198     {
1199         if( fmt_last.audio.i_channels !=
1200             id->p_encoder->fmt_in.audio.i_channels ||
1201             fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate ||
1202             fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1203         {
1204             id->pp_filter[id->i_filter] =
1205                 transcode_audio_filter_new( p_stream, id, &fmt_last,
1206                                             &id->p_encoder->fmt_in );
1207
1208             if( id->pp_filter[id->i_filter] ) id->i_filter++;
1209             else break;
1210         }
1211     }
1212
1213     /* Final checks to see if conversions were successful */
1214     if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1215     {
1216         msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1217                  (char *)&fmt_last.i_codec,
1218                  (char *)&id->p_encoder->fmt_in.i_codec );
1219         transcode_audio_close( p_stream, id );
1220         return VLC_EGENERIC;
1221     }
1222
1223     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1224     {
1225         msg_Err( p_stream, "no audio filter found for mixing from"
1226                  " %i to %i channels", fmt_last.audio.i_channels,
1227                  id->p_encoder->fmt_in.audio.i_channels );
1228 #if 0
1229         /* FIXME : this might work, but only if the encoder is restarted */
1230         id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1231         id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1232
1233         id->p_encoder->fmt_in.audio.i_physical_channels =
1234             id->p_encoder->fmt_in.audio.i_original_channels =
1235                 fmt_last.audio.i_physical_channels;
1236         id->p_encoder->fmt_out.audio.i_physical_channels =
1237             id->p_encoder->fmt_out.audio.i_original_channels =
1238                 fmt_last.audio.i_physical_channels;
1239 #else
1240         transcode_audio_close( p_stream, id );
1241         return VLC_EGENERIC;
1242 #endif
1243     }
1244
1245     if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1246     {
1247         msg_Err( p_stream, "no audio filter found for resampling from"
1248                  " %iHz to %iHz", fmt_last.audio.i_rate,
1249                  id->p_encoder->fmt_in.audio.i_rate );
1250 #if 0
1251         /* FIXME : this might work, but only if the encoder is restarted */
1252         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1253         id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1254 #else
1255         transcode_audio_close( p_stream, id );
1256         return VLC_EGENERIC;
1257 #endif
1258     }
1259
1260     /* FIXME: Hack for mp3 transcoding support */
1261     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1262         id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1263
1264     return VLC_SUCCESS;
1265 }
1266
1267 static void transcode_audio_close( sout_stream_t *p_stream,
1268                                    sout_stream_id_t *id )
1269 {
1270     int i;
1271
1272     /* Close decoder */
1273     if( id->p_decoder->p_module )
1274         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1275     id->p_decoder->p_module = 0;
1276
1277     /* Close encoder */
1278     if( id->p_encoder->p_module )
1279         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1280     id->p_encoder->p_module = 0;
1281
1282     /* Close filters */
1283     for( i = 0; i < id->i_filter; i++ )
1284     {
1285         vlc_object_detach( id->pp_filter[i] );
1286         if( id->pp_filter[i]->p_module )
1287             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
1288         vlc_object_destroy( id->pp_filter[i] );
1289     }
1290 }
1291
1292 static int transcode_audio_process( sout_stream_t *p_stream,
1293                                     sout_stream_id_t *id,
1294                                     block_t *in, block_t **out )
1295 {
1296     sout_stream_sys_t *p_sys = p_stream->p_sys;
1297     aout_buffer_t *p_audio_buf;
1298     block_t *p_block, *p_audio_block;
1299     int i;
1300     *out = NULL;
1301
1302     while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1303                                                           &in )) )
1304     {
1305         if( p_sys->b_master_sync )
1306         {
1307             mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1308             if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1309                   || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1310             {
1311                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1312                 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1313                 i_dts = p_audio_buf->start_date + 1;
1314             }
1315             p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1316             date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1317             p_audio_buf->start_date -= p_sys->i_master_drift;
1318             p_audio_buf->end_date -= p_sys->i_master_drift;
1319         }
1320
1321         p_audio_block = p_audio_buf->p_sys;
1322         p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1323         p_audio_block->i_dts = p_audio_block->i_pts =
1324             p_audio_buf->start_date;
1325         p_audio_block->i_length = p_audio_buf->end_date -
1326             p_audio_buf->start_date;
1327         p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1328
1329         /* Run filter chain */
1330         for( i = 0; i < id->i_filter; i++ )
1331         {
1332             p_audio_block =
1333                 id->pp_filter[i]->pf_audio_filter( id->pp_filter[i],
1334                                                    p_audio_block );
1335         }
1336
1337         p_audio_buf->p_buffer = p_audio_block->p_buffer;
1338         p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1339         p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1340         p_audio_buf->start_date = p_audio_block->i_dts;
1341         p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1342
1343         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1344         block_ChainAppend( out, p_block );
1345         block_Release( p_audio_block );
1346         free( p_audio_buf );
1347     }
1348
1349     return VLC_SUCCESS;
1350 }
1351
1352 static void audio_release_buffer( aout_buffer_t *p_buffer )
1353 {
1354     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1355     if( p_buffer ) free( p_buffer );
1356 }
1357
1358 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1359 {
1360     aout_buffer_t *p_buffer;
1361     block_t *p_block;
1362     int i_size;
1363
1364     if( p_dec->fmt_out.audio.i_bitspersample )
1365     {
1366         i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1367             p_dec->fmt_out.audio.i_channels;
1368     }
1369     else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1370              p_dec->fmt_out.audio.i_frame_length )
1371     {
1372         i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1373             p_dec->fmt_out.audio.i_frame_length;
1374     }
1375     else
1376     {
1377         i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1378     }
1379
1380     p_buffer = malloc( sizeof(aout_buffer_t) );
1381     p_buffer->pf_release = audio_release_buffer;
1382     p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1383
1384     p_buffer->p_buffer = p_block->p_buffer;
1385     p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1386     p_buffer->i_nb_samples = i_samples;
1387     p_block->i_samples = i_samples;
1388
1389     return p_buffer;
1390 }
1391
1392 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1393 {
1394     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1395     if( p_buffer ) free( p_buffer );
1396 }
1397
1398 /*
1399  * video
1400  */
1401 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1402 {
1403     sout_stream_sys_t *p_sys = p_stream->p_sys;
1404     int i;
1405
1406     /*
1407      * Open decoder
1408      */
1409
1410     /* Initialization of decoder structures */
1411     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1412     id->p_decoder->fmt_out.i_extra = 0;
1413     id->p_decoder->fmt_out.p_extra = 0;
1414     id->p_decoder->pf_decode_video = 0;
1415     id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1416     id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1417     id->p_decoder->pf_picture_link    = video_link_picture_decoder;
1418     id->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder;
1419     id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1420     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1421         id->p_decoder->p_owner->pp_pics[i] = 0;
1422     id->p_decoder->p_owner->p_sys = p_sys;
1423     /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1424
1425     id->p_decoder->p_module =
1426         module_Need( id->p_decoder, "decoder", "$codec", 0 );
1427
1428     if( !id->p_decoder->p_module )
1429     {
1430         msg_Err( p_stream, "cannot find decoder" );
1431         return VLC_EGENERIC;
1432     }
1433
1434     /*
1435      * Open encoder.
1436      * Because some info about the decoded input will only be available
1437      * once the first frame is decoded, we actually only test the availability
1438      * of the encoder here.
1439      */
1440
1441     /* Initialization of encoder format structures */
1442     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1443                     id->p_decoder->fmt_out.i_codec );
1444     id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1445
1446     /* The dimensions will be set properly later on.
1447      * Just put sensible values so we can test an encoder is available. */
1448     id->p_encoder->fmt_in.video.i_width =
1449         id->p_encoder->fmt_out.video.i_width ?
1450         id->p_encoder->fmt_out.video.i_width :
1451         id->p_decoder->fmt_in.video.i_width ?
1452         id->p_decoder->fmt_in.video.i_width : 16;
1453     id->p_encoder->fmt_in.video.i_height =
1454         id->p_encoder->fmt_out.video.i_height ?
1455         id->p_encoder->fmt_out.video.i_height :
1456         id->p_decoder->fmt_in.video.i_height ?
1457         id->p_decoder->fmt_in.video.i_height : 16;
1458     id->p_encoder->fmt_in.video.i_frame_rate = 25;
1459     id->p_encoder->fmt_in.video.i_frame_rate_base = 1;
1460
1461     id->p_encoder->i_threads = p_sys->i_threads;
1462     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1463
1464     id->p_encoder->p_module =
1465         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, VLC_TRUE );
1466     if( !id->p_encoder->p_module )
1467     {
1468         msg_Err( p_stream, "cannot find encoder" );
1469         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1470         id->p_decoder->p_module = 0;
1471         return VLC_EGENERIC;
1472     }
1473
1474     /* Close the encoder.
1475      * We'll open it only when we have the first frame. */
1476     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1477     id->p_encoder->p_module = NULL;
1478
1479     if( p_sys->i_threads >= 1 )
1480     {
1481         int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1482                            VLC_THREAD_PRIORITY_VIDEO;
1483         p_sys->id_video = id;
1484         vlc_mutex_init( p_stream, &p_sys->lock_out );
1485         vlc_cond_init( p_stream, &p_sys->cond );
1486         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1487         p_sys->i_first_pic = 0;
1488         p_sys->i_last_pic = 0;
1489         p_sys->p_buffers = NULL;
1490         p_sys->b_die = p_sys->b_error = 0;
1491         if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1492                                VLC_FALSE ) )
1493         {
1494             msg_Err( p_stream, "cannot spawn encoder thread" );
1495             module_Unneed( id->p_decoder, id->p_decoder->p_module );
1496             id->p_decoder->p_module = 0;
1497             return VLC_EGENERIC;
1498         }
1499     }
1500
1501     return VLC_SUCCESS;
1502 }
1503
1504 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1505                                          sout_stream_id_t *id )
1506 {
1507     sout_stream_sys_t *p_sys = p_stream->p_sys;
1508
1509     /* Hack because of the copy packetizer which can fail to detect the
1510      * proper size (which forces us to wait until the 1st frame
1511      * is decoded) */
1512     int i_width = id->p_decoder->fmt_out.video.i_width -
1513         p_sys->i_crop_left - p_sys->i_crop_right;
1514     int i_height = id->p_decoder->fmt_out.video.i_height -
1515         p_sys->i_crop_top - p_sys->i_crop_bottom;
1516
1517     if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1518         id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1519     {
1520         /* Apply the scaling */
1521         id->p_encoder->fmt_out.video.i_width = i_width * p_sys->f_scale;
1522         id->p_encoder->fmt_out.video.i_height = i_height * p_sys->f_scale;
1523     }
1524     else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1525              id->p_encoder->fmt_out.video.i_height <= 0 )
1526     {
1527         id->p_encoder->fmt_out.video.i_height =
1528             id->p_encoder->fmt_out.video.i_width / (double)i_width * i_height;
1529     }
1530     else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1531              id->p_encoder->fmt_out.video.i_height > 0 )
1532     {
1533         id->p_encoder->fmt_out.video.i_width =
1534             id->p_encoder->fmt_out.video.i_height / (double)i_height * i_width;
1535     }
1536
1537     /* Make sure the size is at least a multiple of 2 */
1538     id->p_encoder->fmt_out.video.i_width =
1539         (id->p_encoder->fmt_out.video.i_width + 1) >> 1 << 1;
1540     id->p_encoder->fmt_out.video.i_height =
1541         (id->p_encoder->fmt_out.video.i_height + 1) >> 1 << 1;
1542
1543     id->p_encoder->fmt_in.video.i_width =
1544         id->p_encoder->fmt_out.video.i_width;
1545     id->p_encoder->fmt_in.video.i_height =
1546         id->p_encoder->fmt_out.video.i_height;
1547
1548     if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1549         !id->p_encoder->fmt_out.video.i_frame_rate_base )
1550     {
1551         if( id->p_decoder->fmt_out.video.i_frame_rate &&
1552             id->p_decoder->fmt_out.video.i_frame_rate_base )
1553         {
1554             id->p_encoder->fmt_out.video.i_frame_rate =
1555                 id->p_decoder->fmt_out.video.i_frame_rate;
1556             id->p_encoder->fmt_out.video.i_frame_rate_base =
1557                 id->p_decoder->fmt_out.video.i_frame_rate_base;
1558         }
1559         else
1560         {
1561             /* Pick a sensible default value */
1562             id->p_encoder->fmt_out.video.i_frame_rate = 25;
1563             id->p_encoder->fmt_out.video.i_frame_rate_base = 1;
1564         }
1565     }
1566
1567     id->p_encoder->fmt_in.video.i_frame_rate =
1568         id->p_encoder->fmt_out.video.i_frame_rate;
1569     id->p_encoder->fmt_in.video.i_frame_rate_base =
1570         id->p_encoder->fmt_out.video.i_frame_rate_base;
1571
1572     date_Init( &id->interpolated_pts,
1573                id->p_encoder->fmt_out.video.i_frame_rate,
1574                id->p_encoder->fmt_out.video.i_frame_rate_base );
1575
1576     /* Check whether a particular aspect ratio was requested */
1577     if( !id->p_encoder->fmt_out.video.i_aspect )
1578     {
1579         id->p_encoder->fmt_out.video.i_aspect =
1580             id->p_decoder->fmt_out.video.i_aspect;
1581     }
1582     id->p_encoder->fmt_in.video.i_aspect =
1583         id->p_encoder->fmt_out.video.i_aspect;
1584
1585     id->p_encoder->p_module =
1586         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, VLC_TRUE );
1587     if( !id->p_encoder->p_module )
1588     {
1589         msg_Err( p_stream, "cannot find encoder" );
1590         return VLC_EGENERIC;
1591     }
1592
1593     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1594
1595     /* Hack for mp2v/mp1v transcoding support */
1596     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1597         id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1598     {
1599         id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1600     }
1601
1602     id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1603                                              &id->p_encoder->fmt_out );
1604     if( !id->id )
1605     {
1606         msg_Err( p_stream, "cannot add this stream" );
1607         return VLC_EGENERIC;
1608     }
1609
1610     return VLC_SUCCESS;
1611 }
1612
1613 static void transcode_video_close( sout_stream_t *p_stream,
1614                                    sout_stream_id_t *id )
1615 {
1616     int i, j;
1617
1618     if( p_stream->p_sys->i_threads >= 1 )
1619     {
1620         vlc_mutex_lock( &p_stream->p_sys->lock_out );
1621         p_stream->p_sys->b_die = 1;
1622         vlc_cond_signal( &p_stream->p_sys->cond );
1623         vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1624         vlc_thread_join( p_stream->p_sys );
1625         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1626         vlc_cond_destroy( &p_stream->p_sys->cond );
1627     }
1628
1629     /* Close decoder */
1630     if( id->p_decoder->p_module )
1631         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1632
1633     if( id->p_decoder->p_owner )
1634     {
1635         /* Clean-up pictures ring buffer */
1636         for( i = 0; i < PICTURE_RING_SIZE; i++ )
1637         {
1638             if( id->p_decoder->p_owner->pp_pics[i] )
1639                 video_del_buffer( VLC_OBJECT(id->p_decoder),
1640                                   id->p_decoder->p_owner->pp_pics[i] );
1641         }
1642         free( id->p_decoder->p_owner );
1643     }
1644
1645     /* Close encoder */
1646     if( id->p_encoder->p_module )
1647         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1648
1649     /* Close filters */
1650     for( i = 0; i < id->i_filter; i++ )
1651     {
1652         vlc_object_detach( id->pp_filter[i] );
1653         if( id->pp_filter[i]->p_module )
1654             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
1655
1656         /* Clean-up pictures ring buffer */
1657         for( j = 0; j < PICTURE_RING_SIZE; j++ )
1658         {
1659             if( id->pp_filter[i]->p_owner->pp_pics[j] )
1660                 video_del_buffer( VLC_OBJECT(id->pp_filter[i]),
1661                                   id->pp_filter[i]->p_owner->pp_pics[j] );
1662         }
1663         free( id->pp_filter[i]->p_owner );
1664
1665         vlc_object_destroy( id->pp_filter[i] );
1666     }
1667     for( i = 0; i < id->i_vfilter; i++ )
1668     {
1669         vlc_object_detach( id->pp_vfilter[i] );
1670         if( id->pp_vfilter[i]->p_module )
1671             module_Unneed( id->pp_vfilter[i], id->pp_vfilter[i]->p_module );
1672
1673         /* Clean-up pictures ring buffer */
1674         for( j = 0; j < PICTURE_RING_SIZE; j++ )
1675         {
1676             if( id->pp_vfilter[i]->p_owner->pp_pics[j] )
1677                 video_del_buffer( VLC_OBJECT(id->pp_vfilter[i]),
1678                                   id->pp_vfilter[i]->p_owner->pp_pics[j] );
1679         }
1680         free( id->pp_vfilter[i]->p_owner );
1681
1682         vlc_object_destroy( id->pp_vfilter[i] );
1683     }
1684 }
1685
1686 static int transcode_video_process( sout_stream_t *p_stream,
1687                                     sout_stream_id_t *id,
1688                                     block_t *in, block_t **out )
1689 {
1690     sout_stream_sys_t *p_sys = p_stream->p_sys;
1691     int i_duplicate = 1, i;
1692     picture_t *p_pic;
1693     *out = NULL;
1694
1695     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1696     {
1697         subpicture_t *p_subpic = 0;
1698
1699         if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1700         {
1701             mtime_t current_date = mdate();
1702             if( current_date + 50000 > p_pic->date )
1703             {
1704                 msg_Dbg( p_stream, "late picture skipped ("I64Fd")",
1705                          current_date + 50000 - p_pic->date );
1706                 p_pic->pf_release( p_pic );
1707                 continue;
1708             }
1709         }
1710
1711         if( p_sys->b_master_sync )
1712         {
1713             mtime_t i_video_drift;
1714             mtime_t i_master_drift = p_sys->i_master_drift;
1715             mtime_t i_pts;
1716
1717             i_pts = date_Get( &id->interpolated_pts ) + 1;
1718             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1719                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1720             {
1721                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1722                 date_Set( &id->interpolated_pts, p_pic->date );
1723                 i_pts = p_pic->date + 1;
1724             }
1725             i_video_drift = p_pic->date - i_pts;
1726             i_duplicate = 1;
1727
1728             /* Set the pts of the frame being encoded */
1729             p_pic->date = i_pts;
1730
1731             if( i_video_drift < i_master_drift - 50000 )
1732             {
1733 #if 0
1734                 msg_Dbg( p_stream, "dropping frame (%i)",
1735                          (int)(i_video_drift - i_master_drift) );
1736 #endif
1737                 p_pic->pf_release( p_pic );
1738                 continue;
1739             }
1740             else if( i_video_drift > i_master_drift + 50000 )
1741             {
1742 #if 0
1743                 msg_Dbg( p_stream, "adding frame (%i)",
1744                          (int)(i_video_drift - i_master_drift) );
1745 #endif
1746                 i_duplicate = 2;
1747             }
1748         }
1749
1750         if( !id->p_encoder->p_module )
1751         {
1752             if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1753             {
1754                 p_pic->pf_release( p_pic );
1755                 transcode_video_close( p_stream, id );
1756                 id->b_transcode = VLC_FALSE;
1757                 return VLC_EGENERIC;
1758             }
1759
1760             /* Deinterlace */
1761             if( p_stream->p_sys->b_deinterlace )
1762             {
1763                 id->pp_filter[id->i_filter] =
1764                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1765                 vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
1766
1767                 id->pp_filter[id->i_filter]->pf_vout_buffer_new =
1768                     video_new_buffer_filter;
1769                 id->pp_filter[id->i_filter]->pf_vout_buffer_del =
1770                     video_del_buffer_filter;
1771
1772                 id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
1773                 id->pp_filter[id->i_filter]->fmt_out = id->p_decoder->fmt_out;
1774                 id->pp_filter[id->i_filter]->p_cfg = p_sys->p_deinterlace_cfg;
1775                 id->pp_filter[id->i_filter]->p_module =
1776                     module_Need( id->pp_filter[id->i_filter],
1777                                  "video filter2", p_sys->psz_deinterlace, 0 );
1778                 if( id->pp_filter[id->i_filter]->p_module )
1779                 {
1780                     id->pp_filter[id->i_filter]->p_owner =
1781                         malloc( sizeof(filter_owner_sys_t) );
1782                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1783                         id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
1784                     id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;
1785
1786                     id->i_filter++;
1787                 }
1788                 else
1789                 {
1790                     msg_Dbg( p_stream, "no video filter found" );
1791                     vlc_object_detach( id->pp_filter[id->i_filter] );
1792                     vlc_object_destroy( id->pp_filter[id->i_filter] );
1793                 }
1794             }
1795
1796             /* Check if we need a filter for chroma conversion or resizing */
1797             if( id->p_decoder->fmt_out.video.i_chroma !=
1798                 id->p_encoder->fmt_in.video.i_chroma ||
1799                 id->p_decoder->fmt_out.video.i_width !=
1800                 id->p_encoder->fmt_out.video.i_width ||
1801                 id->p_decoder->fmt_out.video.i_height !=
1802                 id->p_encoder->fmt_out.video.i_height ||
1803                 p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1804                 p_sys->i_crop_left > 0 || p_sys->i_crop_right > 0 )
1805             {
1806                 id->pp_filter[id->i_filter] =
1807                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1808                 vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
1809
1810                 id->pp_filter[id->i_filter]->pf_vout_buffer_new =
1811                     video_new_buffer_filter;
1812                 id->pp_filter[id->i_filter]->pf_vout_buffer_del =
1813                     video_del_buffer_filter;
1814
1815                 id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
1816                 id->pp_filter[id->i_filter]->fmt_out = id->p_encoder->fmt_in;
1817                 id->pp_filter[id->i_filter]->p_cfg = NULL;
1818                 id->pp_filter[id->i_filter]->p_module =
1819                     module_Need( id->pp_filter[id->i_filter],
1820                                  "video filter2", 0, 0 );
1821                 if( id->pp_filter[id->i_filter]->p_module )
1822                 {
1823                     id->pp_filter[id->i_filter]->p_owner =
1824                         malloc( sizeof(filter_owner_sys_t) );
1825                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1826                         id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
1827                     id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;
1828
1829                     id->i_filter++;
1830                 }
1831                 else
1832                 {
1833                     msg_Dbg( p_stream, "no video filter found" );
1834                     vlc_object_detach( id->pp_filter[id->i_filter] );
1835                     vlc_object_destroy( id->pp_filter[id->i_filter] );
1836
1837                     p_pic->pf_release( p_pic );
1838                     transcode_video_close( p_stream, id );
1839                     id->b_transcode = VLC_FALSE;
1840                     return VLC_EGENERIC;
1841                 }
1842             }
1843
1844             for( i = 0; i < p_sys->i_vfilters; i++ )
1845             {
1846                 id->pp_vfilter[id->i_vfilter] =
1847                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1848                 vlc_object_attach( id->pp_vfilter[id->i_vfilter], p_stream );
1849
1850                 id->pp_vfilter[id->i_vfilter]->pf_vout_buffer_new =
1851                     video_new_buffer_filter;
1852                 id->pp_vfilter[id->i_vfilter]->pf_vout_buffer_del =
1853                     video_del_buffer_filter;
1854
1855                 id->pp_vfilter[id->i_vfilter]->fmt_in = id->p_encoder->fmt_in;
1856                 id->pp_vfilter[id->i_vfilter]->fmt_out = id->p_encoder->fmt_in;
1857                 id->pp_vfilter[id->i_vfilter]->p_cfg = p_sys->p_vfilters_cfg[i];
1858                 id->pp_vfilter[id->i_vfilter]->p_module =
1859                     module_Need( id->pp_vfilter[id->i_vfilter],
1860                           "video filter2", p_sys->psz_vfilters[i], 0 );
1861                 if( id->pp_vfilter[id->i_vfilter]->p_module )
1862                 {
1863                     id->pp_vfilter[id->i_vfilter]->p_owner =
1864                         malloc( sizeof(filter_owner_sys_t) );
1865                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1866                         id->pp_vfilter[id->i_vfilter]->p_owner->pp_pics[i] = 0;
1867                     id->pp_vfilter[id->i_vfilter]->p_owner->p_sys = p_sys;
1868
1869                     id->i_vfilter++;
1870                 }
1871                 else
1872                 {
1873                     msg_Dbg( p_stream, "no video filter found" );
1874                     vlc_object_detach( id->pp_vfilter[id->i_vfilter] );
1875                     vlc_object_destroy( id->pp_vfilter[id->i_vfilter] );
1876                 }
1877             }
1878         }
1879
1880         /* Run filter chain */
1881         for( i = 0; i < id->i_filter; i++ )
1882         {
1883             p_pic = id->pp_filter[i]->pf_video_filter(id->pp_filter[i], p_pic);
1884         }
1885
1886         /*
1887          * Encoding
1888          */
1889
1890         /* Check if we have a subpicture to overlay */
1891         if( p_sys->p_spu )
1892         {
1893             p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date );
1894             /* TODO: get another pic */
1895         }
1896
1897         /* Overlay subpicture */
1898         if( p_subpic )
1899         {
1900             int i_scale_width, i_scale_height;
1901             video_format_t *p_fmt;
1902
1903             i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1904                 id->p_decoder->fmt_out.video.i_width;
1905             i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1906                 id->p_decoder->fmt_out.video.i_height;
1907
1908             if( p_pic->i_refcount && !id->i_filter )
1909             {
1910                 /* We can't modify the picture, we need to duplicate it */
1911                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1912                 if( p_tmp )
1913                 {
1914                     vout_CopyPicture( p_stream, p_tmp, p_pic );
1915                     p_pic->pf_release( p_pic );
1916                     p_pic = p_tmp;
1917                 }
1918             }
1919
1920             if( id->i_filter )
1921                 p_fmt = &id->pp_filter[id->i_filter -1]->fmt_out.video;
1922             else
1923                 p_fmt = &id->p_decoder->fmt_out.video;
1924
1925             /* FIXME (shouldn't have to be done here) */
1926             p_fmt->i_sar_num = p_fmt->i_aspect *
1927                 p_fmt->i_height / p_fmt->i_width;
1928             p_fmt->i_sar_den = VOUT_ASPECT_FACTOR;
1929
1930             spu_RenderSubpictures( p_sys->p_spu, p_fmt, p_pic, p_pic, p_subpic,
1931                                    i_scale_width, i_scale_height );
1932         }
1933
1934         /* Run vfilter chain */
1935         for( i = 0; i < id->i_vfilter; i++ )
1936         {
1937             p_pic = id->pp_vfilter[i]->pf_video_filter(id->pp_vfilter[i], p_pic);
1938         }
1939
1940         if( p_sys->i_threads >= 1 )
1941         {
1942             vlc_mutex_lock( &p_sys->lock_out );
1943             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
1944             p_sys->i_last_pic %= PICTURE_RING_SIZE;
1945             *out = p_sys->p_buffers;
1946             p_sys->p_buffers = NULL;
1947             vlc_cond_signal( &p_sys->cond );
1948             vlc_mutex_unlock( &p_sys->lock_out );
1949         }
1950         else
1951         {
1952             block_t *p_block;
1953             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1954             block_ChainAppend( out, p_block );
1955         }
1956
1957         if( p_sys->b_master_sync )
1958         {
1959             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1960             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1961                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1962             {
1963                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1964                 date_Set( &id->interpolated_pts, p_pic->date );
1965                 i_pts = p_pic->date + 1;
1966             }
1967             date_Increment( &id->interpolated_pts, 1 );
1968         }
1969
1970         if( p_sys->b_master_sync && i_duplicate > 1 )
1971         {
1972             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1973             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1974                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1975             {
1976                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1977                 date_Set( &id->interpolated_pts, p_pic->date );
1978                 i_pts = p_pic->date + 1;
1979             }
1980             date_Increment( &id->interpolated_pts, 1 );
1981
1982             if( p_sys->i_threads >= 1 )
1983             {
1984                 /* We can't modify the picture, we need to duplicate it */
1985                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1986                 if( p_tmp != NULL )
1987                 {
1988                     vout_CopyPicture( p_stream, p_tmp, p_pic );
1989                     p_pic = p_tmp;
1990
1991                     vlc_mutex_lock( &p_sys->lock_out );
1992                     p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
1993                     p_sys->i_last_pic %= PICTURE_RING_SIZE;
1994                     vlc_cond_signal( &p_sys->cond );
1995                     vlc_mutex_unlock( &p_sys->lock_out );
1996                 }
1997             }
1998             else
1999             {
2000                 block_t *p_block;
2001                 p_pic->date = i_pts;
2002                 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2003                 block_ChainAppend( out, p_block );
2004             }
2005         }
2006
2007         if( p_sys->i_threads == 0 )
2008             p_pic->pf_release( p_pic );
2009     }
2010
2011     return VLC_SUCCESS;
2012 }
2013
2014 static int EncoderThread( sout_stream_sys_t *p_sys )
2015 {
2016     sout_stream_id_t *id = p_sys->id_video;
2017     picture_t *p_pic;
2018
2019     while( !p_sys->b_die && !p_sys->b_error )
2020     {
2021         block_t *p_block;
2022
2023         vlc_mutex_lock( &p_sys->lock_out );
2024         while( p_sys->i_last_pic == p_sys->i_first_pic )
2025         {
2026             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2027             if( p_sys->b_die || p_sys->b_error ) break;
2028         }
2029         if( p_sys->b_die || p_sys->b_error )
2030         {
2031             vlc_mutex_unlock( &p_sys->lock_out );
2032             break;
2033         }
2034
2035         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2036         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2037         vlc_mutex_unlock( &p_sys->lock_out );
2038
2039         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2040         vlc_mutex_lock( &p_sys->lock_out );
2041         block_ChainAppend( &p_sys->p_buffers, p_block );
2042
2043         vlc_mutex_unlock( &p_sys->lock_out );
2044
2045         p_pic->pf_release( p_pic );
2046     }
2047
2048     while( p_sys->i_last_pic != p_sys->i_first_pic )
2049     {
2050         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2051         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2052
2053         p_pic->pf_release( p_pic );
2054     }
2055
2056     block_ChainRelease( p_sys->p_buffers );
2057
2058     return 0;
2059 }
2060
2061 struct picture_sys_t
2062 {
2063     vlc_object_t *p_owner;
2064 };
2065
2066 static void video_release_buffer( picture_t *p_pic )
2067 {
2068     if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2069     {
2070         video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2071     }
2072     else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2073 }
2074
2075 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2076                                     sout_stream_sys_t *p_sys )
2077 {
2078     decoder_t *p_dec = (decoder_t *)p_this;
2079     picture_t *p_pic;
2080     int i;
2081
2082     /* Find an empty space in the picture ring buffer */
2083     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2084     {
2085         if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2086         {
2087             pp_ring[i]->i_status = RESERVED_PICTURE;
2088             return pp_ring[i];
2089         }
2090     }
2091     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2092     {
2093         if( pp_ring[i] == 0 ) break;
2094     }
2095
2096     if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2097     {
2098         int i_first_pic = p_sys->i_first_pic;
2099
2100         if( p_sys->i_first_pic != p_sys->i_last_pic )
2101         {
2102             /* Encoder still has stuff to encode, wait to clear-up the list */
2103             while( p_sys->i_first_pic == i_first_pic )
2104                 msleep( 100000 );
2105         }
2106
2107         /* Find an empty space in the picture ring buffer */
2108         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2109         {
2110             if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2111             {
2112                 pp_ring[i]->i_status = RESERVED_PICTURE;
2113                 return pp_ring[i];
2114             }
2115         }
2116         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2117         {
2118             if( pp_ring[i] == 0 ) break;
2119         }
2120     }
2121
2122     if( i == PICTURE_RING_SIZE )
2123     {
2124         msg_Err( p_this, "decoder/filter is leaking pictures, "
2125                  "resetting its ring buffer" );
2126
2127         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2128         {
2129             pp_ring[i]->pf_release( pp_ring[i] );
2130         }
2131
2132         i = 0;
2133     }
2134
2135     p_pic = malloc( sizeof(picture_t) );
2136     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2137     vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2138                           p_dec->fmt_out.video.i_chroma,
2139                           p_dec->fmt_out.video.i_width,
2140                           p_dec->fmt_out.video.i_height,
2141                           p_dec->fmt_out.video.i_aspect );
2142
2143     if( !p_pic->i_planes )
2144     {
2145         free( p_pic );
2146         return 0;
2147     }
2148
2149     p_pic->pf_release = video_release_buffer;
2150     p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2151     p_pic->p_sys->p_owner = p_this;
2152     p_pic->i_status = RESERVED_PICTURE;
2153
2154     pp_ring[i] = p_pic;
2155
2156     return p_pic;
2157 }
2158
2159 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2160 {
2161     return video_new_buffer( VLC_OBJECT(p_dec),
2162                              p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2163 }
2164
2165 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2166 {
2167     return video_new_buffer( VLC_OBJECT(p_filter),
2168                              p_filter->p_owner->pp_pics,
2169                              p_filter->p_owner->p_sys );
2170 }
2171
2172 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2173 {
2174     if( p_pic && p_pic->p_data_orig ) free( p_pic->p_data_orig );
2175     if( p_pic && p_pic->p_sys ) free( p_pic->p_sys );
2176     if( p_pic ) free( p_pic );
2177 }
2178
2179 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2180 {
2181     p_pic->i_refcount = 0;
2182     p_pic->i_status = DESTROYED_PICTURE;
2183 }
2184
2185 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2186 {
2187     p_pic->i_refcount = 0;
2188     p_pic->i_status = DESTROYED_PICTURE;
2189 }
2190
2191 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2192 {
2193     p_pic->i_refcount++;
2194 }
2195
2196 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2197 {
2198     video_release_buffer( p_pic );
2199 }
2200
2201 /*
2202  * SPU
2203  */
2204 static subpicture_t *spu_new_buffer( decoder_t * );
2205 static void spu_del_buffer( decoder_t *, subpicture_t * );
2206
2207 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2208 {
2209     sout_stream_sys_t *p_sys = p_stream->p_sys;
2210
2211     /*
2212      * Open decoder
2213      */
2214
2215     /* Initialization of decoder structures */
2216     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2217     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2218     id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2219     /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2220
2221     id->p_decoder->p_module =
2222         module_Need( id->p_decoder, "decoder", "$codec", 0 );
2223
2224     if( !id->p_decoder->p_module )
2225     {
2226         msg_Err( p_stream, "cannot find decoder" );
2227         return VLC_EGENERIC;
2228     }
2229
2230     if( !p_sys->b_soverlay )
2231     {
2232         /*
2233          * Open encoder
2234          */
2235
2236         /* Initialization of encoder format structures */
2237         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2238                         id->p_decoder->fmt_in.i_codec );
2239
2240         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2241
2242         id->p_encoder->p_module =
2243             module_Need( id->p_encoder, "encoder", p_sys->psz_senc, VLC_TRUE );
2244
2245         if( !id->p_encoder->p_module )
2246         {
2247             module_Unneed( id->p_decoder, id->p_decoder->p_module );
2248             msg_Err( p_stream, "cannot find encoder" );
2249             return VLC_EGENERIC;
2250         }
2251     }
2252
2253     if( !p_sys->p_spu )
2254     {
2255         p_sys->p_spu = spu_Create( p_stream );
2256         spu_Init( p_sys->p_spu );
2257     }
2258
2259     return VLC_SUCCESS;
2260 }
2261
2262 static void transcode_spu_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2263 {
2264     /* Close decoder */
2265     if( id->p_decoder->p_module )
2266         module_Unneed( id->p_decoder, id->p_decoder->p_module );
2267
2268     /* Close encoder */
2269     if( id->p_encoder->p_module )
2270         module_Unneed( id->p_encoder, id->p_encoder->p_module );
2271 }
2272
2273 static int transcode_spu_process( sout_stream_t *p_stream,
2274                                   sout_stream_id_t *id,
2275                                   block_t *in, block_t **out )
2276 {
2277     sout_stream_sys_t *p_sys = p_stream->p_sys;
2278     subpicture_t *p_subpic;
2279     *out = NULL;
2280
2281     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2282     if( !p_subpic ) return VLC_EGENERIC;
2283
2284     if( p_sys->b_master_sync && p_sys->i_master_drift )
2285     {
2286         p_subpic->i_start -= p_sys->i_master_drift;
2287         if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2288     }
2289
2290     if( p_sys->b_soverlay )
2291     {
2292         spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2293     }
2294     else
2295     {
2296         block_t *p_block;
2297
2298         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2299         spu_del_buffer( id->p_decoder, p_subpic );
2300
2301         if( p_block )
2302         {
2303             block_ChainAppend( out, p_block );
2304             return VLC_SUCCESS;
2305         }
2306     }
2307
2308     return VLC_EGENERIC;
2309 }
2310
2311 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2312 {
2313     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2314     return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2315 }
2316
2317 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2318 {
2319     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2320     spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2321 }
2322
2323 /*
2324  * OSD menu
2325  */
2326 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2327 {
2328     sout_stream_sys_t *p_sys = p_stream->p_sys;
2329     es_format_t fmt;
2330     
2331     fmt.i_cat = SPU_ES;
2332     fmt.i_id = 0xbd1f; /* pid ?? */
2333     fmt.i_group = 3;   /* pmt entry ?? */
2334     fmt.i_codec = VLC_FOURCC( 'Y', 'U', 'V', 'A' );
2335     fmt.psz_language = strdup( "osd" );
2336     
2337     id = malloc( sizeof( sout_stream_id_t ) );
2338     memset( id, 0, sizeof(sout_stream_id_t) );
2339
2340     id->id = NULL;
2341     id->p_decoder = NULL;
2342     id->p_encoder = NULL;
2343
2344     /* Create encoder object */
2345     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
2346     if( !id->p_encoder )
2347     {
2348         msg_Err( p_stream, "out of memory" );
2349         goto error;
2350     }
2351     vlc_object_attach( id->p_encoder, p_stream );
2352     id->p_encoder->p_module = NULL;
2353
2354     /* Create fake destination format */
2355     es_format_Init( &id->p_encoder->fmt_out, fmt.i_cat, 0 );
2356     id->p_encoder->fmt_out.i_id    = fmt.i_id;
2357     id->p_encoder->fmt_out.i_group = fmt.i_group;
2358     id->p_encoder->fmt_out.psz_language = strdup( fmt.psz_language );
2359     
2360     if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2361     {
2362         msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2363                  "to fcc=`%4.4s'", (char*)&fmt.i_codec,
2364                  (char*)&p_sys->i_osdcodec );
2365
2366         /* Complete destination format */
2367         id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2368         
2369         /*
2370          * Open encoder
2371          */
2372         
2373         /* Initialization of encoder format structures */
2374         es_format_Init( &id->p_encoder->fmt_in, fmt.i_cat, fmt.i_codec );
2375         id->p_encoder->fmt_in.psz_language = strdup( fmt.psz_language );
2376
2377         id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2378
2379         id->p_encoder->p_module =
2380             module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, VLC_TRUE );
2381
2382         if( !id->p_encoder->p_module )
2383         {
2384             msg_Err( p_stream, "cannot find encoder" );
2385             goto error;
2386         }
2387         
2388         /* open output stream */
2389         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2390         id->b_transcode = VLC_TRUE;
2391
2392         if( !id->id ) goto error;
2393     }
2394     else
2395     {
2396         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2397                  (char*)&fmt.i_codec );
2398         id->id = p_sys->p_out->pf_add( p_sys->p_out, &fmt );
2399         id->b_transcode = VLC_FALSE;
2400
2401         if( !id->id ) goto error;
2402     }
2403
2404     p_sys->id_osd = id;
2405     p_sys->b_es_osd = VLC_TRUE;
2406
2407     if( !p_sys->p_spu )
2408     {
2409         p_sys->p_spu = spu_Create( p_stream );
2410         if( spu_Init( p_sys->p_spu ) != VLC_SUCCESS )
2411             msg_Err( p_sys, "spu initialisation failed" );
2412     }
2413     
2414     if( fmt.psz_language )
2415         free( fmt.psz_language );
2416         
2417     return VLC_SUCCESS;
2418     
2419  error:
2420     msg_Err( p_stream, "starting osd encoding thread failed" );
2421     if( id->p_encoder->p_module )
2422             module_Unneed( id->p_encoder, id->p_encoder->p_module );
2423     if( id->p_encoder )
2424     {
2425         vlc_object_detach( id->p_encoder );
2426         vlc_object_destroy( id->p_encoder );
2427     }
2428     if( fmt.psz_language ) free( fmt.psz_language );
2429     if( id ) free( id );
2430     p_sys->id_osd = NULL;
2431     p_sys->b_es_osd = VLC_FALSE;
2432     return VLC_EGENERIC;
2433 }
2434     
2435 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2436 {    
2437     sout_stream_sys_t *p_sys = p_stream->p_sys;
2438     
2439     /* Close encoder */
2440     if( p_sys->b_es_osd && id )
2441     {
2442         if( id->p_encoder->p_module )
2443             module_Unneed( id->p_encoder, id->p_encoder->p_module );
2444         
2445         if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
2446     
2447         if( id->p_encoder )
2448         {
2449             vlc_object_detach( id->p_encoder );
2450             vlc_object_destroy( id->p_encoder );
2451         }
2452     }
2453     p_sys->b_es_osd = VLC_FALSE;
2454     if( id ) free( id );
2455 }
2456
2457 static int transcode_osd_process( sout_stream_t *p_stream,
2458                                   sout_stream_id_t *id,
2459                                   block_t *in, block_t **out )
2460 {
2461     sout_stream_sys_t *p_sys = p_stream->p_sys;
2462     subpicture_t *p_subpic = NULL;
2463     
2464     /* Check if we have a subpicture to send */
2465     if( p_sys->p_spu && in->i_dts > 0)
2466     {
2467         p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts );
2468     }
2469     else
2470     {
2471         msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2472         if( !p_sys->p_spu )
2473         {
2474             p_sys->p_spu = spu_Create( p_stream );
2475             if( spu_Init( p_sys->p_spu ) != VLC_SUCCESS )
2476                 msg_Err( p_stream, "spu initialisation failed" );
2477         }
2478     }
2479         
2480     if( p_subpic )
2481     {
2482         block_t *p_block = NULL;
2483         
2484         if( p_sys->b_master_sync && p_sys->i_master_drift )
2485         {
2486             p_subpic->i_start -= p_sys->i_master_drift;
2487             if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2488         }
2489     
2490         p_block = p_sys->id_osd->p_encoder->pf_encode_sub( p_sys->id_osd->p_encoder, p_subpic );
2491         if( p_block )
2492         {
2493             p_block->i_dts = p_block->i_pts = in->i_dts;
2494             block_ChainAppend( out, p_block );
2495             if( *out )
2496             {
2497                 if( p_sys->p_out->pf_send( p_sys->p_out, p_sys->id_osd->id, *out ) == VLC_SUCCESS )
2498                     spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2499             }            
2500             return VLC_SUCCESS;            
2501         }
2502     }
2503     return VLC_EGENERIC;
2504 }