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