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