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