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