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