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