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