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