Use sout_StreamId* wrappers
[vlc.git] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c: transcoding stream output module
3  *****************************************************************************
4  * Copyright (C) 2003-2008 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
10  *          Antoine Cellerier <dionoea at videolan dot org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_input.h>
37 #include <vlc_sout.h>
38 #include <vlc_aout.h>
39 #include <vlc_vout.h>
40 #include <vlc_codec.h>
41 #include <vlc_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     while( p_sys->p_audio_cfg != NULL )
647     {
648         config_chain_t *p_next = p_sys->p_audio_cfg->p_next;
649
650         free( p_sys->p_audio_cfg->psz_name );
651         free( p_sys->p_audio_cfg->psz_value );
652         free( p_sys->p_audio_cfg );
653
654         p_sys->p_audio_cfg = p_next;
655     }
656     free( p_sys->psz_aenc );
657
658     free( p_sys->psz_vf2 );
659
660     while( p_sys->p_video_cfg != NULL )
661     {
662         config_chain_t *p_next = p_sys->p_video_cfg->p_next;
663
664         free( p_sys->p_video_cfg->psz_name );
665         free( p_sys->p_video_cfg->psz_value );
666         free( p_sys->p_video_cfg );
667
668         p_sys->p_video_cfg = p_next;
669     }
670     free( p_sys->psz_venc );
671
672     while( p_sys->p_deinterlace_cfg != NULL )
673     {
674         config_chain_t *p_next = p_sys->p_deinterlace_cfg->p_next;
675
676         free( p_sys->p_deinterlace_cfg->psz_name );
677         free( p_sys->p_deinterlace_cfg->psz_value );
678         free( p_sys->p_deinterlace_cfg );
679
680         p_sys->p_deinterlace_cfg = p_next;
681     }
682     free( p_sys->psz_deinterlace );
683
684     while( p_sys->p_spu_cfg != NULL )
685     {
686         config_chain_t *p_next = p_sys->p_spu_cfg->p_next;
687
688         free( p_sys->p_spu_cfg->psz_name );
689         free( p_sys->p_spu_cfg->psz_value );
690         free( p_sys->p_spu_cfg );
691
692         p_sys->p_spu_cfg = p_next;
693     }
694     free( p_sys->psz_senc );
695
696     if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
697
698     while( p_sys->p_osd_cfg != NULL )
699     {
700         config_chain_t *p_next = p_sys->p_osd_cfg->p_next;
701
702         free( p_sys->p_osd_cfg->psz_name );
703         free( p_sys->p_osd_cfg->psz_value );
704         free( p_sys->p_osd_cfg );
705
706         p_sys->p_osd_cfg = p_next;
707     }
708     free( p_sys->psz_osdenc );
709
710     vlc_object_release( p_sys );
711 }
712
713 struct sout_stream_id_t
714 {
715     vlc_fourcc_t  b_transcode;
716
717     /* id of the out stream */
718     void *id;
719
720     /* Decoder */
721     decoder_t       *p_decoder;
722
723     /* Filters */
724     filter_chain_t  *p_f_chain;
725     /* User specified filters */
726     filter_chain_t  *p_uf_chain;
727
728     /* Encoder */
729     encoder_t       *p_encoder;
730
731     /* Sync */
732     date_t          interpolated_pts;
733 };
734
735 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
736 {
737     sout_stream_sys_t *p_sys = p_stream->p_sys;
738     sout_stream_id_t *id;
739
740     id = malloc( sizeof( sout_stream_id_t ) );
741     if( !id )
742         goto error;
743     memset( id, 0, sizeof(sout_stream_id_t) );
744
745     id->id = NULL;
746     id->p_decoder = NULL;
747     id->p_encoder = NULL;
748
749     /* Create decoder object */
750     id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
751     if( !id->p_decoder )
752         goto error;
753     vlc_object_attach( id->p_decoder, p_stream );
754     id->p_decoder->p_module = NULL;
755     id->p_decoder->fmt_in = *p_fmt;
756     id->p_decoder->b_pace_control = true;
757
758     /* Create encoder object */
759     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
760     if( !id->p_encoder )
761         goto error;
762     vlc_object_attach( id->p_encoder, p_stream );
763     id->p_encoder->p_module = NULL;
764
765     /* Create destination format */
766     es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
767     id->p_encoder->fmt_out.i_id    = p_fmt->i_id;
768     id->p_encoder->fmt_out.i_group = p_fmt->i_group;
769     if( p_fmt->psz_language )
770         id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
771
772     if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
773     {
774         msg_Dbg( p_stream,
775                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
776                  (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
777
778         /* Complete destination format */
779         id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
780         id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
781             p_sys->i_sample_rate : p_fmt->audio.i_rate;
782         id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
783         id->p_encoder->fmt_out.audio.i_bitspersample =
784             p_fmt->audio.i_bitspersample;
785         id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
786             p_sys->i_channels : p_fmt->audio.i_channels;
787         /* Sanity check for audio channels */
788         id->p_encoder->fmt_out.audio.i_channels =
789             __MIN( id->p_encoder->fmt_out.audio.i_channels,
790                    id->p_decoder->fmt_in.audio.i_channels );
791         id->p_encoder->fmt_out.audio.i_original_channels =
792             id->p_decoder->fmt_in.audio.i_physical_channels;
793         if( id->p_decoder->fmt_in.audio.i_channels ==
794             id->p_encoder->fmt_out.audio.i_channels )
795         {
796             id->p_encoder->fmt_out.audio.i_physical_channels =
797                 id->p_decoder->fmt_in.audio.i_physical_channels;
798         }
799         else
800         {
801             id->p_encoder->fmt_out.audio.i_physical_channels =
802                 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
803         }
804
805         /* Build decoder -> filter -> encoder chain */
806         if( transcode_audio_new( p_stream, id ) )
807         {
808             msg_Err( p_stream, "cannot create audio chain" );
809             goto error;
810         }
811
812         /* Open output stream */
813         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
814         id->b_transcode = true;
815
816         if( !id->id )
817         {
818             transcode_audio_close( id );
819             goto error;
820         }
821
822         date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
823     }
824     else if( p_fmt->i_cat == VIDEO_ES &&
825              (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
826     {
827         msg_Dbg( p_stream,
828                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
829                  (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
830
831         /* Complete destination format */
832         id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
833         id->p_encoder->fmt_out.video.i_width  = p_sys->i_width & ~1;
834         id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
835         id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
836
837         /* Build decoder -> filter -> encoder chain */
838         if( transcode_video_new( p_stream, id ) )
839         {
840             msg_Err( p_stream, "cannot create video chain" );
841             goto error;
842         }
843
844         /* Stream will be added later on because we don't know
845          * all the characteristics of the decoded stream yet */
846         id->b_transcode = true;
847
848         if( p_sys->f_fps > 0 )
849         {
850             id->p_encoder->fmt_out.video.i_frame_rate =
851                 (p_sys->f_fps * 1000) + 0.5;
852             id->p_encoder->fmt_out.video.i_frame_rate_base =
853                 ENC_FRAMERATE_BASE;
854         }
855     }
856     else if( ( p_fmt->i_cat == SPU_ES ) &&
857              ( p_sys->i_scodec || p_sys->psz_senc ) )
858     {
859         msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
860                  "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
861                  (char*)&p_sys->i_scodec );
862
863         /* Complete destination format */
864         id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
865
866         /* build decoder -> filter -> encoder */
867         if( transcode_spu_new( p_stream, id ) )
868         {
869             msg_Err( p_stream, "cannot create subtitles chain" );
870             goto error;
871         }
872
873         /* open output stream */
874         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
875         id->b_transcode = true;
876
877         if( !id->id )
878         {
879             transcode_spu_close( id );
880             goto error;
881         }
882     }
883     else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
884     {
885         msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
886                  (char*)&p_fmt->i_codec );
887
888         id->b_transcode = true;
889
890         /* Build decoder -> filter -> overlaying chain */
891         if( transcode_spu_new( p_stream, id ) )
892         {
893             msg_Err( p_stream, "cannot create subtitles chain" );
894             goto error;
895         }
896     }
897     else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
898     {
899         msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
900                  "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
901                  (char*)&p_sys->i_scodec );
902
903         id->b_transcode = true;
904
905         /* Create a fake OSD menu elementary stream */
906         if( transcode_osd_new( p_stream, id ) )
907         {
908             msg_Err( p_stream, "cannot create osd chain" );
909             goto error;
910         }
911         p_sys->b_osd = true;
912     }
913     else
914     {
915         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
916                  (char*)&p_fmt->i_codec );
917         id->id = sout_StreamIdAdd( p_sys->p_out, p_fmt );
918         id->b_transcode = false;
919
920         if( !id->id ) goto error;
921     }
922
923     return id;
924
925 error:
926     if( 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
943         free( id );
944     }
945     return NULL;
946 }
947
948 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
949 {
950     sout_stream_sys_t *p_sys = p_stream->p_sys;
951
952     if( id->b_transcode )
953     {
954         switch( id->p_decoder->fmt_in.i_cat )
955         {
956         case AUDIO_ES:
957             transcode_audio_close( id );
958             break;
959         case VIDEO_ES:
960             transcode_video_close( p_stream, id );
961             break;
962         case SPU_ES:
963             if( p_sys->b_osd )
964                 transcode_osd_close( p_stream, id );
965             else
966                 transcode_spu_close( id );
967             break;
968         }
969     }
970
971     if( id->id ) sout_StreamIdDel( p_sys->p_out, id->id );
972
973     if( id->p_decoder )
974     {
975         vlc_object_detach( id->p_decoder );
976         vlc_object_release( id->p_decoder );
977         id->p_decoder = NULL;
978     }
979
980     if( id->p_encoder )
981     {
982         vlc_object_detach( id->p_encoder );
983         es_format_Clean( &id->p_encoder->fmt_out );
984         vlc_object_release( id->p_encoder );
985         id->p_encoder = NULL;
986     }
987     free( id );
988
989     return VLC_SUCCESS;
990 }
991
992 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
993                  block_t *p_buffer )
994 {
995     sout_stream_sys_t *p_sys = p_stream->p_sys;
996     block_t *p_out = NULL;
997
998     if( !id->b_transcode && id->id )
999     {
1000         return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
1001     }
1002     else if( !id->b_transcode )
1003     {
1004         block_Release( p_buffer );
1005         return VLC_EGENERIC;
1006     }
1007
1008     switch( id->p_decoder->fmt_in.i_cat )
1009     {
1010     case AUDIO_ES:
1011         transcode_audio_process( p_stream, id, p_buffer, &p_out );
1012         break;
1013
1014     case VIDEO_ES:
1015         if( transcode_video_process( p_stream, id, p_buffer, &p_out )
1016             != VLC_SUCCESS )
1017         {
1018             return VLC_EGENERIC;
1019         }
1020         break;
1021
1022     case SPU_ES:
1023         /* Transcode OSD menu pictures. */
1024         if( p_sys->b_osd )
1025         {
1026             if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
1027                 VLC_SUCCESS )
1028             {
1029                 return VLC_EGENERIC;
1030             }
1031         }
1032         else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
1033             VLC_SUCCESS )
1034         {
1035             return VLC_EGENERIC;
1036         }
1037         break;
1038
1039     default:
1040         p_out = NULL;
1041         block_Release( p_buffer );
1042         break;
1043     }
1044
1045     if( p_out )
1046         return sout_StreamIdSend( p_sys->p_out, id->id, p_out );
1047     return VLC_SUCCESS;
1048 }
1049
1050 /****************************************************************************
1051  * decoder helper
1052  ****************************************************************************/
1053 static inline void video_timer_start( encoder_t * p_encoder )
1054 {
1055     stats_TimerStart( p_encoder, "encoding video frame",
1056                       STATS_TIMER_VIDEO_FRAME_ENCODING );
1057 }
1058
1059 static inline void video_timer_stop( encoder_t * p_encoder )
1060 {
1061     stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1062 }
1063
1064 static inline void video_timer_close( encoder_t * p_encoder )
1065 {
1066     stats_TimerDump(  p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1067     stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1068 }
1069
1070 static inline void audio_timer_start( encoder_t * p_encoder )
1071 {
1072     stats_TimerStart( p_encoder, "encoding audio frame",
1073                       STATS_TIMER_AUDIO_FRAME_ENCODING );
1074 }
1075
1076 static inline void audio_timer_stop( encoder_t * p_encoder )
1077 {
1078     stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1079 }
1080
1081 static inline void audio_timer_close( encoder_t * p_encoder )
1082 {
1083     stats_TimerDump(  p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1084     stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1085 }
1086
1087 /****************************************************************************
1088  * decoder reencoder part
1089  ****************************************************************************/
1090
1091 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1092 {
1093     VLC_UNUSED( p_filter );
1094     return block_Alloc( size );
1095 }
1096
1097 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1098                                                    void *data )
1099 {
1100     VLC_UNUSED(data);
1101     p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1102     return VLC_SUCCESS;
1103 }
1104
1105 static int transcode_audio_new( sout_stream_t *p_stream,
1106                                 sout_stream_id_t *id )
1107 {
1108     sout_stream_sys_t *p_sys = p_stream->p_sys;
1109     es_format_t fmt_last;
1110     int i;
1111
1112     /*
1113      * Open decoder
1114      */
1115
1116     /* Initialization of decoder structures */
1117     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1118     id->p_decoder->fmt_out.i_extra = 0;
1119     id->p_decoder->fmt_out.p_extra = 0;
1120     id->p_decoder->pf_decode_audio = NULL;
1121     id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1122     id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1123     /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1124
1125     id->p_decoder->p_module =
1126         module_need( id->p_decoder, "decoder", "$codec", 0 );
1127     if( !id->p_decoder->p_module )
1128     {
1129         msg_Err( p_stream, "cannot find audio decoder" );
1130         return VLC_EGENERIC;
1131     }
1132     id->p_decoder->fmt_out.audio.i_bitspersample =
1133         aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1134     fmt_last = id->p_decoder->fmt_out;
1135     /* Fix AAC SBR changing number of channels and sampling rate */
1136     if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1137         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1138         fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1139         fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1140
1141     /*
1142      * Open encoder
1143      */
1144
1145     /* Initialization of encoder format structures */
1146     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1147                     id->p_decoder->fmt_out.i_codec );
1148     id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1149
1150     id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1151     id->p_encoder->fmt_in.audio.i_physical_channels =
1152         id->p_encoder->fmt_out.audio.i_physical_channels;
1153     id->p_encoder->fmt_in.audio.i_original_channels =
1154         id->p_encoder->fmt_out.audio.i_original_channels;
1155     id->p_encoder->fmt_in.audio.i_channels =
1156         id->p_encoder->fmt_out.audio.i_channels;
1157     id->p_encoder->fmt_in.audio.i_bitspersample =
1158         aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1159
1160     id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1161     id->p_encoder->p_module =
1162         module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1163     if( !id->p_encoder->p_module )
1164     {
1165         msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1166                  p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1167                  (char *)&p_sys->i_acodec );
1168         module_unneed( id->p_decoder, id->p_decoder->p_module );
1169         id->p_decoder->p_module = NULL;
1170         return VLC_EGENERIC;
1171     }
1172     id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1173     id->p_encoder->fmt_in.audio.i_bitspersample =
1174         aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1175
1176     /* Init filter chain */
1177     id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1178                     transcode_audio_filter_allocation_init, NULL, NULL );
1179     filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1180
1181     /* Load conversion filters */
1182     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1183         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1184     {
1185         /* We'll have to go through fl32 first */
1186         fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1187         fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1188         filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1189         fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1190     }
1191
1192     for( i = 0; i < 4; i++ )
1193     {
1194         if( (fmt_last.audio.i_channels !=
1195             id->p_encoder->fmt_in.audio.i_channels) ||
1196             (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1197             (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1198         {
1199             msg_Dbg( p_stream, "Looking for filter "
1200                      "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1201                  (char *)&fmt_last.i_codec,
1202                  (char *)&id->p_encoder->fmt_in.i_codec,
1203                  fmt_last.audio.i_channels,
1204                  id->p_encoder->fmt_in.audio.i_channels,
1205                  fmt_last.audio.i_rate,
1206                  id->p_encoder->fmt_in.audio.i_rate );
1207             filter_chain_AppendFilter( id->p_f_chain, NULL, NULL,
1208                                        &fmt_last, &id->p_encoder->fmt_in );
1209             fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1210         }
1211         else break;
1212     }
1213
1214     /* Final checks to see if conversions were successful */
1215     if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1216     {
1217         msg_Err( p_stream, "no audio filter found "
1218                            "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1219                  (char *)&fmt_last.i_codec,
1220                  (char *)&id->p_encoder->fmt_in.i_codec,
1221                  fmt_last.audio.i_channels,
1222                  id->p_encoder->fmt_in.audio.i_channels,
1223                  fmt_last.audio.i_rate,
1224                  id->p_encoder->fmt_in.audio.i_rate );
1225         transcode_audio_close( id );
1226         return VLC_EGENERIC;
1227     }
1228
1229     /* Load user specified audio filters now */
1230     if( p_sys->psz_af2 )
1231     {
1232         id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1233                        transcode_audio_filter_allocation_init, NULL, NULL );
1234         filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1235         filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1236         fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1237     }
1238
1239     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1240     {
1241 #if 1
1242         module_unneed( id->p_encoder, id->p_encoder->p_module );
1243         id->p_encoder->p_module = NULL;
1244
1245         /* This might work, but only if the encoder is restarted */
1246         id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1247         id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1248
1249         id->p_encoder->fmt_in.audio.i_physical_channels =
1250             id->p_encoder->fmt_in.audio.i_original_channels =
1251                 fmt_last.audio.i_physical_channels;
1252         id->p_encoder->fmt_out.audio.i_physical_channels =
1253             id->p_encoder->fmt_out.audio.i_original_channels =
1254                 fmt_last.audio.i_physical_channels;
1255
1256         msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1257                  "trying to reopen the encoder for mixing %i to %i channels",
1258                  fmt_last.audio.i_channels,
1259                  id->p_encoder->fmt_in.audio.i_channels );
1260
1261         /* reload encoder */
1262         id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1263         id->p_encoder->p_module =
1264             module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1265         if( !id->p_encoder->p_module ||
1266             fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels  ||
1267             fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1268         {
1269             if( id->p_encoder->p_module )
1270             {
1271                 module_unneed( id->p_encoder, id->p_encoder->p_module );
1272                 id->p_encoder->p_module = NULL;
1273             }
1274             msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1275                      p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1276                      (char *)&p_sys->i_acodec );
1277             transcode_audio_close( id );
1278             return VLC_EGENERIC;
1279         }
1280         id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1281         id->p_encoder->fmt_in.audio.i_bitspersample =
1282             aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1283 #else
1284         msg_Err( p_stream, "no audio filter found for mixing from"
1285                  " %i to %i channels", fmt_last.audio.i_channels,
1286                  id->p_encoder->fmt_in.audio.i_channels );
1287
1288         transcode_audio_close( id );
1289         return VLC_EGENERIC;
1290 #endif
1291     }
1292
1293     if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1294     {
1295         msg_Err( p_stream, "no audio filter found for resampling from"
1296                  " %iHz to %iHz", fmt_last.audio.i_rate,
1297                  id->p_encoder->fmt_in.audio.i_rate );
1298 #if 0
1299         /* FIXME : this might work, but only if the encoder is restarted */
1300         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1301         id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1302 #else
1303         transcode_audio_close( id );
1304         return VLC_EGENERIC;
1305 #endif
1306     }
1307
1308     /* FIXME: Hack for mp3 transcoding support */
1309     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1310         id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1311
1312     return VLC_SUCCESS;
1313 }
1314
1315 static void transcode_audio_close( sout_stream_id_t *id )
1316 {
1317     audio_timer_close( id->p_encoder );
1318
1319     /* Close decoder */
1320     if( id->p_decoder->p_module )
1321         module_unneed( id->p_decoder, id->p_decoder->p_module );
1322     id->p_decoder->p_module = NULL;
1323
1324     /* Close encoder */
1325     if( id->p_encoder->p_module )
1326         module_unneed( id->p_encoder, id->p_encoder->p_module );
1327     id->p_encoder->p_module = NULL;
1328
1329     /* Close filters */
1330     if( id->p_f_chain )
1331         filter_chain_Delete( id->p_f_chain );
1332     if( id->p_uf_chain )
1333         filter_chain_Delete( id->p_uf_chain );
1334 }
1335
1336 static int transcode_audio_process( sout_stream_t *p_stream,
1337                                     sout_stream_id_t *id,
1338                                     block_t *in, block_t **out )
1339 {
1340     sout_stream_sys_t *p_sys = p_stream->p_sys;
1341     aout_buffer_t *p_audio_buf;
1342     block_t *p_block, *p_audio_block;
1343     *out = NULL;
1344
1345     while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1346                                                           &in )) )
1347     {
1348         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1349         if( p_sys->b_master_sync )
1350         {
1351             mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1352             if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1353                   || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1354             {
1355                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1356                 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1357                 i_dts = p_audio_buf->start_date + 1;
1358             }
1359             p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1360             date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1361             p_audio_buf->start_date -= p_sys->i_master_drift;
1362             p_audio_buf->end_date -= p_sys->i_master_drift;
1363         }
1364
1365         p_audio_block = p_audio_buf->p_sys;
1366         p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1367         p_audio_block->i_dts = p_audio_block->i_pts =
1368             p_audio_buf->start_date;
1369         p_audio_block->i_length = p_audio_buf->end_date -
1370             p_audio_buf->start_date;
1371         p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1372
1373         /* Run filter chain */
1374         p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1375         if( id->p_uf_chain )
1376             p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1377         assert( p_audio_block );
1378
1379         p_audio_buf->p_buffer = p_audio_block->p_buffer;
1380         p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1381         p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1382         p_audio_buf->start_date = p_audio_block->i_dts;
1383         p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1384
1385         audio_timer_start( id->p_encoder );
1386         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1387         audio_timer_stop( id->p_encoder );
1388
1389         block_ChainAppend( out, p_block );
1390         block_Release( p_audio_block );
1391         free( p_audio_buf );
1392     }
1393
1394     return VLC_SUCCESS;
1395 }
1396
1397 static void audio_release_buffer( aout_buffer_t *p_buffer )
1398 {
1399     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1400     free( p_buffer );
1401 }
1402
1403 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1404 {
1405     aout_buffer_t *p_buffer;
1406     block_t *p_block;
1407     int i_size;
1408
1409     if( p_dec->fmt_out.audio.i_bitspersample )
1410     {
1411         i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1412             p_dec->fmt_out.audio.i_channels;
1413     }
1414     else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1415              p_dec->fmt_out.audio.i_frame_length )
1416     {
1417         i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1418             p_dec->fmt_out.audio.i_frame_length;
1419     }
1420     else
1421     {
1422         i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1423     }
1424
1425     p_buffer = malloc( sizeof(aout_buffer_t) );
1426     if( !p_buffer ) return NULL;
1427     p_buffer->b_discontinuity = false;
1428     p_buffer->pf_release = audio_release_buffer;
1429     p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1430
1431     p_buffer->p_buffer = p_block->p_buffer;
1432     p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1433     p_buffer->i_nb_samples = i_samples;
1434     p_block->i_samples = i_samples;
1435
1436     return p_buffer;
1437 }
1438
1439 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1440 {
1441     VLC_UNUSED(p_dec);
1442     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1443     free( p_buffer );
1444 }
1445
1446 /*
1447  * video
1448  */
1449
1450 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1451                                                    void *p_data )
1452 {
1453     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1454     int i;
1455
1456     p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1457     p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1458
1459     p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1460     if( !p_filter->p_owner )
1461         return VLC_EGENERIC;
1462
1463     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1464         p_filter->p_owner->pp_pics[i] = 0;
1465     p_filter->p_owner->p_sys = p_sys;
1466
1467     return VLC_SUCCESS;
1468 }
1469
1470 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1471 {
1472     int j;
1473
1474     /* Clean-up pictures ring buffer */
1475     for( j = 0; j < PICTURE_RING_SIZE; j++ )
1476     {
1477         if( p_filter->p_owner->pp_pics[j] )
1478             video_del_buffer( VLC_OBJECT(p_filter),
1479                               p_filter->p_owner->pp_pics[j] );
1480     }
1481     free( p_filter->p_owner );
1482 }
1483
1484 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1485 {
1486     sout_stream_sys_t *p_sys = p_stream->p_sys;
1487     int i;
1488
1489     /* Open decoder
1490      * Initialization of decoder structures
1491      */
1492     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1493     id->p_decoder->fmt_out.i_extra = 0;
1494     id->p_decoder->fmt_out.p_extra = 0;
1495     id->p_decoder->pf_decode_video = NULL;
1496     id->p_decoder->pf_get_cc = NULL;
1497     id->p_decoder->pf_get_cc = 0;
1498     id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1499     id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1500     id->p_decoder->pf_picture_link    = video_link_picture_decoder;
1501     id->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder;
1502     id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1503     if( !id->p_decoder->p_owner )
1504         return VLC_EGENERIC;
1505
1506     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1507         id->p_decoder->p_owner->pp_pics[i] = 0;
1508     id->p_decoder->p_owner->p_sys = p_sys;
1509     /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1510
1511     id->p_decoder->p_module =
1512         module_need( id->p_decoder, "decoder", "$codec", 0 );
1513
1514     if( !id->p_decoder->p_module )
1515     {
1516         msg_Err( p_stream, "cannot find video decoder" );
1517         free( id->p_decoder->p_owner );
1518         return VLC_EGENERIC;
1519     }
1520
1521     /*
1522      * Open encoder.
1523      * Because some info about the decoded input will only be available
1524      * once the first frame is decoded, we actually only test the availability
1525      * of the encoder here.
1526      */
1527
1528     /* Initialization of encoder format structures */
1529     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1530                     id->p_decoder->fmt_out.i_codec );
1531     id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1532
1533     /* The dimensions will be set properly later on.
1534      * Just put sensible values so we can test an encoder is available. */
1535     id->p_encoder->fmt_in.video.i_width =
1536         id->p_encoder->fmt_out.video.i_width ?:
1537         id->p_decoder->fmt_in.video.i_width ?: 16;
1538     id->p_encoder->fmt_in.video.i_height =
1539         id->p_encoder->fmt_out.video.i_height ?:
1540         id->p_decoder->fmt_in.video.i_height ?: 16;
1541     id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1542     id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1543
1544     id->p_encoder->i_threads = p_sys->i_threads;
1545     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1546
1547     id->p_encoder->p_module =
1548         module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1549     if( !id->p_encoder->p_module )
1550     {
1551         msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1552                  p_sys->psz_venc ? p_sys->psz_venc : "any",
1553                  (char *)&p_sys->i_vcodec );
1554         module_unneed( id->p_decoder, id->p_decoder->p_module );
1555         id->p_decoder->p_module = 0;
1556         free( id->p_decoder->p_owner );
1557         return VLC_EGENERIC;
1558     }
1559
1560     /* Close the encoder.
1561      * We'll open it only when we have the first frame. */
1562     module_unneed( id->p_encoder, id->p_encoder->p_module );
1563     if( id->p_encoder->fmt_out.p_extra )
1564     {
1565         free( id->p_encoder->fmt_out.p_extra );
1566         id->p_encoder->fmt_out.p_extra = NULL;
1567         id->p_encoder->fmt_out.i_extra = 0;
1568     }
1569     id->p_encoder->p_module = NULL;
1570
1571     if( p_sys->i_threads >= 1 )
1572     {
1573         int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1574                            VLC_THREAD_PRIORITY_VIDEO;
1575         p_sys->id_video = id;
1576         vlc_mutex_init( &p_sys->lock_out );
1577         vlc_cond_init( &p_sys->cond );
1578         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1579         p_sys->i_first_pic = 0;
1580         p_sys->i_last_pic = 0;
1581         p_sys->p_buffers = NULL;
1582         p_sys->b_die = p_sys->b_error = 0;
1583         if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1584                                false ) )
1585         {
1586             msg_Err( p_stream, "cannot spawn encoder thread" );
1587             module_unneed( id->p_decoder, id->p_decoder->p_module );
1588             id->p_decoder->p_module = 0;
1589             free( id->p_decoder->p_owner );
1590             return VLC_EGENERIC;
1591         }
1592     }
1593
1594     return VLC_SUCCESS;
1595 }
1596
1597 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1598                                           sout_stream_id_t *id )
1599 {
1600     sout_stream_sys_t *p_sys = p_stream->p_sys;
1601
1602     /* Calculate scaling
1603      * width/height of source */
1604     int i_src_width = id->p_decoder->fmt_out.video.i_width;
1605     int i_src_height = id->p_decoder->fmt_out.video.i_height;
1606
1607     /* with/height scaling */
1608     float f_scale_width = 1;
1609     float f_scale_height = 1;
1610
1611     /* width/height of output stream */
1612     int i_dst_width;
1613     int i_dst_height;
1614
1615     /* aspect ratio */
1616     float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1617                             VOUT_ASPECT_FACTOR;
1618
1619     msg_Dbg( p_stream, "decoder aspect is %i:%i",
1620                  id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1621
1622     /* Change f_aspect from source frame to source pixel */
1623     f_aspect = f_aspect * i_src_height / i_src_width;
1624     msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1625
1626     /* Calculate scaling factor for specified parameters */
1627     if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1628         id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1629     {
1630         /* Global scaling. Make sure width will remain a factor of 16 */
1631         float f_real_scale;
1632         int  i_new_height;
1633         int i_new_width = i_src_width * p_sys->f_scale;
1634
1635         if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1636             i_new_width -= i_new_width % 16;
1637         else
1638             i_new_width += 16 - i_new_width % 16;
1639
1640         f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1641
1642         i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1643
1644         f_scale_width = f_real_scale;
1645         f_scale_height = (float) i_new_height / (float) i_src_height;
1646     }
1647     else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1648              id->p_encoder->fmt_out.video.i_height <= 0 )
1649     {
1650         /* Only width specified */
1651         f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1652         f_scale_height = f_scale_width;
1653     }
1654     else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1655              id->p_encoder->fmt_out.video.i_height > 0 )
1656     {
1657          /* Only height specified */
1658          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1659          f_scale_width = f_scale_height;
1660      }
1661      else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1662               id->p_encoder->fmt_out.video.i_height > 0 )
1663      {
1664          /* Width and height specified */
1665          f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1666          f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1667      }
1668
1669      /* check maxwidth and maxheight
1670       */
1671      if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1672                                                      i_src_width )
1673      {
1674          f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1675      }
1676
1677      if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1678                                                        i_src_height )
1679      {
1680          f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1681      }
1682
1683
1684      /* Change aspect ratio from source pixel to scaled pixel */
1685      f_aspect = f_aspect * f_scale_height / f_scale_width;
1686      msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1687
1688      /* f_scale_width and f_scale_height are now final */
1689      /* Calculate width, height from scaling
1690       * Make sure its multiple of 2
1691       */
1692      i_dst_width =  2 * (int)(f_scale_width*i_src_width/2+0.5);
1693      i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1694
1695      /* Change aspect ratio from scaled pixel to output frame */
1696      f_aspect = f_aspect * i_dst_width / i_dst_height;
1697
1698      /* Store calculated values */
1699      id->p_encoder->fmt_out.video.i_width =
1700      id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1701      id->p_encoder->fmt_out.video.i_height =
1702      id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1703
1704      id->p_encoder->fmt_in.video.i_width =
1705      id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1706      id->p_encoder->fmt_in.video.i_height =
1707      id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1708
1709      msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1710          i_src_width, i_src_height,
1711          i_dst_width, i_dst_height
1712      );
1713
1714     /* Handle frame rate conversion */
1715     if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1716         !id->p_encoder->fmt_out.video.i_frame_rate_base )
1717     {
1718         if( id->p_decoder->fmt_out.video.i_frame_rate &&
1719             id->p_decoder->fmt_out.video.i_frame_rate_base )
1720         {
1721             id->p_encoder->fmt_out.video.i_frame_rate =
1722                 id->p_decoder->fmt_out.video.i_frame_rate;
1723             id->p_encoder->fmt_out.video.i_frame_rate_base =
1724                 id->p_decoder->fmt_out.video.i_frame_rate_base;
1725         }
1726         else
1727         {
1728             /* Pick a sensible default value */
1729             id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1730             id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1731         }
1732     }
1733
1734     id->p_encoder->fmt_in.video.i_frame_rate =
1735         id->p_encoder->fmt_out.video.i_frame_rate;
1736     id->p_encoder->fmt_in.video.i_frame_rate_base =
1737         id->p_encoder->fmt_out.video.i_frame_rate_base;
1738
1739     date_Init( &id->interpolated_pts,
1740                id->p_encoder->fmt_out.video.i_frame_rate,
1741                id->p_encoder->fmt_out.video.i_frame_rate_base );
1742
1743     /* Check whether a particular aspect ratio was requested */
1744     if( !id->p_encoder->fmt_out.video.i_aspect )
1745     {
1746         id->p_encoder->fmt_out.video.i_aspect =
1747                 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1748     }
1749     id->p_encoder->fmt_in.video.i_aspect =
1750         id->p_encoder->fmt_out.video.i_aspect;
1751
1752     msg_Dbg( p_stream, "encoder aspect is %i:%i",
1753              id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1754
1755     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1756 }
1757
1758 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1759                                          sout_stream_id_t *id )
1760 {
1761     sout_stream_sys_t *p_sys = p_stream->p_sys;
1762
1763
1764     msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1765              id->p_encoder->fmt_in.video.i_width,
1766              id->p_encoder->fmt_in.video.i_height );
1767
1768     id->p_encoder->p_module =
1769         module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1770     if( !id->p_encoder->p_module )
1771     {
1772         msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1773                  p_sys->psz_venc ? p_sys->psz_venc : "any",
1774                  (char *)&p_sys->i_vcodec );
1775         return VLC_EGENERIC;
1776     }
1777
1778     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1779
1780     /* Hack for mp2v/mp1v transcoding support */
1781     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1782         id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1783     {
1784         id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1785     }
1786
1787     id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1788                                &id->p_encoder->fmt_out );
1789     if( !id->id )
1790     {
1791         msg_Err( p_stream, "cannot add this stream" );
1792         return VLC_EGENERIC;
1793     }
1794
1795     return VLC_SUCCESS;
1796 }
1797
1798 static void transcode_video_close( sout_stream_t *p_stream,
1799                                    sout_stream_id_t *id )
1800 {
1801     int i;
1802
1803     if( p_stream->p_sys->i_threads >= 1 )
1804     {
1805         vlc_mutex_lock( &p_stream->p_sys->lock_out );
1806         vlc_object_kill( p_stream->p_sys );
1807         vlc_cond_signal( &p_stream->p_sys->cond );
1808         vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1809         vlc_thread_join( p_stream->p_sys );
1810         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1811         vlc_cond_destroy( &p_stream->p_sys->cond );
1812     }
1813
1814     video_timer_close( id->p_encoder );
1815
1816     /* Close decoder */
1817     if( id->p_decoder->p_module )
1818         module_unneed( id->p_decoder, id->p_decoder->p_module );
1819
1820     if( id->p_decoder->p_owner )
1821     {
1822         /* Clean-up pictures ring buffer */
1823         for( i = 0; i < PICTURE_RING_SIZE; i++ )
1824         {
1825             if( id->p_decoder->p_owner->pp_pics[i] )
1826                 video_del_buffer( VLC_OBJECT(id->p_decoder),
1827                                   id->p_decoder->p_owner->pp_pics[i] );
1828         }
1829         free( id->p_decoder->p_owner );
1830     }
1831
1832     /* Close encoder */
1833     if( id->p_encoder->p_module )
1834         module_unneed( id->p_encoder, id->p_encoder->p_module );
1835
1836     /* Close filters */
1837     if( id->p_f_chain )
1838         filter_chain_Delete( id->p_f_chain );
1839     if( id->p_uf_chain )
1840         filter_chain_Delete( id->p_uf_chain );
1841 }
1842
1843 static int transcode_video_process( sout_stream_t *p_stream,
1844                                     sout_stream_id_t *id,
1845                                     block_t *in, block_t **out )
1846 {
1847     sout_stream_sys_t *p_sys = p_stream->p_sys;
1848     int i_duplicate = 1;
1849     picture_t *p_pic, *p_pic2 = NULL;
1850     *out = NULL;
1851
1852     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1853     {
1854         subpicture_t *p_subpic = NULL;
1855
1856         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1857
1858         if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1859         {
1860             mtime_t current_date = mdate();
1861             if( current_date + 50000 > p_pic->date )
1862             {
1863                 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1864                          current_date + 50000 - p_pic->date );
1865                 p_pic->pf_release( p_pic );
1866                 continue;
1867             }
1868         }
1869
1870         if( p_sys->b_master_sync )
1871         {
1872             mtime_t i_video_drift;
1873             mtime_t i_master_drift = p_sys->i_master_drift;
1874             mtime_t i_pts;
1875
1876             i_pts = date_Get( &id->interpolated_pts ) + 1;
1877             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1878                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1879             {
1880                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1881                 date_Set( &id->interpolated_pts, p_pic->date );
1882                 i_pts = p_pic->date + 1;
1883             }
1884             i_video_drift = p_pic->date - i_pts;
1885             i_duplicate = 1;
1886
1887             /* Set the pts of the frame being encoded */
1888             p_pic->date = i_pts;
1889
1890             if( i_video_drift < (i_master_drift - 50000) )
1891             {
1892 #if 0
1893                 msg_Dbg( p_stream, "dropping frame (%i)",
1894                          (int)(i_video_drift - i_master_drift) );
1895 #endif
1896                 p_pic->pf_release( p_pic );
1897                 continue;
1898             }
1899             else if( i_video_drift > (i_master_drift + 50000) )
1900             {
1901 #if 0
1902                 msg_Dbg( p_stream, "adding frame (%i)",
1903                          (int)(i_video_drift - i_master_drift) );
1904 #endif
1905                 i_duplicate = 2;
1906             }
1907         }
1908
1909         if( !id->p_encoder->p_module )
1910         {
1911             transcode_video_encoder_init( p_stream, id );
1912
1913             id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1914                                               false,
1915                                transcode_video_filter_allocation_init,
1916                                transcode_video_filter_allocation_clear,
1917                                p_stream->p_sys );
1918
1919             /* Deinterlace */
1920             if( p_stream->p_sys->b_deinterlace )
1921             {
1922                 filter_chain_AppendFilter( id->p_f_chain,
1923                                            p_sys->psz_deinterlace,
1924                                            p_sys->p_deinterlace_cfg,
1925                                            &id->p_decoder->fmt_out,
1926                                            &id->p_decoder->fmt_out );
1927             }
1928
1929             /* Take care of the scaling and chroma conversions */
1930             if( ( id->p_decoder->fmt_out.video.i_chroma !=
1931                   id->p_encoder->fmt_in.video.i_chroma ) ||
1932                 ( id->p_decoder->fmt_out.video.i_width !=
1933                   id->p_encoder->fmt_in.video.i_width ) ||
1934                 ( id->p_decoder->fmt_out.video.i_height !=
1935                   id->p_encoder->fmt_in.video.i_height ) )
1936             {
1937                 filter_chain_AppendFilter( id->p_f_chain,
1938                                            NULL, NULL,
1939                                            &id->p_decoder->fmt_out,
1940                                            &id->p_encoder->fmt_in );
1941             }
1942
1943             if( p_sys->psz_vf2 )
1944             {
1945                 const es_format_t *p_fmt_out;
1946                 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1947                                                    true,
1948                                    transcode_video_filter_allocation_init,
1949                                    transcode_video_filter_allocation_clear,
1950                                    p_stream->p_sys );
1951                 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1952                                     &id->p_encoder->fmt_in );
1953                 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1954                 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1955                 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1956                 id->p_encoder->fmt_out.video.i_width =
1957                     id->p_encoder->fmt_in.video.i_width;
1958                 id->p_encoder->fmt_out.video.i_height =
1959                     id->p_encoder->fmt_in.video.i_height;
1960                 id->p_encoder->fmt_out.video.i_aspect =
1961                     id->p_encoder->fmt_in.video.i_aspect;
1962             }
1963
1964             if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1965             {
1966                 p_pic->pf_release( p_pic );
1967                 transcode_video_close( p_stream, id );
1968                 id->b_transcode = false;
1969                 return VLC_EGENERIC;
1970             }
1971         }
1972
1973         /* Run filter chain */
1974         if( id->p_f_chain )
1975             p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1976
1977         /*
1978          * Encoding
1979          */
1980
1981         /* Check if we have a subpicture to overlay */
1982         if( p_sys->p_spu )
1983         {
1984             p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1985                        false /* Fixme: check if stream is paused */, false );
1986             /* TODO: get another pic */
1987         }
1988
1989         /* Overlay subpicture */
1990         if( p_subpic )
1991         {
1992             video_format_t fmt;
1993
1994             if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1995             {
1996                 /* We can't modify the picture, we need to duplicate it */
1997                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1998                 if( p_tmp )
1999                 {
2000                     picture_Copy( p_tmp, p_pic );
2001                     p_pic->pf_release( p_pic );
2002                     p_pic = p_tmp;
2003                 }
2004             }
2005
2006             if( filter_chain_GetLength( id->p_f_chain ) > 0 )
2007                 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
2008             else
2009                 fmt = id->p_decoder->fmt_out.video;
2010
2011             /* FIXME (shouldn't have to be done here) */
2012             fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
2013             fmt.i_sar_den = VOUT_ASPECT_FACTOR;
2014
2015             spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
2016                                    p_subpic, &id->p_decoder->fmt_out.video, false );
2017         }
2018
2019         /* Run user specified filter chain */
2020         if( id->p_uf_chain )
2021             p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2022
2023         if( p_sys->i_threads == 0 )
2024         {
2025             block_t *p_block;
2026
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
2031             block_ChainAppend( out, p_block );
2032         }
2033
2034         if( p_sys->b_master_sync )
2035         {
2036             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2037             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2038                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2039             {
2040                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2041                 date_Set( &id->interpolated_pts, p_pic->date );
2042                 i_pts = p_pic->date + 1;
2043             }
2044             date_Increment( &id->interpolated_pts, 1 );
2045         }
2046
2047         if( p_sys->b_master_sync && i_duplicate > 1 )
2048         {
2049             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2050             if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2051                  || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2052             {
2053                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2054                 date_Set( &id->interpolated_pts, p_pic->date );
2055                 i_pts = p_pic->date + 1;
2056             }
2057             date_Increment( &id->interpolated_pts, 1 );
2058
2059             if( p_sys->i_threads >= 1 )
2060             {
2061                 /* We can't modify the picture, we need to duplicate it */
2062                 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2063                 if( p_pic2 != NULL )
2064                 {
2065                     picture_Copy( p_pic2, p_pic );
2066                     p_pic2->date = i_pts;
2067                 }
2068             }
2069             else
2070             {
2071                 block_t *p_block;
2072                 p_pic->date = i_pts;
2073                 video_timer_start( id->p_encoder );
2074                 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2075                 video_timer_stop( id->p_encoder );
2076                 block_ChainAppend( out, p_block );
2077             }
2078         }
2079
2080         if( p_sys->i_threads == 0 )
2081         {
2082             p_pic->pf_release( p_pic );
2083         }
2084         else
2085         {
2086             vlc_mutex_lock( &p_sys->lock_out );
2087             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2088             p_sys->i_last_pic %= PICTURE_RING_SIZE;
2089             *out = p_sys->p_buffers;
2090             p_sys->p_buffers = NULL;
2091             if( p_pic2 != NULL )
2092             {
2093                 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2094                 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2095             }
2096             vlc_cond_signal( &p_sys->cond );
2097             vlc_mutex_unlock( &p_sys->lock_out );
2098         }
2099     }
2100
2101     return VLC_SUCCESS;
2102 }
2103
2104 static void* EncoderThread( vlc_object_t* p_this )
2105 {
2106     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2107     sout_stream_id_t *id = p_sys->id_video;
2108     picture_t *p_pic;
2109     int canc = vlc_savecancel ();
2110
2111     while( vlc_object_alive (p_sys) && !p_sys->b_error )
2112     {
2113         block_t *p_block;
2114
2115         vlc_mutex_lock( &p_sys->lock_out );
2116         while( p_sys->i_last_pic == p_sys->i_first_pic )
2117         {
2118             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2119             if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2120         }
2121         if( !vlc_object_alive (p_sys) || p_sys->b_error )
2122         {
2123             vlc_mutex_unlock( &p_sys->lock_out );
2124             break;
2125         }
2126
2127         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2128         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2129         vlc_mutex_unlock( &p_sys->lock_out );
2130
2131         video_timer_start( id->p_encoder );
2132         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2133         video_timer_stop( id->p_encoder );
2134
2135         vlc_mutex_lock( &p_sys->lock_out );
2136         block_ChainAppend( &p_sys->p_buffers, p_block );
2137
2138         vlc_mutex_unlock( &p_sys->lock_out );
2139         p_pic->pf_release( p_pic );
2140     }
2141
2142     while( p_sys->i_last_pic != p_sys->i_first_pic )
2143     {
2144         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2145         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2146         p_pic->pf_release( p_pic );
2147     }
2148     block_ChainRelease( p_sys->p_buffers );
2149
2150     vlc_restorecancel (canc);
2151     return NULL;
2152 }
2153
2154 struct picture_sys_t
2155 {
2156     vlc_object_t *p_owner;
2157 };
2158
2159 static void video_release_buffer( picture_t *p_pic )
2160 {
2161     if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2162     {
2163         video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2164     }
2165     else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2166 }
2167
2168 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2169                                     sout_stream_sys_t *p_sys )
2170 {
2171     decoder_t *p_dec = (decoder_t *)p_this;
2172     picture_t *p_pic;
2173     int i;
2174
2175     /* Find an empty space in the picture ring buffer */
2176     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2177     {
2178         if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2179         {
2180             pp_ring[i]->i_status = RESERVED_PICTURE;
2181             return pp_ring[i];
2182         }
2183     }
2184     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2185     {
2186         if( pp_ring[i] == 0 ) break;
2187     }
2188
2189     if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2190     {
2191         int i_first_pic = p_sys->i_first_pic;
2192
2193         if( p_sys->i_first_pic != p_sys->i_last_pic )
2194         {
2195             /* Encoder still has stuff to encode, wait to clear-up the list */
2196             while( p_sys->i_first_pic == i_first_pic )
2197                 msleep( 100000 );
2198         }
2199
2200         /* Find an empty space in the picture ring buffer */
2201         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2202         {
2203             if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2204             {
2205                 pp_ring[i]->i_status = RESERVED_PICTURE;
2206                 return pp_ring[i];
2207             }
2208         }
2209         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2210         {
2211             if( pp_ring[i] == 0 ) break;
2212         }
2213     }
2214
2215     if( i == PICTURE_RING_SIZE )
2216     {
2217         msg_Err( p_this, "decoder/filter is leaking pictures, "
2218                  "resetting its ring buffer" );
2219
2220         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2221         {
2222             pp_ring[i]->pf_release( pp_ring[i] );
2223         }
2224
2225         i = 0;
2226     }
2227
2228     p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2229                          p_dec->fmt_out.video.i_width,
2230                          p_dec->fmt_out.video.i_height,
2231                          p_dec->fmt_out.video.i_aspect );
2232     if( !p_pic ) return NULL;
2233     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2234     p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2235     if( !p_pic->p_sys )
2236     {
2237         picture_Release( p_pic );
2238         return NULL;
2239     }
2240     p_pic->pf_release = video_release_buffer;
2241     p_pic->i_refcount = 0;
2242
2243     pp_ring[i] = p_pic;
2244     return p_pic;
2245 }
2246
2247 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2248 {
2249     return video_new_buffer( VLC_OBJECT(p_dec),
2250                              p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2251 }
2252
2253 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2254 {
2255     return video_new_buffer( VLC_OBJECT(p_filter),
2256                              p_filter->p_owner->pp_pics,
2257                              p_filter->p_owner->p_sys );
2258 }
2259
2260 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2261 {
2262     VLC_UNUSED(p_this);
2263     if( p_pic )
2264     {
2265         free( p_pic->p_q );
2266         free( p_pic->p_data_orig );
2267         free( p_pic->p_sys );
2268         free( p_pic );
2269     }
2270 }
2271
2272 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2273 {
2274     VLC_UNUSED(p_decoder);
2275     p_pic->i_refcount = 0;
2276     p_pic->i_status = DESTROYED_PICTURE;
2277     picture_CleanupQuant( p_pic );
2278 }
2279
2280 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2281 {
2282     VLC_UNUSED(p_filter);
2283     p_pic->i_refcount = 0;
2284     p_pic->i_status = DESTROYED_PICTURE;
2285     picture_CleanupQuant( p_pic );
2286 }
2287
2288 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2289 {
2290     VLC_UNUSED(p_dec);
2291     p_pic->i_refcount++;
2292 }
2293
2294 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2295 {
2296     VLC_UNUSED(p_dec);
2297     video_release_buffer( p_pic );
2298 }
2299
2300 /*
2301  * SPU
2302  */
2303 static subpicture_t *spu_new_buffer( decoder_t * );
2304 static void spu_del_buffer( decoder_t *, subpicture_t * );
2305
2306 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2307 {
2308     sout_stream_sys_t *p_sys = p_stream->p_sys;
2309
2310     /*
2311      * Open decoder
2312      */
2313
2314     /* Initialization of decoder structures */
2315     id->p_decoder->pf_decode_sub = NULL;
2316     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2317     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2318     id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2319     /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2320
2321     id->p_decoder->p_module =
2322         module_need( id->p_decoder, "decoder", "$codec", 0 );
2323
2324     if( !id->p_decoder->p_module )
2325     {
2326         msg_Err( p_stream, "cannot find spu decoder" );
2327         return VLC_EGENERIC;
2328     }
2329
2330     if( !p_sys->b_soverlay )
2331     {
2332         /* Open encoder */
2333         /* Initialization of encoder format structures */
2334         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2335                         id->p_decoder->fmt_in.i_codec );
2336
2337         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2338
2339         id->p_encoder->p_module =
2340             module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2341
2342         if( !id->p_encoder->p_module )
2343         {
2344             module_unneed( id->p_decoder, id->p_decoder->p_module );
2345             msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2346             return VLC_EGENERIC;
2347         }
2348     }
2349
2350     if( !p_sys->p_spu )
2351     {
2352         p_sys->p_spu = spu_Create( p_stream );
2353         spu_Init( p_sys->p_spu );
2354     }
2355
2356     return VLC_SUCCESS;
2357 }
2358
2359 static void transcode_spu_close( sout_stream_id_t *id)
2360 {
2361     /* Close decoder */
2362     if( id->p_decoder->p_module )
2363         module_unneed( id->p_decoder, id->p_decoder->p_module );
2364
2365     /* Close encoder */
2366     if( id->p_encoder->p_module )
2367         module_unneed( id->p_encoder, id->p_encoder->p_module );
2368 }
2369
2370 static int transcode_spu_process( sout_stream_t *p_stream,
2371                                   sout_stream_id_t *id,
2372                                   block_t *in, block_t **out )
2373 {
2374     sout_stream_sys_t *p_sys = p_stream->p_sys;
2375     subpicture_t *p_subpic;
2376     *out = NULL;
2377
2378     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2379     if( !p_subpic )
2380         return VLC_EGENERIC;
2381
2382     sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2383
2384     if( p_sys->b_master_sync && p_sys->i_master_drift )
2385     {
2386         p_subpic->i_start -= p_sys->i_master_drift;
2387         if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2388     }
2389
2390     if( p_sys->b_soverlay )
2391     {
2392         spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2393     }
2394     else
2395     {
2396         block_t *p_block;
2397
2398         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2399         spu_del_buffer( id->p_decoder, p_subpic );
2400         if( p_block )
2401         {
2402             block_ChainAppend( out, p_block );
2403             return VLC_SUCCESS;
2404         }
2405     }
2406
2407     return VLC_EGENERIC;
2408 }
2409
2410 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2411 {
2412     VLC_UNUSED( p_dec );
2413     return subpicture_New();
2414 }
2415
2416 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2417 {
2418     VLC_UNUSED( p_dec );
2419     subpicture_Delete( p_subpic );
2420 }
2421
2422 /*
2423  * OSD menu
2424  */
2425 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2426 {
2427     sout_stream_sys_t *p_sys = p_stream->p_sys;
2428
2429     id->p_decoder->fmt_in.i_cat = SPU_ES;
2430     id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2431
2432     if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2433     {
2434         msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2435                  "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2436                  (char*)&p_sys->i_osdcodec );
2437
2438         /* Complete destination format */
2439         id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2440
2441         /* Open encoder */
2442         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2443                         VLC_FOURCC('Y','U','V','A') );
2444         id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2445
2446         id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2447
2448         id->p_encoder->p_module =
2449             module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2450
2451         if( !id->p_encoder->p_module )
2452         {
2453             msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2454             goto error;
2455         }
2456
2457         /* open output stream */
2458         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2459         id->b_transcode = true;
2460
2461         if( !id->id ) goto error;
2462     }
2463     else
2464     {
2465         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2466                  (char*)&id->p_decoder->fmt_out.i_codec );
2467         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2468         id->b_transcode = false;
2469
2470         if( !id->id ) goto error;
2471     }
2472
2473     if( !p_sys->p_spu )
2474     {
2475         p_sys->p_spu = spu_Create( p_stream );
2476         spu_Init( p_sys->p_spu );
2477     }
2478
2479     return VLC_SUCCESS;
2480
2481  error:
2482     msg_Err( p_stream, "starting osd encoding thread failed" );
2483     if( id->p_encoder->p_module )
2484             module_unneed( id->p_encoder, id->p_encoder->p_module );
2485     p_sys->b_osd = false;
2486     return VLC_EGENERIC;
2487 }
2488
2489 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2490 {
2491     sout_stream_sys_t *p_sys = p_stream->p_sys;
2492
2493     /* Close encoder */
2494     if( id )
2495     {
2496         if( id->p_encoder->p_module )
2497             module_unneed( id->p_encoder, id->p_encoder->p_module );
2498     }
2499     p_sys->b_osd = false;
2500 }
2501
2502 static int transcode_osd_process( sout_stream_t *p_stream,
2503                                   sout_stream_id_t *id,
2504                                   block_t *in, block_t **out )
2505 {
2506     sout_stream_sys_t *p_sys = p_stream->p_sys;
2507     subpicture_t *p_subpic = NULL;
2508
2509     /* Check if we have a subpicture to send */
2510     if( p_sys->p_spu && in->i_dts > 0)
2511     {
2512         p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2513     }
2514     else
2515     {
2516         msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2517         if( !p_sys->p_spu )
2518         {
2519             p_sys->p_spu = spu_Create( p_stream );
2520             spu_Init( p_sys->p_spu );
2521         }
2522     }
2523
2524     if( p_subpic )
2525     {
2526         block_t *p_block = NULL;
2527
2528         if( p_sys->b_master_sync && p_sys->i_master_drift )
2529         {
2530             p_subpic->i_start -= p_sys->i_master_drift;
2531             if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2532         }
2533
2534         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2535         subpicture_Delete( p_subpic );
2536         if( p_block )
2537         {
2538             p_block->i_dts = p_block->i_pts = in->i_dts;
2539             block_ChainAppend( out, p_block );
2540             return VLC_SUCCESS;
2541         }
2542     }
2543     return VLC_EGENERIC;
2544 }