]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
Patch by xxcv: Don't change fmt_last.audio.i_rate when FOURCC is mp4a
[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 AAC SBR changing number of channels and sampling rate */
1309     if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1310         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1311         fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1312         fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1313
1314     /*
1315      * Open encoder
1316      */
1317
1318     /* Initialization of encoder format structures */
1319     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1320                     id->p_decoder->fmt_out.i_codec );
1321     id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1322
1323     /* Initialization of encoder format structures */
1324     es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, VLC_FOURCC('f','l','3','2') );
1325     id->p_encoder->fmt_in.audio.i_format = VLC_FOURCC('f','l','3','2');
1326
1327     id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1328     id->p_encoder->fmt_in.audio.i_physical_channels =
1329         id->p_encoder->fmt_out.audio.i_physical_channels;
1330     id->p_encoder->fmt_in.audio.i_original_channels =
1331         id->p_encoder->fmt_out.audio.i_original_channels;
1332     id->p_encoder->fmt_in.audio.i_channels =
1333         id->p_encoder->fmt_out.audio.i_channels;
1334     id->p_encoder->fmt_in.audio.i_bitspersample =
1335         audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1336
1337     id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1338     id->p_encoder->p_module =
1339         module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, VLC_TRUE );
1340     if( !id->p_encoder->p_module )
1341     {
1342         msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
1343         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1344         id->p_decoder->p_module = NULL;
1345         return VLC_EGENERIC;
1346     }
1347     id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1348     id->p_encoder->fmt_in.audio.i_bitspersample =
1349         audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1350
1351     /* Fix AAC SBR changing number of channels and sampling rate */
1352     if( id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1353         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1354         fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1355     {
1356       id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1357       id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1358     }
1359
1360     /* Load conversion filters */
1361     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1362         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1363     {
1364         /* We'll have to go through fl32 first */
1365         es_format_t fmt_out = id->p_encoder->fmt_in;
1366         fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2');
1367
1368         id->pp_filter[id->i_filter] =
1369             transcode_audio_filter_new( p_stream, id, &fmt_last, &fmt_out, NULL );
1370
1371         if( id->pp_filter[id->i_filter] ) id->i_filter++;
1372     }
1373
1374     for( i = 0; i < TRANSCODE_FILTERS; i++ )
1375     {
1376         if( (fmt_last.audio.i_channels !=
1377             id->p_encoder->fmt_in.audio.i_channels) ||
1378             (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1379             (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1380         {
1381             id->pp_filter[id->i_filter] =
1382                 transcode_audio_filter_new( p_stream, id, &fmt_last,
1383                                             &id->p_encoder->fmt_in, NULL );
1384
1385             if( id->pp_filter[id->i_filter] )
1386                 id->i_filter++;
1387             else
1388                 break;
1389         }
1390     }
1391
1392     /* Final checks to see if conversions were successful */
1393     if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1394     {
1395         msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1396                  (char *)&fmt_last.i_codec,
1397                  (char *)&id->p_encoder->fmt_in.i_codec );
1398         transcode_audio_close( p_stream, id );
1399         return VLC_EGENERIC;
1400     }
1401
1402     /* Load user specified audio filters now */
1403     for( i = 0; (i < p_sys->i_afilters) &&
1404                 (id->i_ufilter < TRANSCODE_FILTERS); i++ )
1405     {
1406         id->pp_ufilter[id->i_ufilter] =
1407             transcode_audio_filter_new( p_stream, id, &fmt_last,
1408                                         &id->p_encoder->fmt_in,
1409                                         p_sys->psz_afilters[i] );
1410
1411         if( id->pp_ufilter[id->i_ufilter] )
1412             id->i_ufilter++;
1413         else
1414             break;
1415     }
1416
1417     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1418     {
1419 #if 1
1420         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1421         id->p_encoder->p_module = NULL;
1422
1423         /* This might work, but only if the encoder is restarted */
1424         id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1425         id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1426
1427         id->p_encoder->fmt_in.audio.i_physical_channels =
1428             id->p_encoder->fmt_in.audio.i_original_channels =
1429                 fmt_last.audio.i_physical_channels;
1430         id->p_encoder->fmt_out.audio.i_physical_channels =
1431             id->p_encoder->fmt_out.audio.i_original_channels =
1432                 fmt_last.audio.i_physical_channels;
1433
1434         msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1435                  "trying to reopen the encoder for mixing %i to %i channels",
1436                  fmt_last.audio.i_channels,
1437                  id->p_encoder->fmt_in.audio.i_channels );
1438
1439         /* reload encoder */
1440         id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1441         id->p_encoder->p_module =
1442             module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, VLC_TRUE );
1443         if( !id->p_encoder->p_module )
1444         {
1445             msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
1446             transcode_audio_close( p_stream, id );
1447             return VLC_EGENERIC;
1448         }
1449         id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1450         id->p_encoder->fmt_in.audio.i_bitspersample =
1451             audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1452 #else
1453         msg_Err( p_stream, "no audio filter found for mixing from"
1454                  " %i to %i channels", fmt_last.audio.i_channels,
1455                  id->p_encoder->fmt_in.audio.i_channels );
1456
1457         transcode_audio_close( p_stream, id );
1458         return VLC_EGENERIC;
1459 #endif
1460     }
1461
1462     if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1463     {
1464         msg_Err( p_stream, "no audio filter found for resampling from"
1465                  " %iHz to %iHz", fmt_last.audio.i_rate,
1466                  id->p_encoder->fmt_in.audio.i_rate );
1467 #if 0
1468         /* FIXME : this might work, but only if the encoder is restarted */
1469         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1470         id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1471 #else
1472         transcode_audio_close( p_stream, id );
1473         return VLC_EGENERIC;
1474 #endif
1475     }
1476
1477     /* FIXME: Hack for mp3 transcoding support */
1478     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1479         id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1480
1481     return VLC_SUCCESS;
1482 }
1483
1484 static void transcode_audio_close( sout_stream_t *p_stream,
1485                                    sout_stream_id_t *id )
1486 {
1487     int i;
1488
1489     /* Close decoder */
1490     if( id->p_decoder->p_module )
1491         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1492     id->p_decoder->p_module = NULL;
1493
1494     /* Close encoder */
1495     if( id->p_encoder->p_module )
1496         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1497     id->p_encoder->p_module = NULL;
1498
1499     /* Close filters */
1500     for( i = 0; i < id->i_filter; i++ )
1501     {
1502         vlc_object_detach( id->pp_filter[i] );
1503         if( id->pp_filter[i]->p_module )
1504             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
1505         vlc_object_destroy( id->pp_filter[i] );
1506     }
1507     for( i = 0; i < id->i_ufilter; i++ )
1508     {
1509         vlc_object_detach( id->pp_ufilter[i] );
1510         if( id->pp_ufilter[i]->p_module )
1511             module_Unneed( id->pp_ufilter[i], id->pp_ufilter[i]->p_module );
1512         vlc_object_destroy( id->pp_ufilter[i] );
1513     }
1514 }
1515
1516 static int transcode_audio_process( sout_stream_t *p_stream,
1517                                     sout_stream_id_t *id,
1518                                     block_t *in, block_t **out )
1519 {
1520     sout_stream_sys_t *p_sys = p_stream->p_sys;
1521     aout_buffer_t *p_audio_buf;
1522     block_t *p_block, *p_audio_block;
1523     int i;
1524     *out = NULL;
1525     input_thread_t *p_input = NULL;
1526
1527     if( p_stream->p_parent->p_parent && p_stream->p_parent->p_parent->
1528                                 i_object_type == VLC_OBJECT_INPUT )
1529         p_input = (input_thread_t *)p_stream->p_parent->p_parent;
1530
1531     while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1532                                                           &in )) )
1533     {
1534         if( p_input )
1535             stats_UpdateInteger( p_input, p_input->p->counters.p_decoded_audio,
1536                                  1, NULL );
1537         if( p_sys->b_master_sync )
1538         {
1539             mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1540             if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1541                   || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1542             {
1543                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1544                 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1545                 i_dts = p_audio_buf->start_date + 1;
1546             }
1547             p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1548             date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1549             p_audio_buf->start_date -= p_sys->i_master_drift;
1550             p_audio_buf->end_date -= p_sys->i_master_drift;
1551         }
1552
1553         p_audio_block = p_audio_buf->p_sys;
1554         p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1555         p_audio_block->i_dts = p_audio_block->i_pts =
1556             p_audio_buf->start_date;
1557         p_audio_block->i_length = p_audio_buf->end_date -
1558             p_audio_buf->start_date;
1559         p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1560
1561         /* Run filter chain */
1562         for( i = 0; i < id->i_filter; i++ )
1563         {
1564             p_audio_block =
1565                 id->pp_filter[i]->pf_audio_filter( id->pp_filter[i],
1566                                                    p_audio_block );
1567         }
1568
1569         /* Run user specified filter chain */
1570         for( i = 0; i < id->i_ufilter; i++ )
1571         {
1572             p_audio_block =
1573                 id->pp_ufilter[i]->pf_audio_filter( id->pp_ufilter[i],
1574                                                     p_audio_block );
1575         }
1576
1577         p_audio_buf->p_buffer = p_audio_block->p_buffer;
1578         p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1579         p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1580         p_audio_buf->start_date = p_audio_block->i_dts;
1581         p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1582
1583         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1584         block_ChainAppend( out, p_block );
1585         block_Release( p_audio_block );
1586         free( p_audio_buf );
1587     }
1588
1589     return VLC_SUCCESS;
1590 }
1591
1592 static void audio_release_buffer( aout_buffer_t *p_buffer )
1593 {
1594     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1595     if( p_buffer ) free( p_buffer );
1596 }
1597
1598 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1599 {
1600     aout_buffer_t *p_buffer;
1601     block_t *p_block;
1602     int i_size;
1603
1604     if( p_dec->fmt_out.audio.i_bitspersample )
1605     {
1606         i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1607             p_dec->fmt_out.audio.i_channels;
1608     }
1609     else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1610              p_dec->fmt_out.audio.i_frame_length )
1611     {
1612         i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1613             p_dec->fmt_out.audio.i_frame_length;
1614     }
1615     else
1616     {
1617         i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1618     }
1619
1620     p_buffer = malloc( sizeof(aout_buffer_t) );
1621     p_buffer->pf_release = audio_release_buffer;
1622     p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1623
1624     p_buffer->p_buffer = p_block->p_buffer;
1625     p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1626     p_buffer->i_nb_samples = i_samples;
1627     p_block->i_samples = i_samples;
1628
1629     return p_buffer;
1630 }
1631
1632 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1633 {
1634     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1635     if( p_buffer ) free( p_buffer );
1636 }
1637
1638 /*
1639  * video
1640  */
1641 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1642 {
1643     sout_stream_sys_t *p_sys = p_stream->p_sys;
1644     int i;
1645
1646     /* Open decoder
1647      * Initialization of decoder structures
1648      */
1649     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1650     id->p_decoder->fmt_out.i_extra = 0;
1651     id->p_decoder->fmt_out.p_extra = 0;
1652     id->p_decoder->pf_decode_video = 0;
1653     id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1654     id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1655     id->p_decoder->pf_picture_link    = video_link_picture_decoder;
1656     id->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder;
1657     id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1658     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1659         id->p_decoder->p_owner->pp_pics[i] = 0;
1660     id->p_decoder->p_owner->p_sys = p_sys;
1661     /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1662
1663     id->p_decoder->p_module =
1664         module_Need( id->p_decoder, "decoder", "$codec", 0 );
1665
1666     if( !id->p_decoder->p_module )
1667     {
1668         msg_Err( p_stream, "cannot find decoder" );
1669         return VLC_EGENERIC;
1670     }
1671
1672     /*
1673      * Open encoder.
1674      * Because some info about the decoded input will only be available
1675      * once the first frame is decoded, we actually only test the availability
1676      * of the encoder here.
1677      */
1678
1679     /* Initialization of encoder format structures */
1680     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1681                     id->p_decoder->fmt_out.i_codec );
1682     id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1683
1684     /* The dimensions will be set properly later on.
1685      * Just put sensible values so we can test an encoder is available. */
1686     id->p_encoder->fmt_in.video.i_width =
1687         id->p_encoder->fmt_out.video.i_width ?
1688         id->p_encoder->fmt_out.video.i_width :
1689         id->p_decoder->fmt_in.video.i_width ?
1690         id->p_decoder->fmt_in.video.i_width : 16;
1691     id->p_encoder->fmt_in.video.i_height =
1692         id->p_encoder->fmt_out.video.i_height ?
1693         id->p_encoder->fmt_out.video.i_height :
1694         id->p_decoder->fmt_in.video.i_height ?
1695         id->p_decoder->fmt_in.video.i_height : 16;
1696     id->p_encoder->fmt_in.video.i_frame_rate = 25;
1697     id->p_encoder->fmt_in.video.i_frame_rate_base = 1;
1698
1699     id->p_encoder->i_threads = p_sys->i_threads;
1700     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1701
1702     id->p_encoder->p_module =
1703         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, VLC_TRUE );
1704     if( !id->p_encoder->p_module )
1705     {
1706         msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_venc );
1707         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1708         id->p_decoder->p_module = 0;
1709         return VLC_EGENERIC;
1710     }
1711
1712     /* Close the encoder.
1713      * We'll open it only when we have the first frame. */
1714     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1715     if( id->p_encoder->fmt_out.p_extra )
1716     {
1717         free( id->p_encoder->fmt_out.p_extra );
1718         id->p_encoder->fmt_out.p_extra = NULL;
1719         id->p_encoder->fmt_out.i_extra = 0;
1720     }
1721     id->p_encoder->p_module = NULL;
1722
1723     if( p_sys->i_threads >= 1 )
1724     {
1725         int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1726                            VLC_THREAD_PRIORITY_VIDEO;
1727         p_sys->id_video = id;
1728         vlc_mutex_init( p_stream, &p_sys->lock_out );
1729         vlc_cond_init( p_stream, &p_sys->cond );
1730         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1731         p_sys->i_first_pic = 0;
1732         p_sys->i_last_pic = 0;
1733         p_sys->p_buffers = NULL;
1734         p_sys->b_die = p_sys->b_error = 0;
1735         if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1736                                VLC_FALSE ) )
1737         {
1738             msg_Err( p_stream, "cannot spawn encoder thread" );
1739             module_Unneed( id->p_decoder, id->p_decoder->p_module );
1740             id->p_decoder->p_module = 0;
1741             return VLC_EGENERIC;
1742         }
1743     }
1744
1745     return VLC_SUCCESS;
1746 }
1747
1748 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1749                                          sout_stream_id_t *id )
1750 {
1751     sout_stream_sys_t *p_sys = p_stream->p_sys;
1752
1753      /* Calculate scaling, padding, cropping etc. */
1754      /* width/height of source */
1755      int i_src_width = id->p_decoder->fmt_out.video.i_width;
1756      int i_src_height = id->p_decoder->fmt_out.video.i_height;
1757
1758      /* with/height scaling */
1759      float f_scale_width = 1;
1760      float f_scale_height = 1;
1761
1762      /* width/height of output stream */
1763      int i_dst_width;
1764      int i_dst_height;
1765
1766      /* aspect ratio */
1767      float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1768                              VOUT_ASPECT_FACTOR;
1769
1770      msg_Dbg( p_stream, "decoder aspect is %i:%i",
1771                   id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1772
1773      /* Change f_aspect from source frame to source pixel */
1774      f_aspect = f_aspect * i_src_height / i_src_width;
1775      msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1776
1777      /* width/height after cropping */
1778      p_sys->i_src_x_offset = p_sys->i_crop_left & ~1;
1779      p_sys->i_src_y_offset = p_sys->i_crop_top & ~1;
1780      p_sys->i_crop_width = i_src_width - ( p_sys->i_crop_left & ~1 ) -
1781                             ( p_sys->i_crop_right & ~1 );
1782      p_sys->i_crop_height = i_src_height - ( p_sys->i_crop_top & ~1 ) -
1783                             ( p_sys->i_crop_bottom & ~1 );
1784
1785     /* Calculate scaling factor for specified parameters */
1786     if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1787         id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1788     {
1789         /* Global scaling. Make sure width will remain a factor of 16 */
1790         float f_real_scale;
1791         int  i_new_height;
1792         int i_new_width = i_src_width * p_sys->f_scale;
1793
1794         if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1795             i_new_width -= i_new_width % 16;
1796         else
1797             i_new_width += 16 - i_new_width % 16;
1798
1799         f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1800
1801         i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1802
1803         f_scale_width = f_real_scale;
1804         f_scale_height = (float) i_new_height / (float) i_src_height;
1805     }
1806     else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1807              id->p_encoder->fmt_out.video.i_height <= 0 )
1808     {
1809         /* Only width specified */
1810         f_scale_width = (float)id->p_encoder->fmt_out.video.i_width /
1811                              p_sys->i_crop_width;
1812         f_scale_height = f_scale_width;
1813     }
1814     else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1815              id->p_encoder->fmt_out.video.i_height > 0 )
1816     {
1817          /* Only height specified */
1818          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height /
1819                               p_sys->i_crop_height;
1820          f_scale_width = f_scale_height;
1821      }
1822      else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1823               id->p_encoder->fmt_out.video.i_height > 0 )
1824      {
1825          /* Width and height specified */
1826          f_scale_width = (float)id->p_encoder->fmt_out.video.i_width
1827                                / p_sys->i_crop_width;
1828          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height
1829                                / p_sys->i_crop_height;
1830      }
1831
1832      /* check maxwidth and maxheight
1833       * note: maxwidth and maxheight currently does not handle
1834       * canvas and padding, just scaling and cropping.
1835       */
1836      if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1837                                                      p_sys->i_crop_width )
1838      {
1839          f_scale_width = (float)p_sys->i_maxwidth / p_sys->i_crop_width;
1840      }
1841      if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1842                                                        p_sys->i_crop_height )
1843      {
1844          f_scale_height = (float)p_sys->i_maxheight / p_sys->i_crop_height;
1845      }
1846
1847      /* Change aspect ratio from source pixel to scaled pixel */
1848      f_aspect = f_aspect * f_scale_height / f_scale_width;
1849      msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1850
1851      /* Correct scaling for target aspect ratio
1852       * Shrink video if necessary
1853       */
1854      if ( p_sys->i_canvas_aspect > 0 )
1855      {
1856          float f_target_aspect = (float)p_sys->i_canvas_aspect /
1857                                         VOUT_ASPECT_FACTOR;
1858
1859          if( p_sys->i_canvas_width > 0 && p_sys->i_canvas_height > 0)
1860          {
1861              /* Calculate pixel aspect of canvas */
1862              f_target_aspect = f_target_aspect / p_sys->i_canvas_width *
1863                                p_sys->i_canvas_height;
1864          }
1865          if( f_target_aspect > f_aspect )
1866          {
1867              /* Reduce width scale to increase aspect */
1868              f_scale_width = f_scale_width * f_aspect / f_target_aspect;
1869          }
1870          else
1871          {
1872              /* Reduce height scale to decrease aspect */
1873              f_scale_height = f_scale_height * f_target_aspect / f_aspect;
1874          }
1875          f_aspect = f_target_aspect;
1876          msg_Dbg( p_stream, "canvas scaled pixel aspect is %f:1", f_aspect );
1877      }
1878
1879      /* f_scale_width and f_scale_height are now final */
1880      /* Calculate width, height from scaling
1881       * Make sure its multiple of 2
1882       */
1883      i_dst_width = 2 * (int)( p_sys->i_crop_width * f_scale_width / 2 + 0.5 );
1884      i_dst_height = 2 *
1885                     (int)( p_sys->i_crop_height * f_scale_height / 2 + 0.5 );
1886
1887      p_sys->i_nopadd_width = i_dst_width;
1888      p_sys->i_nopadd_height = i_dst_height;
1889      p_sys->i_dst_x_offset = 0;
1890      p_sys->i_dst_y_offset = 0;
1891
1892      /* Handle canvas and padding */
1893      if( p_sys->i_canvas_width <= 0 )
1894      {
1895          /* No canvas width set, add explicit padding border */
1896          i_dst_width = p_sys->i_nopadd_width + ( p_sys->i_padd_left & ~1 ) +
1897                       ( p_sys->i_padd_right & ~1 );
1898          p_sys->i_dst_x_offset = ( p_sys->i_padd_left & ~1 );
1899      }
1900      else
1901      {
1902          /* Canvas set, check if we have to padd or crop */
1903          if( p_sys->i_canvas_width < p_sys->i_nopadd_width )
1904          {
1905              /* need to crop more, but keep same scaling */
1906              int i_crop = 2 * (int)( ( p_sys->i_canvas_width & ~1 ) /
1907                                        f_scale_width / 2 + 0.5 );
1908
1909              p_sys->i_src_x_offset += ( ( p_sys->i_crop_width - i_crop ) / 2 )
1910                                            & ~1;
1911              p_sys->i_crop_width = i_crop;
1912              i_dst_width = p_sys->i_canvas_width & ~1;
1913              p_sys->i_nopadd_width = i_dst_width;
1914          }
1915          else if( p_sys->i_canvas_width > p_sys->i_nopadd_width )
1916          {
1917              /* need to padd */
1918              i_dst_width = p_sys->i_canvas_width & ~1;
1919              p_sys->i_dst_x_offset = ( i_dst_width - p_sys->i_nopadd_width )/2;
1920              p_sys->i_dst_x_offset = p_sys->i_dst_x_offset & ~1;
1921          }
1922      }
1923
1924      if( p_sys->i_canvas_height <= 0 )
1925      {
1926          /* No canvas set, add padding border */
1927          i_dst_height = p_sys->i_nopadd_height + ( p_sys->i_padd_top & ~1 ) +
1928                         ( p_sys->i_padd_bottom & ~1 );
1929          p_sys->i_dst_y_offset = ( p_sys->i_padd_top & ~1 );
1930      }
1931      else
1932      {
1933          /* Canvas set, check if we have to padd or crop */
1934          if( p_sys->i_canvas_height < p_sys->i_nopadd_height )
1935          {
1936              /* need to crop more, but keep same scaling */
1937              int i_crop = 2 * (int)( ( p_sys->i_canvas_height & ~1 ) /
1938                                         f_scale_height / 2 + 0.5 );
1939
1940              p_sys->i_src_y_offset += ( ( p_sys->i_crop_height - i_crop ) / 2 )
1941                                                 & ~1;
1942              p_sys->i_crop_height = i_crop;
1943              i_dst_height = p_sys->i_canvas_height & ~1;
1944              p_sys->i_nopadd_height = i_dst_height;
1945          }
1946          else if( p_sys->i_canvas_height > p_sys->i_nopadd_height )
1947          {
1948              /* need to padd */
1949              i_dst_height = p_sys->i_canvas_height & ~1;
1950              p_sys->i_dst_y_offset = ( i_dst_height - p_sys->i_nopadd_height )
1951                                         /2;
1952              p_sys->i_dst_y_offset = p_sys->i_dst_y_offset & ~1;
1953          }
1954      }
1955
1956      /* Change aspect ratio from scaled pixel to output frame */
1957      f_aspect = f_aspect * i_dst_width / i_dst_height;
1958
1959      /* Store calculated values */
1960      id->p_encoder->fmt_out.video.i_width = i_dst_width;
1961      id->p_encoder->fmt_out.video.i_height = i_dst_height;
1962
1963      id->p_encoder->fmt_in.video.i_width = i_dst_width;
1964      id->p_encoder->fmt_in.video.i_height = i_dst_height;
1965
1966      msg_Dbg( p_stream, "source %ix%i, crop %ix%i, "
1967                         "destination %ix%i, padding %ix%i",
1968          i_src_width, i_src_height,
1969          p_sys->i_crop_width, p_sys->i_crop_height,
1970          p_sys->i_nopadd_width, p_sys->i_nopadd_height,
1971          i_dst_width, i_dst_height
1972      );
1973
1974     /* Handle frame rate conversion */
1975     if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1976         !id->p_encoder->fmt_out.video.i_frame_rate_base )
1977     {
1978         if( id->p_decoder->fmt_out.video.i_frame_rate &&
1979             id->p_decoder->fmt_out.video.i_frame_rate_base )
1980         {
1981             id->p_encoder->fmt_out.video.i_frame_rate =
1982                 id->p_decoder->fmt_out.video.i_frame_rate;
1983             id->p_encoder->fmt_out.video.i_frame_rate_base =
1984                 id->p_decoder->fmt_out.video.i_frame_rate_base;
1985         }
1986         else
1987         {
1988             /* Pick a sensible default value */
1989             id->p_encoder->fmt_out.video.i_frame_rate = 25;
1990             id->p_encoder->fmt_out.video.i_frame_rate_base = 1;
1991         }
1992     }
1993
1994     id->p_encoder->fmt_in.video.i_frame_rate =
1995         id->p_encoder->fmt_out.video.i_frame_rate;
1996     id->p_encoder->fmt_in.video.i_frame_rate_base =
1997         id->p_encoder->fmt_out.video.i_frame_rate_base;
1998
1999     date_Init( &id->interpolated_pts,
2000                id->p_encoder->fmt_out.video.i_frame_rate,
2001                id->p_encoder->fmt_out.video.i_frame_rate_base );
2002
2003     /* Check whether a particular aspect ratio was requested */
2004     if( !id->p_encoder->fmt_out.video.i_aspect )
2005     {
2006         id->p_encoder->fmt_out.video.i_aspect = (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
2007     }
2008     id->p_encoder->fmt_in.video.i_aspect =
2009         id->p_encoder->fmt_out.video.i_aspect;
2010
2011     msg_Dbg( p_stream, "encoder aspect is %i:%i", id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
2012
2013     id->p_encoder->p_module =
2014         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, VLC_TRUE );
2015     if( !id->p_encoder->p_module )
2016     {
2017         msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_venc );
2018         return VLC_EGENERIC;
2019     }
2020
2021     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
2022
2023     /* Hack for mp2v/mp1v transcoding support */
2024     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
2025         id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
2026     {
2027         id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
2028     }
2029
2030     id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
2031                                              &id->p_encoder->fmt_out );
2032     if( !id->id )
2033     {
2034         msg_Err( p_stream, "cannot add this stream" );
2035         return VLC_EGENERIC;
2036     }
2037
2038     return VLC_SUCCESS;
2039 }
2040
2041 static void transcode_video_close( sout_stream_t *p_stream,
2042                                    sout_stream_id_t *id )
2043 {
2044     int i, j;
2045
2046     if( p_stream->p_sys->i_threads >= 1 )
2047     {
2048         vlc_mutex_lock( &p_stream->p_sys->lock_out );
2049         p_stream->p_sys->b_die = 1;
2050         vlc_cond_signal( &p_stream->p_sys->cond );
2051         vlc_mutex_unlock( &p_stream->p_sys->lock_out );
2052         vlc_thread_join( p_stream->p_sys );
2053         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
2054         vlc_cond_destroy( &p_stream->p_sys->cond );
2055     }
2056
2057     /* Close decoder */
2058     if( id->p_decoder->p_module )
2059         module_Unneed( id->p_decoder, id->p_decoder->p_module );
2060
2061     if( id->p_decoder->p_owner )
2062     {
2063         /* Clean-up pictures ring buffer */
2064         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2065         {
2066             if( id->p_decoder->p_owner->pp_pics[i] )
2067                 video_del_buffer( VLC_OBJECT(id->p_decoder),
2068                                   id->p_decoder->p_owner->pp_pics[i] );
2069         }
2070         free( id->p_decoder->p_owner );
2071     }
2072
2073     /* Close encoder */
2074     if( id->p_encoder->p_module )
2075         module_Unneed( id->p_encoder, id->p_encoder->p_module );
2076
2077     /* Close filters */
2078     for( i = 0; i < id->i_filter; i++ )
2079     {
2080         vlc_object_detach( id->pp_filter[i] );
2081         if( id->pp_filter[i]->p_module )
2082             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
2083
2084         /* Clean-up pictures ring buffer */
2085         for( j = 0; j < PICTURE_RING_SIZE; j++ )
2086         {
2087             if( id->pp_filter[i]->p_owner->pp_pics[j] )
2088                 video_del_buffer( VLC_OBJECT(id->pp_filter[i]),
2089                                   id->pp_filter[i]->p_owner->pp_pics[j] );
2090         }
2091         free( id->pp_filter[i]->p_owner );
2092         vlc_object_destroy( id->pp_filter[i] );
2093         id->pp_filter[i] = NULL;
2094     }
2095
2096     for( i = 0; i < id->i_ufilter; i++ )
2097     {
2098         vlc_object_detach( id->pp_ufilter[i] );
2099         if( id->pp_ufilter[i]->p_module )
2100             module_Unneed( id->pp_ufilter[i], id->pp_ufilter[i]->p_module );
2101
2102         /* Clean-up pictures ring buffer */
2103         for( j = 0; j < PICTURE_RING_SIZE; j++ )
2104         {
2105             if( id->pp_ufilter[i]->p_owner->pp_pics[j] )
2106                 video_del_buffer( VLC_OBJECT(id->pp_ufilter[i]),
2107                                   id->pp_ufilter[i]->p_owner->pp_pics[j] );
2108         }
2109         free( id->pp_ufilter[i]->p_owner );
2110         vlc_object_destroy( id->pp_ufilter[i] );
2111         id->pp_ufilter[i] = NULL;
2112     }
2113 }
2114
2115 static int transcode_video_process( sout_stream_t *p_stream,
2116                                     sout_stream_id_t *id,
2117                                     block_t *in, block_t **out )
2118 {
2119     sout_stream_sys_t *p_sys = p_stream->p_sys;
2120     int i_duplicate = 1, i;
2121     picture_t *p_pic, *p_pic2 = NULL;
2122     *out = NULL;
2123     input_thread_t *p_input = NULL;
2124
2125     if( p_stream->p_parent->p_parent && p_stream->p_parent->p_parent->
2126                                 i_object_type == VLC_OBJECT_INPUT )
2127         p_input = (input_thread_t *)p_stream->p_parent->p_parent;
2128
2129     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
2130     {
2131         subpicture_t *p_subpic = 0;
2132         if( p_input )
2133             stats_UpdateInteger( p_input, p_input->p->counters.p_decoded_video,
2134                                  1, NULL );
2135
2136         if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
2137         {
2138             mtime_t current_date = mdate();
2139             if( current_date + 50000 > p_pic->date )
2140             {
2141                 msg_Dbg( p_stream, "late picture skipped ("I64Fd")",
2142                          current_date + 50000 - p_pic->date );
2143                 p_pic->pf_release( p_pic );
2144                 continue;
2145             }
2146         }
2147
2148         if( p_sys->b_master_sync )
2149         {
2150             mtime_t i_video_drift;
2151             mtime_t i_master_drift = p_sys->i_master_drift;
2152             mtime_t i_pts;
2153
2154             i_pts = date_Get( &id->interpolated_pts ) + 1;
2155             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2156                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2157             {
2158                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2159                 date_Set( &id->interpolated_pts, p_pic->date );
2160                 i_pts = p_pic->date + 1;
2161             }
2162             i_video_drift = p_pic->date - i_pts;
2163             i_duplicate = 1;
2164
2165             /* Set the pts of the frame being encoded */
2166             p_pic->date = i_pts;
2167
2168             if( i_video_drift < i_master_drift - 50000 )
2169             {
2170 #if 0
2171                 msg_Dbg( p_stream, "dropping frame (%i)",
2172                          (int)(i_video_drift - i_master_drift) );
2173 #endif
2174                 p_pic->pf_release( p_pic );
2175                 continue;
2176             }
2177             else if( i_video_drift > i_master_drift + 50000 )
2178             {
2179 #if 0
2180                 msg_Dbg( p_stream, "adding frame (%i)",
2181                          (int)(i_video_drift - i_master_drift) );
2182 #endif
2183                 i_duplicate = 2;
2184             }
2185         }
2186
2187         if( !id->p_encoder->p_module )
2188         {
2189             if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
2190             {
2191                 p_pic->pf_release( p_pic );
2192                 transcode_video_close( p_stream, id );
2193                 id->b_transcode = VLC_FALSE;
2194                 return VLC_EGENERIC;
2195             }
2196
2197             /* Deinterlace */
2198             if( p_stream->p_sys->b_deinterlace )
2199             {
2200                 id->pp_filter[id->i_filter] =
2201                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
2202                 vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
2203
2204                 id->pp_filter[id->i_filter]->pf_vout_buffer_new =
2205                     video_new_buffer_filter;
2206                 id->pp_filter[id->i_filter]->pf_vout_buffer_del =
2207                     video_del_buffer_filter;
2208
2209                 id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
2210                 id->pp_filter[id->i_filter]->fmt_out = id->p_decoder->fmt_out;
2211                 id->pp_filter[id->i_filter]->p_cfg = p_sys->p_deinterlace_cfg;
2212                 id->pp_filter[id->i_filter]->p_module =
2213                     module_Need( id->pp_filter[id->i_filter],
2214                                  "video filter2", p_sys->psz_deinterlace, 0 );
2215                 if( id->pp_filter[id->i_filter]->p_module )
2216                 {
2217                     id->pp_filter[id->i_filter]->p_owner =
2218                         malloc( sizeof(filter_owner_sys_t) );
2219                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2220                         id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
2221                     id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;
2222
2223                     id->i_filter++;
2224                 }
2225                 else
2226                 {
2227                     msg_Dbg( p_stream, "no video filter found" );
2228                     vlc_object_detach( id->pp_filter[id->i_filter] );
2229                     vlc_object_destroy( id->pp_filter[id->i_filter] );
2230                 }
2231             }
2232
2233             /* Check if we need a filter for chroma conversion or resizing */
2234             if( id->p_decoder->fmt_out.video.i_chroma !=
2235                 id->p_encoder->fmt_in.video.i_chroma ||
2236
2237                 (int)id->p_decoder->fmt_out.video.i_width != p_sys->i_crop_width ||
2238                 p_sys->i_crop_width != p_sys->i_nopadd_width ||
2239                 p_sys->i_nopadd_width != (int)id->p_encoder->fmt_out.video.i_width ||
2240
2241                 (int)id->p_decoder->fmt_out.video.i_height != p_sys->i_crop_height ||
2242                 p_sys->i_crop_height != p_sys->i_nopadd_height ||
2243                 p_sys->i_nopadd_height != (int)id->p_encoder->fmt_out.video.i_height)
2244             {
2245                 id->pp_filter[id->i_filter] =
2246                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
2247                 vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
2248
2249                 id->pp_filter[id->i_filter]->pf_vout_buffer_new =
2250                     video_new_buffer_filter;
2251                 id->pp_filter[id->i_filter]->pf_vout_buffer_del =
2252                     video_del_buffer_filter;
2253
2254                 id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
2255                 id->pp_filter[id->i_filter]->fmt_out = id->p_encoder->fmt_in;
2256                 id->pp_filter[id->i_filter]->p_cfg = NULL;
2257
2258                 id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset;
2259                 id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset;
2260                 id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width;
2261                 id->pp_filter[id->i_filter]->fmt_in.video.i_visible_height = p_sys->i_crop_height;
2262
2263                 id->pp_filter[id->i_filter]->fmt_out.video.i_x_offset = p_sys->i_dst_x_offset;
2264                 id->pp_filter[id->i_filter]->fmt_out.video.i_y_offset = p_sys->i_dst_y_offset;
2265                 id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width;
2266                 id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height;
2267
2268                 id->pp_filter[id->i_filter]->p_module =
2269                     module_Need( id->pp_filter[id->i_filter],
2270                                  "crop padd", 0, 0 );
2271                 if( id->pp_filter[id->i_filter]->p_module )
2272                 {
2273                     id->pp_filter[id->i_filter]->p_owner =
2274                         malloc( sizeof(filter_owner_sys_t) );
2275                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2276                         id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
2277                     id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;
2278
2279                     id->i_filter++;
2280                 }
2281                 else
2282                 {
2283                     msg_Dbg( p_stream, "no video filter found" );
2284                     vlc_object_detach( id->pp_filter[id->i_filter] );
2285                     vlc_object_destroy( id->pp_filter[id->i_filter] );
2286
2287                     p_pic->pf_release( p_pic );
2288                     transcode_video_close( p_stream, id );
2289                     id->b_transcode = VLC_FALSE;
2290                     return VLC_EGENERIC;
2291                 }
2292             }
2293
2294             for( i = 0; (i < p_sys->i_vfilters) && (id->i_ufilter < TRANSCODE_FILTERS); i++ )
2295             {
2296                 id->pp_ufilter[id->i_ufilter] =
2297                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
2298                 vlc_object_attach( id->pp_ufilter[id->i_ufilter], p_stream );
2299
2300                 id->pp_ufilter[id->i_ufilter]->pf_vout_buffer_new =
2301                     video_new_buffer_filter;
2302                 id->pp_ufilter[id->i_ufilter]->pf_vout_buffer_del =
2303                     video_del_buffer_filter;
2304
2305                 id->pp_ufilter[id->i_ufilter]->fmt_in = id->p_encoder->fmt_in;
2306                 id->pp_ufilter[id->i_ufilter]->fmt_out = id->p_encoder->fmt_in;
2307                 id->pp_ufilter[id->i_ufilter]->p_cfg = p_sys->p_vfilters_cfg[i];
2308                 id->pp_ufilter[id->i_ufilter]->p_module =
2309                     module_Need( id->pp_ufilter[id->i_ufilter],
2310                           "video filter2", p_sys->psz_vfilters[i], 0 );
2311                 if( id->pp_ufilter[id->i_ufilter]->p_module )
2312                 {
2313                     id->pp_ufilter[id->i_ufilter]->p_owner =
2314                         malloc( sizeof(filter_owner_sys_t) );
2315                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2316                         id->pp_ufilter[id->i_ufilter]->p_owner->pp_pics[i] = 0;
2317                     id->pp_ufilter[id->i_ufilter]->p_owner->p_sys = p_sys;
2318                     id->i_ufilter++;
2319                 }
2320                 else
2321                 {
2322                     msg_Dbg( p_stream, "no video filter found" );
2323                     vlc_object_detach( id->pp_ufilter[id->i_ufilter] );
2324                     vlc_object_destroy( id->pp_ufilter[id->i_ufilter] );
2325                     id->pp_ufilter[id->i_ufilter] = NULL;
2326                 }
2327             }
2328         }
2329
2330         /* Run filter chain */
2331         for( i = 0; i < id->i_filter; i++ )
2332         {
2333             p_pic = id->pp_filter[i]->pf_video_filter(id->pp_filter[i], p_pic);
2334         }
2335
2336         /*
2337          * Encoding
2338          */
2339
2340         /* Check if we have a subpicture to overlay */
2341         if( p_sys->p_spu )
2342         {
2343             p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
2344                        VLC_FALSE /* Fixme: check if stream is paused */ );
2345             /* TODO: get another pic */
2346         }
2347
2348         /* Overlay subpicture */
2349         if( p_subpic )
2350         {
2351             int i_scale_width, i_scale_height;
2352             video_format_t *p_fmt;
2353
2354             i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
2355                 id->p_decoder->fmt_out.video.i_width;
2356             i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
2357                 id->p_decoder->fmt_out.video.i_height;
2358
2359             if( p_pic->i_refcount && !id->i_filter )
2360             {
2361                 /* We can't modify the picture, we need to duplicate it */
2362                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
2363                 if( p_tmp )
2364                 {
2365                     vout_CopyPicture( p_stream, p_tmp, p_pic );
2366                     p_pic->pf_release( p_pic );
2367                     p_pic = p_tmp;
2368                 }
2369             }
2370
2371             if( id->i_filter )
2372                 p_fmt = &id->pp_filter[id->i_filter -1]->fmt_out.video;
2373             else
2374                 p_fmt = &id->p_decoder->fmt_out.video;
2375
2376             /* FIXME (shouldn't have to be done here) */
2377             p_fmt->i_sar_num = p_fmt->i_aspect *
2378                 p_fmt->i_height / p_fmt->i_width;
2379             p_fmt->i_sar_den = VOUT_ASPECT_FACTOR;
2380
2381             spu_RenderSubpictures( p_sys->p_spu, p_fmt, p_pic, p_pic, p_subpic,
2382                                    i_scale_width, i_scale_height );
2383         }
2384
2385         /* Run user specified filter chain */
2386         for( i = 0; i < id->i_ufilter; i++ )
2387         {
2388             p_pic = id->pp_ufilter[i]->pf_video_filter(id->pp_ufilter[i], p_pic);
2389         }
2390
2391         if( p_sys->i_threads == 0 )
2392         {
2393             block_t *p_block;
2394             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2395             block_ChainAppend( out, p_block );
2396         }
2397
2398         if( p_sys->b_master_sync )
2399         {
2400             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2401             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2402                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2403             {
2404                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2405                 date_Set( &id->interpolated_pts, p_pic->date );
2406                 i_pts = p_pic->date + 1;
2407             }
2408             date_Increment( &id->interpolated_pts, 1 );
2409         }
2410
2411         if( p_sys->b_master_sync && i_duplicate > 1 )
2412         {
2413             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2414             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2415                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2416             {
2417                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2418                 date_Set( &id->interpolated_pts, p_pic->date );
2419                 i_pts = p_pic->date + 1;
2420             }
2421             date_Increment( &id->interpolated_pts, 1 );
2422
2423             if( p_sys->i_threads >= 1 )
2424             {
2425                 /* We can't modify the picture, we need to duplicate it */
2426                 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2427                 if( p_pic2 != NULL )
2428                 {
2429                     vout_CopyPicture( p_stream, p_pic2, p_pic );
2430                     p_pic2->date = i_pts;
2431                 }
2432             }
2433             else
2434             {
2435                 block_t *p_block;
2436                 p_pic->date = i_pts;
2437                 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2438                 block_ChainAppend( out, p_block );
2439             }
2440         }
2441
2442         if( p_sys->i_threads == 0 )
2443         {
2444             p_pic->pf_release( p_pic );
2445         }
2446         else
2447         {
2448             vlc_mutex_lock( &p_sys->lock_out );
2449             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2450             p_sys->i_last_pic %= PICTURE_RING_SIZE;
2451             *out = p_sys->p_buffers;
2452             p_sys->p_buffers = NULL;
2453             if( p_pic2 != NULL )
2454             {
2455                 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2456                 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2457             }
2458             vlc_cond_signal( &p_sys->cond );
2459             vlc_mutex_unlock( &p_sys->lock_out );
2460         }
2461     }
2462
2463     return VLC_SUCCESS;
2464 }
2465
2466 static int EncoderThread( sout_stream_sys_t *p_sys )
2467 {
2468     sout_stream_id_t *id = p_sys->id_video;
2469     picture_t *p_pic;
2470
2471     while( !p_sys->b_die && !p_sys->b_error )
2472     {
2473         block_t *p_block;
2474
2475         vlc_mutex_lock( &p_sys->lock_out );
2476         while( p_sys->i_last_pic == p_sys->i_first_pic )
2477         {
2478             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2479             if( p_sys->b_die || p_sys->b_error ) break;
2480         }
2481         if( p_sys->b_die || p_sys->b_error )
2482         {
2483             vlc_mutex_unlock( &p_sys->lock_out );
2484             break;
2485         }
2486
2487         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2488         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2489         vlc_mutex_unlock( &p_sys->lock_out );
2490
2491         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2492         vlc_mutex_lock( &p_sys->lock_out );
2493         block_ChainAppend( &p_sys->p_buffers, p_block );
2494
2495         vlc_mutex_unlock( &p_sys->lock_out );
2496         p_pic->pf_release( p_pic );
2497     }
2498
2499     while( p_sys->i_last_pic != p_sys->i_first_pic )
2500     {
2501         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2502         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2503         p_pic->pf_release( p_pic );
2504     }
2505     block_ChainRelease( p_sys->p_buffers );
2506
2507     return 0;
2508 }
2509
2510 struct picture_sys_t
2511 {
2512     vlc_object_t *p_owner;
2513 };
2514
2515 static void video_release_buffer( picture_t *p_pic )
2516 {
2517     if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2518     {
2519         video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2520     }
2521     else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2522 }
2523
2524 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2525                                     sout_stream_sys_t *p_sys )
2526 {
2527     decoder_t *p_dec = (decoder_t *)p_this;
2528     picture_t *p_pic;
2529     int i;
2530
2531     /* Find an empty space in the picture ring buffer */
2532     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2533     {
2534         if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2535         {
2536             pp_ring[i]->i_status = RESERVED_PICTURE;
2537             return pp_ring[i];
2538         }
2539     }
2540     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2541     {
2542         if( pp_ring[i] == 0 ) break;
2543     }
2544
2545     if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2546     {
2547         int i_first_pic = p_sys->i_first_pic;
2548
2549         if( p_sys->i_first_pic != p_sys->i_last_pic )
2550         {
2551             /* Encoder still has stuff to encode, wait to clear-up the list */
2552             while( p_sys->i_first_pic == i_first_pic )
2553                 msleep( 100000 );
2554         }
2555
2556         /* Find an empty space in the picture ring buffer */
2557         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2558         {
2559             if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2560             {
2561                 pp_ring[i]->i_status = RESERVED_PICTURE;
2562                 return pp_ring[i];
2563             }
2564         }
2565         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2566         {
2567             if( pp_ring[i] == 0 ) break;
2568         }
2569     }
2570
2571     if( i == PICTURE_RING_SIZE )
2572     {
2573         msg_Err( p_this, "decoder/filter is leaking pictures, "
2574                  "resetting its ring buffer" );
2575
2576         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2577         {
2578             pp_ring[i]->pf_release( pp_ring[i] );
2579         }
2580
2581         i = 0;
2582     }
2583
2584     p_pic = malloc( sizeof(picture_t) );
2585     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2586     vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2587                           p_dec->fmt_out.video.i_chroma,
2588                           p_dec->fmt_out.video.i_width,
2589                           p_dec->fmt_out.video.i_height,
2590                           p_dec->fmt_out.video.i_aspect );
2591
2592     if( !p_pic->i_planes )
2593     {
2594         free( p_pic );
2595         return 0;
2596     }
2597
2598     p_pic->pf_release = video_release_buffer;
2599     p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2600     p_pic->p_sys->p_owner = p_this;
2601     p_pic->i_status = RESERVED_PICTURE;
2602
2603     pp_ring[i] = p_pic;
2604     return p_pic;
2605 }
2606
2607 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2608 {
2609     return video_new_buffer( VLC_OBJECT(p_dec),
2610                              p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2611 }
2612
2613 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2614 {
2615     return video_new_buffer( VLC_OBJECT(p_filter),
2616                              p_filter->p_owner->pp_pics,
2617                              p_filter->p_owner->p_sys );
2618 }
2619
2620 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2621 {
2622     if( p_pic && p_pic->p_data_orig ) free( p_pic->p_data_orig );
2623     if( p_pic && p_pic->p_sys ) free( p_pic->p_sys );
2624     if( p_pic ) free( p_pic );
2625 }
2626
2627 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2628 {
2629     p_pic->i_refcount = 0;
2630     p_pic->i_status = DESTROYED_PICTURE;
2631 }
2632
2633 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2634 {
2635     p_pic->i_refcount = 0;
2636     p_pic->i_status = DESTROYED_PICTURE;
2637 }
2638
2639 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2640 {
2641     p_pic->i_refcount++;
2642 }
2643
2644 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2645 {
2646     video_release_buffer( p_pic );
2647 }
2648
2649 /*
2650  * SPU
2651  */
2652 static subpicture_t *spu_new_buffer( decoder_t * );
2653 static void spu_del_buffer( decoder_t *, subpicture_t * );
2654
2655 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2656 {
2657     sout_stream_sys_t *p_sys = p_stream->p_sys;
2658
2659     /*
2660      * Open decoder
2661      */
2662
2663     /* Initialization of decoder structures */
2664     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2665     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2666     id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2667     /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2668
2669     id->p_decoder->p_module =
2670         module_Need( id->p_decoder, "decoder", "$codec", 0 );
2671
2672     if( !id->p_decoder->p_module )
2673     {
2674         msg_Err( p_stream, "cannot find decoder" );
2675         return VLC_EGENERIC;
2676     }
2677
2678     if( !p_sys->b_soverlay )
2679     {
2680         /* Open encoder */
2681         /* Initialization of encoder format structures */
2682         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2683                         id->p_decoder->fmt_in.i_codec );
2684
2685         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2686
2687         id->p_encoder->p_module =
2688             module_Need( id->p_encoder, "encoder", p_sys->psz_senc, VLC_TRUE );
2689
2690         if( !id->p_encoder->p_module )
2691         {
2692             module_Unneed( id->p_decoder, id->p_decoder->p_module );
2693             msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_senc );
2694             return VLC_EGENERIC;
2695         }
2696     }
2697
2698     if( !p_sys->p_spu )
2699     {
2700         p_sys->p_spu = spu_Create( p_stream );
2701         spu_Init( p_sys->p_spu );
2702     }
2703
2704     return VLC_SUCCESS;
2705 }
2706
2707 static void transcode_spu_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2708 {
2709     /* Close decoder */
2710     if( id->p_decoder->p_module )
2711         module_Unneed( id->p_decoder, id->p_decoder->p_module );
2712
2713     /* Close encoder */
2714     if( id->p_encoder->p_module )
2715         module_Unneed( id->p_encoder, id->p_encoder->p_module );
2716 }
2717
2718 static int transcode_spu_process( sout_stream_t *p_stream,
2719                                   sout_stream_id_t *id,
2720                                   block_t *in, block_t **out )
2721 {
2722     sout_stream_sys_t *p_sys = p_stream->p_sys;
2723     subpicture_t *p_subpic;
2724     *out = NULL;
2725
2726     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2727     if( !p_subpic ) return VLC_EGENERIC;
2728
2729     if( p_sys->b_master_sync && p_sys->i_master_drift )
2730     {
2731         p_subpic->i_start -= p_sys->i_master_drift;
2732         if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2733     }
2734
2735     if( p_sys->b_soverlay )
2736     {
2737         spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2738     }
2739     else
2740     {
2741         block_t *p_block;
2742
2743         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2744         spu_del_buffer( id->p_decoder, p_subpic );
2745
2746         if( p_block )
2747         {
2748             block_ChainAppend( out, p_block );
2749             return VLC_SUCCESS;
2750         }
2751     }
2752
2753     return VLC_EGENERIC;
2754 }
2755
2756 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2757 {
2758     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2759     return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2760 }
2761
2762 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2763 {
2764     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2765     spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2766 }
2767
2768 /*
2769  * OSD menu
2770  */
2771 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2772 {
2773     sout_stream_sys_t *p_sys = p_stream->p_sys;
2774     es_format_t fmt;
2775
2776     fmt.i_cat = SPU_ES;
2777     fmt.i_id = 0xbd1f; /* pid ?? */
2778     fmt.i_group = 3;   /* pmt entry ?? */
2779     fmt.i_codec = VLC_FOURCC( 'Y', 'U', 'V', 'A' );
2780     fmt.psz_language = strdup( "osd" );
2781
2782     id = malloc( sizeof( sout_stream_id_t ) );
2783     memset( id, 0, sizeof(sout_stream_id_t) );
2784
2785     id->id = NULL;
2786     id->p_decoder = NULL;
2787     id->p_encoder = NULL;
2788
2789     /* Create encoder object */
2790     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
2791     if( !id->p_encoder )
2792     {
2793         msg_Err( p_stream, "out of memory" );
2794         goto error;
2795     }
2796     vlc_object_attach( id->p_encoder, p_stream );
2797     id->p_encoder->p_module = NULL;
2798
2799     /* Create fake destination format */
2800     es_format_Init( &id->p_encoder->fmt_out, fmt.i_cat, 0 );
2801     id->p_encoder->fmt_out.i_id    = fmt.i_id;
2802     id->p_encoder->fmt_out.i_group = fmt.i_group;
2803     id->p_encoder->fmt_out.psz_language = strdup( fmt.psz_language );
2804
2805     if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2806     {
2807         msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2808                  "to fcc=`%4.4s'", (char*)&fmt.i_codec,
2809                  (char*)&p_sys->i_osdcodec );
2810
2811         /* Complete destination format */
2812         id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2813
2814         /* Open encoder */
2815         /* Initialization of encoder format structures */
2816         es_format_Init( &id->p_encoder->fmt_in, fmt.i_cat, fmt.i_codec );
2817         id->p_encoder->fmt_in.psz_language = strdup( fmt.psz_language );
2818
2819         id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2820
2821         id->p_encoder->p_module =
2822             module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, VLC_TRUE );
2823
2824         if( !id->p_encoder->p_module )
2825         {
2826             msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_osdenc );
2827             goto error;
2828         }
2829
2830         /* open output stream */
2831         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2832         id->b_transcode = VLC_TRUE;
2833
2834         if( !id->id ) goto error;
2835     }
2836     else
2837     {
2838         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2839                  (char*)&fmt.i_codec );
2840         id->id = p_sys->p_out->pf_add( p_sys->p_out, &fmt );
2841         id->b_transcode = VLC_FALSE;
2842
2843         if( !id->id ) goto error;
2844     }
2845
2846     p_sys->id_osd = id;
2847     p_sys->b_es_osd = VLC_TRUE;
2848
2849     if( !p_sys->p_spu )
2850     {
2851         p_sys->p_spu = spu_Create( p_stream );
2852         if( spu_Init( p_sys->p_spu ) != VLC_SUCCESS )
2853             msg_Err( p_sys, "spu initialisation failed" );
2854     }
2855
2856     if( fmt.psz_language )
2857         free( fmt.psz_language );
2858
2859     return VLC_SUCCESS;
2860
2861  error:
2862     msg_Err( p_stream, "starting osd encoding thread failed" );
2863     if( id->p_encoder->p_module )
2864             module_Unneed( id->p_encoder, id->p_encoder->p_module );
2865     if( id->p_encoder )
2866     {
2867         vlc_object_detach( id->p_encoder );
2868         vlc_object_destroy( id->p_encoder );
2869     }
2870     if( fmt.psz_language ) free( fmt.psz_language );
2871     if( id ) free( id );
2872     p_sys->id_osd = NULL;
2873     p_sys->b_es_osd = VLC_FALSE;
2874     return VLC_EGENERIC;
2875 }
2876
2877 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2878 {
2879     sout_stream_sys_t *p_sys = p_stream->p_sys;
2880
2881     /* Close encoder */
2882     if( p_sys->b_es_osd && id )
2883     {
2884         if( id->p_encoder->p_module )
2885             module_Unneed( id->p_encoder, id->p_encoder->p_module );
2886
2887         if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
2888
2889         if( id->p_encoder )
2890         {
2891             vlc_object_detach( id->p_encoder );
2892             vlc_object_destroy( id->p_encoder );
2893         }
2894     }
2895     p_sys->b_es_osd = VLC_FALSE;
2896     if( id ) free( id );
2897 }
2898
2899 static int transcode_osd_process( sout_stream_t *p_stream,
2900                                   sout_stream_id_t *id,
2901                                   block_t *in, block_t **out )
2902 {
2903     sout_stream_sys_t *p_sys = p_stream->p_sys;
2904     subpicture_t *p_subpic = NULL;
2905
2906     /* Check if we have a subpicture to send */
2907     if( p_sys->p_spu && in->i_dts > 0)
2908     {
2909         p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, VLC_FALSE );
2910     }
2911     else
2912     {
2913         msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2914         if( !p_sys->p_spu )
2915         {
2916             p_sys->p_spu = spu_Create( p_stream );
2917             if( spu_Init( p_sys->p_spu ) != VLC_SUCCESS )
2918                 msg_Err( p_stream, "spu initialisation failed" );
2919         }
2920     }
2921
2922     if( p_subpic )
2923     {
2924         block_t *p_block = NULL;
2925
2926         if( p_sys->b_master_sync && p_sys->i_master_drift )
2927         {
2928             p_subpic->i_start -= p_sys->i_master_drift;
2929             if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2930         }
2931
2932         p_block = p_sys->id_osd->p_encoder->pf_encode_sub( p_sys->id_osd->p_encoder, p_subpic );
2933         if( p_block )
2934         {
2935             p_block->i_dts = p_block->i_pts = in->i_dts;
2936             block_ChainAppend( out, p_block );
2937             if( *out )
2938             {
2939                 if( p_sys->p_out->pf_send( p_sys->p_out, p_sys->id_osd->id, *out ) == VLC_SUCCESS )
2940                     spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2941             }
2942             return VLC_SUCCESS;
2943         }
2944     }
2945     return VLC_EGENERIC;
2946 }