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