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