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