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