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