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