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