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