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