]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
9b24835a5bd5f62e6293ce4b2a06ebb04f4fe335
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.44 2003/10/27 01:04:38 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@netcourrier.com>
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
37 /* ffmpeg header */
38 #ifdef HAVE_FFMPEG_AVCODEC_H
39 #   include <ffmpeg/avcodec.h>
40 #else
41 #   include <avcodec.h>
42 #endif
43
44 /*****************************************************************************
45  * Exported prototypes
46  *****************************************************************************/
47 static int      Open    ( vlc_object_t * );
48 static void     Close   ( vlc_object_t * );
49
50 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
51 static int               Del ( sout_stream_t *, sout_stream_id_t * );
52 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
53
54 static int  transcode_audio_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
55 static void transcode_audio_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
56 static int  transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
57
58 static int  transcode_video_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
59 static void transcode_video_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
60 static int  transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
61
62 static int  transcode_video_ffmpeg_getframebuf( struct AVCodecContext *, AVFrame *);
63
64 static int pi_channels_maps[6] =
65 {
66     0,
67     AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
68     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
69     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
70      | AOUT_CHAN_REARRIGHT,
71     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
72      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
73 };
74
75 /*****************************************************************************
76  * Module descriptor
77  *****************************************************************************/
78 vlc_module_begin();
79     set_description( _("Transcode stream") );
80     set_capability( "sout stream", 50 );
81     add_shortcut( "transcode" );
82     set_callbacks( Open, Close );
83 vlc_module_end();
84
85 struct sout_stream_sys_t
86 {
87     sout_stream_t   *p_out;
88
89     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
90     int             i_sample_rate;
91     int             i_channels;
92     int             i_abitrate;
93
94     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
95     int             i_vbitrate;
96     int             i_vtolerance;
97     int             i_width;
98     int             i_height;
99     int             i_b_frames;
100     int             i_key_int;
101     int             i_qmin;
102     int             i_qmax;
103     vlc_bool_t      i_hq;
104     vlc_bool_t      b_deinterlace;
105
106     int             i_crop_top;
107     int             i_crop_bottom;
108     int             i_crop_right;
109     int             i_crop_left;
110
111     mtime_t         i_input_pts;
112     mtime_t         i_output_pts;
113 };
114
115 /*****************************************************************************
116  * Open:
117  *****************************************************************************/
118 static int Open( vlc_object_t *p_this )
119 {
120     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
121     sout_stream_sys_t *p_sys;
122     char *codec;
123
124     p_sys = malloc( sizeof( sout_stream_sys_t ) );
125     p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
126
127     p_sys->i_acodec      = 0;
128     p_sys->i_sample_rate = 0;
129     p_sys->i_channels    = 0;
130     p_sys->i_abitrate    = 0;
131
132     p_sys->i_vcodec     = 0;
133     p_sys->i_vbitrate   = 0;
134     p_sys->i_vtolerance = -1;
135     p_sys->i_width      = 0;
136     p_sys->i_height     = 0;
137     p_sys->i_key_int    = -1;
138     p_sys->i_b_frames   = 0;
139     p_sys->i_qmin       = 2;
140     p_sys->i_qmax       = 31;
141 #if LIBAVCODEC_BUILD >= 4673
142     p_sys->i_hq         = FF_MB_DECISION_SIMPLE;
143 #else
144     p_sys->i_hq         = VLC_FALSE;
145 #endif
146     p_sys->b_deinterlace= VLC_FALSE;
147
148     p_sys->i_crop_top   = 0;
149     p_sys->i_crop_bottom= 0;
150     p_sys->i_crop_right = 0;
151     p_sys->i_crop_left  = 0;
152
153     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "acodec" ) ) )
154     {
155         char fcc[4] = "    ";
156         char *val;
157
158         memcpy( fcc, codec, strlen( codec ) );
159
160         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
161
162         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "samplerate" ) ) )
163         {
164             p_sys->i_sample_rate = atoi( val );
165         }
166         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "channels" ) ) )
167         {
168             p_sys->i_channels = atoi( val );
169         }
170         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
171         {
172             p_sys->i_abitrate = atoi( val );
173             if( p_sys->i_abitrate < 4000 )
174             {
175                 p_sys->i_abitrate *= 1000;
176             }
177         }
178
179         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", fcc,
180                  p_sys->i_sample_rate, p_sys->i_channels,
181                  p_sys->i_abitrate / 1024 );
182     }
183
184     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
185     {
186         char fcc[4] = "    ";
187         char *val;
188
189         memcpy( fcc, codec, strlen( codec ) );
190
191         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
192
193         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
194         {
195             p_sys->i_width = atoi( val );
196         }
197         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
198         {
199             p_sys->i_height = atoi( val );
200         }
201         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
202         {
203             p_sys->i_vbitrate = atoi( val );
204             if( p_sys->i_vbitrate < 16000 )
205             {
206                 p_sys->i_vbitrate *= 1000;
207             }
208         }
209         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
210         {
211             p_sys->i_vtolerance = atoi( val );
212         }
213         if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
214         {
215             p_sys->b_deinterlace = VLC_TRUE;
216         }
217         /* crop */
218         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
219         {
220             p_sys->i_crop_top = atoi( val );
221         }
222         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
223         {
224             p_sys->i_crop_bottom = atoi( val );
225         }
226         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
227         {
228             p_sys->i_crop_left = atoi( val );
229         }
230         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
231         {
232             p_sys->i_crop_right = atoi( val );
233         }
234         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
235         {
236             p_sys->i_key_int    = atoi( val );
237         }
238         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "bframes" ) ) )
239         {
240             p_sys->i_b_frames   = atoi( val );
241         }
242 #if LIBAVCODEC_BUILD >= 4673
243         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "hq" ) ) )
244         {
245             if( !strcmp( val, "rd" ) )
246             {
247                 p_sys->i_hq = FF_MB_DECISION_RD;
248             }
249             else if( !strcmp( val, "bits" ) )
250             {
251                 p_sys->i_hq = FF_MB_DECISION_BITS;
252             }
253             else if( !strcmp( val, "simple" ) )
254             {
255                 p_sys->i_hq = FF_MB_DECISION_SIMPLE;
256             }
257             else
258             {
259                 p_sys->i_hq = FF_MB_DECISION_RD;
260             }
261         }
262 #else
263         if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
264         {
265             p_sys->i_hq = VLC_TRUE;
266         }
267 #endif
268         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
269         {
270             p_sys->i_qmin   = atoi( val );
271         }
272         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
273         {
274             p_sys->i_qmax   = atoi( val );
275         }
276
277         msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
278                  fcc,
279                  p_sys->i_width, p_sys->i_height,
280                  p_sys->i_vbitrate / 1024 );
281     }
282
283     if( !p_sys->p_out )
284     {
285         msg_Err( p_stream, "cannot create chain" );
286         free( p_sys );
287         return VLC_EGENERIC;
288     }
289     p_stream->pf_add    = Add;
290     p_stream->pf_del    = Del;
291     p_stream->pf_send   = Send;
292
293     p_stream->p_sys     = p_sys;
294
295     avcodec_init();
296     avcodec_register_all();
297
298     /* ffmpeg needs some padding at the end of each buffer */
299     p_stream->p_sout->i_padding += FF_INPUT_BUFFER_PADDING_SIZE;
300
301     return VLC_SUCCESS;
302 }
303
304 /*****************************************************************************
305  * Close:
306  *****************************************************************************/
307 static void Close( vlc_object_t * p_this )
308 {
309     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
310     sout_stream_sys_t   *p_sys = p_stream->p_sys;
311
312     sout_stream_delete( p_sys->p_out );
313     free( p_sys );
314 }
315
316 struct sout_stream_id_t
317 {
318     vlc_fourcc_t  b_transcode;
319     sout_format_t f_src;        /* only if transcoding */
320     sout_format_t f_dst;        /*  "   "      " */
321     unsigned int  i_inter_pixfmt; /* intermediary format when transcoding */
322
323     /* id of the out stream */
324     void *id;
325
326     /* Encoder */
327     encoder_t       *p_encoder;
328     vlc_fourcc_t    b_enc_inited;
329
330     /* ffmpeg part */
331     AVCodec         *ff_dec;
332     AVCodecContext  *ff_dec_c;
333
334     mtime_t         i_dts;
335     mtime_t         i_length;
336
337     int             i_buffer_in;
338     int             i_buffer_in_pos;
339     uint8_t         *p_buffer_in;
340
341     int             i_buffer;
342     int             i_buffer_pos;
343     uint8_t         *p_buffer;
344
345     AVFrame         *p_ff_pic;
346     AVFrame         *p_ff_pic_tmp0; /* to do deinterlace */
347     AVFrame         *p_ff_pic_tmp1; /* to do pix conversion */
348     AVFrame         *p_ff_pic_tmp2; /* to do resample */
349
350     ImgReSampleContext *p_vresample;
351 };
352
353
354 static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
355 {
356     sout_stream_sys_t   *p_sys = p_stream->p_sys;
357     sout_stream_id_t    *id;
358
359     id = malloc( sizeof( sout_stream_id_t ) );
360     id->i_dts = 0;
361     id->id = NULL;
362     id->p_encoder = NULL;
363
364     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
365     {
366         msg_Dbg( p_stream,
367                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
368                  (char*)&p_fmt->i_fourcc,
369                  (char*)&p_sys->i_acodec );
370
371         /* src format */
372         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
373
374         /* create dst format */
375         id->f_dst.i_cat    = AUDIO_ES;
376         id->f_dst.i_fourcc = p_sys->i_acodec;
377         id->f_dst.i_sample_rate = p_sys->i_sample_rate  > 0 ? p_sys->i_sample_rate : id->f_src.i_sample_rate;
378         id->f_dst.i_channels    = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.i_channels;
379         id->f_dst.i_bitrate     = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
380         id->f_dst.i_block_align = 0;
381         id->f_dst.i_extra_data  = 0;
382         id->f_dst.p_extra_data  = NULL;
383
384         /* build decoder -> filter -> encoder */
385         if( transcode_audio_ffmpeg_new( p_stream, id ) )
386         {
387             msg_Err( p_stream, "cannot create audio chain" );
388             free( id );
389             return NULL;
390         }
391
392         /* open output stream */
393         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
394         id->b_transcode = VLC_TRUE;
395
396         if( id->id == NULL )
397         {
398             free( id );
399             return NULL;
400         }
401     }
402     else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
403     {
404         msg_Dbg( p_stream,
405                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
406                  (char*)&p_fmt->i_fourcc,
407                  (char*)&p_sys->i_vcodec );
408
409         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
410
411         /* create dst format */
412         id->f_dst.i_cat         = VIDEO_ES;
413         id->f_dst.i_fourcc      = p_sys->i_vcodec;
414         id->f_dst.i_width       = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
415         id->f_dst.i_height      = p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
416         id->f_dst.i_bitrate     = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
417         id->f_dst.i_extra_data  = 0;
418         id->f_dst.p_extra_data  = NULL;
419
420         /* build decoder -> filter -> encoder */
421         if( transcode_video_ffmpeg_new( p_stream, id ) )
422         {
423             msg_Err( p_stream, "cannot create video chain" );
424             free( id );
425             return NULL;
426         }
427 #if 0
428         /* open output stream */
429         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
430 #endif
431         id->b_transcode = VLC_TRUE;
432     }
433     else
434     {
435         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_fourcc );
436         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
437         id->b_transcode = VLC_FALSE;
438
439         if( id->id == NULL )
440         {
441             free( id );
442             return NULL;
443         }
444     }
445
446     return id;
447 }
448
449 static int     Del      ( sout_stream_t *p_stream, sout_stream_id_t *id )
450 {
451     sout_stream_sys_t   *p_sys = p_stream->p_sys;
452
453     if( id->b_transcode )
454     {
455         if( id->f_src.i_cat == AUDIO_ES )
456         {
457             transcode_audio_ffmpeg_close( p_stream, id );
458         }
459         else if( id->f_src.i_cat == VIDEO_ES )
460         {
461             transcode_video_ffmpeg_close( p_stream, id );
462         }
463     }
464
465     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
466     free( id );
467
468     return VLC_SUCCESS;
469 }
470
471 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
472                  sout_buffer_t *p_buffer )
473 {
474     sout_stream_sys_t   *p_sys = p_stream->p_sys;
475
476     if( id->b_transcode )
477     {
478         sout_buffer_t *p_buffer_out;
479         if( id->f_src.i_cat == AUDIO_ES )
480         {
481             transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
482         }
483         else if( id->f_src.i_cat == VIDEO_ES )
484         {
485             transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
486         }
487         sout_BufferDelete( p_stream->p_sout, p_buffer );
488
489         if( p_buffer_out )
490         {
491             return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
492         }
493         return VLC_SUCCESS;
494     }
495     else if( id->id != NULL )
496     {
497         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
498     }
499     else
500     {
501         sout_BufferDelete( p_stream->p_sout, p_buffer );
502         return VLC_EGENERIC;
503     }
504 }
505
506 /****************************************************************************
507  * ffmpeg decoder reencocdr part
508  ****************************************************************************/
509
510 static struct
511 {
512     vlc_fourcc_t i_fcc;
513     int          i_ff_codec;
514 } fourcc_to_ff_code[] =
515 {
516     /* audio */
517     { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
518     { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
519     { VLC_FOURCC( 'm', 'p', '4', 'a' ), CODEC_ID_AAC },
520     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
521     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
522     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
523     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
524     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
525     { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
526
527     /* video */
528     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
529     { VLC_FOURCC( 'm', 'p', '1', 'v' ), CODEC_ID_MPEG1VIDEO },
530 #if LIBAVCODEC_BUILD >= 4676
531     { VLC_FOURCC( 'm', 'p', '2', 'v' ), CODEC_ID_MPEG2VIDEO },
532 #endif
533     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
534     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
535     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
536     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
537     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
538     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
539     { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
540     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
541     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
542     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
543     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
544     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
545     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
546 #if LIBAVCODEC_BUILD >= 4666
547     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
548 #endif
549
550     /* raw video code, only used for 'encoding' */
551     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
552     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
553     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
554     { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
555     { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
556     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
557     { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
558     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
559
560     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
561 };
562
563 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
564 {
565     int i;
566
567     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
568     {
569         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
570         {
571             return fourcc_to_ff_code[i].i_ff_codec;
572         }
573     }
574
575     return 0;
576 }
577
578 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
579 {
580     switch( i_chroma )
581     {
582         case VLC_FOURCC( 'I', '4', '2', '0' ):
583             return PIX_FMT_YUV420P;
584         case VLC_FOURCC( 'I', '4', '2', '2' ):
585             return PIX_FMT_YUV422P;
586         case VLC_FOURCC( 'I', '4', '4', '4' ):
587             return PIX_FMT_YUV444P;
588         case VLC_FOURCC( 'R', 'V', '1', '5' ):
589             return PIX_FMT_RGB555;
590         case VLC_FOURCC( 'R', 'V', '1', '6' ):
591             return PIX_FMT_RGB565;
592         case VLC_FOURCC( 'R', 'V', '2', '4' ):
593             return PIX_FMT_RGB24;
594         case VLC_FOURCC( 'R', 'V', '3', '2' ):
595             return PIX_FMT_RGBA32;
596         case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
597             return PIX_FMT_GRAY8;
598         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
599             return PIX_FMT_YUV422;
600         default:
601             return 0;
602     }
603 }
604
605 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
606                                        sout_stream_id_t *id )
607 {
608     int i_ff_codec;
609
610     if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
611         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
612         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
613         id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
614     {
615         id->ff_dec = NULL;
616
617         id->ff_dec_c = avcodec_alloc_context();
618         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
619         id->ff_dec_c->channels    = id->f_src.i_channels;
620         id->ff_dec_c->block_align = id->f_src.i_block_align;
621         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
622     }
623     else
624     {
625         /* find decoder */
626         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
627         if( i_ff_codec == 0 )
628         {
629             msg_Err( p_stream, "cannot find decoder id" );
630             return VLC_EGENERIC;
631         }
632
633         id->ff_dec = avcodec_find_decoder( i_ff_codec );
634         if( !id->ff_dec )
635         {
636             msg_Err( p_stream, "cannot find decoder (avcodec)" );
637             return VLC_EGENERIC;
638         }
639
640         id->ff_dec_c = avcodec_alloc_context();
641         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
642         id->ff_dec_c->channels    = id->f_src.i_channels;
643         id->ff_dec_c->block_align = id->f_src.i_block_align;
644         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
645
646         id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
647         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
648         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
649         {
650             msg_Err( p_stream, "cannot open decoder" );
651             return VLC_EGENERIC;
652         }
653     }
654
655     id->i_buffer_in      = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
656     id->i_buffer_in_pos = 0;
657     id->p_buffer_in      = malloc( id->i_buffer_in );
658
659     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
660     id->i_buffer_pos = 0;
661     id->p_buffer     = malloc( id->i_buffer );
662
663     /* Sanity check for audio channels */
664     id->f_dst.i_channels = __MIN( id->f_dst.i_channels, id->f_src.i_channels );
665
666     /* find encoder */
667     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
668     id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
669     id->p_encoder->format.audio.i_format = AOUT_FMT_S16_NE;
670     id->p_encoder->format.audio.i_rate = id->f_dst.i_sample_rate;
671     id->p_encoder->format.audio.i_physical_channels =
672         id->p_encoder->format.audio.i_original_channels =
673             pi_channels_maps[id->f_dst.i_channels];
674     id->p_encoder->i_bitrate = id->f_dst.i_bitrate;
675     id->p_encoder->i_extra_data = 0;
676     id->p_encoder->p_extra_data = NULL;
677
678     id->p_encoder->p_module =
679         module_Need( id->p_encoder, "audio encoder", NULL );
680     if( !id->p_encoder->p_module )
681     {
682         vlc_object_destroy( id->p_encoder );
683         id->p_encoder = NULL;
684     }
685
686     id->b_enc_inited = VLC_FALSE;
687
688     id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
689     id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
690
691     return VLC_SUCCESS;
692 }
693
694 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
695                                           sout_stream_id_t *id )
696 {
697     if( id->ff_dec )
698     {
699         avcodec_close( id->ff_dec_c );
700         free( id->ff_dec_c );
701     }
702
703     module_Unneed( id->p_encoder, id->p_encoder->p_module );
704     vlc_object_destroy( id->p_encoder );
705
706     free( id->p_buffer_in );
707     free( id->p_buffer );
708 }
709
710 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
711                                            sout_stream_id_t *id,
712                                            sout_buffer_t *in,
713                                            sout_buffer_t **out )
714 {
715     vlc_bool_t b_again = VLC_FALSE;
716     aout_buffer_t aout_buf;
717     block_t *p_block;
718     *out = NULL;
719
720     /* gather data into p_buffer_in */
721     id->i_dts = in->i_dts -
722                 (mtime_t)1000000 *
723                 (mtime_t)(id->i_buffer_pos / 2 / id->ff_dec_c->channels )/
724                 (mtime_t)id->ff_dec_c->sample_rate;
725
726     if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
727     {
728         /* extend buffer_in */
729         id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
730         id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
731     }
732     memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
733             in->p_buffer, in->i_size );
734     id->i_buffer_in_pos += in->i_size;
735
736     do
737     {
738         /* decode as much data as possible */
739         if( id->ff_dec )
740         {
741             for( ;; )
742             {
743                 int i_buffer_size;
744                 int i_used;
745
746                 i_used = avcodec_decode_audio( id->ff_dec_c,
747                          (int16_t*)&id->p_buffer,
748                          &i_buffer_size, id->p_buffer_in,
749                          id->i_buffer_in_pos );
750
751 #if 0
752                 msg_Warn( p_stream, "avcodec_decode_audio: %d used on %d",
753                           i_used, id->i_buffer_in_pos );
754 #endif
755
756                 id->i_buffer_pos += i_buffer_size;
757
758                 if( i_used < 0 )
759                 {
760                     msg_Warn( p_stream, "error audio decoding");
761                     id->i_buffer_in_pos = 0;
762                     break;
763                 }
764                 else if( i_used < id->i_buffer_in_pos )
765                 {
766                     memmove( id->p_buffer_in,
767                              &id->p_buffer_in[i_used],
768                              id->i_buffer_in - i_used );
769                     id->i_buffer_in_pos -= i_used;
770                 }
771                 else
772                 {
773                     id->i_buffer_in_pos = 0;
774                     break;
775                 }
776
777                 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
778                 {
779                     /* buffer full */
780                     b_again = VLC_TRUE;
781                     break;
782                 }
783             }
784         }
785         else
786         {
787             int16_t *sout  = (int16_t*)&id->p_buffer[id->i_buffer_pos];
788             int     i_used = 0;
789
790             if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
791             {
792                 int8_t *sin = (int8_t*)id->p_buffer_in;
793                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
794                                            / 2, id->i_buffer_in_pos );
795                 i_used = i_samples;
796                 while( i_samples > 0 )
797                 {
798                     *sout++ = ( *sin++ ) << 8;
799                     i_samples--;
800                 }
801             }
802             else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
803             {
804                 int8_t *sin = (int8_t*)id->p_buffer_in;
805                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
806                                            / 2, id->i_buffer_in_pos );
807                 i_used = i_samples;
808                 while( i_samples > 0 )
809                 {
810                     *sout++ = ( *sin++ - 128 ) << 8;
811                     i_samples--;
812                 }
813             }
814             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
815             {
816                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
817                                            / 2, id->i_buffer_in_pos / 2);
818 #ifdef WORDS_BIGENDIAN
819                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
820                 i_used = i_samples * 2;
821                 while( i_samples > 0 )
822                 {
823                     uint8_t tmp[2];
824
825                     tmp[1] = *sin++;
826                     tmp[0] = *sin++;
827                     *sout++ = *(int16_t*)tmp;
828                     i_samples--;
829                 }
830
831 #else
832                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
833                 sout += i_samples;
834                 i_used = i_samples * 2;
835 #endif
836             }
837             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
838             {
839                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
840                                            / 2, id->i_buffer_in_pos / 2);
841 #ifdef WORDS_BIGENDIAN
842                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
843                 sout += i_samples;
844                 i_used = i_samples * 2;
845 #else
846                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
847                 i_used = i_samples * 2;
848                 while( i_samples > 0 )
849                 {
850                     uint8_t tmp[2];
851
852                     tmp[1] = *sin++;
853                     tmp[0] = *sin++;
854                     *sout++ = *(int16_t*)tmp;
855                     i_samples--;
856                 }
857 #endif
858             }
859
860             id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
861             if( i_used < id->i_buffer_in_pos )
862             {
863                 memmove( id->p_buffer_in,
864                          &id->p_buffer_in[i_used],
865                          id->i_buffer_in - i_used );
866             }
867             id->i_buffer_in_pos -= i_used;
868         }
869
870         if( id->i_buffer_pos == 0 ) continue;
871
872         /* Encode as much data as possible */
873         if( id->b_enc_inited )
874         {
875             while( id->p_encoder->pf_header &&
876                    (p_block = id->p_encoder->pf_header( id->p_encoder )) )
877             {
878                 sout_buffer_t *p_out;
879                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
880                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
881                 p_out->i_dts = in->i_dts;
882                 p_out->i_pts = in->i_dts;
883                 sout_BufferChain( out, p_out );
884             }
885
886             id->b_enc_inited = VLC_TRUE;
887         }
888
889         aout_buf.p_buffer = id->p_buffer;
890         aout_buf.i_nb_bytes = id->i_buffer_pos;
891         aout_buf.i_nb_samples = id->i_buffer_pos / 2 / id->ff_dec_c->channels;
892         aout_buf.start_date = id->i_dts;
893         aout_buf.end_date = id->i_dts;
894
895         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf );
896         while( p_block )
897         {
898             sout_buffer_t *p_out;
899             block_t *p_prev_block = p_block;
900
901             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
902             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
903             p_out->i_dts = p_block->i_dts;
904             p_out->i_pts = p_block->i_pts;
905             p_out->i_length = p_block->i_length;
906             sout_BufferChain( out, p_out );
907
908             p_block = p_block->p_next;
909             block_Release( p_prev_block );
910         }
911         id->i_buffer_pos = 0;
912
913     } while( b_again );
914
915     return VLC_SUCCESS;
916 }
917
918
919 /*
920  * video
921  */
922 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
923                                        sout_stream_id_t *id )
924 {
925     sout_stream_sys_t   *p_sys = p_stream->p_sys;
926
927     int i_ff_codec;
928
929     /* Open decoder */
930     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
931         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
932         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
933         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
934         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
935         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
936         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
937         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
938         id->f_src.i_fourcc == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
939     {
940         id->ff_dec              = NULL;
941         id->ff_dec_c            = avcodec_alloc_context();
942         id->ff_dec_c->width     = id->f_src.i_width;
943         id->ff_dec_c->height    = id->f_src.i_height;
944         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
945     }
946     else
947     {
948         /* find decoder */
949         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
950         if( i_ff_codec == 0 )
951         {
952             msg_Err( p_stream, "cannot find decoder" );
953             return VLC_EGENERIC;
954         }
955
956         id->ff_dec = avcodec_find_decoder( i_ff_codec );
957         if( !id->ff_dec )
958         {
959             msg_Err( p_stream, "cannot find decoder" );
960             return VLC_EGENERIC;
961         }
962
963         id->ff_dec_c = avcodec_alloc_context();
964         id->ff_dec_c->width         = id->f_src.i_width;
965         id->ff_dec_c->height        = id->f_src.i_height;
966         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
967         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
968         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
969         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
970         id->ff_dec_c->error_resilience= -1;
971         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
972         id->ff_dec_c->opaque        = p_sys;
973
974         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
975         {
976             msg_Err( p_stream, "cannot open decoder" );
977             return VLC_EGENERIC;
978         }
979
980         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
981         {
982             int b_gotpicture;
983             AVFrame frame;
984             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
985                                      FF_INPUT_BUFFER_PADDING_SIZE );
986
987             memcpy( p_vol, id->ff_dec_c->extradata,
988                     id->ff_dec_c->extradata_size );
989             memset( p_vol + id->ff_dec_c->extradata_size, 0,
990                     FF_INPUT_BUFFER_PADDING_SIZE );
991
992             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
993                                   id->ff_dec_c->extradata,
994                                   id->ff_dec_c->extradata_size );
995             free( p_vol );
996         }
997     }
998
999     /* Open encoder */
1000     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
1001     id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
1002     id->p_encoder->format.video.i_width = p_sys->i_width;
1003     id->p_encoder->format.video.i_height = p_sys->i_height;
1004     id->p_encoder->i_bitrate = p_sys->i_vbitrate;
1005
1006     id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
1007     id->p_encoder->i_key_int = p_sys->i_key_int;
1008     id->p_encoder->i_b_frames = p_sys->i_b_frames;
1009     id->p_encoder->i_qmin = p_sys->i_qmin;
1010     id->p_encoder->i_qmax = p_sys->i_qmax;
1011     id->p_encoder->i_hq = p_sys->i_hq;
1012
1013     if( id->p_encoder->format.video.i_width <= 0 )
1014     {
1015         id->p_encoder->format.video.i_width = id->f_dst.i_width =
1016             id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1017     }
1018     if( id->p_encoder->format.video.i_height <= 0 )
1019     {
1020         id->p_encoder->format.video.i_height = id->f_dst.i_height =
1021             id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1022     }
1023
1024     id->p_ff_pic         = avcodec_alloc_frame();
1025     id->p_ff_pic_tmp0    = NULL;
1026     id->p_ff_pic_tmp1    = NULL;
1027     id->p_ff_pic_tmp2    = NULL;
1028     id->p_vresample      = NULL;
1029
1030     if( id->ff_dec )
1031     {
1032         id->p_encoder->i_frame_rate = id->ff_dec_c->frame_rate;
1033 #if LIBAVCODEC_BUILD >= 4662
1034         id->p_encoder->i_frame_rate_base= id->ff_dec_c->frame_rate_base;
1035 #endif
1036     }
1037     else
1038     {
1039 #if LIBAVCODEC_BUILD >= 4662
1040         id->p_encoder->i_frame_rate     = 25 ; /* FIXME as it break mpeg */
1041         id->p_encoder->i_frame_rate_base= 1;
1042 #else
1043         id->p_encoder->i_frame_rate     = 25 * FRAME_RATE_BASE;
1044 #endif
1045     }
1046
1047     id->p_encoder->p_module =
1048         module_Need( id->p_encoder, "video encoder", NULL );
1049
1050     if( !id->p_encoder->p_module )
1051     {
1052         vlc_object_destroy( id->p_encoder );
1053         msg_Err( p_stream, "cannot find encoder" );
1054         return VLC_EGENERIC;
1055     }
1056
1057     /* Close the encoder.
1058      * We'll open it only when we have the first frame */
1059     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1060
1061     id->b_enc_inited = VLC_FALSE;
1062
1063     return VLC_SUCCESS;
1064 }
1065
1066 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream,
1067                                            sout_stream_id_t *id )
1068 {
1069     /* Close decoder */
1070     if( id->ff_dec )
1071     {
1072         avcodec_close( id->ff_dec_c );
1073         free( id->ff_dec_c );
1074     }
1075
1076     /* Close encoder */
1077     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1078     vlc_object_destroy( id->p_encoder );
1079
1080     /* Misc cleanup */
1081     if( id->p_ff_pic)
1082     {
1083         free( id->p_ff_pic );
1084     }
1085
1086     if( id->p_ff_pic_tmp0 )
1087     {
1088         free( id->p_ff_pic_tmp0->data[0] );
1089         free( id->p_ff_pic_tmp0 );
1090     }
1091     if( id->p_ff_pic_tmp1)
1092     {
1093         free( id->p_ff_pic_tmp1->data[0] );
1094         free( id->p_ff_pic_tmp1 );
1095     }
1096     if( id->p_ff_pic_tmp2)
1097     {
1098         free( id->p_ff_pic_tmp2->data[0] );
1099         free( id->p_ff_pic_tmp2 );
1100     }
1101     if( id->p_vresample )
1102     {
1103         free( id->p_vresample );
1104     }
1105 }
1106
1107 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1108                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1109 {
1110     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1111     int     i_used;
1112     int     b_gotpicture;
1113     AVFrame *frame;
1114
1115     int     i_data;
1116     uint8_t *p_data;
1117
1118     *out = NULL;
1119
1120     i_data = in->i_size;
1121     p_data = in->p_buffer;
1122
1123     for( ;; )
1124     {
1125         /* decode frame */
1126         frame = id->p_ff_pic;
1127         p_sys->i_input_pts = in->i_pts;
1128         if( id->ff_dec )
1129         {
1130             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1131                                            &b_gotpicture,
1132                                            p_data, i_data );
1133         }
1134         else
1135         {
1136             /* raw video */
1137             avpicture_fill( (AVPicture*)frame,
1138                             p_data,
1139                             id->ff_dec_c->pix_fmt,
1140                             id->ff_dec_c->width, id->ff_dec_c->height );
1141             i_used = i_data;
1142             b_gotpicture = 1;
1143
1144             /* Set PTS */
1145             frame->pts = p_sys->i_input_pts;
1146         }
1147
1148         if( i_used < 0 )
1149         {
1150             msg_Warn( p_stream, "error");
1151             return VLC_EGENERIC;
1152         }
1153         i_data -= i_used;
1154         p_data += i_used;
1155
1156         if( !b_gotpicture )
1157         {
1158             return VLC_SUCCESS;
1159         }
1160
1161         /* Get the pts of the decoded frame if any, otherwise keep the
1162          * interpolated one */
1163         if( frame->pts > 0 )
1164         {
1165             p_sys->i_output_pts = frame->pts;
1166         }
1167
1168         if( !id->b_enc_inited )
1169         {
1170             block_t *p_block;
1171
1172             /* XXX hack because of copy packetizer and mpeg4video that can fail
1173              * detecting size */
1174             if( id->p_encoder->format.video.i_width <= 0 )
1175             {
1176                 id->p_encoder->format.video.i_width = id->f_dst.i_width =
1177                     id->ff_dec_c->width - p_sys->i_crop_left -
1178                     p_sys->i_crop_right;
1179             }
1180             if( id->p_encoder->format.video.i_height <= 0 )
1181             {
1182                 id->p_encoder->format.video.i_height = id->f_dst.i_height =
1183                     id->ff_dec_c->height - p_sys->i_crop_top -
1184                     p_sys->i_crop_bottom;
1185             }
1186
1187             id->p_encoder->i_bitrate = p_sys->i_vbitrate;
1188
1189             id->p_encoder->i_extra_data = 0;
1190             id->p_encoder->p_extra_data = NULL;
1191
1192             id->p_encoder->p_module =
1193                 module_Need( id->p_encoder, "video encoder", NULL );
1194             if( !id->p_encoder->p_module )
1195             {
1196                 vlc_object_destroy( id->p_encoder );
1197                 msg_Err( p_stream, "cannot find encoder" );
1198                 return VLC_EGENERIC;
1199             }
1200
1201             id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
1202             id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
1203
1204             if( !( id->id =
1205                      p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1206                                                      &id->f_dst ) ) )
1207             {
1208                 msg_Err( p_stream, "cannot add this stream" );
1209                 transcode_video_ffmpeg_close( p_stream, id );
1210                 id->b_transcode = VLC_FALSE;
1211                 return VLC_EGENERIC;
1212             }
1213
1214             while( id->p_encoder->pf_header &&
1215                    (p_block = id->p_encoder->pf_header( id->p_encoder )) )
1216             {
1217                 sout_buffer_t *p_out;
1218                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1219                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1220                 p_out->i_dts = in->i_dts;
1221                 p_out->i_pts = in->i_dts;
1222                 sout_BufferChain( out, p_out );
1223             }
1224
1225             id->i_inter_pixfmt =
1226                 get_ff_chroma( id->p_encoder->format.video.i_chroma );
1227
1228             id->b_enc_inited = VLC_TRUE;
1229         }
1230
1231         /* deinterlace */
1232         if( p_stream->p_sys->b_deinterlace )
1233         {
1234             if( id->p_ff_pic_tmp0 == NULL )
1235             {
1236                 int     i_size;
1237                 uint8_t *buf;
1238                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1239                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1240                                              id->ff_dec_c->width, id->ff_dec_c->height );
1241
1242                 buf = malloc( i_size );
1243
1244                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1245                                 id->i_inter_pixfmt,
1246                                 id->ff_dec_c->width, id->ff_dec_c->height );
1247             }
1248
1249             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1250                                    id->ff_dec_c->pix_fmt,
1251                                    id->ff_dec_c->width, id->ff_dec_c->height );
1252
1253             frame = id->p_ff_pic_tmp0;
1254         }
1255
1256         /* convert pix format */
1257         if( id->ff_dec_c->pix_fmt != id->i_inter_pixfmt )
1258         {
1259             if( id->p_ff_pic_tmp1 == NULL )
1260             {
1261                 int     i_size;
1262                 uint8_t *buf;
1263                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1264                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1265                                              id->ff_dec_c->width,
1266                                              id->ff_dec_c->height );
1267
1268                 buf = malloc( i_size );
1269
1270                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1271                                 id->i_inter_pixfmt,
1272                                 id->ff_dec_c->width, id->ff_dec_c->height );
1273             }
1274
1275             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->i_inter_pixfmt,
1276                          (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1277                          id->ff_dec_c->width, id->ff_dec_c->height );
1278
1279             frame = id->p_ff_pic_tmp1;
1280         }
1281
1282         /* convert size and crop */
1283         if( id->ff_dec_c->width  != id->f_dst.i_width ||
1284             id->ff_dec_c->height != id->f_dst.i_height ||
1285             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1286             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1287         {
1288             if( id->p_ff_pic_tmp2 == NULL )
1289             {
1290                 int     i_size;
1291                 uint8_t *buf;
1292                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1293                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1294                                              id->f_dst.i_width,
1295                                              id->f_dst.i_height );
1296
1297                 buf = malloc( i_size );
1298
1299                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1300                                 id->i_inter_pixfmt,
1301                                 id->f_dst.i_width, id->f_dst.i_height );
1302
1303                 id->p_vresample =
1304                     img_resample_full_init( id->f_dst.i_width,
1305                                             id->f_dst.i_height,
1306                                             id->ff_dec_c->width, id->ff_dec_c->height,
1307                                             p_stream->p_sys->i_crop_top,
1308                                             p_stream->p_sys->i_crop_bottom,
1309                                             p_stream->p_sys->i_crop_left,
1310                                             p_stream->p_sys->i_crop_right );
1311             }
1312
1313             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1314                           (AVPicture*)frame );
1315
1316             frame = id->p_ff_pic_tmp2;
1317         }
1318
1319         /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
1320         if( id->p_encoder ||
1321             id->f_dst.i_fourcc == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
1322             frame->pts = p_sys->i_output_pts;
1323         else
1324             frame->pts = 0;
1325
1326         /* Interpolate the next PTS
1327          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1328         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1329         {
1330             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1331               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1332         }
1333
1334         /* Encoding */
1335         block_t *p_block;
1336         picture_t pic;
1337         int i_plane;
1338
1339         vout_InitPicture( VLC_OBJECT(p_stream), &pic,
1340                           id->p_encoder->format.video.i_chroma,
1341                           id->f_dst.i_width, id->f_dst.i_height,
1342                           id->f_dst.i_width * VOUT_ASPECT_FACTOR /
1343                           id->f_dst.i_height );
1344
1345         for( i_plane = 0; i_plane < pic.i_planes; i_plane++ )
1346         {
1347             pic.p[i_plane].p_pixels = frame->data[i_plane];
1348             pic.p[i_plane].i_pitch = frame->linesize[i_plane];
1349         }
1350
1351         pic.date = frame->pts;
1352
1353         p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic );
1354         while( p_block )
1355         {
1356             sout_buffer_t *p_out;
1357             block_t *p_prev_block = p_block;
1358
1359             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1360             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1361             p_out->i_dts = p_block->i_dts;
1362             p_out->i_pts = p_block->i_pts;
1363             p_out->i_length = p_block->i_length;
1364             sout_BufferChain( out, p_out );
1365
1366             p_block = p_block->p_next;
1367             block_Release( p_prev_block );
1368         }
1369
1370         if( i_data <= 0 )
1371         {
1372             return VLC_SUCCESS;
1373         }
1374     }
1375
1376     return VLC_SUCCESS;
1377 }
1378
1379 /*****************************************************************************
1380  * transcode_video_ffmpeg_getframebuf:
1381  *
1382  * Callback used by ffmpeg to get a frame buffer.
1383  * We use it to get the right PTS for each decoded picture.
1384  *****************************************************************************/
1385 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1386                                               AVFrame *p_frame)
1387 {
1388     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1389
1390     /* Set PTS */
1391     p_frame->pts = p_sys->i_input_pts;
1392
1393     return avcodec_default_get_buffer( p_context, p_frame );
1394 }