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