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