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