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