]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
* modules/stream_out/transcode.c: Bail out when no audio filter is available.
[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_Err( 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_Err( 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 #if 0
1139         /* FIXME : this might work, but only if the encoder is restarted */
1140         id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1141         id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1142
1143         id->p_encoder->fmt_in.audio.i_physical_channels =
1144             id->p_encoder->fmt_in.audio.i_original_channels =
1145                 fmt_last.audio.i_physical_channels;
1146         id->p_encoder->fmt_out.audio.i_physical_channels =
1147             id->p_encoder->fmt_out.audio.i_original_channels =
1148                 fmt_last.audio.i_physical_channels;
1149 #else
1150         transcode_audio_close( p_stream, id );
1151         return VLC_EGENERIC;
1152 #endif
1153     }
1154
1155     if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1156     {
1157         msg_Err( p_stream, "no audio filter found for resampling from"
1158                  " %iHz to %iHz", fmt_last.audio.i_rate,
1159                  id->p_encoder->fmt_in.audio.i_rate );
1160 #if 0
1161         /* FIXME : this might work, but only if the encoder is restarted */
1162         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1163         id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1164 #else
1165         transcode_audio_close( p_stream, id );
1166         return VLC_EGENERIC;
1167 #endif
1168     }
1169
1170     /* FIXME: Hack for mp3 transcoding support */
1171     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1172         id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1173
1174     return VLC_SUCCESS;
1175 }
1176
1177 static void transcode_audio_close( sout_stream_t *p_stream,
1178                                    sout_stream_id_t *id )
1179 {
1180     int i;
1181
1182     /* Close decoder */
1183     if( id->p_decoder->p_module )
1184         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1185     id->p_decoder->p_module = 0;
1186
1187     /* Close encoder */
1188     if( id->p_encoder->p_module )
1189         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1190     id->p_encoder->p_module = 0;
1191
1192     /* Close filters */
1193     for( i = 0; i < id->i_filter; i++ )
1194     {
1195         vlc_object_detach( id->pp_filter[i] );
1196         if( id->pp_filter[i]->p_module )
1197             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
1198         vlc_object_destroy( id->pp_filter[i] );
1199     }
1200 }
1201
1202 static int transcode_audio_process( sout_stream_t *p_stream,
1203                                     sout_stream_id_t *id,
1204                                     block_t *in, block_t **out )
1205 {
1206     sout_stream_sys_t *p_sys = p_stream->p_sys;
1207     aout_buffer_t *p_audio_buf;
1208     block_t *p_block, *p_audio_block;
1209     int i;
1210     *out = NULL;
1211
1212     while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1213                                                           &in )) )
1214     {
1215         if( p_sys->b_master_sync )
1216         {
1217             mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1218             p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1219             date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1220             p_audio_buf->start_date -= p_sys->i_master_drift;
1221             p_audio_buf->end_date -= p_sys->i_master_drift;
1222         }
1223
1224         p_audio_block = p_audio_buf->p_sys;
1225         p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1226         p_audio_block->i_dts = p_audio_block->i_pts =
1227             p_audio_buf->start_date;
1228         p_audio_block->i_length = p_audio_buf->end_date -
1229             p_audio_buf->start_date;
1230         p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1231
1232         /* Run filter chain */
1233         for( i = 0; i < id->i_filter; i++ )
1234         {
1235             p_audio_block =
1236                 id->pp_filter[i]->pf_audio_filter( id->pp_filter[i],
1237                                                    p_audio_block );
1238         }
1239
1240         p_audio_buf->p_buffer = p_audio_block->p_buffer;
1241         p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1242         p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1243         p_audio_buf->start_date = p_audio_block->i_dts;
1244         p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1245
1246         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1247         block_ChainAppend( out, p_block );
1248         block_Release( p_audio_block );
1249         free( p_audio_buf );
1250     }
1251
1252     return VLC_SUCCESS;
1253 }
1254
1255 static void audio_release_buffer( aout_buffer_t *p_buffer )
1256 {
1257     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1258     if( p_buffer ) free( p_buffer );
1259 }
1260
1261 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1262 {
1263     aout_buffer_t *p_buffer;
1264     block_t *p_block;
1265     int i_size;
1266
1267     if( p_dec->fmt_out.audio.i_bitspersample )
1268     {
1269         i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1270             p_dec->fmt_out.audio.i_channels;
1271     }
1272     else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1273              p_dec->fmt_out.audio.i_frame_length )
1274     {
1275         i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1276             p_dec->fmt_out.audio.i_frame_length;
1277     }
1278     else
1279     {
1280         i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1281     }
1282
1283     p_buffer = malloc( sizeof(aout_buffer_t) );
1284     p_buffer->pf_release = audio_release_buffer;
1285     p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1286
1287     p_buffer->p_buffer = p_block->p_buffer;
1288     p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1289     p_buffer->i_nb_samples = i_samples;
1290     p_block->i_samples = i_samples;
1291
1292     return p_buffer;
1293 }
1294
1295 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1296 {
1297     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1298     if( p_buffer ) free( p_buffer );
1299 }
1300
1301 /*
1302  * video
1303  */
1304 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1305 {
1306     sout_stream_sys_t *p_sys = p_stream->p_sys;
1307     int i;
1308
1309     /*
1310      * Open decoder
1311      */
1312
1313     /* Initialization of decoder structures */
1314     id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1315     id->p_decoder->fmt_out.i_extra = 0;
1316     id->p_decoder->fmt_out.p_extra = 0;
1317     id->p_decoder->pf_decode_video = 0;
1318     id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1319     id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1320     id->p_decoder->pf_picture_link    = video_link_picture_decoder;
1321     id->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder;
1322     id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1323     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1324         id->p_decoder->p_owner->pp_pics[i] = 0;
1325     //id->p_decoder->p_cfg = p_sys->p_video_cfg;
1326
1327     id->p_decoder->p_module =
1328         module_Need( id->p_decoder, "decoder", "$codec", 0 );
1329
1330     if( !id->p_decoder->p_module )
1331     {
1332         msg_Err( p_stream, "cannot find decoder" );
1333         return VLC_EGENERIC;
1334     }
1335
1336     /*
1337      * Open encoder.
1338      * Because some info about the decoded input will only be available
1339      * once the first frame is decoded, we actually only test the availability
1340      * of the encoder here.
1341      */
1342
1343     /* Initialization of encoder format structures */
1344     es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1345                     id->p_decoder->fmt_out.i_codec );
1346     id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1347
1348     /* The dimensions will be set properly later on.
1349      * Just put sensible values so we can test an encoder is available. */
1350     id->p_encoder->fmt_in.video.i_width =
1351         id->p_encoder->fmt_out.video.i_width ?
1352         id->p_encoder->fmt_out.video.i_width :
1353         id->p_decoder->fmt_in.video.i_width ?
1354         id->p_decoder->fmt_in.video.i_width : 16;
1355     id->p_encoder->fmt_in.video.i_height =
1356         id->p_encoder->fmt_out.video.i_height ?
1357         id->p_encoder->fmt_out.video.i_height :
1358         id->p_decoder->fmt_in.video.i_height ?
1359         id->p_decoder->fmt_in.video.i_height : 16;
1360     id->p_encoder->fmt_in.video.i_frame_rate = 25;
1361     id->p_encoder->fmt_in.video.i_frame_rate_base = 1;
1362
1363     id->p_encoder->i_threads = p_sys->i_threads;
1364     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1365
1366     id->p_encoder->p_module =
1367         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, VLC_TRUE );
1368     if( !id->p_encoder->p_module )
1369     {
1370         msg_Err( p_stream, "cannot find encoder" );
1371         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1372         id->p_decoder->p_module = 0;
1373         return VLC_EGENERIC;
1374     }
1375
1376     /* Close the encoder.
1377      * We'll open it only when we have the first frame. */
1378     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1379     id->p_encoder->p_module = NULL;
1380
1381     if( p_sys->i_threads >= 1 )
1382     {
1383         int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1384                            VLC_THREAD_PRIORITY_VIDEO;
1385         p_sys->id_video = id;
1386         vlc_mutex_init( p_stream, &p_sys->lock_out );
1387         vlc_cond_init( p_stream, &p_sys->cond );
1388         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1389         p_sys->i_first_pic = 0;
1390         p_sys->i_last_pic = 0;
1391         p_sys->p_buffers = NULL;
1392         p_sys->b_die = p_sys->b_error = 0;
1393         if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1394                                VLC_FALSE ) )
1395         {
1396             msg_Err( p_stream, "cannot spawn encoder thread" );
1397             module_Unneed( id->p_decoder, id->p_decoder->p_module );
1398             id->p_decoder->p_module = 0;
1399             return VLC_EGENERIC;
1400         }
1401     }
1402
1403     date_Set( &id->interpolated_pts, 0 );
1404
1405     return VLC_SUCCESS;
1406 }
1407
1408 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1409                                          sout_stream_id_t *id )
1410 {
1411     sout_stream_sys_t *p_sys = p_stream->p_sys;
1412
1413     /* Hack because of the copy packetizer which can fail to detect the
1414      * proper size (which forces us to wait until the 1st frame
1415      * is decoded) */
1416     int i_width = id->p_decoder->fmt_out.video.i_width -
1417         p_sys->i_crop_left - p_sys->i_crop_right;
1418     int i_height = id->p_decoder->fmt_out.video.i_height -
1419         p_sys->i_crop_top - p_sys->i_crop_bottom;
1420
1421     if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1422         id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1423     {
1424         /* Apply the scaling */
1425         id->p_encoder->fmt_out.video.i_width = i_width * p_sys->f_scale;
1426         id->p_encoder->fmt_out.video.i_height = i_height * p_sys->f_scale;
1427     }
1428     else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1429              id->p_encoder->fmt_out.video.i_height <= 0 )
1430     {
1431         id->p_encoder->fmt_out.video.i_height =
1432             id->p_encoder->fmt_out.video.i_width / (double)i_width * i_height;
1433     }
1434     else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1435              id->p_encoder->fmt_out.video.i_height > 0 )
1436     {
1437         id->p_encoder->fmt_out.video.i_width =
1438             id->p_encoder->fmt_out.video.i_height / (double)i_height * i_width;
1439     }
1440
1441     /* Make sure the size is at least a multiple of 2 */
1442     id->p_encoder->fmt_out.video.i_width =
1443         (id->p_encoder->fmt_out.video.i_width + 1) >> 1 << 1;
1444     id->p_encoder->fmt_out.video.i_height =
1445         (id->p_encoder->fmt_out.video.i_height + 1) >> 1 << 1;
1446
1447     id->p_encoder->fmt_in.video.i_width =
1448         id->p_encoder->fmt_out.video.i_width;
1449     id->p_encoder->fmt_in.video.i_height =
1450         id->p_encoder->fmt_out.video.i_height;
1451
1452     if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1453         !id->p_encoder->fmt_out.video.i_frame_rate_base )
1454     {
1455         if( id->p_decoder->fmt_out.video.i_frame_rate &&
1456             id->p_decoder->fmt_out.video.i_frame_rate_base )
1457         {
1458             id->p_encoder->fmt_out.video.i_frame_rate =
1459                 id->p_decoder->fmt_out.video.i_frame_rate;
1460             id->p_encoder->fmt_out.video.i_frame_rate_base =
1461                 id->p_decoder->fmt_out.video.i_frame_rate_base;
1462         }
1463         else
1464         {
1465             /* Pick a sensible default value */
1466             id->p_encoder->fmt_out.video.i_frame_rate = 25;
1467             id->p_encoder->fmt_out.video.i_frame_rate_base = 1;
1468         }
1469     }
1470
1471     id->p_encoder->fmt_in.video.i_frame_rate =
1472         id->p_encoder->fmt_out.video.i_frame_rate;
1473     id->p_encoder->fmt_in.video.i_frame_rate_base =
1474         id->p_encoder->fmt_out.video.i_frame_rate_base;
1475
1476     date_Init( &id->interpolated_pts,
1477                id->p_encoder->fmt_out.video.i_frame_rate,
1478                id->p_encoder->fmt_out.video.i_frame_rate_base );
1479
1480     /* Check whether a particular aspect ratio was requested */
1481     if( !id->p_encoder->fmt_out.video.i_aspect )
1482     {
1483         id->p_encoder->fmt_out.video.i_aspect =
1484             id->p_decoder->fmt_out.video.i_aspect;
1485     }
1486     id->p_encoder->fmt_in.video.i_aspect =
1487         id->p_encoder->fmt_out.video.i_aspect;
1488
1489     id->p_encoder->p_module =
1490         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, VLC_TRUE );
1491     if( !id->p_encoder->p_module )
1492     {
1493         msg_Err( p_stream, "cannot find encoder" );
1494         return VLC_EGENERIC;
1495     }
1496
1497     id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1498
1499     /* Hack for mp2v/mp1v transcoding support */
1500     if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1501         id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1502     {
1503         id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1504     }
1505
1506     id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1507                                              &id->p_encoder->fmt_out );
1508     if( !id->id )
1509     {
1510         msg_Err( p_stream, "cannot add this stream" );
1511         return VLC_EGENERIC;
1512     }
1513
1514     return VLC_SUCCESS;
1515 }
1516
1517 static void transcode_video_close( sout_stream_t *p_stream,
1518                                    sout_stream_id_t *id )
1519 {
1520     int i, j;
1521
1522     if( p_stream->p_sys->i_threads >= 1 )
1523     {
1524         vlc_mutex_lock( &p_stream->p_sys->lock_out );
1525         p_stream->p_sys->b_die = 1;
1526         vlc_cond_signal( &p_stream->p_sys->cond );
1527         vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1528         vlc_thread_join( p_stream->p_sys );
1529         vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1530         vlc_cond_destroy( &p_stream->p_sys->cond );
1531     }
1532
1533     /* Close decoder */
1534     if( id->p_decoder->p_module )
1535         module_Unneed( id->p_decoder, id->p_decoder->p_module );
1536
1537     if( id->p_decoder->p_owner )
1538     {
1539         /* Clean-up pictures ring buffer */
1540         for( i = 0; i < PICTURE_RING_SIZE; i++ )
1541         {
1542             if( id->p_decoder->p_owner->pp_pics[i] )
1543                 video_del_buffer( VLC_OBJECT(id->p_decoder),
1544                                   id->p_decoder->p_owner->pp_pics[i] );
1545         }
1546         free( id->p_decoder->p_owner );
1547     }
1548
1549     /* Close encoder */
1550     if( id->p_encoder->p_module )
1551         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1552
1553     /* Close filters */
1554     for( i = 0; i < id->i_filter; i++ )
1555     {
1556         vlc_object_detach( id->pp_filter[i] );
1557         if( id->pp_filter[i]->p_module )
1558             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
1559
1560         /* Clean-up pictures ring buffer */
1561         for( j = 0; j < PICTURE_RING_SIZE; j++ )
1562         {
1563             if( id->pp_filter[i]->p_owner->pp_pics[j] )
1564                 video_del_buffer( VLC_OBJECT(id->pp_filter[i]),
1565                                   id->pp_filter[i]->p_owner->pp_pics[j] );
1566         }
1567         free( id->pp_filter[i]->p_owner );
1568
1569         vlc_object_destroy( id->pp_filter[i] );
1570     }
1571     for( i = 0; i < id->i_vfilter; i++ )
1572     {
1573         vlc_object_detach( id->pp_vfilter[i] );
1574         if( id->pp_vfilter[i]->p_module )
1575             module_Unneed( id->pp_vfilter[i], id->pp_vfilter[i]->p_module );
1576
1577         /* Clean-up pictures ring buffer */
1578         for( j = 0; j < PICTURE_RING_SIZE; j++ )
1579         {
1580             if( id->pp_vfilter[i]->p_owner->pp_pics[j] )
1581                 video_del_buffer( VLC_OBJECT(id->pp_vfilter[i]),
1582                                   id->pp_vfilter[i]->p_owner->pp_pics[j] );
1583         }
1584         free( id->pp_vfilter[i]->p_owner );
1585
1586         vlc_object_destroy( id->pp_vfilter[i] );
1587     }
1588 }
1589
1590 static int transcode_video_process( sout_stream_t *p_stream,
1591                                     sout_stream_id_t *id,
1592                                     block_t *in, block_t **out )
1593 {
1594     sout_stream_sys_t *p_sys = p_stream->p_sys;
1595     int i_duplicate = 1, i;
1596     picture_t *p_pic;
1597     *out = NULL;
1598
1599     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1600     {
1601         subpicture_t *p_subpic = 0;
1602
1603         if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1604         {
1605             mtime_t current_date = mdate();
1606             if( current_date + 50000 > p_pic->date )
1607             {
1608                 msg_Dbg( p_stream, "late picture skipped ("I64Fd")",
1609                          current_date + 50000 - p_pic->date );
1610                 p_pic->pf_release( p_pic );
1611                 continue;
1612             }
1613         }
1614
1615         if( p_sys->b_master_sync )
1616         {
1617             mtime_t i_video_drift;
1618             mtime_t i_master_drift = p_sys->i_master_drift;
1619             mtime_t i_pts;
1620
1621             if( !i_master_drift )
1622             {
1623                 /* No audio track ? */
1624                 p_sys->i_master_drift = i_master_drift = p_pic->date;
1625             }
1626
1627             i_pts = date_Get( &id->interpolated_pts ) + 1;
1628             i_video_drift = p_pic->date - i_pts;
1629             i_duplicate = 1;
1630
1631             /* Set the pts of the frame being encoded */
1632             p_pic->date = i_pts;
1633
1634             if( i_video_drift < i_master_drift - 50000 )
1635             {
1636 #if 0
1637                 msg_Dbg( p_stream, "dropping frame (%i)",
1638                          (int)(i_video_drift - i_master_drift) );
1639 #endif
1640                 p_pic->pf_release( p_pic );
1641                 continue;
1642             }
1643             else if( i_video_drift > i_master_drift + 50000 )
1644             {
1645 #if 0
1646                 msg_Dbg( p_stream, "adding frame (%i)",
1647                          (int)(i_video_drift - i_master_drift) );
1648 #endif
1649                 i_duplicate = 2;
1650             }
1651         }
1652
1653         if( !id->p_encoder->p_module )
1654         {
1655             if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1656             {
1657                 p_pic->pf_release( p_pic );
1658                 transcode_video_close( p_stream, id );
1659                 id->b_transcode = VLC_FALSE;
1660                 return VLC_EGENERIC;
1661             }
1662
1663             /* Deinterlace */
1664             if( p_stream->p_sys->b_deinterlace )
1665             {
1666                 id->pp_filter[id->i_filter] =
1667                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1668                 vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
1669
1670                 id->pp_filter[id->i_filter]->pf_vout_buffer_new =
1671                     video_new_buffer_filter;
1672                 id->pp_filter[id->i_filter]->pf_vout_buffer_del =
1673                     video_del_buffer_filter;
1674
1675                 id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
1676                 id->pp_filter[id->i_filter]->fmt_out = id->p_decoder->fmt_out;
1677                 id->pp_filter[id->i_filter]->p_cfg = p_sys->p_deinterlace_cfg;
1678                 id->pp_filter[id->i_filter]->p_module =
1679                     module_Need( id->pp_filter[id->i_filter],
1680                                  "video filter2", p_sys->psz_deinterlace, 0 );
1681                 if( id->pp_filter[id->i_filter]->p_module )
1682                 {
1683                     id->pp_filter[id->i_filter]->p_owner =
1684                         malloc( sizeof(filter_owner_sys_t) );
1685                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1686                         id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
1687
1688                     id->i_filter++;
1689                 }
1690                 else
1691                 {
1692                     msg_Dbg( p_stream, "no video filter found" );
1693                     vlc_object_detach( id->pp_filter[id->i_filter] );
1694                     vlc_object_destroy( id->pp_filter[id->i_filter] );
1695                 }
1696             }
1697
1698             /* Check if we need a filter for chroma conversion or resizing */
1699             if( id->p_decoder->fmt_out.video.i_chroma !=
1700                 id->p_encoder->fmt_in.video.i_chroma ||
1701                 id->p_decoder->fmt_out.video.i_width !=
1702                 id->p_encoder->fmt_out.video.i_width ||
1703                 id->p_decoder->fmt_out.video.i_height !=
1704                 id->p_encoder->fmt_out.video.i_height ||
1705                 p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1706                 p_sys->i_crop_left > 0 || p_sys->i_crop_right > 0 )
1707             {
1708                 id->pp_filter[id->i_filter] =
1709                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1710                 vlc_object_attach( id->pp_filter[id->i_filter], p_stream );
1711
1712                 id->pp_filter[id->i_filter]->pf_vout_buffer_new =
1713                     video_new_buffer_filter;
1714                 id->pp_filter[id->i_filter]->pf_vout_buffer_del =
1715                     video_del_buffer_filter;
1716
1717                 id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;
1718                 id->pp_filter[id->i_filter]->fmt_out = id->p_encoder->fmt_in;
1719                 id->pp_filter[id->i_filter]->p_cfg = NULL;
1720                 id->pp_filter[id->i_filter]->p_module =
1721                     module_Need( id->pp_filter[id->i_filter],
1722                                  "video filter2", 0, 0 );
1723                 if( id->pp_filter[id->i_filter]->p_module )
1724                 {
1725                     id->pp_filter[id->i_filter]->p_owner =
1726                         malloc( sizeof(filter_owner_sys_t) );
1727                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1728                         id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;
1729
1730                     id->i_filter++;
1731                 }
1732                 else
1733                 {
1734                     msg_Dbg( p_stream, "no video filter found" );
1735                     vlc_object_detach( id->pp_filter[id->i_filter] );
1736                     vlc_object_destroy( id->pp_filter[id->i_filter] );
1737
1738                     p_pic->pf_release( p_pic );
1739                     transcode_video_close( p_stream, id );
1740                     id->b_transcode = VLC_FALSE;
1741                     return VLC_EGENERIC;
1742                 }
1743             }
1744
1745             for( i = 0; i < p_sys->i_vfilters; i++ )
1746             {
1747                 id->pp_vfilter[id->i_vfilter] =
1748                     vlc_object_create( p_stream, VLC_OBJECT_FILTER );
1749                 vlc_object_attach( id->pp_vfilter[id->i_vfilter], p_stream );
1750
1751                 id->pp_vfilter[id->i_vfilter]->pf_vout_buffer_new =
1752                     video_new_buffer_filter;
1753                 id->pp_vfilter[id->i_vfilter]->pf_vout_buffer_del =
1754                     video_del_buffer_filter;
1755
1756                 id->pp_vfilter[id->i_vfilter]->fmt_in = id->p_encoder->fmt_in;
1757                 id->pp_vfilter[id->i_vfilter]->fmt_out = id->p_encoder->fmt_in;
1758                 id->pp_vfilter[id->i_vfilter]->p_cfg = p_sys->p_vfilters_cfg[i];
1759                 id->pp_vfilter[id->i_vfilter]->p_module =
1760                     module_Need( id->pp_vfilter[id->i_vfilter],
1761                           "video filter2", p_sys->psz_vfilters[i], 0 );
1762                 if( id->pp_vfilter[id->i_vfilter]->p_module )
1763                 {
1764                     id->pp_vfilter[id->i_vfilter]->p_owner =
1765                         malloc( sizeof(filter_owner_sys_t) );
1766                     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1767                         id->pp_vfilter[id->i_vfilter]->p_owner->pp_pics[i] = 0;
1768
1769                     id->i_vfilter++;
1770                 }
1771                 else
1772                 {
1773                     msg_Dbg( p_stream, "no video filter found" );
1774                     vlc_object_detach( id->pp_vfilter[id->i_vfilter] );
1775                     vlc_object_destroy( id->pp_vfilter[id->i_vfilter] );
1776                 }
1777             }
1778         }
1779
1780         /* Run filter chain */
1781         for( i = 0; i < id->i_filter; i++ )
1782         {
1783             p_pic = id->pp_filter[i]->pf_video_filter(id->pp_filter[i], p_pic);
1784         }
1785
1786         /*
1787          * Encoding
1788          */
1789
1790         /* Check if we have a subpicture to overlay */
1791         if( p_sys->p_spu )
1792         {
1793             p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date );
1794             /* TODO: get another pic */
1795         }
1796
1797         /* Overlay subpicture */
1798         if( p_subpic )
1799         {
1800             int i_scale_width, i_scale_height;
1801             video_format_t *p_fmt;
1802
1803             i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1804                 id->p_decoder->fmt_out.video.i_width;
1805             i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1806                 id->p_decoder->fmt_out.video.i_height;
1807
1808             if( p_pic->i_refcount && !id->i_filter )
1809             {
1810                 /* We can't modify the picture, we need to duplicate it */
1811                 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1812                 if( p_tmp )
1813                 {
1814                     vout_CopyPicture( p_stream, p_tmp, p_pic );
1815                     p_pic->pf_release( p_pic );
1816                     p_pic = p_tmp;
1817                 }
1818             }
1819
1820             if( id->i_filter )
1821                 p_fmt = &id->pp_filter[id->i_filter -1]->fmt_out.video;
1822             else
1823                 p_fmt = &id->p_decoder->fmt_out.video;
1824
1825             /* FIXME (shouldn't have to be done here) */
1826             p_fmt->i_sar_num = p_fmt->i_aspect *
1827                 p_fmt->i_height / p_fmt->i_width;
1828             p_fmt->i_sar_den = VOUT_ASPECT_FACTOR;
1829
1830             spu_RenderSubpictures( p_sys->p_spu, p_fmt, p_pic, p_pic, p_subpic,
1831                                    i_scale_width, i_scale_height );
1832         }
1833
1834         /* Run vfilter chain */
1835         for( i = 0; i < id->i_vfilter; i++ )
1836         {
1837             p_pic = id->pp_vfilter[i]->pf_video_filter(id->pp_vfilter[i], p_pic);
1838         }
1839
1840         if( p_sys->i_threads >= 1 )
1841         {
1842             vlc_mutex_lock( &p_sys->lock_out );
1843             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
1844             p_sys->i_last_pic %= PICTURE_RING_SIZE;
1845             *out = p_sys->p_buffers;
1846             p_sys->p_buffers = NULL;
1847             vlc_cond_signal( &p_sys->cond );
1848             vlc_mutex_unlock( &p_sys->lock_out );
1849         }
1850         else
1851         {
1852             block_t *p_block;
1853             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1854             block_ChainAppend( out, p_block );
1855
1856             if( p_sys->b_master_sync )
1857                 date_Increment( &id->interpolated_pts, 1 );
1858
1859             if( p_sys->b_master_sync && i_duplicate > 1 )
1860             {
1861                 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1862                 date_Increment( &id->interpolated_pts, 1 );
1863                 p_pic->date = i_pts;
1864                 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
1865                 block_ChainAppend( out, p_block );
1866             }
1867
1868             p_pic->pf_release( p_pic );
1869         }
1870     }
1871
1872     return VLC_SUCCESS;
1873 }
1874
1875 static int EncoderThread( sout_stream_sys_t *p_sys )
1876 {
1877     sout_stream_id_t *id = p_sys->id_video;
1878     picture_t *p_pic;
1879
1880     while( !p_sys->b_die && !p_sys->b_error )
1881     {
1882         block_t *p_block;
1883
1884         vlc_mutex_lock( &p_sys->lock_out );
1885         while( p_sys->i_last_pic == p_sys->i_first_pic )
1886         {
1887             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
1888             if( p_sys->b_die || p_sys->b_error ) break;
1889         }
1890         if( p_sys->b_die || p_sys->b_error )
1891         {
1892             vlc_mutex_unlock( &p_sys->lock_out );
1893             break;
1894         }
1895
1896         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
1897         p_sys->i_first_pic %= PICTURE_RING_SIZE;
1898         vlc_mutex_unlock( &p_sys->lock_out );
1899
1900         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1901         vlc_mutex_lock( &p_sys->lock_out );
1902         block_ChainAppend( &p_sys->p_buffers, p_block );
1903
1904         if( p_sys->b_master_sync )
1905             date_Increment( &id->interpolated_pts, 1 );
1906
1907 #if 0
1908         if( p_sys->b_master_sync && i_duplicate > 1 )
1909         {
1910             mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1911             date_Increment( &id->interpolated_pts, 1 );
1912             p_pic->date = i_pts;
1913             p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
1914             block_ChainAppend( &p_sys->p_buffers, p_block );
1915         }
1916 #endif
1917         vlc_mutex_unlock( &p_sys->lock_out );
1918
1919         p_pic->pf_release( p_pic );
1920     }
1921
1922     while( p_sys->i_last_pic != p_sys->i_first_pic )
1923     {
1924         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
1925         p_sys->i_first_pic %= PICTURE_RING_SIZE;
1926
1927         p_pic->pf_release( p_pic );
1928     }
1929
1930     block_ChainRelease( p_sys->p_buffers );
1931
1932     return 0;
1933 }
1934
1935 struct picture_sys_t
1936 {
1937     vlc_object_t *p_owner;
1938 };
1939
1940 static void video_release_buffer( picture_t *p_pic )
1941 {
1942     if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
1943     {
1944         video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
1945     }
1946     else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
1947 }
1948
1949 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring )
1950 {
1951     decoder_t *p_dec = (decoder_t *)p_this;
1952     picture_t *p_pic;
1953     int i;
1954
1955     /* Find an empty space in the picture ring buffer */
1956     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1957     {
1958         if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
1959         {
1960             pp_ring[i]->i_status = RESERVED_PICTURE;
1961             return pp_ring[i];
1962         }
1963     }
1964     for( i = 0; i < PICTURE_RING_SIZE; i++ )
1965     {
1966         if( pp_ring[i] == 0 ) break;
1967     }
1968
1969     if( i == PICTURE_RING_SIZE )
1970     {
1971         msg_Err( p_this, "decoder/filter is leaking pictures, "
1972                  "resetting its ring buffer" );
1973
1974         for( i = 0; i < PICTURE_RING_SIZE; i++ )
1975         {
1976             pp_ring[i]->pf_release( pp_ring[i] );
1977         }
1978
1979         i = 0;
1980     }
1981
1982     p_pic = malloc( sizeof(picture_t) );
1983     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
1984     vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
1985                           p_dec->fmt_out.video.i_chroma,
1986                           p_dec->fmt_out.video.i_width,
1987                           p_dec->fmt_out.video.i_height,
1988                           p_dec->fmt_out.video.i_aspect );
1989
1990     if( !p_pic->i_planes )
1991     {
1992         free( p_pic );
1993         return 0;
1994     }
1995
1996     p_pic->pf_release = video_release_buffer;
1997     p_pic->p_sys = malloc( sizeof(picture_sys_t) );
1998     p_pic->p_sys->p_owner = p_this;
1999     p_pic->i_status = RESERVED_PICTURE;
2000
2001     pp_ring[i] = p_pic;
2002
2003     return p_pic;
2004 }
2005
2006 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2007 {
2008     return video_new_buffer( VLC_OBJECT(p_dec),
2009                              p_dec->p_owner->pp_pics );
2010 }
2011
2012 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2013 {
2014     return video_new_buffer( VLC_OBJECT(p_filter),
2015                              p_filter->p_owner->pp_pics );
2016 }
2017
2018 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2019 {
2020     if( p_pic && p_pic->p_data_orig ) free( p_pic->p_data_orig );
2021     if( p_pic && p_pic->p_sys ) free( p_pic->p_sys );
2022     if( p_pic ) free( p_pic );
2023 }
2024
2025 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2026 {
2027     p_pic->i_refcount = 0;
2028     p_pic->i_status = DESTROYED_PICTURE;
2029 }
2030
2031 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2032 {
2033     p_pic->i_refcount = 0;
2034     p_pic->i_status = DESTROYED_PICTURE;
2035 }
2036
2037 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2038 {
2039     p_pic->i_refcount++;
2040 }
2041
2042 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2043 {
2044     video_release_buffer( p_pic );
2045 }
2046
2047 /*
2048  * SPU
2049  */
2050 static subpicture_t *spu_new_buffer( decoder_t * );
2051 static void spu_del_buffer( decoder_t *, subpicture_t * );
2052
2053 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2054 {
2055     sout_stream_sys_t *p_sys = p_stream->p_sys;
2056
2057     /*
2058      * Open decoder
2059      */
2060
2061     /* Initialization of decoder structures */
2062     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2063     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2064     id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2065     //id->p_decoder->p_cfg = p_sys->p_spu_cfg;
2066
2067     id->p_decoder->p_module =
2068         module_Need( id->p_decoder, "decoder", "$codec", 0 );
2069
2070     if( !id->p_decoder->p_module )
2071     {
2072         msg_Err( p_stream, "cannot find decoder" );
2073         return VLC_EGENERIC;
2074     }
2075
2076     if( !p_sys->b_soverlay )
2077     {
2078         /*
2079          * Open encoder
2080          */
2081
2082         /* Initialization of encoder format structures */
2083         es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2084                         id->p_decoder->fmt_in.i_codec );
2085
2086         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2087
2088         id->p_encoder->p_module =
2089             module_Need( id->p_encoder, "encoder", p_sys->psz_senc, VLC_TRUE );
2090
2091         if( !id->p_encoder->p_module )
2092         {
2093             module_Unneed( id->p_decoder, id->p_decoder->p_module );
2094             msg_Err( p_stream, "cannot find encoder" );
2095             return VLC_EGENERIC;
2096         }
2097     }
2098
2099     if( !p_sys->p_spu )
2100     {
2101         p_sys->p_spu = spu_Create( p_stream );
2102         spu_Init( p_sys->p_spu );
2103     }
2104
2105     return VLC_SUCCESS;
2106 }
2107
2108 static void transcode_spu_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2109 {
2110     /* Close decoder */
2111     if( id->p_decoder->p_module )
2112         module_Unneed( id->p_decoder, id->p_decoder->p_module );
2113
2114     /* Close encoder */
2115     if( id->p_encoder->p_module )
2116         module_Unneed( id->p_encoder, id->p_encoder->p_module );
2117 }
2118
2119 static int transcode_spu_process( sout_stream_t *p_stream,
2120                                   sout_stream_id_t *id,
2121                                   block_t *in, block_t **out )
2122 {
2123     sout_stream_sys_t *p_sys = p_stream->p_sys;
2124     subpicture_t *p_subpic;
2125     *out = NULL;
2126
2127     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2128     if( !p_subpic ) return VLC_EGENERIC;
2129
2130     if( p_sys->b_master_sync && p_sys->i_master_drift )
2131     {
2132         p_subpic->i_start -= p_sys->i_master_drift;
2133         if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2134     }
2135
2136     if( p_sys->b_soverlay )
2137     {
2138         spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2139     }
2140     else
2141     {
2142         block_t *p_block;
2143
2144         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2145         spu_del_buffer( id->p_decoder, p_subpic );
2146
2147         if( p_block )
2148         {
2149             block_ChainAppend( out, p_block );
2150             return VLC_SUCCESS;
2151         }
2152     }
2153
2154     return VLC_EGENERIC;
2155 }
2156
2157 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2158 {
2159     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2160     return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2161 }
2162
2163 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2164 {
2165     sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2166     spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2167 }