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