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