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