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