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