]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
Use gettext_noop() consistently
[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 reencoder part
1226  ****************************************************************************/
1227 static int audio_BitsPerSample( vlc_fourcc_t i_format )
1228 {
1229     switch( i_format )
1230     {
1231     case VLC_FOURCC('u','8',' ',' '):
1232     case VLC_FOURCC('s','8',' ',' '):
1233         return 8;
1234
1235     case VLC_FOURCC('u','1','6','l'):
1236     case VLC_FOURCC('s','1','6','l'):
1237     case VLC_FOURCC('u','1','6','b'):
1238     case VLC_FOURCC('s','1','6','b'):
1239         return 16;
1240
1241     case VLC_FOURCC('u','2','4','l'):
1242     case VLC_FOURCC('s','2','4','l'):
1243     case VLC_FOURCC('u','2','4','b'):
1244     case VLC_FOURCC('s','2','4','b'):
1245         return 24;
1246
1247     case VLC_FOURCC('u','3','2','l'):
1248     case VLC_FOURCC('s','3','2','l'):
1249     case VLC_FOURCC('u','3','2','b'):
1250     case VLC_FOURCC('s','3','2','b'):
1251     case VLC_FOURCC('f','l','3','2'):
1252     case VLC_FOURCC('f','i','3','2'):
1253         return 32;
1254
1255     case VLC_FOURCC('f','l','6','4'):
1256         return 64;
1257     }
1258
1259     return 0;
1260 }
1261
1262 static block_t *transcode_audio_alloc (filter_t *filter, int size)
1263 {
1264     return block_New (filter, size);
1265 }
1266
1267 static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream,
1268                                              sout_stream_id_t *id,
1269                                              es_format_t *p_fmt_in,
1270                                              es_format_t *p_fmt_out,
1271                                              char *psz_name )
1272 {
1273     sout_stream_sys_t *p_sys = p_stream->p_sys;
1274     filter_t *p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1275
1276     vlc_object_attach( p_filter, p_stream );
1277     p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1278
1279     p_filter->fmt_in = *p_fmt_in;
1280     p_filter->fmt_out = *p_fmt_out;
1281     if( psz_name )
1282         p_filter->p_cfg = p_sys->p_afilters_cfg[id->i_ufilter];
1283
1284     p_filter->p_module = module_Need( p_filter, "audio filter2", psz_name,
1285                                       true );
1286     if( p_filter->p_module )
1287     {
1288         p_filter->fmt_out.audio.i_bitspersample =
1289             audio_BitsPerSample( p_filter->fmt_out.i_codec );
1290         *p_fmt_in = p_filter->fmt_out;
1291     }
1292     else
1293     {
1294         vlc_object_detach( p_filter );
1295         vlc_object_release( p_filter );
1296         p_filter = 0;
1297     }
1298
1299     return p_filter;
1300 }
1301
1302 static int transcode_audio_new( sout_stream_t *p_stream,
1303                                 sout_stream_id_t *id )
1304 {
1305     sout_stream_sys_t *p_sys = p_stream->p_sys;
1306     es_format_t fmt_last;
1307     int i;
1308
1309     /*
1310      * Open decoder
1311      */
1312
1313     /* Initialization of decoder structures */
1314     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1315     id->p_decoder->fmt_out.i_extra = 0;
1316     id->p_decoder->fmt_out.p_extra = 0;
1317     id->p_decoder->pf_decode_audio = NULL;
1318     id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1319     id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1320     /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1321
1322     id->p_decoder->p_module =
1323         module_Need( id->p_decoder, "decoder", "$codec", 0 );
1324     if( !id->p_decoder->p_module )
1325     {
1326         msg_Err( p_stream, "cannot find decoder" );
1327         return VLC_EGENERIC;
1328     }
1329     id->p_decoder->fmt_out.audio.i_bitspersample =
1330         audio_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1331     fmt_last = id->p_decoder->fmt_out;
1332     /* Fix AAC SBR changing number of channels and sampling rate */
1333     if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1334         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1335         fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1336         fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1337
1338     /*
1339      * Open encoder
1340      */
1341
1342     /* Initialization of encoder format structures */
1343     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1344                     id->p_decoder->fmt_out.i_codec );
1345     id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1346
1347     if( ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','m','r') ) ||
1348         ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','w','b') ) )
1349          id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1350     else
1351         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1352     id->p_encoder->fmt_in.audio.i_physical_channels =
1353         id->p_encoder->fmt_out.audio.i_physical_channels;
1354     id->p_encoder->fmt_in.audio.i_original_channels =
1355         id->p_encoder->fmt_out.audio.i_original_channels;
1356     id->p_encoder->fmt_in.audio.i_channels =
1357         id->p_encoder->fmt_out.audio.i_channels;
1358     id->p_encoder->fmt_in.audio.i_bitspersample =
1359         audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1360
1361     id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1362     id->p_encoder->p_module =
1363         module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1364     if( !id->p_encoder->p_module )
1365     {
1366         msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
1367         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1368         id->p_decoder->p_module = NULL;
1369         return VLC_EGENERIC;
1370     }
1371     id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1372     id->p_encoder->fmt_in.audio.i_bitspersample =
1373         audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1374
1375     /* Load conversion filters */
1376     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1377         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1378     {
1379         /* We'll have to go through fl32 first */
1380         es_format_t fmt_out = id->p_encoder->fmt_in;
1381         fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2');
1382
1383         id->pp_filter[id->i_filter] =
1384             transcode_audio_filter_new( p_stream, id, &fmt_last, &fmt_out, NULL );
1385
1386         if( id->pp_filter[id->i_filter] ) id->i_filter++;
1387     }
1388
1389     for( i = 0; i < TRANSCODE_FILTERS; i++ )
1390     {
1391         if( (fmt_last.audio.i_channels !=
1392             id->p_encoder->fmt_in.audio.i_channels) ||
1393             (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1394             (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1395         {
1396             id->pp_filter[id->i_filter] =
1397                 transcode_audio_filter_new( p_stream, id, &fmt_last,
1398                                             &id->p_encoder->fmt_in, NULL );
1399
1400             if( id->pp_filter[id->i_filter] )
1401                 id->i_filter++;
1402             else
1403                 break;
1404         }
1405     }
1406
1407     /* Final checks to see if conversions were successful */
1408     if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1409     {
1410         msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1411                  (char *)&fmt_last.i_codec,
1412                  (char *)&id->p_encoder->fmt_in.i_codec );
1413         transcode_audio_close( id );
1414         return VLC_EGENERIC;
1415     }
1416
1417     /* Load user specified audio filters now */
1418     for( i = 0; (i < p_sys->i_afilters) &&
1419                 (id->i_ufilter < TRANSCODE_FILTERS); i++ )
1420     {
1421         id->pp_ufilter[id->i_ufilter] =
1422             transcode_audio_filter_new( p_stream, id, &fmt_last,
1423                                         &id->p_encoder->fmt_in,
1424                                         p_sys->psz_afilters[i] );
1425
1426         if( id->pp_ufilter[id->i_ufilter] )
1427             id->i_ufilter++;
1428         else
1429             break;
1430     }
1431
1432     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1433     {
1434 #if 1
1435         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1436         id->p_encoder->p_module = NULL;
1437
1438         /* This might work, but only if the encoder is restarted */
1439         id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1440         id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1441
1442         id->p_encoder->fmt_in.audio.i_physical_channels =
1443             id->p_encoder->fmt_in.audio.i_original_channels =
1444                 fmt_last.audio.i_physical_channels;
1445         id->p_encoder->fmt_out.audio.i_physical_channels =
1446             id->p_encoder->fmt_out.audio.i_original_channels =
1447                 fmt_last.audio.i_physical_channels;
1448
1449         msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1450                  "trying to reopen the encoder for mixing %i to %i channels",
1451                  fmt_last.audio.i_channels,
1452                  id->p_encoder->fmt_in.audio.i_channels );
1453
1454         /* reload encoder */
1455         id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1456         id->p_encoder->p_module =
1457             module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1458         if( !id->p_encoder->p_module )
1459         {
1460             msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
1461             transcode_audio_close( id );
1462             return VLC_EGENERIC;
1463         }
1464         id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1465         id->p_encoder->fmt_in.audio.i_bitspersample =
1466             audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1467 #else
1468         msg_Err( p_stream, "no audio filter found for mixing from"
1469                  " %i to %i channels", fmt_last.audio.i_channels,
1470                  id->p_encoder->fmt_in.audio.i_channels );
1471
1472         transcode_audio_close( id );
1473         return VLC_EGENERIC;
1474 #endif
1475     }
1476
1477     if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1478     {
1479         msg_Err( p_stream, "no audio filter found for resampling from"
1480                  " %iHz to %iHz", fmt_last.audio.i_rate,
1481                  id->p_encoder->fmt_in.audio.i_rate );
1482 #if 0
1483         /* FIXME : this might work, but only if the encoder is restarted */
1484         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1485         id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1486 #else
1487         transcode_audio_close( id );
1488         return VLC_EGENERIC;
1489 #endif
1490     }
1491
1492     /* FIXME: Hack for mp3 transcoding support */
1493     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1494         id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1495
1496     return VLC_SUCCESS;
1497 }
1498
1499 static void transcode_audio_close( sout_stream_id_t *id )
1500 {
1501     int i;
1502
1503     /* Close decoder */
1504     if( id->p_decoder->p_module )
1505         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1506     id->p_decoder->p_module = NULL;
1507
1508     /* Close encoder */
1509     if( id->p_encoder->p_module )
1510         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1511     id->p_encoder->p_module = NULL;
1512
1513     /* Close filters */
1514     for( i = 0; i < id->i_filter; i++ )
1515     {
1516         vlc_object_detach( id->pp_filter[i] );
1517         if( id->pp_filter[i]->p_module )
1518             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
1519         vlc_object_release( id->pp_filter[i] );
1520     }
1521     id->i_filter = 0;
1522
1523     for( i = 0; i < id->i_ufilter; i++ )
1524     {
1525         vlc_object_detach( id->pp_ufilter[i] );
1526         if( id->pp_ufilter[i]->p_module )
1527             module_Unneed( id->pp_ufilter[i], id->pp_ufilter[i]->p_module );
1528         vlc_object_release( id->pp_ufilter[i] );
1529     }
1530     id->i_ufilter = 0;
1531 }
1532
1533 static int transcode_audio_process( sout_stream_t *p_stream,
1534                                     sout_stream_id_t *id,
1535                                     block_t *in, block_t **out )
1536 {
1537     sout_stream_sys_t *p_sys = p_stream->p_sys;
1538     aout_buffer_t *p_audio_buf;
1539     block_t *p_block, *p_audio_block;
1540     int i;
1541     *out = NULL;
1542
1543     while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1544                                                           &in )) )
1545     {
1546         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1547         if( p_sys->b_master_sync )
1548         {
1549             mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1550             if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1551                   || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1552             {
1553                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1554                 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1555                 i_dts = p_audio_buf->start_date + 1;
1556             }
1557             p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1558             date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1559             p_audio_buf->start_date -= p_sys->i_master_drift;
1560             p_audio_buf->end_date -= p_sys->i_master_drift;
1561         }
1562
1563         p_audio_block = p_audio_buf->p_sys;
1564         p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1565         p_audio_block->i_dts = p_audio_block->i_pts =
1566             p_audio_buf->start_date;
1567         p_audio_block->i_length = p_audio_buf->end_date -
1568             p_audio_buf->start_date;
1569         p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1570
1571         /* Run filter chain */
1572         for( i = 0; i < id->i_filter; i++ )
1573         {
1574             p_audio_block =
1575                 id->pp_filter[i]->pf_audio_filter( id->pp_filter[i],
1576                                                    p_audio_block );
1577         }
1578
1579         /* Run user specified filter chain */
1580         for( i = 0; i < id->i_ufilter; i++ )
1581         {
1582             p_audio_block =
1583                 id->pp_ufilter[i]->pf_audio_filter( id->pp_ufilter[i],
1584                                                     p_audio_block );
1585         }
1586
1587         assert( p_audio_block );
1588
1589         p_audio_buf->p_buffer = p_audio_block->p_buffer;
1590         p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1591         p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1592         p_audio_buf->start_date = p_audio_block->i_dts;
1593         p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1594
1595         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1596         block_ChainAppend( out, p_block );
1597         block_Release( p_audio_block );
1598         free( p_audio_buf );
1599     }
1600
1601     return VLC_SUCCESS;
1602 }
1603
1604 static void audio_release_buffer( aout_buffer_t *p_buffer )
1605 {
1606     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1607     free( p_buffer );
1608 }
1609
1610 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1611 {
1612     aout_buffer_t *p_buffer;
1613     block_t *p_block;
1614     int i_size;
1615
1616     if( p_dec->fmt_out.audio.i_bitspersample )
1617     {
1618         i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1619             p_dec->fmt_out.audio.i_channels;
1620     }
1621     else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1622              p_dec->fmt_out.audio.i_frame_length )
1623     {
1624         i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1625             p_dec->fmt_out.audio.i_frame_length;
1626     }
1627     else
1628     {
1629         i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1630     }
1631
1632     p_buffer = malloc( sizeof(aout_buffer_t) );
1633     if( !p_buffer ) return NULL;
1634     p_buffer->b_discontinuity = false;
1635     p_buffer->pf_release = audio_release_buffer;
1636     p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1637
1638     p_buffer->p_buffer = p_block->p_buffer;
1639     p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1640     p_buffer->i_nb_samples = i_samples;
1641     p_block->i_samples = i_samples;
1642
1643     return p_buffer;
1644 }
1645
1646 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1647 {
1648     VLC_UNUSED(p_dec);
1649     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1650     free( p_buffer );
1651 }
1652
1653 /*
1654  * video
1655  */
1656
1657 static filter_t *transcode_video_filter_new( sout_stream_t *p_stream,
1658                                              es_format_t *p_fmt_in,
1659                                              es_format_t *p_fmt_out,
1660                                              config_chain_t  *p_cfg,
1661                                              const char *psz_name )
1662 {
1663     sout_stream_sys_t *p_sys = p_stream->p_sys;
1664     filter_t *p_filter;
1665     int i;
1666
1667     if( !p_stream || !p_fmt_in || !p_fmt_out ) return NULL;
1668
1669     p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1670     vlc_object_attach( p_filter, p_stream );
1671
1672     p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1673     p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1674
1675     es_format_Copy( &p_filter->fmt_in,  p_fmt_in );
1676     es_format_Copy( &p_filter->fmt_out, p_fmt_out );
1677     p_filter->p_cfg = p_cfg;
1678
1679     p_filter->p_module = module_Need( p_filter, "video filter2",
1680                                       psz_name, true );
1681     if( !p_filter->p_module )
1682     {
1683         msg_Dbg( p_stream, "no video filter found" );
1684         vlc_object_detach( p_filter );
1685         vlc_object_release( p_filter );
1686         return NULL;
1687     }
1688
1689     p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1690     if( !p_filter->p_owner )
1691     {
1692         module_Unneed( p_filter,p_filter->p_module );
1693         vlc_object_detach( p_filter );
1694         vlc_object_release( p_filter );
1695         return NULL;
1696     }
1697
1698     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1699         p_filter->p_owner->pp_pics[i] = 0;
1700     p_filter->p_owner->p_sys = p_sys;
1701
1702     return p_filter;
1703 }
1704
1705 static void transcode_video_filter_close( sout_stream_t *p_stream,
1706                                           filter_t *p_filter )
1707 {
1708     int j;
1709
1710     if( !p_stream || !p_filter ) return;
1711
1712     vlc_object_detach( p_filter );
1713     if( p_filter->p_module )
1714         module_Unneed( p_filter, p_filter->p_module );
1715
1716     /* Clean-up pictures ring buffer */
1717     for( j = 0; j < PICTURE_RING_SIZE; j++ )
1718     {
1719         if( p_filter->p_owner->pp_pics[j] )
1720             video_del_buffer( VLC_OBJECT(p_filter),
1721                               p_filter->p_owner->pp_pics[j] );
1722     }
1723     free( p_filter->p_owner );
1724     vlc_object_release( p_filter );
1725     p_filter = NULL;
1726 }
1727
1728 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1729 {
1730     sout_stream_sys_t *p_sys = p_stream->p_sys;
1731     int i;
1732
1733     /* Open decoder
1734      * Initialization of decoder structures
1735      */
1736     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1737     id->p_decoder->fmt_out.i_extra = 0;
1738     id->p_decoder->fmt_out.p_extra = 0;
1739     id->p_decoder->pf_decode_video = NULL;
1740     id->p_decoder->pf_get_cc = NULL;
1741     id->p_decoder->pf_get_cc = 0;
1742     id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1743     id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1744     id->p_decoder->pf_picture_link    = video_link_picture_decoder;
1745     id->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder;
1746     id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1747     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1748         id->p_decoder->p_owner->pp_pics[i] = 0;
1749     id->p_decoder->p_owner->p_sys = p_sys;
1750     /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1751
1752     id->p_decoder->p_module =
1753         module_Need( id->p_decoder, "decoder", "$codec", 0 );
1754
1755     if( !id->p_decoder->p_module )
1756     {
1757         msg_Err( p_stream, "cannot find decoder" );
1758         return VLC_EGENERIC;
1759     }
1760
1761     /*
1762      * Open encoder.
1763      * Because some info about the decoded input will only be available
1764      * once the first frame is decoded, we actually only test the availability
1765      * of the encoder here.
1766      */
1767
1768     /* Initialization of encoder format structures */
1769     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1770                     id->p_decoder->fmt_out.i_codec );
1771     id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1772
1773     /* The dimensions will be set properly later on.
1774      * Just put sensible values so we can test an encoder is available. */
1775     id->p_encoder->fmt_in.video.i_width =
1776         id->p_encoder->fmt_out.video.i_width ?
1777         id->p_encoder->fmt_out.video.i_width :
1778         id->p_decoder->fmt_in.video.i_width ?
1779         id->p_decoder->fmt_in.video.i_width : 16;
1780     id->p_encoder->fmt_in.video.i_height =
1781         id->p_encoder->fmt_out.video.i_height ?
1782         id->p_encoder->fmt_out.video.i_height :
1783         id->p_decoder->fmt_in.video.i_height ?
1784         id->p_decoder->fmt_in.video.i_height : 16;
1785     id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1786     id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1787
1788     id->p_encoder->i_threads = p_sys->i_threads;
1789     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1790
1791     id->p_encoder->p_module =
1792         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1793     if( !id->p_encoder->p_module )
1794     {
1795         msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_venc );
1796         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1797         id->p_decoder->p_module = 0;
1798         return VLC_EGENERIC;
1799     }
1800
1801     /* Close the encoder.
1802      * We'll open it only when we have the first frame. */
1803     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1804     if( id->p_encoder->fmt_out.p_extra )
1805     {
1806         free( id->p_encoder->fmt_out.p_extra );
1807         id->p_encoder->fmt_out.p_extra = NULL;
1808         id->p_encoder->fmt_out.i_extra = 0;
1809     }
1810     id->p_encoder->p_module = NULL;
1811
1812     if( p_sys->i_threads >= 1 )
1813     {
1814         int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1815                            VLC_THREAD_PRIORITY_VIDEO;
1816         p_sys->id_video = id;
1817         vlc_mutex_init( &p_sys->lock_out );
1818         vlc_cond_init( p_stream, &p_sys->cond );
1819         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1820         p_sys->i_first_pic = 0;
1821         p_sys->i_last_pic = 0;
1822         p_sys->p_buffers = NULL;
1823         p_sys->b_die = p_sys->b_error = 0;
1824         if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1825                                false ) )
1826         {
1827             msg_Err( p_stream, "cannot spawn encoder thread" );
1828             module_Unneed( id->p_decoder, id->p_decoder->p_module );
1829             id->p_decoder->p_module = 0;
1830             return VLC_EGENERIC;
1831         }
1832     }
1833
1834     return VLC_SUCCESS;
1835 }
1836
1837 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1838                                          sout_stream_id_t *id )
1839 {
1840      sout_stream_sys_t *p_sys = p_stream->p_sys;
1841
1842      /* Calculate scaling, padding, cropping etc.
1843       * width/height of source */
1844      int i_src_width = id->p_decoder->fmt_out.video.i_width;
1845      int i_src_height = id->p_decoder->fmt_out.video.i_height;
1846
1847      /* with/height scaling */
1848      float f_scale_width = 1;
1849      float f_scale_height = 1;
1850
1851      /* width/height of output stream */
1852      int i_dst_width;
1853      int i_dst_height;
1854
1855      /* aspect ratio */
1856      float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1857                              VOUT_ASPECT_FACTOR;
1858
1859      msg_Dbg( p_stream, "decoder aspect is %i:%i",
1860                   id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1861
1862      /* Change f_aspect from source frame to source pixel */
1863      f_aspect = f_aspect * i_src_height / i_src_width;
1864      msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1865
1866      /* width/height after cropping */
1867      p_sys->i_src_x_offset = p_sys->i_crop_left & ~1;
1868      p_sys->i_src_y_offset = p_sys->i_crop_top & ~1;
1869      p_sys->i_crop_width = i_src_width - ( p_sys->i_crop_left & ~1 ) -
1870                             ( p_sys->i_crop_right & ~1 );
1871      p_sys->i_crop_height = i_src_height - ( p_sys->i_crop_top & ~1 ) -
1872                             ( p_sys->i_crop_bottom & ~1 );
1873
1874     /* Calculate scaling factor for specified parameters */
1875     if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1876         id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1877     {
1878         /* Global scaling. Make sure width will remain a factor of 16 */
1879         float f_real_scale;
1880         int  i_new_height;
1881         int i_new_width = i_src_width * p_sys->f_scale;
1882
1883         if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1884             i_new_width -= i_new_width % 16;
1885         else
1886             i_new_width += 16 - i_new_width % 16;
1887
1888         f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1889
1890         i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1891
1892         f_scale_width = f_real_scale;
1893         f_scale_height = (float) i_new_height / (float) i_src_height;
1894     }
1895     else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1896              id->p_encoder->fmt_out.video.i_height <= 0 )
1897     {
1898         /* Only width specified */
1899         f_scale_width = (float)id->p_encoder->fmt_out.video.i_width /
1900                              p_sys->i_crop_width;
1901         f_scale_height = f_scale_width;
1902     }
1903     else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1904              id->p_encoder->fmt_out.video.i_height > 0 )
1905     {
1906          /* Only height specified */
1907          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height /
1908                               p_sys->i_crop_height;
1909          f_scale_width = f_scale_height;
1910      }
1911      else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1912               id->p_encoder->fmt_out.video.i_height > 0 )
1913      {
1914          /* Width and height specified */
1915          f_scale_width = (float)id->p_encoder->fmt_out.video.i_width
1916                                / p_sys->i_crop_width;
1917          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height
1918                                / p_sys->i_crop_height;
1919      }
1920
1921      /* check maxwidth and maxheight
1922       * note: maxwidth and maxheight currently does not handle
1923       * canvas and padding, just scaling and cropping.
1924       */
1925      if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1926                                                      p_sys->i_crop_width )
1927      {
1928          f_scale_width = (float)p_sys->i_maxwidth / p_sys->i_crop_width;
1929      }
1930
1931      if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1932                                                        p_sys->i_crop_height )
1933      {
1934          f_scale_height = (float)p_sys->i_maxheight / p_sys->i_crop_height;
1935      }
1936
1937      /* Change aspect ratio from source pixel to scaled pixel */
1938      f_aspect = f_aspect * f_scale_height / f_scale_width;
1939      msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1940
1941      /* Correct scaling for target aspect ratio
1942       * Shrink video if necessary
1943       */
1944      if ( p_sys->i_canvas_aspect > 0 )
1945      {
1946          float f_target_aspect = (float)p_sys->i_canvas_aspect /
1947                                         VOUT_ASPECT_FACTOR;
1948
1949          if( p_sys->i_canvas_width > 0 && p_sys->i_canvas_height > 0)
1950          {
1951              /* Calculate pixel aspect of canvas */
1952              f_target_aspect = f_target_aspect / p_sys->i_canvas_width *
1953                                p_sys->i_canvas_height;
1954          }
1955          if( f_target_aspect > f_aspect )
1956          {
1957              /* Reduce width scale to increase aspect */
1958              f_scale_width = f_scale_width * f_aspect / f_target_aspect;
1959          }
1960          else
1961          {
1962              /* Reduce height scale to decrease aspect */
1963              f_scale_height = f_scale_height * f_target_aspect / f_aspect;
1964          }
1965          f_aspect = f_target_aspect;
1966          msg_Dbg( p_stream, "canvas scaled pixel aspect is %f:1", f_aspect );
1967      }
1968
1969      /* f_scale_width and f_scale_height are now final */
1970      /* Calculate width, height from scaling
1971       * Make sure its multiple of 2
1972       */
1973      i_dst_width = 2 * (int)( p_sys->i_crop_width * f_scale_width / 2 + 0.5 );
1974      i_dst_height = 2 *
1975                     (int)( p_sys->i_crop_height * f_scale_height / 2 + 0.5 );
1976
1977      p_sys->i_nopadd_width = i_dst_width;
1978      p_sys->i_nopadd_height = i_dst_height;
1979      p_sys->i_dst_x_offset = 0;
1980      p_sys->i_dst_y_offset = 0;
1981
1982      /* Handle canvas and padding */
1983      if( p_sys->i_canvas_width <= 0 )
1984      {
1985          /* No canvas width set, add explicit padding border */
1986          i_dst_width = p_sys->i_nopadd_width + ( p_sys->i_padd_left & ~1 ) +
1987                       ( p_sys->i_padd_right & ~1 );
1988          p_sys->i_dst_x_offset = ( p_sys->i_padd_left & ~1 );
1989      }
1990      else
1991      {
1992          /* Canvas set, check if we have to padd or crop */
1993          if( p_sys->i_canvas_width < p_sys->i_nopadd_width )
1994          {
1995              /* need to crop more, but keep same scaling */
1996              int i_crop = 2 * (int)( ( p_sys->i_canvas_width & ~1 ) /
1997                                        f_scale_width / 2 + 0.5 );
1998
1999              p_sys->i_src_x_offset += ( ( p_sys->i_crop_width - i_crop ) / 2 )
2000                                            & ~1;
2001              p_sys->i_crop_width = i_crop;
2002              i_dst_width = p_sys->i_canvas_width & ~1;
2003              p_sys->i_nopadd_width = i_dst_width;
2004          }
2005          else if( p_sys->i_canvas_width > p_sys->i_nopadd_width )
2006          {
2007              /* need to padd */
2008              i_dst_width = p_sys->i_canvas_width & ~1;
2009              p_sys->i_dst_x_offset = ( i_dst_width - p_sys->i_nopadd_width )/2;
2010              p_sys->i_dst_x_offset = p_sys->i_dst_x_offset & ~1;
2011          }
2012      }
2013
2014      if( p_sys->i_canvas_height <= 0 )
2015      {
2016          /* No canvas set, add padding border */
2017          i_dst_height = p_sys->i_nopadd_height + ( p_sys->i_padd_top & ~1 ) +
2018                         ( p_sys->i_padd_bottom & ~1 );
2019          p_sys->i_dst_y_offset = ( p_sys->i_padd_top & ~1 );
2020      }
2021      else
2022      {
2023          /* Canvas set, check if we have to padd or crop */
2024          if( p_sys->i_canvas_height < p_sys->i_nopadd_height )
2025          {
2026              /* need to crop more, but keep same scaling */
2027              int i_crop = 2 * (int)( ( p_sys->i_canvas_height & ~1 ) /
2028                                         f_scale_height / 2 + 0.5 );
2029
2030              p_sys->i_src_y_offset += ( ( p_sys->i_crop_height - i_crop ) / 2 )
2031                                                 & ~1;
2032              p_sys->i_crop_height = i_crop;
2033              i_dst_height = p_sys->i_canvas_height & ~1;
2034              p_sys->i_nopadd_height = i_dst_height;
2035          }
2036          else if( p_sys->i_canvas_height > p_sys->i_nopadd_height )
2037          {
2038              /* need to padd */
2039              i_dst_height = p_sys->i_canvas_height & ~1;
2040              p_sys->i_dst_y_offset = ( i_dst_height - p_sys->i_nopadd_height )
2041                                         /2;
2042              p_sys->i_dst_y_offset = p_sys->i_dst_y_offset & ~1;
2043          }
2044      }
2045
2046      /* Change aspect ratio from scaled pixel to output frame */
2047      f_aspect = f_aspect * i_dst_width / i_dst_height;
2048
2049      /* Store calculated values */
2050      id->p_encoder->fmt_out.video.i_width = i_dst_width;
2051      id->p_encoder->fmt_out.video.i_height = i_dst_height;
2052
2053      id->p_encoder->fmt_in.video.i_width = i_dst_width;
2054      id->p_encoder->fmt_in.video.i_height = i_dst_height;
2055
2056      msg_Dbg( p_stream, "source %ix%i, crop %ix%i, "
2057                         "destination %ix%i, padding %ix%i",
2058          i_src_width, i_src_height,
2059          p_sys->i_crop_width, p_sys->i_crop_height,
2060          p_sys->i_nopadd_width, p_sys->i_nopadd_height,
2061          i_dst_width, i_dst_height
2062      );
2063
2064     /* Handle frame rate conversion */
2065     if( !id->p_encoder->fmt_out.video.i_frame_rate ||
2066         !id->p_encoder->fmt_out.video.i_frame_rate_base )
2067     {
2068         if( id->p_decoder->fmt_out.video.i_frame_rate &&
2069             id->p_decoder->fmt_out.video.i_frame_rate_base )
2070         {
2071             id->p_encoder->fmt_out.video.i_frame_rate =
2072                 id->p_decoder->fmt_out.video.i_frame_rate;
2073             id->p_encoder->fmt_out.video.i_frame_rate_base =
2074                 id->p_decoder->fmt_out.video.i_frame_rate_base;
2075         }
2076         else
2077         {
2078             /* Pick a sensible default value */
2079             id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
2080             id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
2081         }
2082     }
2083
2084     id->p_encoder->fmt_in.video.i_frame_rate =
2085         id->p_encoder->fmt_out.video.i_frame_rate;
2086     id->p_encoder->fmt_in.video.i_frame_rate_base =
2087         id->p_encoder->fmt_out.video.i_frame_rate_base;
2088
2089     date_Init( &id->interpolated_pts,
2090                id->p_encoder->fmt_out.video.i_frame_rate,
2091                id->p_encoder->fmt_out.video.i_frame_rate_base );
2092
2093     /* Check whether a particular aspect ratio was requested */
2094     if( !id->p_encoder->fmt_out.video.i_aspect )
2095     {
2096         id->p_encoder->fmt_out.video.i_aspect =
2097                 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
2098     }
2099     id->p_encoder->fmt_in.video.i_aspect =
2100         id->p_encoder->fmt_out.video.i_aspect;
2101
2102     msg_Dbg( p_stream, "encoder aspect is %i:%i",
2103              id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
2104
2105     id->p_encoder->p_module =
2106         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
2107     if( !id->p_encoder->p_module )
2108     {
2109         msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_venc );
2110         return VLC_EGENERIC;
2111     }
2112
2113     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
2114
2115     /* Hack for mp2v/mp1v transcoding support */
2116     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
2117         id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
2118     {
2119         id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
2120     }
2121
2122     id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
2123                                              &id->p_encoder->fmt_out );
2124     if( !id->id )
2125     {
2126         msg_Err( p_stream, "cannot add this stream" );
2127         return VLC_EGENERIC;
2128     }
2129
2130     return VLC_SUCCESS;
2131 }
2132
2133 static void transcode_video_close( sout_stream_t *p_stream,
2134                                    sout_stream_id_t *id )
2135 {
2136     int i;
2137
2138     if( p_stream->p_sys->i_threads >= 1 )
2139     {
2140         vlc_mutex_lock( &p_stream->p_sys->lock_out );
2141         vlc_object_kill( p_stream->p_sys );
2142         vlc_cond_signal( &p_stream->p_sys->cond );
2143         vlc_mutex_unlock( &p_stream->p_sys->lock_out );
2144         vlc_thread_join( p_stream->p_sys );
2145         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
2146         vlc_cond_destroy( &p_stream->p_sys->cond );
2147     }
2148
2149     /* Close decoder */
2150     if( id->p_decoder->p_module )
2151         module_Unneed( id->p_decoder, id->p_decoder->p_module );
2152
2153     if( id->p_decoder->p_owner )
2154     {
2155         /* Clean-up pictures ring buffer */
2156         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2157         {
2158             if( id->p_decoder->p_owner->pp_pics[i] )
2159                 video_del_buffer( VLC_OBJECT(id->p_decoder),
2160                                   id->p_decoder->p_owner->pp_pics[i] );
2161         }
2162         free( id->p_decoder->p_owner );
2163     }
2164
2165     /* Close encoder */
2166     if( id->p_encoder->p_module )
2167         module_Unneed( id->p_encoder, id->p_encoder->p_module );
2168
2169     /* Close filters */
2170     for( i = 0; i < id->i_filter; i++ )
2171     {
2172         transcode_video_filter_close( p_stream, id->pp_filter[i] );
2173         id->pp_filter[i] = NULL;
2174     }
2175     id->i_filter = 0;
2176
2177     for( i = 0; i < id->i_ufilter; i++ )
2178     {
2179         transcode_video_filter_close( p_stream, id->pp_ufilter[i] );
2180         id->pp_ufilter[i] = NULL;
2181     }
2182     id->i_ufilter = 0;
2183 }
2184
2185 static int transcode_video_process( sout_stream_t *p_stream,
2186                                     sout_stream_id_t *id,
2187                                     block_t *in, block_t **out )
2188 {
2189     sout_stream_sys_t *p_sys = p_stream->p_sys;
2190     int i_duplicate = 1, i;
2191     picture_t *p_pic, *p_pic2 = NULL;
2192     *out = NULL;
2193
2194     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
2195     {
2196         subpicture_t *p_subpic = NULL;
2197
2198         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
2199
2200         if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
2201         {
2202             mtime_t current_date = mdate();
2203             if( current_date + 50000 > p_pic->date )
2204             {
2205                 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
2206                          current_date + 50000 - p_pic->date );
2207                 p_pic->pf_release( p_pic );
2208                 continue;
2209             }
2210         }
2211
2212         if( p_sys->b_master_sync )
2213         {
2214             mtime_t i_video_drift;
2215             mtime_t i_master_drift = p_sys->i_master_drift;
2216             mtime_t i_pts;
2217
2218             i_pts = date_Get( &id->interpolated_pts ) + 1;
2219             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2220                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2221             {
2222                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2223                 date_Set( &id->interpolated_pts, p_pic->date );
2224                 i_pts = p_pic->date + 1;
2225             }
2226             i_video_drift = p_pic->date - i_pts;
2227             i_duplicate = 1;
2228
2229             /* Set the pts of the frame being encoded */
2230             p_pic->date = i_pts;
2231
2232             if( i_video_drift < (i_master_drift - 50000) )
2233             {
2234 #if 0
2235                 msg_Dbg( p_stream, "dropping frame (%i)",
2236                          (int)(i_video_drift - i_master_drift) );
2237 #endif
2238                 p_pic->pf_release( p_pic );
2239                 continue;
2240             }
2241             else if( i_video_drift > (i_master_drift + 50000) )
2242             {
2243 #if 0
2244                 msg_Dbg( p_stream, "adding frame (%i)",
2245                          (int)(i_video_drift - i_master_drift) );
2246 #endif
2247                 i_duplicate = 2;
2248             }
2249         }
2250
2251         if( !id->p_encoder->p_module )
2252         {
2253             if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
2254             {
2255                 p_pic->pf_release( p_pic );
2256                 transcode_video_close( p_stream, id );
2257                 id->b_transcode = false;
2258                 return VLC_EGENERIC;
2259             }
2260
2261             /* Deinterlace */
2262             if( p_stream->p_sys->b_deinterlace )
2263             {
2264                 id->pp_filter[id->i_filter] =
2265                     transcode_video_filter_new( p_stream,
2266                             &id->p_decoder->fmt_out,
2267                             &id->p_decoder->fmt_out,
2268                             p_sys->p_deinterlace_cfg,
2269                             p_sys->psz_deinterlace );
2270
2271                 if( id->pp_filter[id->i_filter] )
2272                     id->i_filter++;
2273             }
2274
2275 #if (defined(HAVE_FFMPEG_SWSCALE_H) || defined(HAVE_LIBSWSCALE_TREE)) || defined(HAVE_LIBSWSCALE_SWSCALE_H)
2276             if( ( id->p_decoder->fmt_out.video.i_chroma !=
2277                   id->p_encoder->fmt_in.video.i_chroma ) ||
2278                 ( id->p_decoder->fmt_out.video.i_width !=
2279                   id->p_encoder->fmt_in.video.i_width ) ||
2280                 ( id->p_decoder->fmt_out.video.i_height !=
2281                   id->p_encoder->fmt_in.video.i_height ) )
2282             {
2283                 id->pp_filter[id->i_filter] =
2284                     transcode_video_filter_new( p_stream,
2285                             &id->p_decoder->fmt_out,
2286                             &id->p_encoder->fmt_in,
2287                             NULL, "scale" );
2288                 if( !id->pp_filter[id->i_filter] )
2289                 {
2290                     p_pic->pf_release( p_pic );
2291                     transcode_video_close( p_stream, id );
2292                     id->b_transcode = false;
2293                     return VLC_EGENERIC;
2294                 }
2295                 id->i_filter++;
2296             }
2297 #if 0 /* FIXME: */
2298             /* we don't do chroma conversion or scaling in croppad */
2299 //             es_format_t fmt_in, fmt_out;
2300 //             es_format_Copy( &fmt_out, &id->p_encoder->fmt_in );
2301 //             es_format_Copy( &fmt_in, &id->p_encoder->fmt_in );
2302
2303             if( ( id->p_decoder->fmt_out.video.i_chroma ==
2304                   id->p_encoder->fmt_in.video.i_chroma ) &&
2305
2306                 ( ( (int)id->p_decoder->fmt_out.video.i_width !=
2307                     p_sys->i_crop_width ) ||
2308                   ( p_sys->i_crop_width != p_sys->i_nopadd_width ) ||
2309                   ( p_sys->i_nopadd_width !=
2310                     (int)id->p_encoder->fmt_out.video.i_width ) ||
2311
2312                   ( (int)id->p_decoder->fmt_out.video.i_height !=
2313                     p_sys->i_crop_height ) ||
2314                   ( p_sys->i_crop_height != p_sys->i_nopadd_height ) ||
2315                   ( p_sys->i_nopadd_height !=
2316                     (int)id->p_encoder->fmt_out.video.i_height ) ) )
2317             {
2318                 id->pp_filter[id->i_filter] =
2319                     transcode_video_filter_new( p_stream,
2320                             &id->p_decoder->fmt_out,
2321                             &id->p_encoder->fmt_in,
2322                             NULL, "croppadd" );
2323                 if( id->pp_filter[id->i_filter] )
2324                 {
2325                     /* Set crop and padding information */
2326                     id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset;
2327                     id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset;
2328                     id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width;
2329                     id->pp_filter[id->i_filter]->fmt_in.video.i_visible_height = p_sys->i_crop_height;
2330
2331                     id->pp_filter[id->i_filter]->fmt_out.video.i_x_offset = p_sys->i_dst_x_offset;
2332                     id->pp_filter[id->i_filter]->fmt_out.video.i_y_offset = p_sys->i_dst_y_offset;
2333                     id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width;
2334                     id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height;
2335
2336                     id->i_filter++;
2337                 }
2338             }
2339 #endif
2340 #else
2341             /* Check if we need a filter for chroma conversion or resizing */
2342             if( id->p_decoder->fmt_out.video.i_chroma !=
2343                 id->p_encoder->fmt_in.video.i_chroma ||
2344
2345                 (int)id->p_decoder->fmt_out.video.i_width != p_sys->i_crop_width ||
2346                 p_sys->i_crop_width != p_sys->i_nopadd_width ||
2347                 p_sys->i_nopadd_width != (int)id->p_encoder->fmt_out.video.i_width ||
2348
2349                 (int)id->p_decoder->fmt_out.video.i_height != p_sys->i_crop_height ||
2350                 p_sys->i_crop_height != p_sys->i_nopadd_height ||
2351                 p_sys->i_nopadd_height != (int)id->p_encoder->fmt_out.video.i_height)
2352             {
2353                 id->pp_filter[id->i_filter] =
2354                     transcode_video_filter_new( p_stream,
2355                             &id->p_decoder->fmt_out,
2356                             &id->p_encoder->fmt_in,
2357                             NULL, "crop padd" );
2358                 if( !id->pp_filter[id->i_filter] )
2359                 {
2360                     p_pic->pf_release( p_pic );
2361                     transcode_video_close( p_stream, id );
2362                     id->b_transcode = false;
2363                     return VLC_EGENERIC;
2364                 }
2365
2366                 /* Set crop and padding information */ 
2367                 id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset;
2368                 id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset;
2369                 id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width;
2370                 id->pp_filter[id->i_filter]->fmt_in.video.i_visible_height = p_sys->i_crop_height;
2371
2372                 id->pp_filter[id->i_filter]->fmt_out.video.i_x_offset = p_sys->i_dst_x_offset;
2373                 id->pp_filter[id->i_filter]->fmt_out.video.i_y_offset = p_sys->i_dst_y_offset;
2374                 id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width;
2375                 id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height;
2376
2377                 id->i_filter++;
2378             }
2379 #endif
2380             for( i = 0; (i < p_sys->i_vfilters) && (id->i_ufilter < TRANSCODE_FILTERS); i++ )
2381             {
2382                 id->pp_ufilter[id->i_ufilter] =
2383                     transcode_video_filter_new( p_stream,
2384                             &id->p_decoder->fmt_out, &id->p_encoder->fmt_in,
2385                             p_sys->p_vfilters_cfg[i], p_sys->psz_vfilters[i] );
2386                 if( id->pp_ufilter[id->i_filter] )
2387                     id->i_ufilter++;
2388                 else
2389                     id->pp_ufilter[id->i_ufilter] = NULL;
2390             }
2391         }
2392
2393         /* Run filter chain */
2394         for( i = 0; i < id->i_filter; i++ )
2395         {
2396             p_pic = id->pp_filter[i]->pf_video_filter(id->pp_filter[i], p_pic);
2397         }
2398
2399         /*
2400          * Encoding
2401          */
2402
2403         /* Check if we have a subpicture to overlay */
2404         if( p_sys->p_spu )
2405         {
2406             p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
2407                        false /* Fixme: check if stream is paused */ );
2408             /* TODO: get another pic */
2409         }
2410
2411         /* Overlay subpicture */
2412         if( p_subpic )
2413         {
2414             int i_scale_width, i_scale_height;
2415             video_format_t *p_fmt;
2416
2417             i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
2418                 id->p_decoder->fmt_out.video.i_width;
2419             i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
2420                 id->p_decoder->fmt_out.video.i_height;
2421
2422             if( p_pic->i_refcount && !id->i_filter )
2423             {
2424                 /* We can't modify the picture, we need to duplicate it */
2425                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
2426                 if( p_tmp )
2427                 {
2428                     vout_CopyPicture( p_stream, p_tmp, p_pic );
2429                     p_pic->pf_release( p_pic );
2430                     p_pic = p_tmp;
2431                 }
2432             }
2433
2434             if( id->i_filter )
2435                 p_fmt = &id->pp_filter[id->i_filter -1]->fmt_out.video;
2436             else
2437                 p_fmt = &id->p_decoder->fmt_out.video;
2438
2439             /* FIXME (shouldn't have to be done here) */
2440             p_fmt->i_sar_num = p_fmt->i_aspect *
2441                 p_fmt->i_height / p_fmt->i_width;
2442             p_fmt->i_sar_den = VOUT_ASPECT_FACTOR;
2443
2444             spu_RenderSubpictures( p_sys->p_spu, p_fmt, p_pic, p_pic, p_subpic,
2445                                    i_scale_width, i_scale_height );
2446         }
2447
2448         /* Run user specified filter chain */
2449         for( i = 0; i < id->i_ufilter; i++ )
2450         {
2451             p_pic = id->pp_ufilter[i]->pf_video_filter( id->pp_ufilter[i],
2452                                                         p_pic );
2453         }
2454
2455         if( p_sys->i_threads == 0 )
2456         {
2457             block_t *p_block;
2458             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2459             block_ChainAppend( out, p_block );
2460         }
2461
2462         if( p_sys->b_master_sync )
2463         {
2464             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2465             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2466                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2467             {
2468                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2469                 date_Set( &id->interpolated_pts, p_pic->date );
2470                 i_pts = p_pic->date + 1;
2471             }
2472             date_Increment( &id->interpolated_pts, 1 );
2473         }
2474
2475         if( p_sys->b_master_sync && i_duplicate > 1 )
2476         {
2477             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2478             if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2479                  || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2480             {
2481                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2482                 date_Set( &id->interpolated_pts, p_pic->date );
2483                 i_pts = p_pic->date + 1;
2484             }
2485             date_Increment( &id->interpolated_pts, 1 );
2486
2487             if( p_sys->i_threads >= 1 )
2488             {
2489                 /* We can't modify the picture, we need to duplicate it */
2490                 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2491                 if( p_pic2 != NULL )
2492                 {
2493                     vout_CopyPicture( p_stream, p_pic2, p_pic );
2494                     p_pic2->date = i_pts;
2495                 }
2496             }
2497             else
2498             {
2499                 block_t *p_block;
2500                 p_pic->date = i_pts;
2501                 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2502                 block_ChainAppend( out, p_block );
2503             }
2504         }
2505
2506         if( p_sys->i_threads == 0 )
2507         {
2508             p_pic->pf_release( p_pic );
2509         }
2510         else
2511         {
2512             vlc_mutex_lock( &p_sys->lock_out );
2513             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2514             p_sys->i_last_pic %= PICTURE_RING_SIZE;
2515             *out = p_sys->p_buffers;
2516             p_sys->p_buffers = NULL;
2517             if( p_pic2 != NULL )
2518             {
2519                 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2520                 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2521             }
2522             vlc_cond_signal( &p_sys->cond );
2523             vlc_mutex_unlock( &p_sys->lock_out );
2524         }
2525     }
2526
2527     return VLC_SUCCESS;
2528 }
2529
2530 static int EncoderThread( sout_stream_sys_t *p_sys )
2531 {
2532     sout_stream_id_t *id = p_sys->id_video;
2533     picture_t *p_pic;
2534
2535     while( !p_sys->b_die && !p_sys->b_error )
2536     {
2537         block_t *p_block;
2538
2539         vlc_mutex_lock( &p_sys->lock_out );
2540         while( p_sys->i_last_pic == p_sys->i_first_pic )
2541         {
2542             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2543             if( p_sys->b_die || p_sys->b_error ) break;
2544         }
2545         if( p_sys->b_die || p_sys->b_error )
2546         {
2547             vlc_mutex_unlock( &p_sys->lock_out );
2548             break;
2549         }
2550
2551         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2552         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2553         vlc_mutex_unlock( &p_sys->lock_out );
2554
2555         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2556         vlc_mutex_lock( &p_sys->lock_out );
2557         block_ChainAppend( &p_sys->p_buffers, p_block );
2558
2559         vlc_mutex_unlock( &p_sys->lock_out );
2560         p_pic->pf_release( p_pic );
2561     }
2562
2563     while( p_sys->i_last_pic != p_sys->i_first_pic )
2564     {
2565         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2566         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2567         p_pic->pf_release( p_pic );
2568     }
2569     block_ChainRelease( p_sys->p_buffers );
2570
2571     return 0;
2572 }
2573
2574 struct picture_sys_t
2575 {
2576     vlc_object_t *p_owner;
2577 };
2578
2579 static void video_release_buffer( picture_t *p_pic )
2580 {
2581     if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2582     {
2583         video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2584     }
2585     else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2586 }
2587
2588 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2589                                     sout_stream_sys_t *p_sys )
2590 {
2591     decoder_t *p_dec = (decoder_t *)p_this;
2592     picture_t *p_pic;
2593     int i;
2594
2595     /* Find an empty space in the picture ring buffer */
2596     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2597     {
2598         if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2599         {
2600             pp_ring[i]->i_status = RESERVED_PICTURE;
2601             return pp_ring[i];
2602         }
2603     }
2604     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2605     {
2606         if( pp_ring[i] == 0 ) break;
2607     }
2608
2609     if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2610     {
2611         int i_first_pic = p_sys->i_first_pic;
2612
2613         if( p_sys->i_first_pic != p_sys->i_last_pic )
2614         {
2615             /* Encoder still has stuff to encode, wait to clear-up the list */
2616             while( p_sys->i_first_pic == i_first_pic )
2617                 msleep( 100000 );
2618         }
2619
2620         /* Find an empty space in the picture ring buffer */
2621         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2622         {
2623             if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2624             {
2625                 pp_ring[i]->i_status = RESERVED_PICTURE;
2626                 return pp_ring[i];
2627             }
2628         }
2629         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2630         {
2631             if( pp_ring[i] == 0 ) break;
2632         }
2633     }
2634
2635     if( i == PICTURE_RING_SIZE )
2636     {
2637         msg_Err( p_this, "decoder/filter is leaking pictures, "
2638                  "resetting its ring buffer" );
2639
2640         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2641         {
2642             pp_ring[i]->pf_release( pp_ring[i] );
2643         }
2644
2645         i = 0;
2646     }
2647
2648     p_pic = malloc( sizeof(picture_t) );
2649     if( !p_pic ) return NULL;
2650     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2651     vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2652                           p_dec->fmt_out.video.i_chroma,
2653                           p_dec->fmt_out.video.i_width,
2654                           p_dec->fmt_out.video.i_height,
2655                           p_dec->fmt_out.video.i_aspect );
2656
2657     if( !p_pic->i_planes )
2658     {
2659         free( p_pic );
2660         return NULL;
2661     }
2662
2663     p_pic->pf_release = video_release_buffer;
2664     p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2665     if( !p_pic->p_sys )
2666     {
2667         free( p_pic );
2668         return NULL;
2669     }
2670
2671     p_pic->p_sys->p_owner = p_this;
2672     p_pic->i_status = RESERVED_PICTURE;
2673
2674     pp_ring[i] = p_pic;
2675     return p_pic;
2676 }
2677
2678 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2679 {
2680     return video_new_buffer( VLC_OBJECT(p_dec),
2681                              p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2682 }
2683
2684 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2685 {
2686     return video_new_buffer( VLC_OBJECT(p_filter),
2687                              p_filter->p_owner->pp_pics,
2688                              p_filter->p_owner->p_sys );
2689 }
2690
2691 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2692 {
2693     VLC_UNUSED(p_this);
2694     if( p_pic )
2695     {
2696         free( p_pic->p_data_orig );
2697         free( p_pic->p_sys );
2698         free( p_pic );
2699     }
2700 }
2701
2702 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2703 {
2704     VLC_UNUSED(p_decoder);
2705     p_pic->i_refcount = 0;
2706     p_pic->i_status = DESTROYED_PICTURE;
2707 }
2708
2709 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2710 {
2711     VLC_UNUSED(p_filter);
2712     p_pic->i_refcount = 0;
2713     p_pic->i_status = DESTROYED_PICTURE;
2714 }
2715
2716 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2717 {
2718     VLC_UNUSED(p_dec);
2719     p_pic->i_refcount++;
2720 }
2721
2722 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2723 {
2724     VLC_UNUSED(p_dec);
2725     video_release_buffer( p_pic );
2726 }
2727
2728 /*
2729  * SPU
2730  */
2731 static subpicture_t *spu_new_buffer( decoder_t * );
2732 static void spu_del_buffer( decoder_t *, subpicture_t * );
2733
2734 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2735 {
2736     sout_stream_sys_t *p_sys = p_stream->p_sys;
2737
2738     /*
2739      * Open decoder
2740      */
2741
2742     /* Initialization of decoder structures */
2743     id->p_decoder->pf_decode_sub = NULL;
2744     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2745     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2746     id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2747     /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2748
2749     id->p_decoder->p_module =
2750         module_Need( id->p_decoder, "decoder", "$codec", 0 );
2751
2752     if( !id->p_decoder->p_module )
2753     {
2754         msg_Err( p_stream, "cannot find decoder" );
2755         return VLC_EGENERIC;
2756     }
2757
2758     if( !p_sys->b_soverlay )
2759     {
2760         /* Open encoder */
2761         /* Initialization of encoder format structures */
2762         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2763                         id->p_decoder->fmt_in.i_codec );
2764
2765         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2766
2767         id->p_encoder->p_module =
2768             module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2769
2770         if( !id->p_encoder->p_module )
2771         {
2772             module_Unneed( id->p_decoder, id->p_decoder->p_module );
2773             msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_senc );
2774             return VLC_EGENERIC;
2775         }
2776     }
2777
2778     if( !p_sys->p_spu )
2779     {
2780         p_sys->p_spu = spu_Create( p_stream );
2781         spu_Init( p_sys->p_spu );
2782     }
2783
2784     return VLC_SUCCESS;
2785 }
2786
2787 static void transcode_spu_close( sout_stream_id_t *id)
2788 {
2789     /* Close decoder */
2790     if( id->p_decoder->p_module )
2791         module_Unneed( id->p_decoder, id->p_decoder->p_module );
2792
2793     /* Close encoder */
2794     if( id->p_encoder->p_module )
2795         module_Unneed( id->p_encoder, id->p_encoder->p_module );
2796 }
2797
2798 static int transcode_spu_process( sout_stream_t *p_stream,
2799                                   sout_stream_id_t *id,
2800                                   block_t *in, block_t **out )
2801 {
2802     sout_stream_sys_t *p_sys = p_stream->p_sys;
2803     subpicture_t *p_subpic;
2804     *out = NULL;
2805
2806     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2807     if( !p_subpic )
2808         return VLC_EGENERIC;
2809
2810     sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2811
2812     if( p_sys->b_master_sync && p_sys->i_master_drift )
2813     {
2814         p_subpic->i_start -= p_sys->i_master_drift;
2815         if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2816     }
2817
2818     if( p_sys->b_soverlay )
2819     {
2820         spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2821     }
2822     else
2823     {
2824         block_t *p_block;
2825
2826         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2827         spu_del_buffer( id->p_decoder, p_subpic );
2828         if( p_block )
2829         {
2830             block_ChainAppend( out, p_block );
2831             return VLC_SUCCESS;
2832         }
2833     }
2834
2835     return VLC_EGENERIC;
2836 }
2837
2838 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2839 {
2840     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2841     return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2842 }
2843
2844 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2845 {
2846     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2847     spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2848 }
2849
2850 /*
2851  * OSD menu
2852  */
2853 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2854 {
2855     sout_stream_sys_t *p_sys = p_stream->p_sys;
2856
2857     id->p_decoder->fmt_in.i_cat = SPU_ES;
2858     id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2859
2860     if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2861     {
2862         msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2863                  "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2864                  (char*)&p_sys->i_osdcodec );
2865
2866         /* Complete destination format */
2867         id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2868
2869         /* Open encoder */
2870         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2871                         VLC_FOURCC('Y','U','V','A') );
2872         id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2873
2874         id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2875
2876         id->p_encoder->p_module =
2877             module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2878
2879         if( !id->p_encoder->p_module )
2880         {
2881             msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_osdenc );
2882             goto error;
2883         }
2884
2885         /* open output stream */
2886         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2887         id->b_transcode = true;
2888
2889         if( !id->id ) goto error;
2890     }
2891     else
2892     {
2893         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2894                  (char*)&id->p_decoder->fmt_out.i_codec );
2895         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2896         id->b_transcode = false;
2897
2898         if( !id->id ) goto error;
2899     }
2900
2901     if( !p_sys->p_spu )
2902     {
2903         p_sys->p_spu = spu_Create( p_stream );
2904         spu_Init( p_sys->p_spu );
2905     }
2906
2907     return VLC_SUCCESS;
2908
2909  error:
2910     msg_Err( p_stream, "starting osd encoding thread failed" );
2911     if( id->p_encoder->p_module )
2912             module_Unneed( id->p_encoder, id->p_encoder->p_module );
2913     p_sys->b_osd = false;
2914     return VLC_EGENERIC;
2915 }
2916
2917 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2918 {
2919     sout_stream_sys_t *p_sys = p_stream->p_sys;
2920
2921     /* Close encoder */
2922     if( p_sys->b_osd && id )
2923     {
2924         if( id->p_encoder->p_module )
2925             module_Unneed( id->p_encoder, id->p_encoder->p_module );
2926     }
2927     p_sys->b_osd = false;
2928 }
2929
2930 static int transcode_osd_process( sout_stream_t *p_stream,
2931                                   sout_stream_id_t *id,
2932                                   block_t *in, block_t **out )
2933 {
2934     sout_stream_sys_t *p_sys = p_stream->p_sys;
2935     subpicture_t *p_subpic = NULL;
2936
2937     /* Check if we have a subpicture to send */
2938     if( p_sys->p_spu && in->i_dts > 0)
2939     {
2940         p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2941     }
2942     else
2943     {
2944         msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2945         if( !p_sys->p_spu )
2946         {
2947             p_sys->p_spu = spu_Create( p_stream );
2948             spu_Init( p_sys->p_spu );
2949         }
2950     }
2951
2952     if( p_subpic )
2953     {
2954         block_t *p_block = NULL;
2955
2956         if( p_sys->b_master_sync && p_sys->i_master_drift )
2957         {
2958             p_subpic->i_start -= p_sys->i_master_drift;
2959             if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2960         }
2961
2962         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2963         spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2964         if( p_block )
2965         {
2966             p_block->i_dts = p_block->i_pts = in->i_dts;
2967             block_ChainAppend( out, p_block );
2968             return VLC_SUCCESS;
2969         }
2970     }
2971     return VLC_EGENERIC;
2972 }