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