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