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