]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
* modules/mux/mpeg/ts.c: reworked muxing of subtitles ES.
[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 /* ffmpeg header */
40 #ifdef HAVE_FFMPEG_AVCODEC_H
41 #   include <ffmpeg/avcodec.h>
42 #else
43 #   include <avcodec.h>
44 #endif
45
46 #if LIBAVCODEC_BUILD < 4704
47 #   define AV_NOPTS_VALUE 0
48 #endif
49
50 /*****************************************************************************
51  * Module descriptor
52  *****************************************************************************/
53 #define VENC_TEXT N_("Video encoder")
54 #define VENC_LONGTEXT N_( \
55     "Allows you to specify the video encoder to use and its associated " \
56     "options." )
57 #define VCODEC_TEXT N_("Destination video codec")
58 #define VCODEC_LONGTEXT N_( \
59     "Allows you to specify the destination video codec used for the " \
60     "streaming output." )
61 #define VB_TEXT N_("Video bitrate")
62 #define VB_LONGTEXT N_( \
63     "Allows you to specify the video bitrate used for the streaming " \
64     "output." )
65 #define SCALE_TEXT N_("Video scaling")
66 #define SCALE_LONGTEXT N_( \
67     "Allows you to scale the video before encoding." )
68 #define DEINTERLACE_TEXT N_("Deinterlace video")
69 #define DEINTERLACE_LONGTEXT N_( \
70     "Allows you to deinterlace the video before encoding." )
71 #define WIDTH_TEXT N_("Video width")
72 #define WIDTH_LONGTEXT N_( \
73     "Allows you to specify the output video width." )
74 #define HEIGHT_TEXT N_("Video height")
75 #define HEIGHT_LONGTEXT N_( \
76     "Allows you to specify the output video height." )
77
78 #define CROPTOP_TEXT N_("Video crop top")
79 #define CROPTOP_LONGTEXT N_( \
80     "Allows you to specify the top coordinate for the video cropping." )
81 #define CROPLEFT_TEXT N_("Video crop left")
82 #define CROPLEFT_LONGTEXT N_( \
83     "Allows you to specify the left coordinate for the video cropping." )
84 #define CROPBOTTOM_TEXT N_("Video crop bottom")
85 #define CROPBOTTOM_LONGTEXT N_( \
86     "Allows you to specify the bottom coordinate for the video cropping." )
87 #define CROPRIGHT_TEXT N_("Video crop right")
88 #define CROPRIGHT_LONGTEXT N_( \
89     "Allows you to specify the right coordinate for the video cropping." )
90
91 #define AENC_TEXT N_("Audio encoder")
92 #define AENC_LONGTEXT N_( \
93     "Allows you to specify the audio encoder to use and its associated " \
94     "options." )
95 #define ACODEC_TEXT N_("Destination audio codec")
96 #define ACODEC_LONGTEXT N_( \
97     "Allows you to specify the destination audio codec used for the " \
98     "streaming output." )
99 #define AB_TEXT N_("Audio bitrate")
100 #define AB_LONGTEXT N_( \
101     "Allows you to specify the audio bitrate used for the streaming " \
102     "output." )
103 #define ARATE_TEXT N_("Audio sample rate")
104 #define ARATE_LONGTEXT N_( \
105     "Allows you to specify the audio sample rate used for the streaming " \
106     "output." )
107 #define ACHANS_TEXT N_("Audio channels")
108 #define ACHANS_LONGTEXT N_( \
109     "Allows you to specify the number of audio channels used for the " \
110     "streaming output." )
111
112 #define SENC_TEXT N_("Subtitles encoder")
113 #define SENC_LONGTEXT N_( \
114     "Allows you to specify the subtitles encoder to use and its associated " \
115     "options." )
116 #define SCODEC_TEXT N_("Destination subtitles codec")
117 #define SCODEC_LONGTEXT N_( \
118     "Allows you to specify the destination subtitles codec used for the " \
119     "streaming output." )
120
121 #define THREADS_TEXT N_("Number of threads")
122 #define THREADS_LONGTEXT N_( \
123     "Allows you to specify the number of threads used for the transcoding." )
124
125 static int  Open ( vlc_object_t * );
126 static void Close( vlc_object_t * );
127
128 #define SOUT_CFG_PREFIX "sout-transcode-"
129
130 vlc_module_begin();
131     set_description( _("Transcode stream output") );
132     set_capability( "sout stream", 50 );
133     add_shortcut( "transcode" );
134     set_callbacks( Open, Close );
135
136     add_string( SOUT_CFG_PREFIX "venc", NULL, NULL, VENC_TEXT,
137                 VENC_LONGTEXT, VLC_FALSE );
138     add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
139                 VCODEC_LONGTEXT, VLC_FALSE );
140     add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT,
141                  VB_LONGTEXT, VLC_FALSE );
142     add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
143                SCALE_LONGTEXT, VLC_FALSE );
144     add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
145               DEINTERLACE_LONGTEXT, VLC_FALSE );
146     add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
147                  WIDTH_LONGTEXT, VLC_TRUE );
148     add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
149                  HEIGHT_LONGTEXT, VLC_TRUE );
150
151     add_integer( SOUT_CFG_PREFIX "croptop", 0, NULL, CROPTOP_TEXT,
152                  CROPTOP_LONGTEXT, VLC_TRUE );
153     add_integer( SOUT_CFG_PREFIX "cropleft", 0, NULL, CROPLEFT_TEXT,
154                  CROPLEFT_LONGTEXT, VLC_TRUE );
155     add_integer( SOUT_CFG_PREFIX "cropbottom", 0, NULL, CROPBOTTOM_TEXT,
156                  CROPBOTTOM_LONGTEXT, VLC_TRUE );
157     add_integer( SOUT_CFG_PREFIX "cropright", 0, NULL, CROPRIGHT_TEXT,
158                  CROPRIGHT_LONGTEXT, VLC_TRUE );
159
160     add_string( SOUT_CFG_PREFIX "aenc", NULL, NULL, AENC_TEXT,
161                 AENC_LONGTEXT, VLC_FALSE );
162     add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
163                 ACODEC_LONGTEXT, VLC_FALSE );
164     add_integer( SOUT_CFG_PREFIX "ab", 64000, NULL, AB_TEXT,
165                  AB_LONGTEXT, VLC_FALSE );
166     add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
167                  ACHANS_LONGTEXT, VLC_FALSE );
168     add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
169                  ARATE_LONGTEXT, VLC_TRUE );
170
171     add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT,
172                 SENC_LONGTEXT, VLC_FALSE );
173     add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
174                 SCODEC_LONGTEXT, VLC_FALSE );
175     add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
176                SCODEC_LONGTEXT, VLC_FALSE );
177
178     add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
179                  THREADS_LONGTEXT, VLC_TRUE );
180 vlc_module_end();
181
182 static const char *ppsz_sout_options[] = {
183     "venc", "vcodec", "vb", "croptop", "cropbottom", "cropleft", "cropright",
184     "scale", "width", "height", "deinterlace", "threads",
185     "aenc", "acodec", "ab", "samplerate", "channels",
186     "senc", "scodec", "soverlay", NULL
187 };
188
189 /*****************************************************************************
190  * Exported prototypes
191  *****************************************************************************/
192 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
193 static int               Del ( sout_stream_t *, sout_stream_id_t * );
194 static int               Send( sout_stream_t *, sout_stream_id_t *, block_t* );
195
196 static int  transcode_audio_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
197 static void transcode_audio_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
198 static int  transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, block_t *, block_t ** );
199
200 static int  transcode_video_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
201 static void transcode_video_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
202 static int  transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, block_t *, block_t ** );
203
204 static int  transcode_video_ffmpeg_getframebuf( struct AVCodecContext *, AVFrame *);
205
206 static int  transcode_spu_new    ( sout_stream_t *, sout_stream_id_t * );
207 static void transcode_spu_close  ( sout_stream_t *, sout_stream_id_t * );
208 static int  transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
209                                    block_t *, block_t ** );
210 static subpicture_t *transcode_spu_get( sout_stream_t *, sout_stream_id_t *,
211                                         mtime_t );
212
213 static int  EncoderThread( struct sout_stream_sys_t * p_sys );
214
215 static int pi_channels_maps[6] =
216 {
217     0,
218     AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
219     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
220     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
221      | AOUT_CHAN_REARRIGHT,
222     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
223      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
224 };
225
226 #define PICTURE_RING_SIZE 64
227 #define SUBPICTURE_RING_SIZE 20
228
229 struct sout_stream_sys_t
230 {
231     VLC_COMMON_MEMBERS
232
233     sout_stream_t * p_out;
234     sout_stream_id_t * id_video;
235     block_t * p_buffers;
236     vlc_mutex_t     lock_out;
237     vlc_cond_t      cond;
238     picture_t *     pp_pics[PICTURE_RING_SIZE];
239     int             i_first_pic, i_last_pic;
240
241     /* Audio */
242     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
243     char            *psz_aenc;
244     sout_cfg_t      *p_audio_cfg;
245     int             i_sample_rate;
246     int             i_channels;
247     int             i_abitrate;
248
249     /* Video */
250     vlc_fourcc_t    i_vcodec;   /* codec video (0 if not transcode) */
251     char            *psz_venc;
252     sout_cfg_t      *p_video_cfg;
253     int             i_vbitrate;
254     double          f_scale;
255     int             i_width;
256     int             i_height;
257     vlc_bool_t      b_deinterlace;
258     int             i_threads;
259
260     int             i_crop_top;
261     int             i_crop_bottom;
262     int             i_crop_right;
263     int             i_crop_left;
264
265     mtime_t         i_input_dts;
266     mtime_t         i_input_pts;
267     vlc_bool_t      b_input_has_b_frames;
268
269     mtime_t         i_output_pts;
270
271     /* SPU */
272     vlc_fourcc_t    i_scodec;   /* codec spu (0 if not transcode) */
273     char            *psz_senc;
274     vlc_bool_t      b_soverlay;
275     sout_cfg_t      *p_spu_cfg;
276     subpicture_t    *pp_subpics[SUBPICTURE_RING_SIZE];
277
278     /* Filters */
279     filter_t        *p_filter_blend;
280 };
281
282 /*****************************************************************************
283  * Open:
284  *****************************************************************************/
285 static int Open( vlc_object_t *p_this )
286 {
287     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
288     sout_stream_sys_t *p_sys;
289     vlc_value_t       val;
290     int               i;
291
292     p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
293
294     p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
295     if( !p_sys->p_out )
296     {
297         msg_Err( p_stream, "cannot create chain" );
298         free( p_sys );
299         return VLC_EGENERIC;
300     }
301
302     p_sys->b_input_has_b_frames = VLC_FALSE;
303     p_sys->i_output_pts = 0;
304
305     sout_CfgParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
306                    p_stream->p_cfg );
307
308     /* Audio transcoding parameters */
309     var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
310     p_sys->psz_aenc = NULL;
311     p_sys->p_audio_cfg = NULL;
312     if( val.psz_string && *val.psz_string )
313     {
314         char *psz_next;
315         psz_next = sout_CfgCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
316                                    val.psz_string );
317         if( psz_next ) free( psz_next );
318     }
319     if( val.psz_string ) free( val.psz_string );
320
321     var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
322     p_sys->i_acodec = 0;
323     if( val.psz_string && *val.psz_string )
324     {
325         char fcc[4] = "    ";
326         memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
327         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
328     }
329     if( val.psz_string ) free( val.psz_string );
330
331     var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
332     p_sys->i_abitrate = val.i_int;
333     if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
334
335     var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
336     p_sys->i_sample_rate = val.i_int;
337
338     var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
339     p_sys->i_channels = val.i_int;
340
341     if( p_sys->i_acodec )
342     {
343         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
344                  (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
345                  p_sys->i_channels, p_sys->i_abitrate / 1000 );
346     }
347
348     /* Video transcoding parameters */
349     var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
350     p_sys->psz_venc = NULL;
351     p_sys->p_video_cfg = NULL;
352     if( val.psz_string && *val.psz_string )
353     {
354         char *psz_next;
355         psz_next = sout_CfgCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
356                                    val.psz_string );
357         if( psz_next ) free( psz_next );
358     }
359     if( val.psz_string ) free( val.psz_string );
360
361     var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
362     p_sys->i_vcodec = 0;
363     if( val.psz_string && *val.psz_string )
364     {
365         char fcc[4] = "    ";
366         memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
367         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
368     }
369     if( val.psz_string ) free( val.psz_string );
370
371     var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
372     p_sys->i_vbitrate = val.i_int;
373     if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
374
375     var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
376     p_sys->f_scale = val.f_float;
377
378     var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
379     p_sys->i_width = val.i_int;
380
381     var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
382     p_sys->i_height = val.i_int;
383
384     var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
385     p_sys->b_deinterlace = val.b_bool;
386
387     var_Get( p_stream, SOUT_CFG_PREFIX "croptop", &val );
388     p_sys->i_crop_top = val.i_int;
389     var_Get( p_stream, SOUT_CFG_PREFIX "cropbottom", &val );
390     p_sys->i_crop_bottom = val.i_int;
391     var_Get( p_stream, SOUT_CFG_PREFIX "cropleft", &val );
392     p_sys->i_crop_left = val.i_int;
393     var_Get( p_stream, SOUT_CFG_PREFIX "cropright", &val );
394     p_sys->i_crop_right = val.i_int;
395
396     var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
397     p_sys->i_threads = val.i_int;
398
399     if( p_sys->i_vcodec )
400     {
401         msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
402                  (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
403                  p_sys->f_scale, p_sys->i_vbitrate / 1000 );
404     }
405
406     /* Subpictures transcoding parameters */
407     var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
408     p_sys->psz_senc = NULL;
409     p_sys->p_spu_cfg = NULL;
410     if( val.psz_string && *val.psz_string )
411     {
412         char *psz_next;
413         psz_next = sout_CfgCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
414                                    val.psz_string );
415         if( psz_next ) free( psz_next );
416     }
417     if( val.psz_string ) free( val.psz_string );
418
419     var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
420     p_sys->i_scodec = 0;
421     if( val.psz_string && *val.psz_string )
422     {
423         char fcc[4] = "    ";
424         memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
425         p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
426     }
427     if( val.psz_string ) free( val.psz_string );
428
429     if( p_sys->i_scodec )
430     {
431         msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_acodec );
432     }
433
434     var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
435     p_sys->b_soverlay = val.b_bool;
436     p_sys->p_filter_blend = 0;
437
438     for( i = 0; i < SUBPICTURE_RING_SIZE; i++ )
439     {
440         p_sys->pp_subpics[i] = 0;
441     }
442
443     p_stream->pf_add    = Add;
444     p_stream->pf_del    = Del;
445     p_stream->pf_send   = Send;
446     p_stream->p_sys     = p_sys;
447
448     avcodec_init();
449     avcodec_register_all();
450
451     return VLC_SUCCESS;
452 }
453
454 /*****************************************************************************
455  * Close:
456  *****************************************************************************/
457 static void Close( vlc_object_t * p_this )
458 {
459     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
460     sout_stream_sys_t   *p_sys = p_stream->p_sys;
461
462     sout_StreamDelete( p_sys->p_out );
463
464     while( p_sys->p_audio_cfg != NULL )
465     {
466         sout_cfg_t *p_next = p_sys->p_audio_cfg->p_next;
467
468         if( p_sys->p_audio_cfg->psz_name )
469             free( p_sys->p_audio_cfg->psz_name );
470         if( p_sys->p_audio_cfg->psz_value )
471             free( p_sys->p_audio_cfg->psz_value );
472         free( p_sys->p_audio_cfg );
473
474         p_sys->p_audio_cfg = p_next;
475     }
476     if( p_sys->psz_aenc ) free( p_sys->psz_aenc );
477
478     while( p_sys->p_video_cfg != NULL )
479     {
480         sout_cfg_t *p_next = p_sys->p_video_cfg->p_next;
481
482         if( p_sys->p_video_cfg->psz_name )
483             free( p_sys->p_video_cfg->psz_name );
484         if( p_sys->p_video_cfg->psz_value )
485             free( p_sys->p_video_cfg->psz_value );
486         free( p_sys->p_video_cfg );
487
488         p_sys->p_video_cfg = p_next;
489     }
490     if( p_sys->psz_venc ) free( p_sys->psz_venc );
491
492     while( p_sys->p_spu_cfg != NULL )
493     {
494         sout_cfg_t *p_next = p_sys->p_spu_cfg->p_next;
495
496         if( p_sys->p_spu_cfg->psz_name )
497             free( p_sys->p_spu_cfg->psz_name );
498         if( p_sys->p_spu_cfg->psz_value )
499             free( p_sys->p_spu_cfg->psz_value );
500         free( p_sys->p_spu_cfg );
501
502         p_sys->p_spu_cfg = p_next;
503     }
504     if( p_sys->psz_senc ) free( p_sys->psz_senc );
505
506     if( p_sys->p_filter_blend )
507     {
508         if( p_sys->p_filter_blend->p_module )
509             module_Unneed( p_sys->p_filter_blend,
510                            p_sys->p_filter_blend->p_module );
511
512         vlc_object_detach( p_sys->p_filter_blend );
513         vlc_object_destroy( p_sys->p_filter_blend );
514     }
515
516     vlc_object_destroy( p_sys );
517 }
518
519 struct sout_stream_id_t
520 {
521     vlc_fourcc_t  b_transcode;
522     es_format_t f_src;        /* only if transcoding */
523     es_format_t f_dst;        /*  "   "      " */
524     unsigned int  i_inter_pixfmt; /* intermediary format when transcoding */
525
526     /* id of the out stream */
527     void *id;
528
529     /* Decoder */
530     decoder_t       *p_decoder;
531
532     /* Encoder */
533     encoder_t       *p_encoder;
534     vlc_fourcc_t    b_enc_inited;
535
536     /* ffmpeg part */
537     AVCodec         *ff_dec;
538     AVCodecContext  *ff_dec_c;
539
540     mtime_t         i_dts;
541     mtime_t         i_length;
542
543     int             i_buffer;
544     int             i_buffer_pos;
545     uint8_t         *p_buffer;
546
547     AVFrame         *p_ff_pic;
548     AVFrame         *p_ff_pic_tmp0; /* to do deinterlace */
549     AVFrame         *p_ff_pic_tmp1; /* to do pix conversion */
550     AVFrame         *p_ff_pic_tmp2; /* to do resample */
551     AVFrame         *p_ff_pic_tmp3; /* to do subpicture overlay */
552
553     ImgReSampleContext *p_vresample;
554 };
555
556
557 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
558 {
559     sout_stream_sys_t *p_sys = p_stream->p_sys;
560     sout_stream_id_t *id;
561
562     id = malloc( sizeof( sout_stream_id_t ) );
563     id->i_dts = 0;
564     id->id = NULL;
565     id->p_decoder = NULL;
566     id->p_encoder = NULL;
567
568     if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
569     {
570         msg_Dbg( p_stream,
571                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
572                  (char*)&p_fmt->i_codec,
573                  (char*)&p_sys->i_acodec );
574
575         /* src format */
576         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
577
578         /* create dst format */
579         es_format_Init( &id->f_dst, AUDIO_ES, p_sys->i_acodec );
580         id->f_dst.i_id    = id->f_src.i_id;
581         id->f_dst.i_group = id->f_src.i_group;
582         if( id->f_src.psz_language )
583             id->f_dst.psz_language = strdup( id->f_src.psz_language );
584         id->f_dst.audio.i_rate = p_sys->i_sample_rate > 0 ?
585             p_sys->i_sample_rate : id->f_src.audio.i_rate;
586         id->f_dst.audio.i_channels = p_sys->i_channels > 0 ?
587             p_sys->i_channels : id->f_src.audio.i_channels;
588         id->f_dst.i_bitrate = p_sys->i_abitrate;
589         id->f_dst.audio.i_blockalign = 0;
590         id->f_dst.i_extra  = 0;
591         id->f_dst.p_extra  = NULL;
592
593         /* build decoder -> filter -> encoder */
594         if( transcode_audio_ffmpeg_new( p_stream, id ) )
595         {
596             msg_Err( p_stream, "cannot create audio chain" );
597             free( id );
598             return NULL;
599         }
600
601         /* open output stream */
602         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
603         id->b_transcode = VLC_TRUE;
604
605         if( id->id == NULL )
606         {
607             free( id );
608             return NULL;
609         }
610     }
611     else if( p_fmt->i_cat == VIDEO_ES &&
612              (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
613     {
614         msg_Dbg( p_stream,
615                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
616                  (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
617
618         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
619
620         /* create dst format */
621         es_format_Init( &id->f_dst, VIDEO_ES, p_sys->i_vcodec );
622         id->f_dst.i_id    = id->f_src.i_id;
623         id->f_dst.i_group = id->f_src.i_group;
624         if( id->f_src.psz_language )
625             id->f_dst.psz_language = strdup( id->f_src.psz_language );
626         id->f_dst.video.i_width  = p_sys->i_width;
627         id->f_dst.video.i_height = p_sys->i_height;
628         id->f_dst.i_bitrate = p_sys->i_vbitrate;
629         id->f_dst.i_extra = 0;
630         id->f_dst.p_extra = NULL;
631
632         /* build decoder -> filter -> encoder */
633         if( transcode_video_ffmpeg_new( p_stream, id ) )
634         {
635             msg_Err( p_stream, "cannot create video chain" );
636             free( id );
637             return NULL;
638         }
639 #if 0
640         /* open output stream */
641         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
642 #endif
643         id->b_transcode = VLC_TRUE;
644     }
645     else if( p_fmt->i_cat == SPU_ES && (p_sys->i_scodec || p_sys->psz_senc) )
646     {
647         msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
648                  "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
649                  (char*)&p_sys->i_scodec );
650
651         /* src format */
652         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
653
654         /* create dst format */
655         es_format_Init( &id->f_dst, SPU_ES, p_sys->i_scodec );
656         id->f_dst.i_id    = id->f_src.i_id;
657         id->f_dst.i_group = id->f_src.i_group;
658         if( id->f_src.psz_language )
659             id->f_dst.psz_language = strdup( id->f_src.psz_language );
660         id->f_dst.i_extra = 0;
661         id->f_dst.p_extra = NULL;
662
663         /* build decoder -> filter -> encoder */
664         if( transcode_spu_new( p_stream, id ) )
665         {
666             msg_Err( p_stream, "cannot create subtitles chain" );
667             free( id );
668             return NULL;
669         }
670
671         /* open output stream */
672         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
673         id->b_transcode = VLC_TRUE;
674
675         if( id->id == NULL )
676         {
677             free( id );
678             return NULL;
679         }
680     }
681     else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
682     {
683         msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
684                  (char*)&p_fmt->i_codec );
685
686         id->b_transcode = VLC_TRUE;
687
688         /* src format */
689         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
690
691         /* build decoder -> filter -> encoder */
692         if( transcode_spu_new( p_stream, id ) )
693         {
694             msg_Err( p_stream, "cannot create subtitles chain" );
695             free( id );
696             return NULL;
697         }
698     }
699     else
700     {
701         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
702                  (char*)&p_fmt->i_codec );
703         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
704         id->b_transcode = VLC_FALSE;
705
706         if( id->id == NULL )
707         {
708             free( id );
709             return NULL;
710         }
711     }
712
713     return id;
714 }
715
716 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
717 {
718     sout_stream_sys_t   *p_sys = p_stream->p_sys;
719
720     if( id->b_transcode )
721     {
722         if( id->f_src.i_cat == AUDIO_ES )
723         {
724             transcode_audio_ffmpeg_close( p_stream, id );
725         }
726         else if( id->f_src.i_cat == VIDEO_ES )
727         {
728             transcode_video_ffmpeg_close( p_stream, id );
729         }
730         else if( id->f_src.i_cat == SPU_ES )
731         {
732             transcode_spu_close( p_stream, id );
733         }
734     }
735
736     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
737     free( id );
738
739     return VLC_SUCCESS;
740 }
741
742 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
743                  block_t *p_buffer )
744 {
745     sout_stream_sys_t   *p_sys = p_stream->p_sys;
746
747     if( id->b_transcode )
748     {
749         block_t *p_buffer_out;
750
751         /* Be sure to have padding */
752         p_buffer = block_Realloc( p_buffer, 0, p_buffer->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
753         if( p_buffer == NULL )
754         {
755             return VLC_EGENERIC;
756         }
757         p_buffer->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
758         memset( &p_buffer->p_buffer[p_buffer->i_buffer], 0, FF_INPUT_BUFFER_PADDING_SIZE );
759
760         if( id->f_src.i_cat == AUDIO_ES )
761         {
762             transcode_audio_ffmpeg_process( p_stream, id, p_buffer,
763                                             &p_buffer_out );
764             block_Release( p_buffer );
765         }
766         else if( id->f_src.i_cat == VIDEO_ES )
767         {
768             if( transcode_video_ffmpeg_process( p_stream, id, p_buffer,
769                 &p_buffer_out ) != VLC_SUCCESS )
770             {
771                 block_Release( p_buffer );
772                 return VLC_EGENERIC;
773             }
774             block_Release( p_buffer );
775         }
776         else if( id->f_src.i_cat == SPU_ES )
777         {
778             if( transcode_spu_process( p_stream, id, p_buffer,
779                 &p_buffer_out ) != VLC_SUCCESS )
780             {
781                 return VLC_EGENERIC;
782             }
783         }
784         else
785         {
786             block_Release( p_buffer );
787         }
788
789         if( p_buffer_out )
790         {
791             return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
792         }
793         return VLC_SUCCESS;
794     }
795     else if( id->id != NULL )
796     {
797         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
798     }
799     else
800     {
801         block_Release( p_buffer );
802         return VLC_EGENERIC;
803     }
804 }
805
806 /****************************************************************************
807  * ffmpeg decoder reencocdr part
808  ****************************************************************************/
809
810 static struct
811 {
812     vlc_fourcc_t i_fcc;
813     int          i_ff_codec;
814 } fourcc_to_ff_code[] =
815 {
816     /* audio */
817     { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
818     { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
819     { VLC_FOURCC( 'm', 'p', '4', 'a' ), CODEC_ID_AAC },
820     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
821     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
822     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
823     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
824     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
825     { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
826
827     /* video */
828     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
829     { VLC_FOURCC( 'm', 'p', '1', 'v' ), CODEC_ID_MPEG1VIDEO },
830 #if LIBAVCODEC_BUILD >= 4676
831     { VLC_FOURCC( 'm', 'p', '2', 'v' ), CODEC_ID_MPEG2VIDEO },
832 #endif
833     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
834     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
835     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
836     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
837     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
838     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
839     { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
840     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
841     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
842     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
843     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
844     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
845     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
846 #if LIBAVCODEC_BUILD >= 4666
847     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
848     { VLC_FOURCC( 'h', '2', '6', '4' ), CODEC_ID_H264 },
849 #endif
850 #if LIBAVCODEC_BUILD >= 4719
851     { VLC_FOURCC( 'S', 'N', 'O', 'W' ), CODEC_ID_SNOW },
852 #endif
853
854     /* raw video code, only used for 'encoding' */
855     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
856     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
857     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
858     { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
859     { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
860     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
861     { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
862     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
863     { VLC_FOURCC( 'Y', 'V', '1', '2' ), CODEC_ID_RAWVIDEO },
864     { VLC_FOURCC( 'I', 'Y', 'U', 'V' ), CODEC_ID_RAWVIDEO },
865
866     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
867 };
868
869 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
870 {
871     int i;
872
873     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
874     {
875         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
876         {
877             return fourcc_to_ff_code[i].i_ff_codec;
878         }
879     }
880
881     return 0;
882 }
883
884 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
885 {
886     switch( i_chroma )
887     {
888         case VLC_FOURCC( 'Y', 'V', '1', '2' ):
889         case VLC_FOURCC( 'I', 'Y', 'U', 'V' ):
890         case VLC_FOURCC( 'I', '4', '2', '0' ):
891             return PIX_FMT_YUV420P;
892         case VLC_FOURCC( 'I', '4', '2', '2' ):
893             return PIX_FMT_YUV422P;
894         case VLC_FOURCC( 'I', '4', '4', '4' ):
895             return PIX_FMT_YUV444P;
896         case VLC_FOURCC( 'R', 'V', '1', '5' ):
897             return PIX_FMT_RGB555;
898         case VLC_FOURCC( 'R', 'V', '1', '6' ):
899             return PIX_FMT_RGB565;
900         case VLC_FOURCC( 'R', 'V', '2', '4' ):
901             return PIX_FMT_BGR24;
902         case VLC_FOURCC( 'R', 'V', '3', '2' ):
903             return PIX_FMT_RGBA32;
904         case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
905             return PIX_FMT_GRAY8;
906         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
907             return PIX_FMT_YUV422;
908         default:
909             return 0;
910     }
911 }
912
913 static inline vlc_fourcc_t get_vlc_chroma( int i_pix_fmt )
914 {
915     switch( i_pix_fmt )
916     {
917     case PIX_FMT_YUV420P:
918         return VLC_FOURCC('I','4','2','0');
919     case PIX_FMT_YUV422P:
920         return VLC_FOURCC('I','4','2','2');
921     case PIX_FMT_YUV444P:
922         return VLC_FOURCC('I','4','4','4');
923
924     case PIX_FMT_YUV422:
925         return VLC_FOURCC('Y','U','Y','2');
926
927     case PIX_FMT_RGB555:
928         return VLC_FOURCC('R','V','1','5');
929     case PIX_FMT_RGB565:
930         return VLC_FOURCC('R','V','1','6');
931     case PIX_FMT_RGB24:
932         return VLC_FOURCC('R','V','2','4');
933     case PIX_FMT_RGBA32:
934         return VLC_FOURCC('R','V','3','2');
935     case PIX_FMT_GRAY8:
936         return VLC_FOURCC('G','R','E','Y');
937
938     case PIX_FMT_YUV410P:
939     case PIX_FMT_YUV411P:
940     case PIX_FMT_BGR24:
941     default:
942         return 0;
943     }
944 }
945
946 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
947                                        sout_stream_id_t *id )
948 {
949     int i_ff_codec;
950
951     if( id->f_src.i_codec == VLC_FOURCC('s','1','6','l') ||
952         id->f_src.i_codec == VLC_FOURCC('s','1','6','b') ||
953         id->f_src.i_codec == VLC_FOURCC('s','8',' ',' ') ||
954         id->f_src.i_codec == VLC_FOURCC('u','8',' ',' ') )
955     {
956         id->ff_dec = NULL;
957
958         id->ff_dec_c = avcodec_alloc_context();
959         id->ff_dec_c->sample_rate = id->f_src.audio.i_rate;
960         id->ff_dec_c->channels    = id->f_src.audio.i_channels;
961         id->ff_dec_c->block_align = id->f_src.audio.i_blockalign;
962         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
963     }
964     else
965     {
966         /* find decoder */
967         i_ff_codec = get_ff_codec( id->f_src.i_codec );
968         if( i_ff_codec == 0 )
969         {
970             msg_Err( p_stream, "cannot find decoder id" );
971             return VLC_EGENERIC;
972         }
973
974         id->ff_dec = avcodec_find_decoder( i_ff_codec );
975         if( !id->ff_dec )
976         {
977             msg_Err( p_stream, "cannot find decoder (avcodec)" );
978             return VLC_EGENERIC;
979         }
980
981         id->ff_dec_c = avcodec_alloc_context();
982         id->ff_dec_c->sample_rate = id->f_src.audio.i_rate;
983         id->ff_dec_c->channels    = id->f_src.audio.i_channels;
984         id->ff_dec_c->block_align = id->f_src.audio.i_blockalign;
985         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
986
987         id->ff_dec_c->extradata_size = id->f_src.i_extra;
988         id->ff_dec_c->extradata      = id->f_src.p_extra;
989         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
990         {
991             msg_Err( p_stream, "cannot open decoder" );
992             av_free( id->ff_dec_c );
993             return VLC_EGENERIC;
994         }
995     }
996
997     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
998     id->i_buffer_pos = 0;
999     id->p_buffer     = malloc( id->i_buffer );
1000
1001     /* Sanity check for audio channels */
1002     id->f_dst.audio.i_channels =
1003         __MIN( id->f_dst.audio.i_channels, id->f_src.audio.i_channels );
1004
1005     /* find encoder */
1006     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
1007
1008     /* Initialization of encoder format structures */
1009     es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, AOUT_FMT_S16_NE );
1010     id->p_encoder->fmt_in.audio.i_format = AOUT_FMT_S16_NE;
1011     id->p_encoder->fmt_in.audio.i_rate = id->f_dst.audio.i_rate;
1012     id->p_encoder->fmt_in.audio.i_physical_channels =
1013         id->p_encoder->fmt_in.audio.i_original_channels =
1014             pi_channels_maps[id->f_dst.audio.i_channels];
1015     id->p_encoder->fmt_in.audio.i_channels = id->f_dst.audio.i_channels;
1016
1017     id->p_encoder->fmt_out = id->p_encoder->fmt_in;
1018     id->p_encoder->fmt_out.i_codec = id->f_dst.i_codec;
1019     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
1020
1021     id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1022
1023     /* Attach object to parent so object variables inheritance works */
1024     vlc_object_attach( id->p_encoder, p_stream );
1025
1026     id->p_encoder->p_module =
1027         module_Need( id->p_encoder, "encoder",
1028                      p_stream->p_sys->psz_aenc, VLC_TRUE );
1029     if( !id->p_encoder->p_module )
1030     {
1031         vlc_object_detach( id->p_encoder );
1032         vlc_object_destroy( id->p_encoder );
1033         msg_Err( p_stream, "cannot open encoder" );
1034         av_free( id->ff_dec_c );
1035         return VLC_EGENERIC;
1036     }
1037
1038     id->b_enc_inited = VLC_FALSE;
1039
1040     id->f_dst.audio.i_channels = id->p_encoder->fmt_in.audio.i_channels;
1041     id->f_dst.audio.i_rate     = id->p_encoder->fmt_in.audio.i_rate;
1042     id->f_dst.i_extra = id->p_encoder->fmt_out.i_extra;
1043     id->f_dst.p_extra = id->p_encoder->fmt_out.p_extra;
1044     id->f_dst.i_codec = id->p_encoder->fmt_out.i_codec;
1045
1046     /* Hack for mp3 transcoding support */
1047     if( id->f_dst.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1048     {
1049         id->f_dst.i_codec = VLC_FOURCC( 'm','p','g','a' );
1050     }
1051
1052     return VLC_SUCCESS;
1053 }
1054
1055 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
1056                                           sout_stream_id_t *id )
1057 {
1058     if( id->ff_dec ) avcodec_close( id->ff_dec_c );
1059     av_free( id->ff_dec_c );
1060
1061     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1062
1063     vlc_object_detach( id->p_encoder );
1064     vlc_object_destroy( id->p_encoder );
1065
1066     free( id->p_buffer );
1067 }
1068
1069 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
1070                                            sout_stream_id_t *id,
1071                                            block_t *in,
1072                                            block_t **out )
1073 {
1074     aout_buffer_t aout_buf;
1075     block_t *p_block;
1076     int i_buffer = in->i_buffer;
1077     char *p_buffer = in->p_buffer;
1078     id->i_dts = in->i_dts;
1079     *out = NULL;
1080
1081     while( i_buffer )
1082     {
1083         id->i_buffer_pos = 0;
1084
1085         /* decode as much data as possible */
1086         if( id->ff_dec )
1087         {
1088             int i_used;
1089
1090             i_used = avcodec_decode_audio( id->ff_dec_c,
1091                          (int16_t*)id->p_buffer, &id->i_buffer_pos,
1092                          p_buffer, i_buffer );
1093
1094 #if 0
1095             msg_Warn( p_stream, "avcodec_decode_audio: %d used on %d",
1096                       i_used, i_buffer );
1097 #endif
1098             if( i_used < 0 )
1099             {
1100                 msg_Warn( p_stream, "error audio decoding");
1101                 break;
1102             }
1103
1104             i_buffer -= i_used;
1105             p_buffer += i_used;
1106
1107             if ( id->i_buffer_pos < 0 )
1108             {
1109                 msg_Warn( p_stream, "weird error audio decoding");
1110                 break;
1111             }
1112         }
1113         else
1114         {
1115             int16_t *sout = (int16_t*)id->p_buffer;
1116
1117             if( id->f_src.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
1118                 id->f_src.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
1119             {
1120                 int8_t *sin = (int8_t*)p_buffer;
1121                 int i_used = __MIN( id->i_buffer/2, i_buffer );
1122                 int i_samples = i_used;
1123
1124                 if( id->f_src.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
1125                     while( i_samples > 0 )
1126                     {
1127                         *sout++ = ( *sin++ ) << 8;
1128                         i_samples--;
1129                     }
1130                 else
1131                     while( i_samples > 0 )
1132                     {
1133                         *sout++ = ( *sin++ - 128 ) << 8;
1134                         i_samples--;
1135                     }
1136
1137                 i_buffer -= i_used;
1138                 p_buffer += i_used;
1139                 id->i_buffer_pos = i_used * 2;
1140             }
1141             else if( id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) ||
1142                      id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'b' ) )
1143             {
1144                 int16_t *sin = (int16_t*)p_buffer;
1145                 int i_used = __MIN( id->i_buffer, i_buffer );
1146                 int i_samples = i_used / 2;
1147
1148                 /* first copy */
1149                 memcpy( sout, sin, i_used );
1150
1151 #ifdef WORDS_BIGENDIAN
1152                 if( id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
1153 #else
1154                 if( id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'b' ) )
1155 #endif
1156                 {
1157                     uint8_t *dat = (uint8_t*)sout;
1158
1159                     while( i_samples > 0 )
1160                     {
1161                         uint8_t tmp;
1162                         tmp    = dat[0];
1163                         dat[0] = dat[1];
1164                         dat[1] = tmp;
1165
1166                         dat += 2;
1167
1168                         i_samples--;
1169                     }
1170                 }
1171
1172                 i_buffer -= i_used;
1173                 p_buffer += i_used;
1174                 id->i_buffer_pos = i_used;
1175             }
1176         }
1177
1178         if( id->i_buffer_pos == 0 ) continue;
1179
1180         /* Encode as much data as possible */
1181         if( !id->b_enc_inited && id->p_encoder->pf_header )
1182         {
1183             block_t *p_block_tmp;
1184
1185             p_block = id->p_encoder->pf_header( id->p_encoder );
1186             p_block_tmp = p_block;
1187             while( p_block_tmp )
1188             {
1189                 p_block_tmp->i_dts = p_block_tmp->i_pts = in->i_dts;
1190                 p_block_tmp = p_block_tmp->p_next;
1191             }
1192             block_ChainAppend( out, p_block );
1193
1194             id->b_enc_inited = VLC_TRUE;
1195         }
1196
1197         aout_buf.p_buffer = id->p_buffer;
1198         aout_buf.i_nb_bytes = id->i_buffer_pos;
1199         aout_buf.i_nb_samples = id->i_buffer_pos / 2 / id->f_src.audio.i_channels;
1200         aout_buf.start_date = id->i_dts;
1201         aout_buf.end_date = id->i_dts;
1202
1203         id->i_dts += ( I64C(1000000) * id->i_buffer_pos / 2 /
1204             id->f_src.audio.i_channels / id->f_src.audio.i_rate );
1205
1206         if( id->p_encoder->fmt_in.audio.i_channels == 1 &&
1207             id->f_src.audio.i_channels > 1 )
1208         {
1209             int16_t *p_sample = (int16_t *)aout_buf.p_buffer;
1210             int i_src_c = id->f_src.audio.i_channels;
1211             unsigned int i;
1212
1213             for( i = 0; i < aout_buf.i_nb_samples; i++ )
1214             {
1215                 int j, c = 0;
1216
1217                 for( j = 1; j < i_src_c; j++ )
1218                 {
1219                     c += p_sample[i_src_c * i + j];
1220                 }
1221                 p_sample[i] = c / (i_src_c-1);
1222             }
1223             aout_buf.i_nb_bytes = i * 2;
1224         }
1225         else if( id->p_encoder->fmt_in.audio.i_channels == 2 &&
1226                  id->f_src.audio.i_channels > 2 )
1227         {
1228             int i_src_c = id->f_src.audio.i_channels;
1229             unsigned int i;
1230
1231             static const float mixf_l[4][6] = /* [i_src_c - 3][channel index] */
1232             {
1233                 { 0.00, 1.00, 0.00, 0.00, 0.00, 0.00 }, /* 3 channels */
1234                 { 0.00, 0.50, 0.50, 0.00, 0.00, 0.00 }, /* 4 channels */
1235                 { 0.00, 0.50, 0.00, 0.50, 0.00, 0.00 }, /* 5 channels */
1236                 { 0.00, 0.34, 0.33, 0.00, 0.33, 0.00 }, /* 6 channels */
1237             };
1238             static const float mixf_r[4][6] = /* [i_src_c - 3][channel index] */
1239             {
1240                 { 0.00, 1.00, 0.00, 0.00, 0.00, 0.00 }, /* 3 channels */
1241                 { 0.00, 0.00, 0.50, 0.50, 0.00, 0.00 }, /* 4 channels */
1242                 { 0.00, 0.00, 0.50, 0.00, 0.50, 0.00 }, /* 5 channels */
1243                 { 0.00, 0.00, 0.33, 0.34, 0.00, 0.33 }, /* 6 channels */
1244             };
1245
1246
1247             for( i = 0; i < aout_buf.i_nb_samples; i++ )
1248             {
1249                 int16_t *p_src = (int16_t *)aout_buf.p_buffer + i_src_c * i;
1250                 int16_t *p_dst = (int16_t *)aout_buf.p_buffer + 2 * i;
1251
1252                 int j;
1253                 float l = 0.0, r = 0.0;
1254                 for( j = 0; j < i_src_c; j++ )
1255                 {
1256                     l += mixf_l[i_src_c-3][j] * p_src[j];
1257                     r += mixf_r[i_src_c-3][j] * p_src[j];
1258                 }
1259
1260                 p_dst[0] = (int)( l + 0.5 );
1261                 p_dst[1] = (int)( r + 0.5 );
1262             }
1263             aout_buf.i_nb_bytes = i * 2 * 2;
1264         }
1265         else if( id->f_src.audio.i_channels !=
1266                  id->p_encoder->fmt_in.audio.i_channels )
1267         {
1268             unsigned int i;
1269             int j;
1270
1271             /* This is for liba52 which is what ffmpeg uses to decode ac3 */
1272             static const int translation[7][6] =
1273             {{ 0, 0, 0, 0, 0, 0 },      /* 0 channels (rarely used) */
1274              { 0, 0, 0, 0, 0, 0 },       /* 1 ch */
1275              { 0, 1, 0, 0, 0, 0 },       /* 2 */
1276              { 1, 2, 0, 0, 0, 0 },       /* 3 */
1277              { 1, 3, 2, 0, 0, 0 },       /* 4 */
1278              { 1, 3, 4, 2, 0, 0 },       /* 5 */
1279              { 1, 3, 4, 5, 2, 0 }};      /* 6 */
1280
1281             /* dumb downmixing */
1282             for( i = 0; i < aout_buf.i_nb_samples; i++ )
1283             {
1284                 uint16_t *p_buffer = (uint16_t *)aout_buf.p_buffer;
1285                 for( j = 0 ; j < id->p_encoder->fmt_in.audio.i_channels; j++ )
1286                 {
1287                     p_buffer[i*id->p_encoder->fmt_in.audio.i_channels+j] =
1288                         p_buffer[i*id->f_src.audio.i_channels+
1289                                  translation[id->f_src.audio.i_channels][j]];
1290                 }
1291             }
1292             aout_buf.i_nb_bytes = i*id->p_encoder->fmt_in.audio.i_channels * 2;
1293         }
1294
1295         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf );
1296         block_ChainAppend( out, p_block );
1297     }
1298
1299     return VLC_SUCCESS;
1300 }
1301
1302
1303 /*
1304  * video
1305  */
1306 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1307                                        sout_stream_id_t *id )
1308 {
1309     sout_stream_sys_t *p_sys = p_stream->p_sys;
1310     int i_ff_codec;
1311
1312     /* Open decoder */
1313     if( id->f_src.i_codec == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1314         id->f_src.i_codec == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1315         id->f_src.i_codec == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1316         id->f_src.i_codec == VLC_FOURCC( 'Y', 'V', '1', '2' ) ||
1317         id->f_src.i_codec == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1318         id->f_src.i_codec == VLC_FOURCC( 'I', 'Y', 'U', 'V' ) ||
1319         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
1320         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
1321         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
1322         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
1323         id->f_src.i_codec == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
1324     {
1325         id->ff_dec              = NULL;
1326         id->ff_dec_c            = avcodec_alloc_context();
1327         id->ff_dec_c->width     = id->f_src.video.i_width;
1328         id->ff_dec_c->height    = id->f_src.video.i_height;
1329         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_codec );
1330
1331 #if LIBAVCODEC_BUILD >= 4687
1332         if( id->ff_dec_c->width )
1333         id->ff_dec_c->sample_aspect_ratio =
1334             av_d2q( id->f_src.video.i_aspect / (double)VOUT_ASPECT_FACTOR *
1335                     id->ff_dec_c->height / id->ff_dec_c->width, 255 );
1336 #else
1337         id->ff_dec_c->aspect_ratio =
1338             id->f_src.video.i_aspect / (float)VOUT_ASPECT_FACTOR;
1339 #endif
1340     }
1341     else
1342     {
1343         /* find decoder */
1344         i_ff_codec = get_ff_codec( id->f_src.i_codec );
1345         if( i_ff_codec == 0 )
1346         {
1347             msg_Err( p_stream, "cannot find decoder" );
1348             return VLC_EGENERIC;
1349         }
1350
1351         id->ff_dec = avcodec_find_decoder( i_ff_codec );
1352         if( !id->ff_dec )
1353         {
1354             msg_Err( p_stream, "cannot find decoder" );
1355             return VLC_EGENERIC;
1356         }
1357
1358         id->ff_dec_c = avcodec_alloc_context();
1359         id->ff_dec_c->width         = id->f_src.video.i_width;
1360         id->ff_dec_c->height        = id->f_src.video.i_height;
1361         id->ff_dec_c->bits_per_sample=id->f_src.video.i_bits_per_pixel;
1362         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
1363
1364         if( id->f_src.i_extra > 0 )
1365         {
1366             if( i_ff_codec == CODEC_ID_SVQ3 )
1367             {
1368                 int i_size = id->f_src.i_extra;
1369                 uint8_t *p;
1370
1371                 id->ff_dec_c->extradata_size = i_size + 12;
1372                 p = id->ff_dec_c->extradata  = malloc( i_size + 12 );
1373
1374                 memcpy( &p[0],  "SVQ3", 4 );
1375                 memset( &p[4], 0, 8 );
1376                 memcpy( &p[12], id->f_src.p_extra, i_size );
1377
1378                 /* Now remove all atoms before the SMI one */
1379                 if( id->ff_dec_c->extradata_size > 0x5a && strncmp( &p[0x56], "SMI ", 4 ) )
1380                 {
1381                     uint8_t *psz = &p[0x52];
1382
1383                     while( psz < &p[id->ff_dec_c->extradata_size - 8] )
1384                     {
1385                         int i_size = GetDWBE( psz );
1386                         if( i_size <= 1 )
1387                         {
1388                             /* FIXME handle 1 as long size */
1389                             break;
1390                         }
1391                         if( !strncmp( &psz[4], "SMI ", 4 ) )
1392                         {
1393                             memmove( &p[0x52], psz, &p[id->ff_dec_c->extradata_size] - psz );
1394                             break;
1395                         }
1396                         psz += i_size;
1397                     }
1398                 }
1399             }
1400             else
1401             {
1402                 id->ff_dec_c->extradata_size= id->f_src.i_extra;
1403                 id->ff_dec_c->extradata = malloc( id->f_src.i_extra + FF_INPUT_BUFFER_PADDING_SIZE );
1404
1405                 memcpy( id->ff_dec_c->extradata, id->f_src.p_extra, id->f_src.i_extra );
1406                 memset( (uint8_t*)id->ff_dec_c->extradata + id->f_src.i_extra, 0, FF_INPUT_BUFFER_PADDING_SIZE );
1407             }
1408         }
1409         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1410         id->ff_dec_c->error_resilience= -1;
1411         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
1412         id->ff_dec_c->opaque        = p_sys;
1413
1414         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1415         {
1416             msg_Err( p_stream, "cannot open decoder" );
1417             av_free( id->ff_dec_c );
1418             return VLC_EGENERIC;
1419         }
1420     }
1421
1422     /* Open encoder */
1423     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
1424
1425     /* Initialization of encoder format structures */
1426     es_format_Init( &id->p_encoder->fmt_in,
1427                     id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
1428
1429     /* The dimensions will be set properly later on.
1430      * Just put sensible values so we can test if there is an encoder. */
1431     id->p_encoder->fmt_in.video.i_width =
1432         id->f_src.video.i_width ?  id->f_src.video.i_width : 16;
1433     id->p_encoder->fmt_in.video.i_height =
1434         id->f_src.video.i_height ? id->f_src.video.i_height : 16;
1435
1436     id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */
1437     id->p_encoder->fmt_in.video.i_frame_rate_base= 1;
1438     if( id->ff_dec )
1439     {
1440         id->p_encoder->fmt_in.video.i_frame_rate = id->ff_dec_c->frame_rate;
1441 #if LIBAVCODEC_BUILD >= 4662
1442         id->p_encoder->fmt_in.video.i_frame_rate_base =
1443             id->ff_dec_c->frame_rate_base;
1444 #endif
1445
1446 #if LIBAVCODEC_BUILD >= 4687
1447         if( id->ff_dec_c->height )
1448         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1449             ( av_q2d(id->ff_dec_c->sample_aspect_ratio) *
1450               id->ff_dec_c->width / id->ff_dec_c->height );
1451 #else
1452         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1453             id->ff_dec_c->aspect_ratio;
1454 #endif
1455     }
1456
1457     /* Check whether a particular aspect ratio was requested */
1458     if( id->f_src.video.i_aspect )
1459     {
1460         id->p_encoder->fmt_in.video.i_aspect = id->f_src.video.i_aspect;
1461         id->f_dst.video.i_aspect = id->f_src.video.i_aspect;
1462     }
1463
1464     id->p_encoder->fmt_out = id->p_encoder->fmt_in;
1465     id->p_encoder->fmt_out.i_codec = id->f_dst.i_codec;
1466     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
1467
1468     id->p_encoder->i_threads = p_sys->i_threads;
1469
1470     id->p_ff_pic         = avcodec_alloc_frame();
1471     id->p_ff_pic_tmp0    = NULL;
1472     id->p_ff_pic_tmp1    = NULL;
1473     id->p_ff_pic_tmp2    = NULL;
1474     id->p_ff_pic_tmp3    = NULL;
1475     id->p_vresample      = NULL;
1476
1477     id->p_encoder->p_cfg = p_sys->p_video_cfg;
1478
1479     /* Attach object to parent so object variables inheritance works */
1480     vlc_object_attach( id->p_encoder, p_stream );
1481
1482     id->p_encoder->p_module =
1483         module_Need( id->p_encoder, "encoder", p_sys->psz_venc, VLC_TRUE );
1484
1485     if( !id->p_encoder->p_module )
1486     {
1487         vlc_object_detach( id->p_encoder );
1488         vlc_object_destroy( id->p_encoder );
1489         av_free( id->ff_dec_c );
1490         msg_Err( p_stream, "cannot find encoder" );
1491         return VLC_EGENERIC;
1492     }
1493
1494     /* Close the encoder.
1495      * We'll open it only when we have the first frame */
1496     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1497     id->p_encoder->p_module = NULL;
1498
1499     id->b_enc_inited = VLC_FALSE;
1500
1501     if ( p_sys->i_threads >= 1 )
1502     {
1503         p_sys->id_video = id;
1504         vlc_mutex_init( p_stream, &p_sys->lock_out );
1505         vlc_cond_init( p_stream, &p_sys->cond );
1506         memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1507         p_sys->i_first_pic = 0;
1508         p_sys->i_last_pic = 0;
1509         p_sys->p_buffers = NULL;
1510         p_sys->b_die = p_sys->b_error = 0;
1511         if( vlc_thread_create( p_sys, "encoder", EncoderThread,
1512                                VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) )
1513         {
1514             vlc_object_detach( id->p_encoder );
1515             vlc_object_destroy( id->p_encoder );
1516             av_free( id->ff_dec_c );
1517             msg_Err( p_stream, "cannot spawn encoder thread" );
1518             return VLC_EGENERIC;
1519         }
1520     }
1521
1522     return VLC_SUCCESS;
1523 }
1524
1525 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream,
1526                                            sout_stream_id_t *id )
1527 {
1528     if ( p_stream->p_sys->i_threads >= 1 )
1529     {
1530        vlc_mutex_lock( &p_stream->p_sys->lock_out );
1531        p_stream->p_sys->b_die = 1;
1532        vlc_cond_signal( &p_stream->p_sys->cond );
1533        vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1534        vlc_thread_join( p_stream->p_sys );
1535        vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1536        vlc_cond_destroy( &p_stream->p_sys->cond );
1537     }
1538
1539     /* Close decoder */
1540     if( id->ff_dec ) avcodec_close( id->ff_dec_c );
1541     av_free( id->ff_dec_c );
1542
1543     /* Close encoder */
1544     if( id->p_encoder->p_module )
1545         module_Unneed( id->p_encoder, id->p_encoder->p_module );
1546     vlc_object_detach( id->p_encoder );
1547     vlc_object_destroy( id->p_encoder );
1548
1549     /* Misc cleanup */
1550     if( id->p_ff_pic)
1551     {
1552         free( id->p_ff_pic );
1553     }
1554
1555     if( id->p_ff_pic_tmp0 )
1556     {
1557         free( id->p_ff_pic_tmp0->data[0] );
1558         free( id->p_ff_pic_tmp0 );
1559     }
1560     if( id->p_ff_pic_tmp1 )
1561     {
1562         free( id->p_ff_pic_tmp1->data[0] );
1563         free( id->p_ff_pic_tmp1 );
1564     }
1565     if( id->p_ff_pic_tmp2 )
1566     {
1567         free( id->p_ff_pic_tmp2->data[0] );
1568         free( id->p_ff_pic_tmp2 );
1569     }
1570     if( id->p_ff_pic_tmp3 )
1571     {
1572         free( id->p_ff_pic_tmp3->data[0] );
1573         free( id->p_ff_pic_tmp3 );
1574     }
1575     if( id->p_vresample )
1576     {
1577         img_resample_close( id->p_vresample );
1578     }
1579 }
1580
1581 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1582                sout_stream_id_t *id, block_t *in, block_t **out )
1583 {
1584     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1585     int     i_used;
1586     int     b_gotpicture;
1587     AVFrame *frame;
1588
1589     int     i_data;
1590     uint8_t *p_data;
1591
1592     *out = NULL;
1593
1594     i_data = in->i_buffer;
1595     p_data = in->p_buffer;
1596
1597     for( ;; )
1598     {
1599         block_t *p_block;
1600         picture_t * p_pic;
1601         int i_plane;
1602         subpicture_t *p_subpic = 0;
1603
1604         /* decode frame */
1605         frame = id->p_ff_pic;
1606         p_sys->i_input_pts = in->i_pts;
1607         p_sys->i_input_dts = in->i_dts;
1608         if( id->ff_dec )
1609         {
1610             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1611                                            &b_gotpicture,
1612                                            p_data, i_data );
1613         }
1614         else
1615         {
1616             /* raw video */
1617             avpicture_fill( (AVPicture*)frame, p_data,
1618                             id->ff_dec_c->pix_fmt,
1619                             id->ff_dec_c->width, id->ff_dec_c->height );
1620             i_used = i_data;
1621             b_gotpicture = 1;
1622
1623             /* Set PTS */
1624             frame->pts = p_sys->i_input_pts ? p_sys->i_input_pts :
1625                          AV_NOPTS_VALUE;
1626
1627             frame->pict_type = FF_I_TYPE;
1628         }
1629
1630         if( i_used < 0 )
1631         {
1632             msg_Warn( p_stream, "error");
1633             return VLC_EGENERIC;
1634         }
1635         i_data -= i_used;
1636         p_data += i_used;
1637
1638         if( !b_gotpicture )
1639         {
1640             return VLC_SUCCESS;
1641         }
1642
1643         /* Get the pts of the decoded frame if any, otherwise keep the
1644          * interpolated one */
1645         if( frame->pts != AV_NOPTS_VALUE )
1646         {
1647             p_sys->i_output_pts = frame->pts;
1648         }
1649
1650         /* Sanity check (seems to be needed for some streams ) */
1651         if( frame->pict_type == FF_B_TYPE )
1652         {
1653             p_sys->b_input_has_b_frames = VLC_TRUE;
1654         }
1655
1656         if( !id->b_enc_inited )
1657         {
1658             /* Hack because of the copy packetizer which can fail to detect the
1659              * proper size (which forces us to wait until the 1st frame
1660              * is decoded) */
1661             int i_width = id->ff_dec_c->width - p_sys->i_crop_left -
1662                           p_sys->i_crop_right;
1663             int i_height = id->ff_dec_c->height - p_sys->i_crop_top -
1664                            p_sys->i_crop_bottom;
1665
1666             if( id->f_dst.video.i_width <= 0 && id->f_dst.video.i_height <= 0
1667                 && p_sys->f_scale )
1668             {
1669                 /* Apply the scaling */
1670                 id->f_dst.video.i_width = i_width * p_sys->f_scale;
1671                 id->f_dst.video.i_height = i_height * p_sys->f_scale;
1672             }
1673             else if( id->f_dst.video.i_width > 0 &&
1674                      id->f_dst.video.i_height <= 0 )
1675             {
1676                 id->f_dst.video.i_height =
1677                     id->f_dst.video.i_width / (double)i_width * i_height;
1678             }
1679             else if( id->f_dst.video.i_width <= 0 &&
1680                      id->f_dst.video.i_height > 0 )
1681             {
1682                 id->f_dst.video.i_width =
1683                     id->f_dst.video.i_height / (double)i_height * i_width;
1684             }
1685
1686             id->p_encoder->fmt_in.video.i_width =
1687               id->p_encoder->fmt_out.video.i_width =
1688                 id->f_dst.video.i_width;
1689             id->p_encoder->fmt_in.video.i_height =
1690               id->p_encoder->fmt_out.video.i_height =
1691                 id->f_dst.video.i_height;
1692
1693             id->p_encoder->fmt_out.i_extra = 0;
1694             id->p_encoder->fmt_out.p_extra = NULL;
1695
1696             id->p_encoder->p_module =
1697                 module_Need( id->p_encoder, "encoder",
1698                              p_sys->psz_venc, VLC_TRUE );
1699             if( !id->p_encoder->p_module )
1700             {
1701                 vlc_object_destroy( id->p_encoder );
1702                 msg_Err( p_stream, "cannot find encoder" );
1703                 id->b_transcode = VLC_FALSE;
1704                 return VLC_EGENERIC;
1705             }
1706
1707             id->f_dst.i_extra = id->p_encoder->fmt_out.i_extra;
1708             id->f_dst.p_extra = id->p_encoder->fmt_out.p_extra;
1709             id->f_dst.i_codec = id->p_encoder->fmt_out.i_codec;
1710
1711             /* Hack for mp2v/mp1v transcoding support */
1712             if( id->f_dst.i_codec == VLC_FOURCC( 'm','p','1','v' ) ||
1713                 id->f_dst.i_codec == VLC_FOURCC( 'm','p','2','v' ) )
1714             {
1715                 id->f_dst.i_codec = VLC_FOURCC( 'm','p','g','v' );
1716             }
1717
1718             if( !( id->id =
1719                      p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1720                                                      &id->f_dst ) ) )
1721             {
1722                 msg_Err( p_stream, "cannot add this stream" );
1723                 transcode_video_ffmpeg_close( p_stream, id );
1724                 id->b_transcode = VLC_FALSE;
1725                 return VLC_EGENERIC;
1726             }
1727
1728             if( id->p_encoder->pf_header )
1729             {
1730                 block_t *p_block_tmp;
1731
1732                 p_block = id->p_encoder->pf_header( id->p_encoder );
1733                 p_block_tmp = p_block;
1734                 while( p_block_tmp )
1735                 {
1736                     p_block_tmp->i_dts = p_block_tmp->i_pts = in->i_dts;
1737                     p_block_tmp = p_block_tmp->p_next;
1738                 }
1739                 block_ChainAppend( out, p_block );
1740             }
1741
1742             id->i_inter_pixfmt =
1743                 get_ff_chroma( id->p_encoder->fmt_in.i_codec );
1744
1745             id->b_enc_inited = VLC_TRUE;
1746         }
1747
1748         /* deinterlace */
1749         if( p_stream->p_sys->b_deinterlace )
1750         {
1751             if( id->p_ff_pic_tmp0 == NULL )
1752             {
1753                 int     i_size;
1754                 uint8_t *buf;
1755                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1756                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1757                                              id->ff_dec_c->width,
1758                                              id->ff_dec_c->height );
1759
1760                 buf = malloc( i_size );
1761
1762                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1763                                 id->i_inter_pixfmt,
1764                                 id->ff_dec_c->width, id->ff_dec_c->height );
1765             }
1766
1767             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0,
1768                                    (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1769                                    id->ff_dec_c->width, id->ff_dec_c->height );
1770
1771 #if LIBAVCODEC_BUILD >= 4685
1772             id->p_ff_pic_tmp0->interlaced_frame = 0;
1773 #endif
1774             id->p_ff_pic_tmp0->repeat_pict = frame->repeat_pict;
1775             frame = id->p_ff_pic_tmp0;
1776         }
1777
1778         /* convert pix format */
1779         if( id->ff_dec_c->pix_fmt != id->i_inter_pixfmt )
1780         {
1781             if( id->p_ff_pic_tmp1 == NULL )
1782             {
1783                 int     i_size;
1784                 uint8_t *buf;
1785                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1786                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1787                                              id->ff_dec_c->width,
1788                                              id->ff_dec_c->height );
1789
1790                 buf = malloc( i_size );
1791
1792                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1793                                 id->i_inter_pixfmt,
1794                                 id->ff_dec_c->width, id->ff_dec_c->height );
1795             }
1796
1797             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->i_inter_pixfmt,
1798                          (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1799                          id->ff_dec_c->width, id->ff_dec_c->height );
1800
1801             id->p_ff_pic_tmp1->repeat_pict = frame->repeat_pict;
1802 #if LIBAVCODEC_BUILD >= 4685
1803             id->p_ff_pic_tmp1->interlaced_frame = frame->interlaced_frame;
1804             id->p_ff_pic_tmp1->top_field_first = frame->top_field_first;
1805 #endif
1806             frame = id->p_ff_pic_tmp1;
1807         }
1808
1809         /* convert size and crop */
1810         if( id->ff_dec_c->width  != id->f_dst.video.i_width ||
1811             id->ff_dec_c->height != id->f_dst.video.i_height ||
1812             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1813             p_sys->i_crop_left > 0 || p_sys->i_crop_right > 0 )
1814         {
1815             if( id->p_ff_pic_tmp2 == NULL )
1816             {
1817                 int     i_size;
1818                 uint8_t *buf;
1819                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1820                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1821                                              id->f_dst.video.i_width,
1822                                              id->f_dst.video.i_height );
1823
1824                 buf = malloc( i_size );
1825
1826                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1827                                 id->i_inter_pixfmt,
1828                                 id->f_dst.video.i_width,
1829                                 id->f_dst.video.i_height );
1830
1831                 id->p_vresample =
1832                     img_resample_full_init( id->f_dst.video.i_width,
1833                                             id->f_dst.video.i_height,
1834                                             id->ff_dec_c->width,
1835                                             id->ff_dec_c->height,
1836                                             p_stream->p_sys->i_crop_top,
1837                                             p_stream->p_sys->i_crop_bottom,
1838                                             p_stream->p_sys->i_crop_left,
1839                                             p_stream->p_sys->i_crop_right
1840 #if LIBAVCODEC_BUILD >= 4708
1841                                             ,0, 0, 0, 0 );
1842 #else
1843                                           );
1844 #endif
1845             }
1846
1847             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1848                           (AVPicture*)frame );
1849
1850             id->p_ff_pic_tmp2->repeat_pict = frame->repeat_pict;
1851 #if LIBAVCODEC_BUILD >= 4685
1852             id->p_ff_pic_tmp2->interlaced_frame = frame->interlaced_frame;
1853             id->p_ff_pic_tmp2->top_field_first = frame->top_field_first;
1854 #endif
1855             frame = id->p_ff_pic_tmp2;
1856         }
1857
1858         /* Encoding */
1859         p_pic = malloc(sizeof(picture_t));
1860         vout_InitPicture( VLC_OBJECT(p_stream), p_pic,
1861                           id->p_encoder->fmt_in.i_codec,
1862                           id->f_dst.video.i_width, id->f_dst.video.i_height,
1863                           id->f_dst.video.i_width * VOUT_ASPECT_FACTOR /
1864                           id->f_dst.video.i_height );
1865
1866         /* Check if we have a subpicture to overlay */
1867         if( p_sys->p_filter_blend )
1868         {
1869             p_subpic = transcode_spu_get( p_stream, id, p_sys->i_output_pts );
1870
1871             if( p_subpic && frame != id->p_ff_pic_tmp0 &&
1872                 frame != id->p_ff_pic_tmp1 && frame != id->p_ff_pic_tmp2 )
1873             {
1874                 if( id->p_ff_pic_tmp3 == NULL )
1875                 {
1876                     uint8_t *buf = malloc( frame->linesize[0] *
1877                                            p_pic->p[0].i_lines * 3 );
1878                     id->p_ff_pic_tmp3 = avcodec_alloc_frame();
1879                     *id->p_ff_pic_tmp3 = *frame;
1880                     id->p_ff_pic_tmp3->data[0] = buf;
1881                     id->p_ff_pic_tmp3->data[1] = id->p_ff_pic_tmp3->data[0] +
1882                         frame->linesize[0] * p_pic->p[0].i_lines;
1883                     id->p_ff_pic_tmp3->data[2] = id->p_ff_pic_tmp3->data[1] +
1884                         frame->linesize[1] * p_pic->p[1].i_lines;
1885                 }
1886
1887                 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
1888                 {
1889                     p_stream->p_vlc->pf_memcpy(
1890                         id->p_ff_pic_tmp3->data[i_plane],
1891                         frame->data[i_plane],
1892                         p_pic->p[i_plane].i_lines * frame->linesize[i_plane] );
1893                 }
1894
1895                 id->p_ff_pic_tmp3->repeat_pict = frame->repeat_pict;
1896 #if LIBAVCODEC_BUILD >= 4685
1897                 id->p_ff_pic_tmp3->interlaced_frame = frame->interlaced_frame;
1898                 id->p_ff_pic_tmp3->top_field_first = frame->top_field_first;
1899 #endif
1900                 frame = id->p_ff_pic_tmp3;
1901             }
1902         }
1903
1904         for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
1905         {
1906             p_pic->p[i_plane].i_pitch = frame->linesize[i_plane];
1907             if ( p_sys->i_threads >= 1 )
1908             {
1909                 p_pic->p[i_plane].p_pixels = malloc(p_pic->p[i_plane].i_lines *
1910                                                     p_pic->p[i_plane].i_pitch);
1911                 p_stream->p_vlc->pf_memcpy( p_pic->p[i_plane].p_pixels,
1912                     frame->data[i_plane], p_pic->p[i_plane].i_lines *
1913                      p_pic->p[i_plane].i_pitch );
1914             }
1915             else
1916             {
1917                 p_pic->p[i_plane].p_pixels = frame->data[i_plane];
1918             }
1919         }
1920
1921         /* Set the pts of the frame being encoded */
1922         p_pic->date = p_sys->i_output_pts;
1923
1924         p_pic->i_nb_fields = frame->repeat_pict;
1925 #if LIBAVCODEC_BUILD >= 4685
1926         p_pic->b_progressive = !frame->interlaced_frame;
1927         p_pic->b_top_field_first = frame->top_field_first;
1928 #endif
1929
1930         /* Interpolate the next PTS
1931          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1932         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1933         {
1934             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1935               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1936         }
1937
1938         /* Overlay subpicture */
1939         if( p_subpic )
1940         {
1941             int i_width, i_height;
1942
1943             p_sys->p_filter_blend->fmt_out = id->p_encoder->fmt_in;
1944             p_sys->p_filter_blend->fmt_out.video.i_visible_width =
1945                 p_sys->p_filter_blend->fmt_out.video.i_width;
1946             p_sys->p_filter_blend->fmt_out.video.i_visible_height =
1947                 p_sys->p_filter_blend->fmt_out.video.i_height;
1948             p_sys->p_filter_blend->fmt_out.video.i_chroma =
1949                 VLC_FOURCC('I','4','2','0');
1950
1951             i_width = id->p_encoder->fmt_in.video.i_width;
1952             i_height = id->p_encoder->fmt_in.video.i_height;
1953
1954             while( p_subpic != NULL )
1955             {
1956                 subpicture_region_t *p_region = p_subpic->p_region;
1957
1958                 while( p_region && p_sys->p_filter_blend &&
1959                        p_sys->p_filter_blend->pf_video_blend )
1960                 {
1961                     int i_x_offset = p_region->i_x + p_subpic->i_x;
1962                     int i_y_offset = p_region->i_y + p_subpic->i_y;
1963
1964                     if( p_subpic->i_flags & OSD_ALIGN_BOTTOM )
1965                     {
1966                         i_y_offset = i_height - p_region->fmt.i_height -
1967                             p_subpic->i_y;
1968                     }
1969                     else if ( !(p_subpic->i_flags & OSD_ALIGN_TOP) )
1970                     {
1971                         i_y_offset = i_height / 2 - p_region->fmt.i_height / 2;
1972                     }
1973
1974                     if( p_subpic->i_flags & OSD_ALIGN_RIGHT )
1975                     {
1976                         i_x_offset = i_width - p_region->fmt.i_width -
1977                             p_subpic->i_x;
1978                     }
1979                     else if ( !(p_subpic->i_flags & OSD_ALIGN_LEFT) )
1980                     {
1981                         i_x_offset = i_width / 2 - p_region->fmt.i_width / 2;
1982                     }
1983
1984                     if( p_subpic->b_absolute )
1985                     {
1986                         i_x_offset = p_region->i_x + p_subpic->i_x;
1987                         i_y_offset = p_region->i_y + p_subpic->i_y;
1988                     }
1989
1990                     p_sys->p_filter_blend->fmt_in.video = p_region->fmt;
1991
1992                     p_sys->p_filter_blend->pf_video_blend(
1993                          p_sys->p_filter_blend, p_pic, p_pic,
1994                          &p_region->picture, i_x_offset, i_y_offset );
1995
1996                     p_region = p_region->p_next;
1997                 }
1998
1999                 p_subpic = p_subpic->p_next;
2000             }
2001         }
2002
2003         if ( p_sys->i_threads >= 1 )
2004         {
2005             vlc_mutex_lock( &p_sys->lock_out );
2006             p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2007             p_sys->i_last_pic %= PICTURE_RING_SIZE;
2008             *out = p_sys->p_buffers;
2009             p_sys->p_buffers = NULL;
2010             vlc_cond_signal( &p_sys->cond );
2011             vlc_mutex_unlock( &p_sys->lock_out );
2012         }
2013         else
2014         {
2015             block_t *p_block;
2016             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2017             block_ChainAppend( out, p_block );
2018             free( p_pic );
2019         }
2020
2021         if( i_data <= 0 )
2022         {
2023             return VLC_SUCCESS;
2024         }
2025     }
2026
2027     return VLC_SUCCESS;
2028 }
2029
2030 static int EncoderThread( sout_stream_sys_t * p_sys )
2031 {
2032     sout_stream_id_t * id = p_sys->id_video;
2033     picture_t * p_pic;
2034     int i_plane;
2035
2036     while ( !p_sys->b_die && !p_sys->b_error )
2037     {
2038         block_t *p_block;
2039
2040         vlc_mutex_lock( &p_sys->lock_out );
2041         while ( p_sys->i_last_pic == p_sys->i_first_pic )
2042         {
2043             vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2044             if ( p_sys->b_die || p_sys->b_error )
2045                 break;
2046         }
2047         if ( p_sys->b_die || p_sys->b_error )
2048         {
2049             vlc_mutex_unlock( &p_sys->lock_out );
2050             break;
2051         }
2052
2053         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2054         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2055         vlc_mutex_unlock( &p_sys->lock_out );
2056
2057         p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2058         vlc_mutex_lock( &p_sys->lock_out );
2059         block_ChainAppend( &p_sys->p_buffers, p_block );
2060         vlc_mutex_unlock( &p_sys->lock_out );
2061
2062         for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
2063         {
2064             free( p_pic->p[i_plane].p_pixels );
2065         }
2066         free( p_pic );
2067     }
2068
2069     while ( p_sys->i_last_pic != p_sys->i_first_pic )
2070     {
2071         p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2072         p_sys->i_first_pic %= PICTURE_RING_SIZE;
2073
2074         for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
2075         {
2076             free( p_pic->p[i_plane].p_pixels );
2077         }
2078         free( p_pic );
2079     }
2080
2081     block_ChainRelease( p_sys->p_buffers );
2082
2083     return 0;
2084 }
2085
2086 /*****************************************************************************
2087  * transcode_video_ffmpeg_getframebuf:
2088  *
2089  * Callback used by ffmpeg to get a frame buffer.
2090  * We use it to get the right PTS for each decoded picture.
2091  *****************************************************************************/
2092 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
2093                                               AVFrame *p_frame)
2094 {
2095     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
2096
2097     /* Set PTS */
2098     if( p_sys->i_input_pts )
2099     {
2100         p_frame->pts = p_sys->i_input_pts;
2101     }
2102     else if( p_sys->i_input_dts )
2103     {
2104         /* Some demuxers/packetizers only set the dts so let's try to find a
2105          * useful timestamp from this */
2106         if( !p_context->has_b_frames || !p_sys->b_input_has_b_frames ||
2107             !p_frame->reference || !p_sys->i_output_pts )
2108         {
2109             p_frame->pts = p_sys->i_input_dts +
2110             /* Hack: ffmpeg encoding doesn't like frames with identical pts */
2111                 (p_sys->i_output_pts ? 0 : 50000);
2112         }
2113         else p_frame->pts = AV_NOPTS_VALUE;
2114     }
2115     else p_frame->pts = AV_NOPTS_VALUE;
2116
2117     if( p_sys->i_output_pts ) /* make sure 1st frame has a pts > 0 */
2118     {
2119         p_sys->i_input_pts = 0;
2120         p_sys->i_input_dts = 0;
2121     }
2122
2123     return avcodec_default_get_buffer( p_context, p_frame );
2124 }
2125
2126 /*
2127  * SPU
2128  */
2129 static subpicture_t *spu_new_buffer( decoder_t * );
2130 static void spu_del_buffer( decoder_t *, subpicture_t * );
2131
2132 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2133 {
2134     sout_stream_sys_t *p_sys = p_stream->p_sys;
2135
2136     /* Open decoder */
2137     id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
2138
2139     /* Initialization of decoder format structures */
2140     id->p_decoder->fmt_in = id->f_src;
2141     id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2142     id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2143     //id->p_decoder->p_cfg = p_sys->p_spu_cfg;
2144
2145     /* Attach object to parent so object variables inheritance works */
2146     vlc_object_attach( id->p_decoder, p_stream );
2147
2148     id->p_decoder->p_module =
2149         module_Need( id->p_decoder, "decoder", "$codec", VLC_TRUE );
2150
2151     if( !id->p_decoder->p_module )
2152     {
2153         vlc_object_detach( id->p_decoder );
2154         vlc_object_destroy( id->p_decoder );
2155         msg_Err( p_stream, "cannot find decoder" );
2156         return VLC_EGENERIC;
2157     }
2158
2159     if( !p_sys->b_soverlay )
2160     {
2161         /* Open encoder */
2162         id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
2163
2164         /* Initialization of encoder format structures */
2165         es_format_Init( &id->p_encoder->fmt_in,
2166                         id->f_src.i_cat, id->f_src.i_codec );
2167
2168         id->p_encoder->fmt_out = id->p_encoder->fmt_in;
2169         id->p_encoder->fmt_out.i_codec = id->f_dst.i_codec;
2170         id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
2171
2172         id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2173
2174         /* Attach object to parent so object variables inheritance works */
2175         vlc_object_attach( id->p_encoder, p_stream );
2176
2177         id->p_encoder->p_module =
2178             module_Need( id->p_encoder, "encoder", p_sys->psz_senc, VLC_TRUE );
2179
2180         if( !id->p_encoder->p_module )
2181         {
2182             module_Unneed( id->p_decoder, id->p_decoder->p_module );
2183             vlc_object_detach( id->p_decoder );
2184             vlc_object_destroy( id->p_decoder );
2185
2186             vlc_object_detach( id->p_encoder );
2187             vlc_object_destroy( id->p_encoder );
2188             msg_Err( p_stream, "cannot find encoder" );
2189             return VLC_EGENERIC;
2190         }
2191
2192         id->f_dst.i_extra = id->p_encoder->fmt_out.i_extra;
2193         id->f_dst.p_extra = id->p_encoder->fmt_out.p_extra;
2194         id->f_dst.i_codec = id->p_encoder->fmt_out.i_codec;
2195         id->f_dst.subs    = id->p_encoder->fmt_out.subs;
2196     }
2197     else
2198     {
2199         p_sys->p_filter_blend =
2200             vlc_object_create( p_stream, sizeof(filter_t) );
2201         vlc_object_attach( p_sys->p_filter_blend, p_stream );
2202         p_sys->p_filter_blend->fmt_out.video.i_chroma =
2203             VLC_FOURCC('I','4','2','0');
2204         p_sys->p_filter_blend->fmt_in.video.i_chroma =
2205             VLC_FOURCC('Y','U','V','A');
2206         p_sys->p_filter_blend->p_module =
2207             module_Need( p_sys->p_filter_blend, "video blending", 0, 0 );
2208     }
2209
2210     return VLC_SUCCESS;
2211 }
2212
2213 static void transcode_spu_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2214 {
2215     sout_stream_sys_t *p_sys = p_stream->p_sys;
2216     int i;
2217
2218     /* Close decoder */
2219     if( id->p_decoder->p_module )
2220         module_Unneed( id->p_decoder, id->p_decoder->p_module );
2221     vlc_object_detach( id->p_decoder );
2222     vlc_object_destroy( id->p_decoder );
2223
2224     /* Close encoder */
2225     if( id->p_encoder )
2226     {
2227         if( id->p_encoder->p_module )
2228             module_Unneed( id->p_encoder, id->p_encoder->p_module );
2229         vlc_object_detach( id->p_encoder );
2230         vlc_object_destroy( id->p_encoder );
2231     }
2232
2233     /* Free subpictures */
2234     for( i = 0; i < SUBPICTURE_RING_SIZE; i++ )
2235     {
2236         if( !p_sys->pp_subpics[i] ) continue;
2237
2238         spu_del_buffer( id->p_decoder, p_sys->pp_subpics[i] );
2239         p_sys->pp_subpics[i] = NULL;
2240     }
2241 }
2242
2243 static int transcode_spu_process( sout_stream_t *p_stream,
2244                                   sout_stream_id_t *id,
2245                                   block_t *in, block_t **out )
2246 {
2247     sout_stream_sys_t *p_sys = p_stream->p_sys;
2248     subpicture_t *p_subpic;
2249     *out = NULL;
2250
2251     p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2252     if( p_subpic && p_sys->b_soverlay )
2253     {
2254         int i;
2255
2256         /* Find a free slot in our supictures ring buffer */
2257         for( i = 0; i < SUBPICTURE_RING_SIZE; i++ )
2258         {
2259             if( !p_sys->pp_subpics[i] )
2260             {
2261                 p_sys->pp_subpics[i] = p_subpic;
2262                 break;
2263             }
2264         }
2265         if( i == SUBPICTURE_RING_SIZE )
2266         {
2267             spu_del_buffer( id->p_decoder, p_subpic );
2268         }
2269     }
2270
2271     if(  p_subpic && !p_sys->b_soverlay )
2272     {
2273         block_t *p_block;
2274
2275         p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2276         spu_del_buffer( id->p_decoder, p_subpic );
2277
2278         if( p_block )
2279         {
2280             block_ChainAppend( out, p_block );
2281             return VLC_SUCCESS;
2282         }
2283     }
2284
2285     return VLC_EGENERIC;
2286 }
2287
2288 static subpicture_t *transcode_spu_get( sout_stream_t *p_stream,
2289                                         sout_stream_id_t *id,
2290                                         mtime_t display_date )
2291 {
2292     sout_stream_sys_t *p_sys = p_stream->p_sys;
2293     subpicture_t *p_subpic = 0;
2294     subpicture_t *p_ephemer = 0;
2295     subpicture_t **pp_subpic = &p_subpic;
2296     int i;
2297
2298     /* Find current subpictures and remove old ones */
2299     for( i = 0; i < SUBPICTURE_RING_SIZE; i++ )
2300     {
2301         if( !p_sys->pp_subpics[i] ) continue;
2302
2303         if( !p_sys->pp_subpics[i]->b_ephemer &&
2304             p_sys->pp_subpics[i]->i_stop < display_date )
2305         {
2306             spu_del_buffer( id->p_decoder, p_sys->pp_subpics[i] );
2307             p_sys->pp_subpics[i] = NULL;
2308             continue;
2309         }
2310
2311         if( p_sys->pp_subpics[i]->i_start > display_date ) continue;
2312
2313         if( p_sys->pp_subpics[i]->b_ephemer && !p_ephemer )
2314         {
2315             p_ephemer = p_sys->pp_subpics[i];
2316         }
2317         else if( p_sys->pp_subpics[i]->b_ephemer )
2318         {
2319             if( p_ephemer->i_start < p_sys->pp_subpics[i]->i_start )
2320             {
2321                 subpicture_t tmp;
2322                 tmp = *p_ephemer;
2323                 *p_ephemer = *p_sys->pp_subpics[i];
2324                 *p_sys->pp_subpics[i] = tmp;
2325             }
2326
2327             spu_del_buffer( id->p_decoder, p_sys->pp_subpics[i] );
2328             p_sys->pp_subpics[i] = NULL;
2329             continue;
2330         }
2331
2332         /* Add subpicture to the list */
2333         *pp_subpic = p_sys->pp_subpics[i];
2334         pp_subpic = &p_sys->pp_subpics[i]->p_next;
2335     }
2336
2337     return p_subpic;
2338 }
2339
2340 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2341 {
2342     subpicture_t *p_subpic = (subpicture_t *)malloc(sizeof(subpicture_t));
2343     memset( p_subpic, 0, sizeof(subpicture_t) );
2344     p_subpic->b_absolute = VLC_TRUE;
2345
2346     p_subpic->pf_create_region = __spu_CreateRegion;
2347     p_subpic->pf_destroy_region = __spu_DestroyRegion;
2348
2349     return p_subpic;
2350 }
2351
2352 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2353 {
2354     while( p_subpic->p_region )
2355     {
2356         subpicture_region_t *p_region = p_subpic->p_region;
2357         p_subpic->p_region = p_region->p_next;
2358         p_subpic->pf_destroy_region( VLC_OBJECT(p_dec), p_region );
2359     }
2360
2361     free( p_subpic );
2362 }