]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
Used VLC_CODEC_* and i_original_fourcc when applicable.
[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_module( SOUT_CFG_PREFIX "venc", "encoder", NULL, NULL, VENC_TEXT,
171                 VENC_LONGTEXT, false )
172     add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
173                 VCODEC_LONGTEXT, false )
174     add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT,
175                  VB_LONGTEXT, false )
176     add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
177                SCALE_LONGTEXT, false )
178     add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT,
179                FPS_LONGTEXT, false )
180     add_bool( SOUT_CFG_PREFIX "hurry-up", true, NULL, HURRYUP_TEXT,
181                HURRYUP_LONGTEXT, false )
182     add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
183               DEINTERLACE_LONGTEXT, false )
184     add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL,
185                 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
186                 false )
187         change_string_list( ppsz_deinterlace_type, 0, 0 )
188     add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
189                  WIDTH_LONGTEXT, true )
190     add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
191                  HEIGHT_LONGTEXT, true )
192     add_integer( SOUT_CFG_PREFIX "maxwidth", 0, NULL, MAXWIDTH_TEXT,
193                  MAXWIDTH_LONGTEXT, true )
194     add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
195                  MAXHEIGHT_LONGTEXT, true )
196     add_module_list( SOUT_CFG_PREFIX "vfilter", "video filter2",
197                      NULL, NULL,
198                      VFILTER_TEXT, VFILTER_LONGTEXT, false )
199
200     set_section( N_("Audio"), NULL )
201     add_module( SOUT_CFG_PREFIX "aenc", "encoder", NULL, NULL, AENC_TEXT,
202                 AENC_LONGTEXT, false )
203     add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
204                 ACODEC_LONGTEXT, false )
205     add_integer( SOUT_CFG_PREFIX "ab", 0, NULL, AB_TEXT,
206                  AB_LONGTEXT, false )
207     add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
208                  ACHANS_LONGTEXT, false )
209     add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
210                  ARATE_LONGTEXT, true )
211     add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
212               ASYNC_LONGTEXT, false )
213     add_module_list( SOUT_CFG_PREFIX "afilter",  "audio filter2",
214                      NULL, NULL,
215                      AFILTER_TEXT, AFILTER_LONGTEXT, false )
216
217     set_section( N_("Overlays/Subtitles"), NULL )
218     add_module( SOUT_CFG_PREFIX "senc", "encoder", NULL, NULL, SENC_TEXT,
219                 SENC_LONGTEXT, false )
220     add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
221                 SCODEC_LONGTEXT, false )
222     add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
223                SCODEC_LONGTEXT, false )
224     add_module_list( SOUT_CFG_PREFIX "sfilter", "video filter",
225                      NULL, NULL,
226                      SFILTER_TEXT, SFILTER_LONGTEXT, false )
227
228     set_section( N_("On Screen Display"), NULL )
229     add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
230               OSD_LONGTEXT, false )
231
232     set_section( N_("Miscellaneous"), NULL )
233     add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
234                  THREADS_LONGTEXT, true )
235     add_bool( SOUT_CFG_PREFIX "high-priority", 0, NULL, HP_TEXT, HP_LONGTEXT,
236               true )
237
238 vlc_module_end ()
239
240 static const char *const ppsz_sout_options[] = {
241     "venc", "vcodec", "vb",
242     "scale", "fps", "width", "height", "vfilter", "deinterlace",
243     "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
244     "afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
245     "sfilter", "osd", "audio-sync", "high-priority", "maxwidth", "maxheight",
246     NULL
247 };
248
249 /*****************************************************************************
250  * Exported prototypes
251  *****************************************************************************/
252 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
253 static int               Del ( sout_stream_t *, sout_stream_id_t * );
254 static int               Send( sout_stream_t *, sout_stream_id_t *, block_t* );
255
256 static int  transcode_audio_new    ( sout_stream_t *, sout_stream_id_t * );
257 static void transcode_audio_close  ( sout_stream_id_t * );
258 static int  transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
259                                      block_t *, block_t ** );
260
261 static aout_buffer_t *audio_new_buffer( decoder_t *, int );
262 static void audio_del_buffer( decoder_t *, aout_buffer_t * );
263
264 static int  transcode_video_new    ( sout_stream_t *, sout_stream_id_t * );
265 static void transcode_video_close  ( sout_stream_t *, sout_stream_id_t * );
266 static void transcode_video_encoder_init( sout_stream_t *, sout_stream_id_t *);
267 static int  transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
268 static int  transcode_video_process( sout_stream_t *, sout_stream_id_t *,
269                                      block_t *, block_t ** );
270
271 static 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',' ') &&
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_CODEC_YUVP;
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 = sout_EncoderCreate( p_stream );
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 bool transcode_audio_filter_needed( const es_format_t *p_fmt1, const es_format_t *p_fmt2 )
1060 {
1061     if( p_fmt1->i_codec != p_fmt2->i_codec ||
1062         p_fmt1->audio.i_channels != p_fmt2->audio.i_channels ||
1063         p_fmt1->audio.i_rate != p_fmt2->audio.i_rate )
1064         return true;
1065     return false;
1066 }
1067 static int transcode_audio_filter_chain_build( sout_stream_t *p_stream, filter_chain_t *p_chain,
1068                                                const es_format_t *p_dst, const es_format_t *p_src )
1069 {
1070     if( !transcode_audio_filter_needed( p_dst, p_src ) )
1071         return VLC_SUCCESS;
1072
1073     es_format_t current = *p_src;
1074
1075     msg_Dbg( p_stream, "Looking for filter "
1076              "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1077          (const char *)&p_src->i_codec,
1078          (const char *)&p_dst->i_codec,
1079          p_src->audio.i_channels,
1080          p_dst->audio.i_channels,
1081          p_src->audio.i_rate,
1082          p_dst->audio.i_rate );
1083
1084     /* If any filter is needed, convert to fl32 */
1085     if( current.i_codec != VLC_CODEC_FL32 )
1086     {
1087         /* First step, convert to fl32 */
1088         current.i_codec =
1089         current.audio.i_format = VLC_CODEC_FL32;
1090
1091         if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
1092         {
1093             msg_Err( p_stream, "Failed to find conversion filter to fl32" );
1094             return VLC_EGENERIC;
1095         }
1096         current = *filter_chain_GetFmtOut( p_chain );
1097     }
1098
1099     /* Fix sample rate */
1100     if( current.audio.i_rate != p_dst->audio.i_rate )
1101     {
1102         current.audio.i_rate = p_dst->audio.i_rate;
1103         if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
1104         {
1105             msg_Err( p_stream, "Failed to find conversion filter for resampling" );
1106             return VLC_EGENERIC;
1107         }
1108         current = *filter_chain_GetFmtOut( p_chain );
1109     }
1110
1111     /* Fix channels */
1112     if( current.audio.i_channels != p_dst->audio.i_channels )
1113     {
1114         current.audio.i_channels = p_dst->audio.i_channels;
1115         current.audio.i_physical_channels = p_dst->audio.i_physical_channels;
1116         current.audio.i_original_channels = p_dst->audio.i_original_channels;
1117
1118         if( ( !current.audio.i_physical_channels || !current.audio.i_original_channels ) &&
1119             current.audio.i_channels < 6 )
1120             current.audio.i_physical_channels =
1121             current.audio.i_original_channels = pi_channels_maps[current.audio.i_channels];
1122
1123         if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
1124         {
1125             msg_Err( p_stream, "Failed to find conversion filter for channel mixing" );
1126             return VLC_EGENERIC;
1127         }
1128         current = *filter_chain_GetFmtOut( p_chain );
1129     }
1130
1131     /* And last step, convert to the requested codec */
1132     if( current.i_codec != p_dst->i_codec )
1133     {
1134         current.i_codec = p_dst->i_codec;
1135         if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
1136         {
1137             msg_Err( p_stream, "Failed to find conversion filter to %4.4s",
1138                      (const char*)&p_dst->i_codec);
1139             return VLC_EGENERIC;
1140         }
1141         current = *filter_chain_GetFmtOut( p_chain );
1142     }
1143
1144     if( transcode_audio_filter_needed( p_dst, &current ) )
1145     {
1146         /* Weird case, a filter has side effects, doomed */
1147         msg_Err( p_stream, "Failed to create a valid audio filter chain" );
1148         return VLC_EGENERIC;
1149     }
1150
1151     msg_Dbg( p_stream, "Got complete audio filter chain" );
1152     return VLC_SUCCESS;
1153 }
1154
1155 static int transcode_audio_new( sout_stream_t *p_stream,
1156                                 sout_stream_id_t *id )
1157 {
1158     sout_stream_sys_t *p_sys = p_stream->p_sys;
1159     es_format_t fmt_last;
1160
1161     /*
1162      * Open decoder
1163      */
1164
1165     /* Initialization of decoder structures */
1166     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1167     id->p_decoder->fmt_out.i_extra = 0;
1168     id->p_decoder->fmt_out.p_extra = 0;
1169     id->p_decoder->pf_decode_audio = NULL;
1170     id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1171     id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1172     /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1173
1174     id->p_decoder->p_module =
1175         module_need( id->p_decoder, "decoder", "$codec", false );
1176     if( !id->p_decoder->p_module )
1177     {
1178         msg_Err( p_stream, "cannot find audio decoder" );
1179         return VLC_EGENERIC;
1180     }
1181     id->p_decoder->fmt_out.audio.i_bitspersample =
1182         aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1183     fmt_last = id->p_decoder->fmt_out;
1184     /* Fix AAC SBR changing number of channels and sampling rate */
1185     if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A &&
1186         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1187         fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1188         fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1189
1190     /*
1191      * Open encoder
1192      */
1193
1194     /* Initialization of encoder format structures */
1195     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1196                     id->p_decoder->fmt_out.i_codec );
1197     id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1198
1199     id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1200     id->p_encoder->fmt_in.audio.i_physical_channels =
1201         id->p_encoder->fmt_out.audio.i_physical_channels;
1202     id->p_encoder->fmt_in.audio.i_original_channels =
1203         id->p_encoder->fmt_out.audio.i_original_channels;
1204     id->p_encoder->fmt_in.audio.i_channels =
1205         id->p_encoder->fmt_out.audio.i_channels;
1206     id->p_encoder->fmt_in.audio.i_bitspersample =
1207         aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1208
1209     id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1210     id->p_encoder->p_module =
1211         module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1212     if( !id->p_encoder->p_module )
1213     {
1214         msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1215                  p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1216                  (char *)&p_sys->i_acodec );
1217         module_unneed( id->p_decoder, id->p_decoder->p_module );
1218         id->p_decoder->p_module = NULL;
1219         return VLC_EGENERIC;
1220     }
1221     id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1222     id->p_encoder->fmt_in.audio.i_bitspersample =
1223         aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1224
1225     /* Load user specified audio filters */
1226     if( p_sys->psz_af2 )
1227     {
1228         es_format_t fmt_fl32 = fmt_last;
1229         fmt_fl32.i_codec =
1230         fmt_fl32.audio.i_format = VLC_CODEC_FL32;
1231         if( transcode_audio_filter_chain_build( p_stream, id->p_uf_chain,
1232                                                 &fmt_fl32, &fmt_last ) )
1233         {
1234             transcode_audio_close( id );
1235             return VLC_EGENERIC;
1236         }
1237         fmt_last = fmt_fl32;
1238
1239         id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1240                                            transcode_audio_filter_allocation_init, NULL, NULL );
1241         filter_chain_Reset( id->p_uf_chain, &fmt_last, &fmt_fl32 );
1242         if( filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 ) > 0 )
1243             fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1244     }
1245
1246     /* Load conversion filters */
1247     id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1248                     transcode_audio_filter_allocation_init, NULL, NULL );
1249     filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1250
1251     if( transcode_audio_filter_chain_build( p_stream, id->p_f_chain,
1252                                             &id->p_encoder->fmt_in, &fmt_last ) )
1253     {
1254         transcode_audio_close( id );
1255         return VLC_EGENERIC;
1256     }
1257     fmt_last = id->p_encoder->fmt_in;
1258
1259     /* */
1260     id->p_encoder->fmt_out.i_codec =
1261         vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec );
1262
1263     return VLC_SUCCESS;
1264 }
1265
1266 static void transcode_audio_close( sout_stream_id_t *id )
1267 {
1268     audio_timer_close( id->p_encoder );
1269
1270     /* Close decoder */
1271     if( id->p_decoder->p_module )
1272         module_unneed( id->p_decoder, id->p_decoder->p_module );
1273     id->p_decoder->p_module = NULL;
1274
1275     if( id->p_decoder->p_description )
1276         vlc_meta_Delete( id->p_decoder->p_description );
1277     id->p_decoder->p_description = NULL;
1278
1279     /* Close encoder */
1280     if( id->p_encoder->p_module )
1281         module_unneed( id->p_encoder, id->p_encoder->p_module );
1282     id->p_encoder->p_module = NULL;
1283
1284     /* Close filters */
1285     if( id->p_uf_chain )
1286         filter_chain_Delete( id->p_uf_chain );
1287     if( id->p_f_chain )
1288         filter_chain_Delete( id->p_f_chain );
1289 }
1290
1291 static int transcode_audio_process( sout_stream_t *p_stream,
1292                                     sout_stream_id_t *id,
1293                                     block_t *in, block_t **out )
1294 {
1295     sout_stream_sys_t *p_sys = p_stream->p_sys;
1296     aout_buffer_t *p_audio_buf;
1297     block_t *p_block, *p_audio_block;
1298     *out = NULL;
1299
1300     while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1301                                                           &in )) )
1302     {
1303         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1304         if( p_sys->b_master_sync )
1305         {
1306             mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1307             if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1308                   || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1309             {
1310                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1311                 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1312                 i_dts = p_audio_buf->start_date + 1;
1313             }
1314             p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1315             date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1316             p_audio_buf->start_date -= p_sys->i_master_drift;
1317             p_audio_buf->end_date -= p_sys->i_master_drift;
1318         }
1319
1320         p_audio_block = p_audio_buf->p_sys;
1321         p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1322         p_audio_block->i_dts = p_audio_block->i_pts =
1323             p_audio_buf->start_date;
1324         p_audio_block->i_length = p_audio_buf->end_date -
1325             p_audio_buf->start_date;
1326         p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1327
1328         /* Run filter chain */
1329         if( id->p_uf_chain )
1330         {
1331             p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1332             assert( p_audio_block );
1333         }
1334
1335         p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1336         assert( p_audio_block );
1337
1338         p_audio_buf->p_buffer = p_audio_block->p_buffer;
1339         p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1340         p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1341         p_audio_buf->start_date = p_audio_block->i_dts;
1342         p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1343
1344         audio_timer_start( id->p_encoder );
1345         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1346         audio_timer_stop( id->p_encoder );
1347
1348         block_ChainAppend( out, p_block );
1349         block_Release( p_audio_block );
1350         free( p_audio_buf );
1351     }
1352
1353     return VLC_SUCCESS;
1354 }
1355
1356 static void audio_release_buffer( aout_buffer_t *p_buffer )
1357 {
1358     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1359     free( p_buffer );
1360 }
1361
1362 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1363 {
1364     aout_buffer_t *p_buffer;
1365     block_t *p_block;
1366     int i_size;
1367
1368     if( p_dec->fmt_out.audio.i_bitspersample )
1369     {
1370         i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1371             p_dec->fmt_out.audio.i_channels;
1372     }
1373     else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1374              p_dec->fmt_out.audio.i_frame_length )
1375     {
1376         i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1377             p_dec->fmt_out.audio.i_frame_length;
1378     }
1379     else
1380     {
1381         i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1382     }
1383
1384     p_buffer = malloc( sizeof(aout_buffer_t) );
1385     if( !p_buffer ) return NULL;
1386     p_buffer->b_discontinuity = false;
1387     p_buffer->pf_release = audio_release_buffer;
1388     p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1389
1390     p_buffer->p_buffer = p_block->p_buffer;
1391     p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1392     p_buffer->i_nb_samples = i_samples;
1393     p_block->i_samples = i_samples;
1394
1395     return p_buffer;
1396 }
1397
1398 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1399 {
1400     VLC_UNUSED(p_dec);
1401     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1402     free( p_buffer );
1403 }
1404
1405 /*
1406  * video
1407  */
1408
1409 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1410                                                    void *p_data )
1411 {
1412     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1413     int i;
1414
1415     p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1416     p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1417
1418     p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1419     if( !p_filter->p_owner )
1420         return VLC_EGENERIC;
1421
1422     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1423         p_filter->p_owner->pp_pics[i] = 0;
1424     p_filter->p_owner->p_sys = p_sys;
1425
1426     return VLC_SUCCESS;
1427 }
1428
1429 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1430 {
1431     int j;
1432
1433     /* Clean-up pictures ring buffer */
1434     for( j = 0; j < PICTURE_RING_SIZE; j++ )
1435     {
1436         if( p_filter->p_owner->pp_pics[j] )
1437             video_del_buffer( VLC_OBJECT(p_filter),
1438                               p_filter->p_owner->pp_pics[j] );
1439     }
1440     free( p_filter->p_owner );
1441 }
1442
1443 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1444 {
1445     sout_stream_sys_t *p_sys = p_stream->p_sys;
1446     int i;
1447
1448     /* Open decoder
1449      * Initialization of decoder structures
1450      */
1451     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1452     id->p_decoder->fmt_out.i_extra = 0;
1453     id->p_decoder->fmt_out.p_extra = 0;
1454     id->p_decoder->pf_decode_video = NULL;
1455     id->p_decoder->pf_get_cc = NULL;
1456     id->p_decoder->pf_get_cc = 0;
1457     id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1458     id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1459     id->p_decoder->pf_picture_link    = video_link_picture_decoder;
1460     id->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder;
1461     id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1462     if( !id->p_decoder->p_owner )
1463         return VLC_EGENERIC;
1464
1465     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1466         id->p_decoder->p_owner->pp_pics[i] = 0;
1467     id->p_decoder->p_owner->p_sys = p_sys;
1468     /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1469
1470     id->p_decoder->p_module =
1471         module_need( id->p_decoder, "decoder", "$codec", false );
1472
1473     if( !id->p_decoder->p_module )
1474     {
1475         msg_Err( p_stream, "cannot find video decoder" );
1476         free( id->p_decoder->p_owner );
1477         return VLC_EGENERIC;
1478     }
1479
1480     /*
1481      * Open encoder.
1482      * Because some info about the decoded input will only be available
1483      * once the first frame is decoded, we actually only test the availability
1484      * of the encoder here.
1485      */
1486
1487     /* Initialization of encoder format structures */
1488     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1489                     id->p_decoder->fmt_out.i_codec );
1490     id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1491
1492     /* The dimensions will be set properly later on.
1493      * Just put sensible values so we can test an encoder is available. */
1494     id->p_encoder->fmt_in.video.i_width =
1495         id->p_encoder->fmt_out.video.i_width ?:
1496         id->p_decoder->fmt_in.video.i_width ?: 16;
1497     id->p_encoder->fmt_in.video.i_height =
1498         id->p_encoder->fmt_out.video.i_height ?:
1499         id->p_decoder->fmt_in.video.i_height ?: 16;
1500     id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1501     id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1502
1503     id->p_encoder->i_threads = p_sys->i_threads;
1504     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1505
1506     id->p_encoder->p_module =
1507         module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1508     if( !id->p_encoder->p_module )
1509     {
1510         msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1511                  p_sys->psz_venc ? p_sys->psz_venc : "any",
1512                  (char *)&p_sys->i_vcodec );
1513         module_unneed( id->p_decoder, id->p_decoder->p_module );
1514         id->p_decoder->p_module = 0;
1515         free( id->p_decoder->p_owner );
1516         return VLC_EGENERIC;
1517     }
1518
1519     /* Close the encoder.
1520      * We'll open it only when we have the first frame. */
1521     module_unneed( id->p_encoder, id->p_encoder->p_module );
1522     if( id->p_encoder->fmt_out.p_extra )
1523     {
1524         free( id->p_encoder->fmt_out.p_extra );
1525         id->p_encoder->fmt_out.p_extra = NULL;
1526         id->p_encoder->fmt_out.i_extra = 0;
1527     }
1528     id->p_encoder->p_module = NULL;
1529
1530     if( p_sys->i_threads >= 1 )
1531     {
1532         int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1533                            VLC_THREAD_PRIORITY_VIDEO;
1534         p_sys->id_video = id;
1535         vlc_mutex_init( &p_sys->lock_out );
1536         vlc_cond_init( &p_sys->cond );
1537         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1538         p_sys->i_first_pic = 0;
1539         p_sys->i_last_pic = 0;
1540         p_sys->p_buffers = NULL;
1541         p_sys->b_die = p_sys->b_error = 0;
1542         if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority ) )
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     /*  */
1739     id->p_encoder->fmt_out.i_codec =
1740         vlc_fourcc_GetCodec( VIDEO_ES, id->p_encoder->fmt_out.i_codec );
1741
1742     id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1743                                &id->p_encoder->fmt_out );
1744     if( !id->id )
1745     {
1746         msg_Err( p_stream, "cannot add this stream" );
1747         return VLC_EGENERIC;
1748     }
1749
1750     return VLC_SUCCESS;
1751 }
1752
1753 static void transcode_video_close( sout_stream_t *p_stream,
1754                                    sout_stream_id_t *id )
1755 {
1756     int i;
1757
1758     if( p_stream->p_sys->i_threads >= 1 )
1759     {
1760         vlc_mutex_lock( &p_stream->p_sys->lock_out );
1761         vlc_object_kill( p_stream->p_sys );
1762         vlc_cond_signal( &p_stream->p_sys->cond );
1763         vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1764         vlc_thread_join( p_stream->p_sys );
1765         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1766         vlc_cond_destroy( &p_stream->p_sys->cond );
1767     }
1768
1769     video_timer_close( id->p_encoder );
1770
1771     /* Close decoder */
1772     if( id->p_decoder->p_module )
1773         module_unneed( id->p_decoder, id->p_decoder->p_module );
1774     if( id->p_decoder->p_description )
1775         vlc_meta_Delete( id->p_decoder->p_description );
1776
1777     if( id->p_decoder->p_owner )
1778     {
1779         /* Clean-up pictures ring buffer */
1780         for( i = 0; i < PICTURE_RING_SIZE; i++ )
1781         {
1782             if( id->p_decoder->p_owner->pp_pics[i] )
1783                 video_del_buffer( VLC_OBJECT(id->p_decoder),
1784                                   id->p_decoder->p_owner->pp_pics[i] );
1785         }
1786         free( id->p_decoder->p_owner );
1787     }
1788
1789     /* Close encoder */
1790     if( id->p_encoder->p_module )
1791         module_unneed( id->p_encoder, id->p_encoder->p_module );
1792
1793     /* Close filters */
1794     if( id->p_f_chain )
1795         filter_chain_Delete( id->p_f_chain );
1796     if( id->p_uf_chain )
1797         filter_chain_Delete( id->p_uf_chain );
1798 }
1799
1800 static int transcode_video_process( sout_stream_t *p_stream,
1801                                     sout_stream_id_t *id,
1802                                     block_t *in, block_t **out )
1803 {
1804     sout_stream_sys_t *p_sys = p_stream->p_sys;
1805     int i_duplicate = 1;
1806     picture_t *p_pic, *p_pic2 = NULL;
1807     *out = NULL;
1808
1809     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1810     {
1811         subpicture_t *p_subpic = NULL;
1812
1813         sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1814
1815         if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1816         {
1817             mtime_t current_date = mdate();
1818             if( current_date + 50000 > p_pic->date )
1819             {
1820                 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1821                          current_date + 50000 - p_pic->date );
1822                 p_pic->pf_release( p_pic );
1823                 continue;
1824             }
1825         }
1826
1827         if( p_sys->b_master_sync )
1828         {
1829             mtime_t i_video_drift;
1830             mtime_t i_master_drift = p_sys->i_master_drift;
1831             mtime_t i_pts;
1832
1833             i_pts = date_Get( &id->interpolated_pts ) + 1;
1834             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1835                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1836             {
1837                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1838                 date_Set( &id->interpolated_pts, p_pic->date );
1839                 i_pts = p_pic->date + 1;
1840             }
1841             i_video_drift = p_pic->date - i_pts;
1842             i_duplicate = 1;
1843
1844             /* Set the pts of the frame being encoded */
1845             p_pic->date = i_pts;
1846
1847             if( i_video_drift < (i_master_drift - 50000) )
1848             {
1849 #if 0
1850                 msg_Dbg( p_stream, "dropping frame (%i)",
1851                          (int)(i_video_drift - i_master_drift) );
1852 #endif
1853                 p_pic->pf_release( p_pic );
1854                 continue;
1855             }
1856             else if( i_video_drift > (i_master_drift + 50000) )
1857             {
1858 #if 0
1859                 msg_Dbg( p_stream, "adding frame (%i)",
1860                          (int)(i_video_drift - i_master_drift) );
1861 #endif
1862                 i_duplicate = 2;
1863             }
1864         }
1865
1866         if( !id->p_encoder->p_module )
1867         {
1868             transcode_video_encoder_init( p_stream, id );
1869
1870             id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1871                                               false,
1872                                transcode_video_filter_allocation_init,
1873                                transcode_video_filter_allocation_clear,
1874                                p_stream->p_sys );
1875
1876             /* Deinterlace */
1877             if( p_stream->p_sys->b_deinterlace )
1878             {
1879                 filter_chain_AppendFilter( id->p_f_chain,
1880                                            p_sys->psz_deinterlace,
1881                                            p_sys->p_deinterlace_cfg,
1882                                            &id->p_decoder->fmt_out,
1883                                            &id->p_decoder->fmt_out );
1884             }
1885
1886             /* Take care of the scaling and chroma conversions */
1887             if( ( id->p_decoder->fmt_out.video.i_chroma !=
1888                   id->p_encoder->fmt_in.video.i_chroma ) ||
1889                 ( id->p_decoder->fmt_out.video.i_width !=
1890                   id->p_encoder->fmt_in.video.i_width ) ||
1891                 ( id->p_decoder->fmt_out.video.i_height !=
1892                   id->p_encoder->fmt_in.video.i_height ) )
1893             {
1894                 filter_chain_AppendFilter( id->p_f_chain,
1895                                            NULL, NULL,
1896                                            &id->p_decoder->fmt_out,
1897                                            &id->p_encoder->fmt_in );
1898             }
1899
1900             if( p_sys->psz_vf2 )
1901             {
1902                 const es_format_t *p_fmt_out;
1903                 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1904                                                    true,
1905                                    transcode_video_filter_allocation_init,
1906                                    transcode_video_filter_allocation_clear,
1907                                    p_stream->p_sys );
1908                 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1909                                     &id->p_encoder->fmt_in );
1910                 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1911                 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1912                 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1913                 id->p_encoder->fmt_out.video.i_width =
1914                     id->p_encoder->fmt_in.video.i_width;
1915                 id->p_encoder->fmt_out.video.i_height =
1916                     id->p_encoder->fmt_in.video.i_height;
1917                 id->p_encoder->fmt_out.video.i_aspect =
1918                     id->p_encoder->fmt_in.video.i_aspect;
1919             }
1920
1921             if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1922             {
1923                 p_pic->pf_release( p_pic );
1924                 transcode_video_close( p_stream, id );
1925                 id->b_transcode = false;
1926                 return VLC_EGENERIC;
1927             }
1928         }
1929
1930         /* Run filter chain */
1931         if( id->p_f_chain )
1932             p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1933
1934         /*
1935          * Encoding
1936          */
1937
1938         /* Check if we have a subpicture to overlay */
1939         if( p_sys->p_spu )
1940         {
1941             p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1942                        false /* Fixme: check if stream is paused */, false );
1943             /* TODO: get another pic */
1944         }
1945
1946         /* Overlay subpicture */
1947         if( p_subpic )
1948         {
1949             video_format_t fmt;
1950
1951             if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1952             {
1953                 /* We can't modify the picture, we need to duplicate it */
1954                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1955                 if( p_tmp )
1956                 {
1957                     picture_Copy( p_tmp, p_pic );
1958                     p_pic->pf_release( p_pic );
1959                     p_pic = p_tmp;
1960                 }
1961             }
1962
1963             if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1964                 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1965             else
1966                 fmt = id->p_decoder->fmt_out.video;
1967
1968             /* FIXME (shouldn't have to be done here) */
1969             fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1970             fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1971
1972             spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1973                                    p_subpic, &id->p_decoder->fmt_out.video, false );
1974         }
1975
1976         /* Run user specified filter chain */
1977         if( id->p_uf_chain )
1978             p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1979
1980         if( p_sys->i_threads == 0 )
1981         {
1982             block_t *p_block;
1983
1984             video_timer_start( id->p_encoder );
1985             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1986             video_timer_stop( id->p_encoder );
1987
1988             block_ChainAppend( out, p_block );
1989         }
1990
1991         if( p_sys->b_master_sync )
1992         {
1993             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1994             if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1995                   || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1996             {
1997                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1998                 date_Set( &id->interpolated_pts, p_pic->date );
1999                 i_pts = p_pic->date + 1;
2000             }
2001             date_Increment( &id->interpolated_pts, 1 );
2002         }
2003
2004         if( p_sys->b_master_sync && i_duplicate > 1 )
2005         {
2006             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2007             if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2008                  || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2009             {
2010                 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2011                 date_Set( &id->interpolated_pts, p_pic->date );
2012                 i_pts = p_pic->date + 1;
2013             }
2014             date_Increment( &id->interpolated_pts, 1 );
2015
2016             if( p_sys->i_threads >= 1 )
2017             {
2018                 /* We can't modify the picture, we need to duplicate it */
2019                 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2020                 if( p_pic2 != NULL )
2021                 {
2022                     picture_Copy( p_pic2, p_pic );
2023                     p_pic2->date = i_pts;
2024                 }
2025             }
2026             else
2027             {
2028                 block_t *p_block;
2029                 p_pic->date = i_pts;
2030                 video_timer_start( id->p_encoder );
2031                 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2032                 video_timer_stop( id->p_encoder );
2033                 block_ChainAppend( out, p_block );
2034             }
2035         }
2036
2037         if( p_sys->i_threads == 0 )
2038         {
2039             p_pic->pf_release( p_pic );
2040         }
2041         else
2042         {
2043             vlc_mutex_lock( &p_sys->lock_out );
2044             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2045             p_sys->i_last_pic %= PICTURE_RING_SIZE;
2046             *out = p_sys->p_buffers;
2047             p_sys->p_buffers = NULL;
2048             if( p_pic2 != NULL )
2049             {
2050                 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2051                 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2052             }
2053             vlc_cond_signal( &p_sys->cond );
2054             vlc_mutex_unlock( &p_sys->lock_out );
2055         }
2056     }
2057
2058     return VLC_SUCCESS;
2059 }
2060
2061 static void* EncoderThread( vlc_object_t* p_this )
2062 {
2063     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2064     sout_stream_id_t *id = p_sys->id_video;
2065     picture_t *p_pic;
2066     int canc = vlc_savecancel ();
2067
2068     while( vlc_object_alive (p_sys) && !p_sys->b_error )
2069     {
2070         block_t *p_block;
2071
2072         vlc_mutex_lock( &p_sys->lock_out );
2073         while( p_sys->i_last_pic == p_sys->i_first_pic )
2074         {
2075             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2076             if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2077         }
2078         if( !vlc_object_alive (p_sys) || p_sys->b_error )
2079         {
2080             vlc_mutex_unlock( &p_sys->lock_out );
2081             break;
2082         }
2083
2084         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2085         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2086         vlc_mutex_unlock( &p_sys->lock_out );
2087
2088         video_timer_start( id->p_encoder );
2089         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2090         video_timer_stop( id->p_encoder );
2091
2092         vlc_mutex_lock( &p_sys->lock_out );
2093         block_ChainAppend( &p_sys->p_buffers, p_block );
2094
2095         vlc_mutex_unlock( &p_sys->lock_out );
2096         p_pic->pf_release( p_pic );
2097     }
2098
2099     while( p_sys->i_last_pic != p_sys->i_first_pic )
2100     {
2101         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2102         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2103         p_pic->pf_release( p_pic );
2104     }
2105     block_ChainRelease( p_sys->p_buffers );
2106
2107     vlc_restorecancel (canc);
2108     return NULL;
2109 }
2110
2111 struct picture_sys_t
2112 {
2113     vlc_object_t *p_owner;
2114 };
2115
2116 static void video_release_buffer( picture_t *p_pic )
2117 {
2118     if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2119     {
2120         video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2121     }
2122     else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2123 }
2124
2125 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2126                                     sout_stream_sys_t *p_sys )
2127 {
2128     decoder_t *p_dec = (decoder_t *)p_this;
2129     picture_t *p_pic;
2130     int i;
2131
2132     /* Find an empty space in the picture ring buffer */
2133     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2134     {
2135         if( pp_ring[i] != NULL && pp_ring[i]->i_status == DESTROYED_PICTURE )
2136         {
2137             pp_ring[i]->i_status = RESERVED_PICTURE;
2138             return pp_ring[i];
2139         }
2140     }
2141     for( i = 0; i < PICTURE_RING_SIZE; i++ )
2142     {
2143         if( pp_ring[i] == NULL ) break;
2144     }
2145
2146     if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2147     {
2148         int i_first_pic = p_sys->i_first_pic;
2149
2150         if( p_sys->i_first_pic != p_sys->i_last_pic )
2151         {
2152             /* Encoder still has stuff to encode, wait to clear-up the list */
2153             while( p_sys->i_first_pic == i_first_pic )
2154                 msleep( 100000 );
2155         }
2156
2157         /* Find an empty space in the picture ring buffer */
2158         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2159         {
2160             if( pp_ring[i] != NULL && pp_ring[i]->i_status == DESTROYED_PICTURE )
2161             {
2162                 pp_ring[i]->i_status = RESERVED_PICTURE;
2163                 return pp_ring[i];
2164             }
2165         }
2166         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2167         {
2168             if( pp_ring[i] == NULL ) break;
2169         }
2170     }
2171
2172     if( i == PICTURE_RING_SIZE )
2173     {
2174         msg_Err( p_this, "decoder/filter is leaking pictures, "
2175                  "resetting its ring buffer" );
2176
2177         for( i = 0; i < PICTURE_RING_SIZE; i++ )
2178         {
2179             pp_ring[i]->pf_release( pp_ring[i] );
2180         }
2181
2182         i = 0;
2183     }
2184
2185     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2186     p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2187                          p_dec->fmt_out.video.i_width,
2188                          p_dec->fmt_out.video.i_height,
2189                          p_dec->fmt_out.video.i_aspect );
2190     if( !p_pic ) return NULL;
2191     p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2192     if( !p_pic->p_sys )
2193     {
2194         picture_Release( p_pic );
2195         return NULL;
2196     }
2197     p_pic->pf_release = video_release_buffer;
2198     p_pic->i_refcount = 0;
2199
2200     pp_ring[i] = p_pic;
2201     return p_pic;
2202 }
2203
2204 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2205 {
2206     return video_new_buffer( VLC_OBJECT(p_dec),
2207                              p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2208 }
2209
2210 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2211 {
2212     return video_new_buffer( VLC_OBJECT(p_filter),
2213                              p_filter->p_owner->pp_pics,
2214                              p_filter->p_owner->p_sys );
2215 }
2216
2217 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2218 {
2219     VLC_UNUSED(p_this);
2220     if( p_pic )
2221     {
2222         free( p_pic->p_q );
2223         free( p_pic->p_data_orig );
2224         free( p_pic->p_sys );
2225         free( p_pic );
2226     }
2227 }
2228
2229 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2230 {
2231     VLC_UNUSED(p_decoder);
2232     p_pic->i_refcount = 0;
2233     p_pic->i_status = DESTROYED_PICTURE;
2234     picture_CleanupQuant( p_pic );
2235 }
2236
2237 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2238 {
2239     VLC_UNUSED(p_filter);
2240     p_pic->i_refcount = 0;
2241     p_pic->i_status = DESTROYED_PICTURE;
2242     picture_CleanupQuant( p_pic );
2243 }
2244
2245 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2246 {
2247     VLC_UNUSED(p_dec);
2248     p_pic->i_refcount++;
2249 }
2250
2251 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2252 {
2253     VLC_UNUSED(p_dec);
2254     video_release_buffer( p_pic );
2255 }
2256
2257 /*
2258  * SPU
2259  */
2260 static subpicture_t *spu_new_buffer( decoder_t * );
2261 static void spu_del_buffer( decoder_t *, subpicture_t * );
2262
2263 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2264 {
2265     sout_stream_sys_t *p_sys = p_stream->p_sys;
2266
2267     /*
2268      * Open decoder
2269      */
2270
2271     /* Initialization of decoder structures */
2272     id->p_decoder->pf_decode_sub = NULL;
2273     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2274     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2275     id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2276     /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2277
2278     id->p_decoder->p_module =
2279         module_need( id->p_decoder, "decoder", "$codec", false );
2280
2281     if( !id->p_decoder->p_module )
2282     {
2283         msg_Err( p_stream, "cannot find spu decoder" );
2284         return VLC_EGENERIC;
2285     }
2286
2287     if( !p_sys->b_soverlay )
2288     {
2289         /* Open encoder */
2290         /* Initialization of encoder format structures */
2291         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2292                         id->p_decoder->fmt_in.i_codec );
2293
2294         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2295
2296         id->p_encoder->p_module =
2297             module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2298
2299         if( !id->p_encoder->p_module )
2300         {
2301             module_unneed( id->p_decoder, id->p_decoder->p_module );
2302             msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2303             return VLC_EGENERIC;
2304         }
2305     }
2306
2307     if( !p_sys->p_spu )
2308     {
2309         p_sys->p_spu = spu_Create( p_stream );
2310         spu_Init( p_sys->p_spu );
2311     }
2312
2313     return VLC_SUCCESS;
2314 }
2315
2316 static void transcode_spu_close( sout_stream_id_t *id)
2317 {
2318     /* Close decoder */
2319     if( id->p_decoder->p_module )
2320         module_unneed( id->p_decoder, id->p_decoder->p_module );
2321     if( id->p_decoder->p_description )
2322         vlc_meta_Delete( id->p_decoder->p_description );
2323
2324     /* Close encoder */
2325     if( id->p_encoder->p_module )
2326         module_unneed( id->p_encoder, id->p_encoder->p_module );
2327 }
2328
2329 static int transcode_spu_process( sout_stream_t *p_stream,
2330                                   sout_stream_id_t *id,
2331                                   block_t *in, block_t **out )
2332 {
2333     sout_stream_sys_t *p_sys = p_stream->p_sys;
2334     subpicture_t *p_subpic;
2335     *out = NULL;
2336
2337     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2338     if( !p_subpic )
2339         return VLC_EGENERIC;
2340
2341     sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2342
2343     if( p_sys->b_master_sync && p_sys->i_master_drift )
2344     {
2345         p_subpic->i_start -= p_sys->i_master_drift;
2346         if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2347     }
2348
2349     if( p_sys->b_soverlay )
2350     {
2351         spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2352     }
2353     else
2354     {
2355         block_t *p_block;
2356
2357         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2358         spu_del_buffer( id->p_decoder, p_subpic );
2359         if( p_block )
2360         {
2361             block_ChainAppend( out, p_block );
2362             return VLC_SUCCESS;
2363         }
2364     }
2365
2366     return VLC_EGENERIC;
2367 }
2368
2369 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2370 {
2371     VLC_UNUSED( p_dec );
2372     return subpicture_New();
2373 }
2374
2375 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2376 {
2377     VLC_UNUSED( p_dec );
2378     subpicture_Delete( p_subpic );
2379 }
2380
2381 /*
2382  * OSD menu
2383  */
2384 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2385 {
2386     sout_stream_sys_t *p_sys = p_stream->p_sys;
2387
2388     id->p_decoder->fmt_in.i_cat = SPU_ES;
2389     id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2390
2391     if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2392     {
2393         msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2394                  "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2395                  (char*)&p_sys->i_osdcodec );
2396
2397         /* Complete destination format */
2398         id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2399
2400         /* Open encoder */
2401         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2402                         VLC_CODEC_YUVA );
2403         id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2404
2405         id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2406
2407         id->p_encoder->p_module =
2408             module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2409
2410         if( !id->p_encoder->p_module )
2411         {
2412             msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2413             goto error;
2414         }
2415
2416         /* open output stream */
2417         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2418         id->b_transcode = true;
2419
2420         if( !id->id ) goto error;
2421     }
2422     else
2423     {
2424         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2425                  (char*)&id->p_decoder->fmt_out.i_codec );
2426         id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2427         id->b_transcode = false;
2428
2429         if( !id->id ) goto error;
2430     }
2431
2432     if( !p_sys->p_spu )
2433     {
2434         p_sys->p_spu = spu_Create( p_stream );
2435         spu_Init( p_sys->p_spu );
2436     }
2437
2438     return VLC_SUCCESS;
2439
2440  error:
2441     msg_Err( p_stream, "starting osd encoding thread failed" );
2442     if( id->p_encoder->p_module )
2443             module_unneed( id->p_encoder, id->p_encoder->p_module );
2444     p_sys->b_osd = false;
2445     return VLC_EGENERIC;
2446 }
2447
2448 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2449 {
2450     sout_stream_sys_t *p_sys = p_stream->p_sys;
2451
2452     /* Close encoder */
2453     if( id )
2454     {
2455         if( id->p_encoder->p_module )
2456             module_unneed( id->p_encoder, id->p_encoder->p_module );
2457     }
2458     p_sys->b_osd = false;
2459 }
2460
2461 static int transcode_osd_process( sout_stream_t *p_stream,
2462                                   sout_stream_id_t *id,
2463                                   block_t *in, block_t **out )
2464 {
2465     sout_stream_sys_t *p_sys = p_stream->p_sys;
2466     subpicture_t *p_subpic = NULL;
2467
2468     /* Check if we have a subpicture to send */
2469     if( p_sys->p_spu && in->i_dts > 0)
2470     {
2471         p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2472     }
2473     else
2474     {
2475         msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2476         if( !p_sys->p_spu )
2477         {
2478             p_sys->p_spu = spu_Create( p_stream );
2479             spu_Init( p_sys->p_spu );
2480         }
2481     }
2482
2483     if( p_subpic )
2484     {
2485         block_t *p_block = NULL;
2486
2487         if( p_sys->b_master_sync && p_sys->i_master_drift )
2488         {
2489             p_subpic->i_start -= p_sys->i_master_drift;
2490             if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2491         }
2492
2493         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2494         subpicture_Delete( p_subpic );
2495         if( p_block )
2496         {
2497             p_block->i_dts = p_block->i_pts = in->i_dts;
2498             block_ChainAppend( out, p_block );
2499             return VLC_SUCCESS;
2500         }
2501     }
2502     return VLC_EGENERIC;
2503 }