]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
4a7680e902c949c5c22aa530e18baf3237b4415a
[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_string( SOUT_CFG_PREFIX "venc", 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_string( SOUT_CFG_PREFIX "aenc", 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_string( SOUT_CFG_PREFIX "senc", 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 = malloc( sizeof( sout_stream_id_t ) );
697     if( !id )
698         goto error;
699     memset( id, 0, sizeof(sout_stream_id_t) );
700
701     id->id = NULL;
702     id->p_decoder = NULL;
703     id->p_encoder = NULL;
704
705     /* Create decoder object */
706     id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
707     if( !id->p_decoder )
708         goto error;
709     vlc_object_attach( id->p_decoder, p_stream );
710     id->p_decoder->p_module = NULL;
711     id->p_decoder->fmt_in = *p_fmt;
712     id->p_decoder->b_pace_control = true;
713
714     /* Create encoder object */
715     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
716     if( !id->p_encoder )
717         goto error;
718     vlc_object_attach( id->p_encoder, p_stream );
719     id->p_encoder->p_module = NULL;
720
721     /* Create destination format */
722     es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
723     id->p_encoder->fmt_out.i_id    = p_fmt->i_id;
724     id->p_encoder->fmt_out.i_group = p_fmt->i_group;
725     if( p_fmt->psz_language )
726         id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
727
728     if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
729     {
730         msg_Dbg( p_stream,
731                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
732                  (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
733
734         /* Complete destination format */
735         id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
736         id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
737             p_sys->i_sample_rate : p_fmt->audio.i_rate;
738         id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
739         id->p_encoder->fmt_out.audio.i_bitspersample =
740             p_fmt->audio.i_bitspersample;
741         id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
742             p_sys->i_channels : p_fmt->audio.i_channels;
743         /* Sanity check for audio channels */
744         id->p_encoder->fmt_out.audio.i_channels =
745             __MIN( id->p_encoder->fmt_out.audio.i_channels,
746                    id->p_decoder->fmt_in.audio.i_channels );
747         id->p_encoder->fmt_out.audio.i_original_channels =
748             id->p_decoder->fmt_in.audio.i_physical_channels;
749         if( id->p_decoder->fmt_in.audio.i_channels ==
750             id->p_encoder->fmt_out.audio.i_channels )
751         {
752             id->p_encoder->fmt_out.audio.i_physical_channels =
753                 id->p_decoder->fmt_in.audio.i_physical_channels;
754         }
755         else
756         {
757             id->p_encoder->fmt_out.audio.i_physical_channels =
758                 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
759         }
760
761         /* Build decoder -> filter -> encoder chain */
762         if( transcode_audio_new( p_stream, id ) )
763         {
764             msg_Err( p_stream, "cannot create audio chain" );
765             goto error;
766         }
767
768         /* Open output stream */
769         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
770         id->b_transcode = true;
771
772         if( !id->id )
773         {
774             transcode_audio_close( id );
775             goto error;
776         }
777
778         date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
779     }
780     else if( p_fmt->i_cat == VIDEO_ES &&
781              (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
782     {
783         msg_Dbg( p_stream,
784                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
785                  (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
786
787         /* Complete destination format */
788         id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
789         id->p_encoder->fmt_out.video.i_width  = p_sys->i_width & ~1;
790         id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
791         id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
792
793         /* Build decoder -> filter -> encoder chain */
794         if( transcode_video_new( p_stream, id ) )
795         {
796             msg_Err( p_stream, "cannot create video chain" );
797             goto error;
798         }
799
800         /* Stream will be added later on because we don't know
801          * all the characteristics of the decoded stream yet */
802         id->b_transcode = true;
803
804         if( p_sys->f_fps > 0 )
805         {
806             id->p_encoder->fmt_out.video.i_frame_rate =
807                 (p_sys->f_fps * 1000) + 0.5;
808             id->p_encoder->fmt_out.video.i_frame_rate_base =
809                 ENC_FRAMERATE_BASE;
810         }
811     }
812     else if( ( p_fmt->i_cat == SPU_ES ) &&
813              ( p_sys->i_scodec || p_sys->psz_senc ) )
814     {
815         msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
816                  "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
817                  (char*)&p_sys->i_scodec );
818
819         /* Complete destination format */
820         id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
821
822         /* build decoder -> filter -> encoder */
823         if( transcode_spu_new( p_stream, id ) )
824         {
825             msg_Err( p_stream, "cannot create subtitles chain" );
826             goto error;
827         }
828
829         /* open output stream */
830         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
831         id->b_transcode = true;
832
833         if( !id->id )
834         {
835             transcode_spu_close( id );
836             goto error;
837         }
838     }
839     else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
840     {
841         msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
842                  (char*)&p_fmt->i_codec );
843
844         id->b_transcode = true;
845
846         /* Build decoder -> filter -> overlaying chain */
847         if( transcode_spu_new( p_stream, id ) )
848         {
849             msg_Err( p_stream, "cannot create subtitles chain" );
850             goto error;
851         }
852     }
853     else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
854     {
855         msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
856                  "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
857                  (char*)&p_sys->i_scodec );
858
859         id->b_transcode = true;
860
861         /* Create a fake OSD menu elementary stream */
862         if( transcode_osd_new( p_stream, id ) )
863         {
864             msg_Err( p_stream, "cannot create osd chain" );
865             goto error;
866         }
867         p_sys->b_osd = true;
868     }
869     else
870     {
871         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
872                  (char*)&p_fmt->i_codec );
873         id->id = sout_StreamIdAdd( p_sys->p_out, p_fmt );
874         id->b_transcode = false;
875
876         if( !id->id ) goto error;
877     }
878
879     return id;
880
881 error:
882     if( id )
883     {
884         if( id->p_decoder )
885         {
886             vlc_object_detach( id->p_decoder );
887             vlc_object_release( id->p_decoder );
888             id->p_decoder = NULL;
889         }
890
891         if( id->p_encoder )
892         {
893             vlc_object_detach( id->p_encoder );
894             es_format_Clean( &id->p_encoder->fmt_out );
895             vlc_object_release( id->p_encoder );
896             id->p_encoder = NULL;
897         }
898
899         free( id );
900     }
901     return NULL;
902 }
903
904 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
905 {
906     sout_stream_sys_t *p_sys = p_stream->p_sys;
907
908     if( id->b_transcode )
909     {
910         switch( id->p_decoder->fmt_in.i_cat )
911         {
912         case AUDIO_ES:
913             transcode_audio_close( id );
914             break;
915         case VIDEO_ES:
916             transcode_video_close( p_stream, id );
917             break;
918         case SPU_ES:
919             if( p_sys->b_osd )
920                 transcode_osd_close( p_stream, id );
921             else
922                 transcode_spu_close( id );
923             break;
924         }
925     }
926
927     if( id->id ) sout_StreamIdDel( p_sys->p_out, id->id );
928
929     if( id->p_decoder )
930     {
931         vlc_object_detach( id->p_decoder );
932         vlc_object_release( id->p_decoder );
933         id->p_decoder = NULL;
934     }
935
936     if( id->p_encoder )
937     {
938         vlc_object_detach( id->p_encoder );
939         es_format_Clean( &id->p_encoder->fmt_out );
940         vlc_object_release( id->p_encoder );
941         id->p_encoder = NULL;
942     }
943     free( id );
944
945     return VLC_SUCCESS;
946 }
947
948 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
949                  block_t *p_buffer )
950 {
951     sout_stream_sys_t *p_sys = p_stream->p_sys;
952     block_t *p_out = NULL;
953
954     if( !id->b_transcode )
955     {
956         if( id->id )
957             return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
958
959         block_Release( p_buffer );
960         return VLC_EGENERIC;
961     }
962
963     switch( id->p_decoder->fmt_in.i_cat )
964     {
965     case AUDIO_ES:
966         transcode_audio_process( p_stream, id, p_buffer, &p_out );
967         break;
968
969     case VIDEO_ES:
970         if( transcode_video_process( p_stream, id, p_buffer, &p_out )
971             != VLC_SUCCESS )
972         {
973             return VLC_EGENERIC;
974         }
975         break;
976
977     case SPU_ES:
978         /* Transcode OSD menu pictures. */
979         if( p_sys->b_osd )
980         {
981             if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
982                 VLC_SUCCESS )
983             {
984                 return VLC_EGENERIC;
985             }
986         }
987         else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
988             VLC_SUCCESS )
989         {
990             return VLC_EGENERIC;
991         }
992         break;
993
994     default:
995         p_out = NULL;
996         block_Release( p_buffer );
997         break;
998     }
999
1000     if( p_out )
1001         return sout_StreamIdSend( p_sys->p_out, id->id, p_out );
1002     return VLC_SUCCESS;
1003 }
1004
1005 /****************************************************************************
1006  * decoder helper
1007  ****************************************************************************/
1008 static inline void video_timer_start( encoder_t * p_encoder )
1009 {
1010     stats_TimerStart( p_encoder, "encoding video frame",
1011                       STATS_TIMER_VIDEO_FRAME_ENCODING );
1012 }
1013
1014 static inline void video_timer_stop( encoder_t * p_encoder )
1015 {
1016     stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1017 }
1018
1019 static inline void video_timer_close( encoder_t * p_encoder )
1020 {
1021     stats_TimerDump(  p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1022     stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1023 }
1024
1025 static inline void audio_timer_start( encoder_t * p_encoder )
1026 {
1027     stats_TimerStart( p_encoder, "encoding audio frame",
1028                       STATS_TIMER_AUDIO_FRAME_ENCODING );
1029 }
1030
1031 static inline void audio_timer_stop( encoder_t * p_encoder )
1032 {
1033     stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1034 }
1035
1036 static inline void audio_timer_close( encoder_t * p_encoder )
1037 {
1038     stats_TimerDump(  p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1039     stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1040 }
1041
1042 /****************************************************************************
1043  * decoder reencoder part
1044  ****************************************************************************/
1045
1046 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1047 {
1048     VLC_UNUSED( p_filter );
1049     return block_Alloc( size );
1050 }
1051
1052 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1053                                                    void *data )
1054 {
1055     VLC_UNUSED(data);
1056     p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1057     return VLC_SUCCESS;
1058 }
1059
1060 static int transcode_audio_new( sout_stream_t *p_stream,
1061                                 sout_stream_id_t *id )
1062 {
1063     sout_stream_sys_t *p_sys = p_stream->p_sys;
1064     es_format_t fmt_last;
1065     int i;
1066
1067     /*
1068      * Open decoder
1069      */
1070
1071     /* Initialization of decoder structures */
1072     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1073     id->p_decoder->fmt_out.i_extra = 0;
1074     id->p_decoder->fmt_out.p_extra = 0;
1075     id->p_decoder->pf_decode_audio = NULL;
1076     id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1077     id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1078     /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1079
1080     id->p_decoder->p_module =
1081         module_need( id->p_decoder, "decoder", "$codec", 0 );
1082     if( !id->p_decoder->p_module )
1083     {
1084         msg_Err( p_stream, "cannot find audio decoder" );
1085         return VLC_EGENERIC;
1086     }
1087     id->p_decoder->fmt_out.audio.i_bitspersample =
1088         aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1089     fmt_last = id->p_decoder->fmt_out;
1090     /* Fix AAC SBR changing number of channels and sampling rate */
1091     if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1092         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1093         fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1094         fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1095
1096     /*
1097      * Open encoder
1098      */
1099
1100     /* Initialization of encoder format structures */
1101     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1102                     id->p_decoder->fmt_out.i_codec );
1103     id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1104
1105     id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1106     id->p_encoder->fmt_in.audio.i_physical_channels =
1107         id->p_encoder->fmt_out.audio.i_physical_channels;
1108     id->p_encoder->fmt_in.audio.i_original_channels =
1109         id->p_encoder->fmt_out.audio.i_original_channels;
1110     id->p_encoder->fmt_in.audio.i_channels =
1111         id->p_encoder->fmt_out.audio.i_channels;
1112     id->p_encoder->fmt_in.audio.i_bitspersample =
1113         aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1114
1115     id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1116     id->p_encoder->p_module =
1117         module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1118     if( !id->p_encoder->p_module )
1119     {
1120         msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1121                  p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1122                  (char *)&p_sys->i_acodec );
1123         module_unneed( id->p_decoder, id->p_decoder->p_module );
1124         id->p_decoder->p_module = NULL;
1125         return VLC_EGENERIC;
1126     }
1127     id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1128     id->p_encoder->fmt_in.audio.i_bitspersample =
1129         aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1130
1131     /* Init filter chain */
1132     id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1133                     transcode_audio_filter_allocation_init, NULL, NULL );
1134     filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1135
1136     /* Load conversion filters */
1137     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1138         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1139     {
1140         /* We'll have to go through fl32 first */
1141         fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1142         fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1143         filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1144         fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1145     }
1146
1147     for( i = 0; i < 4; i++ )
1148     {
1149         if( (fmt_last.audio.i_channels !=
1150             id->p_encoder->fmt_in.audio.i_channels) ||
1151             (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1152             (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1153         {
1154             msg_Dbg( p_stream, "Looking for filter "
1155                      "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1156                  (char *)&fmt_last.i_codec,
1157                  (char *)&id->p_encoder->fmt_in.i_codec,
1158                  fmt_last.audio.i_channels,
1159                  id->p_encoder->fmt_in.audio.i_channels,
1160                  fmt_last.audio.i_rate,
1161                  id->p_encoder->fmt_in.audio.i_rate );
1162             filter_chain_AppendFilter( id->p_f_chain, NULL, NULL,
1163                                        &fmt_last, &id->p_encoder->fmt_in );
1164             fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1165         }
1166         else break;
1167     }
1168
1169     /* Final checks to see if conversions were successful */
1170     if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1171     {
1172         msg_Err( p_stream, "no audio filter found "
1173                            "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1174                  (char *)&fmt_last.i_codec,
1175                  (char *)&id->p_encoder->fmt_in.i_codec,
1176                  fmt_last.audio.i_channels,
1177                  id->p_encoder->fmt_in.audio.i_channels,
1178                  fmt_last.audio.i_rate,
1179                  id->p_encoder->fmt_in.audio.i_rate );
1180         transcode_audio_close( id );
1181         return VLC_EGENERIC;
1182     }
1183
1184     /* Load user specified audio filters now */
1185     if( p_sys->psz_af2 )
1186     {
1187         id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1188                        transcode_audio_filter_allocation_init, NULL, NULL );
1189         filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1190         filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1191         fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1192     }
1193
1194     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1195     {
1196 #if 1
1197         module_unneed( id->p_encoder, id->p_encoder->p_module );
1198         id->p_encoder->p_module = NULL;
1199
1200         /* This might work, but only if the encoder is restarted */
1201         id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1202         id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1203
1204         id->p_encoder->fmt_in.audio.i_physical_channels =
1205             id->p_encoder->fmt_in.audio.i_original_channels =
1206                 fmt_last.audio.i_physical_channels;
1207         id->p_encoder->fmt_out.audio.i_physical_channels =
1208             id->p_encoder->fmt_out.audio.i_original_channels =
1209                 fmt_last.audio.i_physical_channels;
1210
1211         msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1212                  "trying to reopen the encoder for mixing %i to %i channels",
1213                  fmt_last.audio.i_channels,
1214                  id->p_encoder->fmt_in.audio.i_channels );
1215
1216         /* reload encoder */
1217         id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1218         id->p_encoder->p_module =
1219             module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1220         if( !id->p_encoder->p_module ||
1221             fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels  ||
1222             fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1223         {
1224             if( id->p_encoder->p_module )
1225             {
1226                 module_unneed( id->p_encoder, id->p_encoder->p_module );
1227                 id->p_encoder->p_module = NULL;
1228             }
1229             msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1230                      p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1231                      (char *)&p_sys->i_acodec );
1232             transcode_audio_close( id );
1233             return VLC_EGENERIC;
1234         }
1235         id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1236         id->p_encoder->fmt_in.audio.i_bitspersample =
1237             aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1238 #else
1239         msg_Err( p_stream, "no audio filter found for mixing from"
1240                  " %i to %i channels", fmt_last.audio.i_channels,
1241                  id->p_encoder->fmt_in.audio.i_channels );
1242
1243         transcode_audio_close( id );
1244         return VLC_EGENERIC;
1245 #endif
1246     }
1247
1248     if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1249     {
1250         msg_Err( p_stream, "no audio filter found for resampling from"
1251                  " %iHz to %iHz", fmt_last.audio.i_rate,
1252                  id->p_encoder->fmt_in.audio.i_rate );
1253 #if 0
1254         /* FIXME : this might work, but only if the encoder is restarted */
1255         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1256         id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1257 #else
1258         transcode_audio_close( id );
1259         return VLC_EGENERIC;
1260 #endif
1261     }
1262
1263     /* FIXME: Hack for mp3 transcoding support */
1264     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1265         id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1266
1267     return VLC_SUCCESS;
1268 }
1269
1270 static void transcode_audio_close( sout_stream_id_t *id )
1271 {
1272     audio_timer_close( id->p_encoder );
1273
1274     /* Close decoder */
1275     if( id->p_decoder->p_module )
1276         module_unneed( id->p_decoder, id->p_decoder->p_module );
1277     id->p_decoder->p_module = NULL;
1278
1279     if( id->p_decoder->p_description )
1280         vlc_meta_Delete( id->p_decoder->p_description );
1281     id->p_decoder->p_description = NULL;
1282
1283     /* Close encoder */
1284     if( id->p_encoder->p_module )
1285         module_unneed( id->p_encoder, id->p_encoder->p_module );
1286     id->p_encoder->p_module = NULL;
1287
1288     /* Close filters */
1289     if( id->p_f_chain )
1290         filter_chain_Delete( id->p_f_chain );
1291     if( id->p_uf_chain )
1292         filter_chain_Delete( id->p_uf_chain );
1293 }
1294
1295 static int transcode_audio_process( sout_stream_t *p_stream,
1296                                     sout_stream_id_t *id,
1297                                     block_t *in, block_t **out )
1298 {
1299     sout_stream_sys_t *p_sys = p_stream->p_sys;
1300     aout_buffer_t *p_audio_buf;
1301     block_t *p_block, *p_audio_block;
1302     *out = NULL;
1303
1304     while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1305                                                           &in )) )
1306     {
1307         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1308         if( p_sys->b_master_sync )
1309         {
1310             mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1311             if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1312                   || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1313             {
1314                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1315                 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1316                 i_dts = p_audio_buf->start_date + 1;
1317             }
1318             p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1319             date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1320             p_audio_buf->start_date -= p_sys->i_master_drift;
1321             p_audio_buf->end_date -= p_sys->i_master_drift;
1322         }
1323
1324         p_audio_block = p_audio_buf->p_sys;
1325         p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1326         p_audio_block->i_dts = p_audio_block->i_pts =
1327             p_audio_buf->start_date;
1328         p_audio_block->i_length = p_audio_buf->end_date -
1329             p_audio_buf->start_date;
1330         p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1331
1332         /* Run filter chain */
1333         p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1334         if( id->p_uf_chain )
1335             p_audio_block = filter_chain_AudioFilter( id->p_uf_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", 0 );
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_decoder->fmt_in.video.i_width ?: 16;
1497     id->p_encoder->fmt_in.video.i_height =
1498         id->p_encoder->fmt_out.video.i_height ?:
1499         id->p_decoder->fmt_in.video.i_height ?: 16;
1500     id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1501     id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1502
1503     id->p_encoder->i_threads = p_sys->i_threads;
1504     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1505
1506     id->p_encoder->p_module =
1507         module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1508     if( !id->p_encoder->p_module )
1509     {
1510         msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1511                  p_sys->psz_venc ? p_sys->psz_venc : "any",
1512                  (char *)&p_sys->i_vcodec );
1513         module_unneed( id->p_decoder, id->p_decoder->p_module );
1514         id->p_decoder->p_module = 0;
1515         free( id->p_decoder->p_owner );
1516         return VLC_EGENERIC;
1517     }
1518
1519     /* Close the encoder.
1520      * We'll open it only when we have the first frame. */
1521     module_unneed( id->p_encoder, id->p_encoder->p_module );
1522     if( id->p_encoder->fmt_out.p_extra )
1523     {
1524         free( id->p_encoder->fmt_out.p_extra );
1525         id->p_encoder->fmt_out.p_extra = NULL;
1526         id->p_encoder->fmt_out.i_extra = 0;
1527     }
1528     id->p_encoder->p_module = NULL;
1529
1530     if( p_sys->i_threads >= 1 )
1531     {
1532         int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1533                            VLC_THREAD_PRIORITY_VIDEO;
1534         p_sys->id_video = id;
1535         vlc_mutex_init( &p_sys->lock_out );
1536         vlc_cond_init( &p_sys->cond );
1537         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1538         p_sys->i_first_pic = 0;
1539         p_sys->i_last_pic = 0;
1540         p_sys->p_buffers = NULL;
1541         p_sys->b_die = p_sys->b_error = 0;
1542         if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1543                                false ) )
1544         {
1545             msg_Err( p_stream, "cannot spawn encoder thread" );
1546             module_unneed( id->p_decoder, id->p_decoder->p_module );
1547             id->p_decoder->p_module = 0;
1548             free( id->p_decoder->p_owner );
1549             return VLC_EGENERIC;
1550         }
1551     }
1552
1553     return VLC_SUCCESS;
1554 }
1555
1556 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1557                                           sout_stream_id_t *id )
1558 {
1559     sout_stream_sys_t *p_sys = p_stream->p_sys;
1560
1561     /* Calculate scaling
1562      * width/height of source */
1563     int i_src_width = id->p_decoder->fmt_out.video.i_width;
1564     int i_src_height = id->p_decoder->fmt_out.video.i_height;
1565
1566     /* with/height scaling */
1567     float f_scale_width = 1;
1568     float f_scale_height = 1;
1569
1570     /* width/height of output stream */
1571     int i_dst_width;
1572     int i_dst_height;
1573
1574     /* aspect ratio */
1575     float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1576                             VOUT_ASPECT_FACTOR;
1577
1578     msg_Dbg( p_stream, "decoder aspect is %i:%i",
1579                  id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1580
1581     /* Change f_aspect from source frame to source pixel */
1582     f_aspect = f_aspect * i_src_height / i_src_width;
1583     msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1584
1585     /* Calculate scaling factor for specified parameters */
1586     if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1587         id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1588     {
1589         /* Global scaling. Make sure width will remain a factor of 16 */
1590         float f_real_scale;
1591         int  i_new_height;
1592         int i_new_width = i_src_width * p_sys->f_scale;
1593
1594         if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1595             i_new_width -= i_new_width % 16;
1596         else
1597             i_new_width += 16 - i_new_width % 16;
1598
1599         f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1600
1601         i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1602
1603         f_scale_width = f_real_scale;
1604         f_scale_height = (float) i_new_height / (float) i_src_height;
1605     }
1606     else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1607              id->p_encoder->fmt_out.video.i_height <= 0 )
1608     {
1609         /* Only width specified */
1610         f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1611         f_scale_height = f_scale_width;
1612     }
1613     else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1614              id->p_encoder->fmt_out.video.i_height > 0 )
1615     {
1616          /* Only height specified */
1617          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1618          f_scale_width = f_scale_height;
1619      }
1620      else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1621               id->p_encoder->fmt_out.video.i_height > 0 )
1622      {
1623          /* Width and height specified */
1624          f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1625          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1626      }
1627
1628      /* check maxwidth and maxheight
1629       */
1630      if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1631                                                      i_src_width )
1632      {
1633          f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1634      }
1635
1636      if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1637                                                        i_src_height )
1638      {
1639          f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1640      }
1641
1642
1643      /* Change aspect ratio from source pixel to scaled pixel */
1644      f_aspect = f_aspect * f_scale_height / f_scale_width;
1645      msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1646
1647      /* f_scale_width and f_scale_height are now final */
1648      /* Calculate width, height from scaling
1649       * Make sure its multiple of 2
1650       */
1651      i_dst_width =  2 * (int)(f_scale_width*i_src_width/2+0.5);
1652      i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1653
1654      /* Change aspect ratio from scaled pixel to output frame */
1655      f_aspect = f_aspect * i_dst_width / i_dst_height;
1656
1657      /* Store calculated values */
1658      id->p_encoder->fmt_out.video.i_width =
1659      id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1660      id->p_encoder->fmt_out.video.i_height =
1661      id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1662
1663      id->p_encoder->fmt_in.video.i_width =
1664      id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1665      id->p_encoder->fmt_in.video.i_height =
1666      id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1667
1668      msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1669          i_src_width, i_src_height,
1670          i_dst_width, i_dst_height
1671      );
1672
1673     /* Handle frame rate conversion */
1674     if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1675         !id->p_encoder->fmt_out.video.i_frame_rate_base )
1676     {
1677         if( id->p_decoder->fmt_out.video.i_frame_rate &&
1678             id->p_decoder->fmt_out.video.i_frame_rate_base )
1679         {
1680             id->p_encoder->fmt_out.video.i_frame_rate =
1681                 id->p_decoder->fmt_out.video.i_frame_rate;
1682             id->p_encoder->fmt_out.video.i_frame_rate_base =
1683                 id->p_decoder->fmt_out.video.i_frame_rate_base;
1684         }
1685         else
1686         {
1687             /* Pick a sensible default value */
1688             id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1689             id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1690         }
1691     }
1692
1693     id->p_encoder->fmt_in.video.i_frame_rate =
1694         id->p_encoder->fmt_out.video.i_frame_rate;
1695     id->p_encoder->fmt_in.video.i_frame_rate_base =
1696         id->p_encoder->fmt_out.video.i_frame_rate_base;
1697
1698     date_Init( &id->interpolated_pts,
1699                id->p_encoder->fmt_out.video.i_frame_rate,
1700                id->p_encoder->fmt_out.video.i_frame_rate_base );
1701
1702     /* Check whether a particular aspect ratio was requested */
1703     if( !id->p_encoder->fmt_out.video.i_aspect )
1704     {
1705         id->p_encoder->fmt_out.video.i_aspect =
1706                 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1707     }
1708     id->p_encoder->fmt_in.video.i_aspect =
1709         id->p_encoder->fmt_out.video.i_aspect;
1710
1711     msg_Dbg( p_stream, "encoder aspect is %i:%i",
1712              id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1713
1714     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1715 }
1716
1717 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1718                                          sout_stream_id_t *id )
1719 {
1720     sout_stream_sys_t *p_sys = p_stream->p_sys;
1721
1722
1723     msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1724              id->p_encoder->fmt_in.video.i_width,
1725              id->p_encoder->fmt_in.video.i_height );
1726
1727     id->p_encoder->p_module =
1728         module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1729     if( !id->p_encoder->p_module )
1730     {
1731         msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1732                  p_sys->psz_venc ? p_sys->psz_venc : "any",
1733                  (char *)&p_sys->i_vcodec );
1734         return VLC_EGENERIC;
1735     }
1736
1737     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1738
1739     /* Hack for mp2v/mp1v transcoding support */
1740     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1741         id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1742     {
1743         id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1744     }
1745
1746     id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1747                                &id->p_encoder->fmt_out );
1748     if( !id->id )
1749     {
1750         msg_Err( p_stream, "cannot add this stream" );
1751         return VLC_EGENERIC;
1752     }
1753
1754     return VLC_SUCCESS;
1755 }
1756
1757 static void transcode_video_close( sout_stream_t *p_stream,
1758                                    sout_stream_id_t *id )
1759 {
1760     int i;
1761
1762     if( p_stream->p_sys->i_threads >= 1 )
1763     {
1764         vlc_mutex_lock( &p_stream->p_sys->lock_out );
1765         vlc_object_kill( p_stream->p_sys );
1766         vlc_cond_signal( &p_stream->p_sys->cond );
1767         vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1768         vlc_thread_join( p_stream->p_sys );
1769         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1770         vlc_cond_destroy( &p_stream->p_sys->cond );
1771     }
1772
1773     video_timer_close( id->p_encoder );
1774
1775     /* Close decoder */
1776     if( id->p_decoder->p_module )
1777         module_unneed( id->p_decoder, id->p_decoder->p_module );
1778     if( id->p_decoder->p_description )
1779         vlc_meta_Delete( id->p_decoder->p_description );
1780
1781     if( id->p_decoder->p_owner )
1782     {
1783         /* Clean-up pictures ring buffer */
1784         for( i = 0; i < PICTURE_RING_SIZE; i++ )
1785         {
1786             if( id->p_decoder->p_owner->pp_pics[i] )
1787                 video_del_buffer( VLC_OBJECT(id->p_decoder),
1788                                   id->p_decoder->p_owner->pp_pics[i] );
1789         }
1790         free( id->p_decoder->p_owner );
1791     }
1792
1793     /* Close encoder */
1794     if( id->p_encoder->p_module )
1795         module_unneed( id->p_encoder, id->p_encoder->p_module );
1796
1797     /* Close filters */
1798     if( id->p_f_chain )
1799         filter_chain_Delete( id->p_f_chain );
1800     if( id->p_uf_chain )
1801         filter_chain_Delete( id->p_uf_chain );
1802 }
1803
1804 static int transcode_video_process( sout_stream_t *p_stream,
1805                                     sout_stream_id_t *id,
1806                                     block_t *in, block_t **out )
1807 {
1808     sout_stream_sys_t *p_sys = p_stream->p_sys;
1809     int i_duplicate = 1;
1810     picture_t *p_pic, *p_pic2 = NULL;
1811     *out = NULL;
1812
1813     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1814     {
1815         subpicture_t *p_subpic = NULL;
1816
1817         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1818
1819         if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1820         {
1821             mtime_t current_date = mdate();
1822             if( current_date + 50000 > p_pic->date )
1823             {
1824                 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1825                          current_date + 50000 - p_pic->date );
1826                 p_pic->pf_release( p_pic );
1827                 continue;
1828             }
1829         }
1830
1831         if( p_sys->b_master_sync )
1832         {
1833             mtime_t i_video_drift;
1834             mtime_t i_master_drift = p_sys->i_master_drift;
1835             mtime_t i_pts;
1836
1837             i_pts = date_Get( &id->interpolated_pts ) + 1;
1838             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1839                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1840             {
1841                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1842                 date_Set( &id->interpolated_pts, p_pic->date );
1843                 i_pts = p_pic->date + 1;
1844             }
1845             i_video_drift = p_pic->date - i_pts;
1846             i_duplicate = 1;
1847
1848             /* Set the pts of the frame being encoded */
1849             p_pic->date = i_pts;
1850
1851             if( i_video_drift < (i_master_drift - 50000) )
1852             {
1853 #if 0
1854                 msg_Dbg( p_stream, "dropping frame (%i)",
1855                          (int)(i_video_drift - i_master_drift) );
1856 #endif
1857                 p_pic->pf_release( p_pic );
1858                 continue;
1859             }
1860             else if( i_video_drift > (i_master_drift + 50000) )
1861             {
1862 #if 0
1863                 msg_Dbg( p_stream, "adding frame (%i)",
1864                          (int)(i_video_drift - i_master_drift) );
1865 #endif
1866                 i_duplicate = 2;
1867             }
1868         }
1869
1870         if( !id->p_encoder->p_module )
1871         {
1872             transcode_video_encoder_init( p_stream, id );
1873
1874             id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1875                                               false,
1876                                transcode_video_filter_allocation_init,
1877                                transcode_video_filter_allocation_clear,
1878                                p_stream->p_sys );
1879
1880             /* Deinterlace */
1881             if( p_stream->p_sys->b_deinterlace )
1882             {
1883                 filter_chain_AppendFilter( id->p_f_chain,
1884                                            p_sys->psz_deinterlace,
1885                                            p_sys->p_deinterlace_cfg,
1886                                            &id->p_decoder->fmt_out,
1887                                            &id->p_decoder->fmt_out );
1888             }
1889
1890             /* Take care of the scaling and chroma conversions */
1891             if( ( id->p_decoder->fmt_out.video.i_chroma !=
1892                   id->p_encoder->fmt_in.video.i_chroma ) ||
1893                 ( id->p_decoder->fmt_out.video.i_width !=
1894                   id->p_encoder->fmt_in.video.i_width ) ||
1895                 ( id->p_decoder->fmt_out.video.i_height !=
1896                   id->p_encoder->fmt_in.video.i_height ) )
1897             {
1898                 filter_chain_AppendFilter( id->p_f_chain,
1899                                            NULL, NULL,
1900                                            &id->p_decoder->fmt_out,
1901                                            &id->p_encoder->fmt_in );
1902             }
1903
1904             if( p_sys->psz_vf2 )
1905             {
1906                 const es_format_t *p_fmt_out;
1907                 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1908                                                    true,
1909                                    transcode_video_filter_allocation_init,
1910                                    transcode_video_filter_allocation_clear,
1911                                    p_stream->p_sys );
1912                 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1913                                     &id->p_encoder->fmt_in );
1914                 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1915                 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1916                 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1917                 id->p_encoder->fmt_out.video.i_width =
1918                     id->p_encoder->fmt_in.video.i_width;
1919                 id->p_encoder->fmt_out.video.i_height =
1920                     id->p_encoder->fmt_in.video.i_height;
1921                 id->p_encoder->fmt_out.video.i_aspect =
1922                     id->p_encoder->fmt_in.video.i_aspect;
1923             }
1924
1925             if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1926             {
1927                 p_pic->pf_release( p_pic );
1928                 transcode_video_close( p_stream, id );
1929                 id->b_transcode = false;
1930                 return VLC_EGENERIC;
1931             }
1932         }
1933
1934         /* Run filter chain */
1935         if( id->p_f_chain )
1936             p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1937
1938         /*
1939          * Encoding
1940          */
1941
1942         /* Check if we have a subpicture to overlay */
1943         if( p_sys->p_spu )
1944         {
1945             p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1946                        false /* Fixme: check if stream is paused */, false );
1947             /* TODO: get another pic */
1948         }
1949
1950         /* Overlay subpicture */
1951         if( p_subpic )
1952         {
1953             video_format_t fmt;
1954
1955             if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1956             {
1957                 /* We can't modify the picture, we need to duplicate it */
1958                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1959                 if( p_tmp )
1960                 {
1961                     picture_Copy( p_tmp, p_pic );
1962                     p_pic->pf_release( p_pic );
1963                     p_pic = p_tmp;
1964                 }
1965             }
1966
1967             if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1968                 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1969             else
1970                 fmt = id->p_decoder->fmt_out.video;
1971
1972             /* FIXME (shouldn't have to be done here) */
1973             fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1974             fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1975
1976             spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1977                                    p_subpic, &id->p_decoder->fmt_out.video, false );
1978         }
1979
1980         /* Run user specified filter chain */
1981         if( id->p_uf_chain )
1982             p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1983
1984         if( p_sys->i_threads == 0 )
1985         {
1986             block_t *p_block;
1987
1988             video_timer_start( id->p_encoder );
1989             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1990             video_timer_stop( id->p_encoder );
1991
1992             block_ChainAppend( out, p_block );
1993         }
1994
1995         if( p_sys->b_master_sync )
1996         {
1997             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1998             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1999                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2000             {
2001                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2002                 date_Set( &id->interpolated_pts, p_pic->date );
2003                 i_pts = p_pic->date + 1;
2004             }
2005             date_Increment( &id->interpolated_pts, 1 );
2006         }
2007
2008         if( p_sys->b_master_sync && i_duplicate > 1 )
2009         {
2010             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2011             if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2012                  || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2013             {
2014                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2015                 date_Set( &id->interpolated_pts, p_pic->date );
2016                 i_pts = p_pic->date + 1;
2017             }
2018             date_Increment( &id->interpolated_pts, 1 );
2019
2020             if( p_sys->i_threads >= 1 )
2021             {
2022                 /* We can't modify the picture, we need to duplicate it */
2023                 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2024                 if( p_pic2 != NULL )
2025                 {
2026                     picture_Copy( p_pic2, p_pic );
2027                     p_pic2->date = i_pts;
2028                 }
2029             }
2030             else
2031             {
2032                 block_t *p_block;
2033                 p_pic->date = i_pts;
2034                 video_timer_start( id->p_encoder );
2035                 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2036                 video_timer_stop( id->p_encoder );
2037                 block_ChainAppend( out, p_block );
2038             }
2039         }
2040
2041         if( p_sys->i_threads == 0 )
2042         {
2043             p_pic->pf_release( p_pic );
2044         }
2045         else
2046         {
2047             vlc_mutex_lock( &p_sys->lock_out );
2048             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2049             p_sys->i_last_pic %= PICTURE_RING_SIZE;
2050             *out = p_sys->p_buffers;
2051             p_sys->p_buffers = NULL;
2052             if( p_pic2 != NULL )
2053             {
2054                 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2055                 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2056             }
2057             vlc_cond_signal( &p_sys->cond );
2058             vlc_mutex_unlock( &p_sys->lock_out );
2059         }
2060     }
2061
2062     return VLC_SUCCESS;
2063 }
2064
2065 static void* EncoderThread( vlc_object_t* p_this )
2066 {
2067     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2068     sout_stream_id_t *id = p_sys->id_video;
2069     picture_t *p_pic;
2070     int canc = vlc_savecancel ();
2071
2072     while( vlc_object_alive (p_sys) && !p_sys->b_error )
2073     {
2074         block_t *p_block;
2075
2076         vlc_mutex_lock( &p_sys->lock_out );
2077         while( p_sys->i_last_pic == p_sys->i_first_pic )
2078         {
2079             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2080             if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2081         }
2082         if( !vlc_object_alive (p_sys) || p_sys->b_error )
2083         {
2084             vlc_mutex_unlock( &p_sys->lock_out );
2085             break;
2086         }
2087
2088         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2089         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2090         vlc_mutex_unlock( &p_sys->lock_out );
2091
2092         video_timer_start( id->p_encoder );
2093         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2094         video_timer_stop( id->p_encoder );
2095
2096         vlc_mutex_lock( &p_sys->lock_out );
2097         block_ChainAppend( &p_sys->p_buffers, p_block );
2098
2099         vlc_mutex_unlock( &p_sys->lock_out );
2100         p_pic->pf_release( p_pic );
2101     }
2102
2103     while( p_sys->i_last_pic != p_sys->i_first_pic )
2104     {
2105         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2106         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2107         p_pic->pf_release( p_pic );
2108     }
2109     block_ChainRelease( p_sys->p_buffers );
2110
2111     vlc_restorecancel (canc);
2112     return NULL;
2113 }
2114
2115 struct picture_sys_t
2116 {
2117     vlc_object_t *p_owner;
2118 };
2119
2120 static void video_release_buffer( picture_t *p_pic )
2121 {
2122     if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2123     {
2124         video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2125     }
2126     else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2127 }
2128
2129 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2130                                     sout_stream_sys_t *p_sys )
2131 {
2132     decoder_t *p_dec = (decoder_t *)p_this;
2133     picture_t *p_pic;
2134     int i;
2135
2136     /* Find an empty space in the picture ring buffer */
2137     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2138     {
2139         if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2140         {
2141             pp_ring[i]->i_status = RESERVED_PICTURE;
2142             return pp_ring[i];
2143         }
2144     }
2145     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2146     {
2147         if( pp_ring[i] == 0 ) break;
2148     }
2149
2150     if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2151     {
2152         int i_first_pic = p_sys->i_first_pic;
2153
2154         if( p_sys->i_first_pic != p_sys->i_last_pic )
2155         {
2156             /* Encoder still has stuff to encode, wait to clear-up the list */
2157             while( p_sys->i_first_pic == i_first_pic )
2158                 msleep( 100000 );
2159         }
2160
2161         /* Find an empty space in the picture ring buffer */
2162         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2163         {
2164             if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2165             {
2166                 pp_ring[i]->i_status = RESERVED_PICTURE;
2167                 return pp_ring[i];
2168             }
2169         }
2170         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2171         {
2172             if( pp_ring[i] == 0 ) break;
2173         }
2174     }
2175
2176     if( i == PICTURE_RING_SIZE )
2177     {
2178         msg_Err( p_this, "decoder/filter is leaking pictures, "
2179                  "resetting its ring buffer" );
2180
2181         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2182         {
2183             pp_ring[i]->pf_release( pp_ring[i] );
2184         }
2185
2186         i = 0;
2187     }
2188
2189     p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2190                          p_dec->fmt_out.video.i_width,
2191                          p_dec->fmt_out.video.i_height,
2192                          p_dec->fmt_out.video.i_aspect );
2193     if( !p_pic ) return NULL;
2194     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2195     p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2196     if( !p_pic->p_sys )
2197     {
2198         picture_Release( p_pic );
2199         return NULL;
2200     }
2201     p_pic->pf_release = video_release_buffer;
2202     p_pic->i_refcount = 0;
2203
2204     pp_ring[i] = p_pic;
2205     return p_pic;
2206 }
2207
2208 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2209 {
2210     return video_new_buffer( VLC_OBJECT(p_dec),
2211                              p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2212 }
2213
2214 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2215 {
2216     return video_new_buffer( VLC_OBJECT(p_filter),
2217                              p_filter->p_owner->pp_pics,
2218                              p_filter->p_owner->p_sys );
2219 }
2220
2221 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2222 {
2223     VLC_UNUSED(p_this);
2224     if( p_pic )
2225     {
2226         free( p_pic->p_q );
2227         free( p_pic->p_data_orig );
2228         free( p_pic->p_sys );
2229         free( p_pic );
2230     }
2231 }
2232
2233 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2234 {
2235     VLC_UNUSED(p_decoder);
2236     p_pic->i_refcount = 0;
2237     p_pic->i_status = DESTROYED_PICTURE;
2238     picture_CleanupQuant( p_pic );
2239 }
2240
2241 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2242 {
2243     VLC_UNUSED(p_filter);
2244     p_pic->i_refcount = 0;
2245     p_pic->i_status = DESTROYED_PICTURE;
2246     picture_CleanupQuant( p_pic );
2247 }
2248
2249 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2250 {
2251     VLC_UNUSED(p_dec);
2252     p_pic->i_refcount++;
2253 }
2254
2255 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2256 {
2257     VLC_UNUSED(p_dec);
2258     video_release_buffer( p_pic );
2259 }
2260
2261 /*
2262  * SPU
2263  */
2264 static subpicture_t *spu_new_buffer( decoder_t * );
2265 static void spu_del_buffer( decoder_t *, subpicture_t * );
2266
2267 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2268 {
2269     sout_stream_sys_t *p_sys = p_stream->p_sys;
2270
2271     /*
2272      * Open decoder
2273      */
2274
2275     /* Initialization of decoder structures */
2276     id->p_decoder->pf_decode_sub = NULL;
2277     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2278     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2279     id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2280     /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2281
2282     id->p_decoder->p_module =
2283         module_need( id->p_decoder, "decoder", "$codec", 0 );
2284
2285     if( !id->p_decoder->p_module )
2286     {
2287         msg_Err( p_stream, "cannot find spu decoder" );
2288         return VLC_EGENERIC;
2289     }
2290
2291     if( !p_sys->b_soverlay )
2292     {
2293         /* Open encoder */
2294         /* Initialization of encoder format structures */
2295         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2296                         id->p_decoder->fmt_in.i_codec );
2297
2298         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2299
2300         id->p_encoder->p_module =
2301             module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2302
2303         if( !id->p_encoder->p_module )
2304         {
2305             module_unneed( id->p_decoder, id->p_decoder->p_module );
2306             msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2307             return VLC_EGENERIC;
2308         }
2309     }
2310
2311     if( !p_sys->p_spu )
2312     {
2313         p_sys->p_spu = spu_Create( p_stream );
2314         spu_Init( p_sys->p_spu );
2315     }
2316
2317     return VLC_SUCCESS;
2318 }
2319
2320 static void transcode_spu_close( sout_stream_id_t *id)
2321 {
2322     /* Close decoder */
2323     if( id->p_decoder->p_module )
2324         module_unneed( id->p_decoder, id->p_decoder->p_module );
2325     if( id->p_decoder->p_description )
2326         vlc_meta_Delete( id->p_decoder->p_description );
2327
2328     /* Close encoder */
2329     if( id->p_encoder->p_module )
2330         module_unneed( id->p_encoder, id->p_encoder->p_module );
2331 }
2332
2333 static int transcode_spu_process( sout_stream_t *p_stream,
2334                                   sout_stream_id_t *id,
2335                                   block_t *in, block_t **out )
2336 {
2337     sout_stream_sys_t *p_sys = p_stream->p_sys;
2338     subpicture_t *p_subpic;
2339     *out = NULL;
2340
2341     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2342     if( !p_subpic )
2343         return VLC_EGENERIC;
2344
2345     sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2346
2347     if( p_sys->b_master_sync && p_sys->i_master_drift )
2348     {
2349         p_subpic->i_start -= p_sys->i_master_drift;
2350         if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2351     }
2352
2353     if( p_sys->b_soverlay )
2354     {
2355         spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2356     }
2357     else
2358     {
2359         block_t *p_block;
2360
2361         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2362         spu_del_buffer( id->p_decoder, p_subpic );
2363         if( p_block )
2364         {
2365             block_ChainAppend( out, p_block );
2366             return VLC_SUCCESS;
2367         }
2368     }
2369
2370     return VLC_EGENERIC;
2371 }
2372
2373 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2374 {
2375     VLC_UNUSED( p_dec );
2376     return subpicture_New();
2377 }
2378
2379 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2380 {
2381     VLC_UNUSED( p_dec );
2382     subpicture_Delete( p_subpic );
2383 }
2384
2385 /*
2386  * OSD menu
2387  */
2388 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2389 {
2390     sout_stream_sys_t *p_sys = p_stream->p_sys;
2391
2392     id->p_decoder->fmt_in.i_cat = SPU_ES;
2393     id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2394
2395     if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2396     {
2397         msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2398                  "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2399                  (char*)&p_sys->i_osdcodec );
2400
2401         /* Complete destination format */
2402         id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2403
2404         /* Open encoder */
2405         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2406                         VLC_FOURCC('Y','U','V','A') );
2407         id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2408
2409         id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2410
2411         id->p_encoder->p_module =
2412             module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2413
2414         if( !id->p_encoder->p_module )
2415         {
2416             msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2417             goto error;
2418         }
2419
2420         /* open output stream */
2421         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2422         id->b_transcode = true;
2423
2424         if( !id->id ) goto error;
2425     }
2426     else
2427     {
2428         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2429                  (char*)&id->p_decoder->fmt_out.i_codec );
2430         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2431         id->b_transcode = false;
2432
2433         if( !id->id ) goto error;
2434     }
2435
2436     if( !p_sys->p_spu )
2437     {
2438         p_sys->p_spu = spu_Create( p_stream );
2439         spu_Init( p_sys->p_spu );
2440     }
2441
2442     return VLC_SUCCESS;
2443
2444  error:
2445     msg_Err( p_stream, "starting osd encoding thread failed" );
2446     if( id->p_encoder->p_module )
2447             module_unneed( id->p_encoder, id->p_encoder->p_module );
2448     p_sys->b_osd = false;
2449     return VLC_EGENERIC;
2450 }
2451
2452 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2453 {
2454     sout_stream_sys_t *p_sys = p_stream->p_sys;
2455
2456     /* Close encoder */
2457     if( id )
2458     {
2459         if( id->p_encoder->p_module )
2460             module_unneed( id->p_encoder, id->p_encoder->p_module );
2461     }
2462     p_sys->b_osd = false;
2463 }
2464
2465 static int transcode_osd_process( sout_stream_t *p_stream,
2466                                   sout_stream_id_t *id,
2467                                   block_t *in, block_t **out )
2468 {
2469     sout_stream_sys_t *p_sys = p_stream->p_sys;
2470     subpicture_t *p_subpic = NULL;
2471
2472     /* Check if we have a subpicture to send */
2473     if( p_sys->p_spu && in->i_dts > 0)
2474     {
2475         p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2476     }
2477     else
2478     {
2479         msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2480         if( !p_sys->p_spu )
2481         {
2482             p_sys->p_spu = spu_Create( p_stream );
2483             spu_Init( p_sys->p_spu );
2484         }
2485     }
2486
2487     if( p_subpic )
2488     {
2489         block_t *p_block = NULL;
2490
2491         if( p_sys->b_master_sync && p_sys->i_master_drift )
2492         {
2493             p_subpic->i_start -= p_sys->i_master_drift;
2494             if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2495         }
2496
2497         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2498         subpicture_Delete( p_subpic );
2499         if( p_block )
2500         {
2501             p_block->i_dts = p_block->i_pts = in->i_dts;
2502             block_ChainAppend( out, p_block );
2503             return VLC_SUCCESS;
2504         }
2505     }
2506     return VLC_EGENERIC;
2507 }