]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
12bcd1db0c31dd788314fc01f36d17c6c7ceac0b
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.54 2003/11/27 10:34:51 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 *, es_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, __MIN( strlen( codec ), 4 ) );
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, __MIN( strlen( codec ), 4 ) );
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     es_format_t f_src;        /* only if transcoding */
320     es_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;
338     int             i_buffer_pos;
339     uint8_t         *p_buffer;
340
341     AVFrame         *p_ff_pic;
342     AVFrame         *p_ff_pic_tmp0; /* to do deinterlace */
343     AVFrame         *p_ff_pic_tmp1; /* to do pix conversion */
344     AVFrame         *p_ff_pic_tmp2; /* to do resample */
345
346     ImgReSampleContext *p_vresample;
347 };
348
349
350 static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
351 {
352     sout_stream_sys_t   *p_sys = p_stream->p_sys;
353     sout_stream_id_t    *id;
354
355     id = malloc( sizeof( sout_stream_id_t ) );
356     id->i_dts = 0;
357     id->id = NULL;
358     id->p_encoder = NULL;
359
360     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
361     {
362         msg_Dbg( p_stream,
363                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
364                  (char*)&p_fmt->i_codec,
365                  (char*)&p_sys->i_acodec );
366
367         /* src format */
368         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
369
370         /* create dst format */
371         id->f_dst.i_cat    = AUDIO_ES;
372         id->f_dst.i_codec = p_sys->i_acodec;
373         id->f_dst.audio.i_rate = p_sys->i_sample_rate  > 0 ? p_sys->i_sample_rate : id->f_src.audio.i_rate;
374         id->f_dst.audio.i_channels    = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.audio.i_channels;
375         id->f_dst.i_bitrate     = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
376         id->f_dst.audio.i_blockalign = 0;
377         id->f_dst.i_extra  = 0;
378         id->f_dst.p_extra  = NULL;
379
380         /* build decoder -> filter -> encoder */
381         if( transcode_audio_ffmpeg_new( p_stream, id ) )
382         {
383             msg_Err( p_stream, "cannot create audio chain" );
384             free( id );
385             return NULL;
386         }
387
388         /* open output stream */
389         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
390         id->b_transcode = VLC_TRUE;
391
392         if( id->id == NULL )
393         {
394             free( id );
395             return NULL;
396         }
397     }
398     else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
399     {
400         msg_Dbg( p_stream,
401                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
402                  (char*)&p_fmt->i_codec,
403                  (char*)&p_sys->i_vcodec );
404
405         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
406
407         /* create dst format */
408         id->f_dst.i_cat         = VIDEO_ES;
409         id->f_dst.i_codec       = p_sys->i_vcodec;
410         id->f_dst.video.i_width = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
411         id->f_dst.video.i_height= p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
412         id->f_dst.i_bitrate     = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
413         id->f_dst.i_extra       = 0;
414         id->f_dst.p_extra       = NULL;
415
416         /* build decoder -> filter -> encoder */
417         if( transcode_video_ffmpeg_new( p_stream, id ) )
418         {
419             msg_Err( p_stream, "cannot create video chain" );
420             free( id );
421             return NULL;
422         }
423 #if 0
424         /* open output stream */
425         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
426 #endif
427         id->b_transcode = VLC_TRUE;
428     }
429     else
430     {
431         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_codec );
432         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
433         id->b_transcode = VLC_FALSE;
434
435         if( id->id == NULL )
436         {
437             free( id );
438             return NULL;
439         }
440     }
441
442     return id;
443 }
444
445 static int     Del      ( sout_stream_t *p_stream, sout_stream_id_t *id )
446 {
447     sout_stream_sys_t   *p_sys = p_stream->p_sys;
448
449     if( id->b_transcode )
450     {
451         if( id->f_src.i_cat == AUDIO_ES )
452         {
453             transcode_audio_ffmpeg_close( p_stream, id );
454         }
455         else if( id->f_src.i_cat == VIDEO_ES )
456         {
457             transcode_video_ffmpeg_close( p_stream, id );
458         }
459     }
460
461     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
462     free( id );
463
464     return VLC_SUCCESS;
465 }
466
467 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
468                  sout_buffer_t *p_buffer )
469 {
470     sout_stream_sys_t   *p_sys = p_stream->p_sys;
471
472     if( id->b_transcode )
473     {
474         sout_buffer_t *p_buffer_out;
475         if( id->f_src.i_cat == AUDIO_ES )
476         {
477             transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
478         }
479         else if( id->f_src.i_cat == VIDEO_ES )
480         {
481             transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
482         }
483         sout_BufferDelete( p_stream->p_sout, p_buffer );
484
485         if( p_buffer_out )
486         {
487             return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
488         }
489         return VLC_SUCCESS;
490     }
491     else if( id->id != NULL )
492     {
493         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
494     }
495     else
496     {
497         sout_BufferDelete( p_stream->p_sout, p_buffer );
498         return VLC_EGENERIC;
499     }
500 }
501
502 /****************************************************************************
503  * ffmpeg decoder reencocdr part
504  ****************************************************************************/
505
506 static struct
507 {
508     vlc_fourcc_t i_fcc;
509     int          i_ff_codec;
510 } fourcc_to_ff_code[] =
511 {
512     /* audio */
513     { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
514     { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
515     { VLC_FOURCC( 'm', 'p', '4', 'a' ), CODEC_ID_AAC },
516     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
517     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
518     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
519     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
520     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
521     { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
522
523     /* video */
524     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
525     { VLC_FOURCC( 'm', 'p', '1', 'v' ), CODEC_ID_MPEG1VIDEO },
526 #if LIBAVCODEC_BUILD >= 4676
527     { VLC_FOURCC( 'm', 'p', '2', 'v' ), CODEC_ID_MPEG2VIDEO },
528 #endif
529     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
530     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
531     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
532     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
533     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
534     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
535     { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
536     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
537     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
538     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
539     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
540     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
541     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
542 #if LIBAVCODEC_BUILD >= 4666
543     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
544 #endif
545
546     /* raw video code, only used for 'encoding' */
547     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
548     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
549     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
550     { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
551     { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
552     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
553     { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
554     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
555
556     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
557 };
558
559 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
560 {
561     int i;
562
563     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
564     {
565         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
566         {
567             return fourcc_to_ff_code[i].i_ff_codec;
568         }
569     }
570
571     return 0;
572 }
573
574 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
575 {
576     switch( i_chroma )
577     {
578         case VLC_FOURCC( 'I', '4', '2', '0' ):
579             return PIX_FMT_YUV420P;
580         case VLC_FOURCC( 'I', '4', '2', '2' ):
581             return PIX_FMT_YUV422P;
582         case VLC_FOURCC( 'I', '4', '4', '4' ):
583             return PIX_FMT_YUV444P;
584         case VLC_FOURCC( 'R', 'V', '1', '5' ):
585             return PIX_FMT_RGB555;
586         case VLC_FOURCC( 'R', 'V', '1', '6' ):
587             return PIX_FMT_RGB565;
588         case VLC_FOURCC( 'R', 'V', '2', '4' ):
589             return PIX_FMT_RGB24;
590         case VLC_FOURCC( 'R', 'V', '3', '2' ):
591             return PIX_FMT_RGBA32;
592         case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
593             return PIX_FMT_GRAY8;
594         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
595             return PIX_FMT_YUV422;
596         default:
597             return 0;
598     }
599 }
600
601 static inline vlc_fourcc_t get_vlc_chroma( int i_pix_fmt )
602 {
603     switch( i_pix_fmt )
604     {
605     case PIX_FMT_YUV420P:
606         return VLC_FOURCC('I','4','2','0');
607     case PIX_FMT_YUV422P:
608         return VLC_FOURCC('I','4','2','2');
609     case PIX_FMT_YUV444P:
610         return VLC_FOURCC('I','4','4','4');
611
612     case PIX_FMT_YUV422:
613         return VLC_FOURCC('Y','U','Y','2');
614
615     case PIX_FMT_RGB555:
616         return VLC_FOURCC('R','V','1','5');
617     case PIX_FMT_RGB565:
618         return VLC_FOURCC('R','V','1','6');
619     case PIX_FMT_RGB24:
620         return VLC_FOURCC('R','V','2','4');
621     case PIX_FMT_RGBA32:
622         return VLC_FOURCC('R','V','3','2');
623     case PIX_FMT_GRAY8:
624         return VLC_FOURCC('G','R','E','Y');
625
626     case PIX_FMT_YUV410P:
627     case PIX_FMT_YUV411P:
628     case PIX_FMT_BGR24:
629     default:
630         return 0;
631     }
632 }
633
634 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
635                                        sout_stream_id_t *id )
636 {
637     int i_ff_codec;
638
639     if( id->f_src.i_codec == VLC_FOURCC('s','1','6','l') ||
640         id->f_src.i_codec == VLC_FOURCC('s','1','6','b') ||
641         id->f_src.i_codec == VLC_FOURCC('s','8',' ',' ') ||
642         id->f_src.i_codec == VLC_FOURCC('u','8',' ',' ') )
643     {
644         id->ff_dec = NULL;
645
646         id->ff_dec_c = avcodec_alloc_context();
647         id->ff_dec_c->sample_rate = id->f_src.audio.i_rate;
648         id->ff_dec_c->channels    = id->f_src.audio.i_channels;
649         id->ff_dec_c->block_align = id->f_src.audio.i_blockalign;
650         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
651     }
652     else
653     {
654         /* find decoder */
655         i_ff_codec = get_ff_codec( id->f_src.i_codec );
656         if( i_ff_codec == 0 )
657         {
658             msg_Err( p_stream, "cannot find decoder id" );
659             return VLC_EGENERIC;
660         }
661
662         id->ff_dec = avcodec_find_decoder( i_ff_codec );
663         if( !id->ff_dec )
664         {
665             msg_Err( p_stream, "cannot find decoder (avcodec)" );
666             return VLC_EGENERIC;
667         }
668
669         id->ff_dec_c = avcodec_alloc_context();
670         id->ff_dec_c->sample_rate = id->f_src.audio.i_rate;
671         id->ff_dec_c->channels    = id->f_src.audio.i_channels;
672         id->ff_dec_c->block_align = id->f_src.audio.i_blockalign;
673         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
674
675         id->ff_dec_c->extradata_size = id->f_src.i_extra;
676         id->ff_dec_c->extradata      = id->f_src.p_extra;
677         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
678         {
679             msg_Err( p_stream, "cannot open decoder" );
680             return VLC_EGENERIC;
681         }
682     }
683
684     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
685     id->i_buffer_pos = 0;
686     id->p_buffer     = malloc( id->i_buffer );
687
688     /* Sanity check for audio channels */
689     id->f_dst.audio.i_channels = __MIN( id->f_dst.audio.i_channels, id->f_src.audio.i_channels );
690
691     /* find encoder */
692     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
693
694     /* Initialization of encoder format structures */
695     es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, AOUT_FMT_S16_NE );
696     id->p_encoder->fmt_in.audio.i_format = AOUT_FMT_S16_NE;
697     id->p_encoder->fmt_in.audio.i_rate = id->f_dst.audio.i_rate;
698     id->p_encoder->fmt_in.audio.i_physical_channels =
699         id->p_encoder->fmt_in.audio.i_original_channels =
700             pi_channels_maps[id->f_dst.audio.i_channels];
701     id->p_encoder->fmt_in.audio.i_channels = id->f_dst.audio.i_channels;
702
703     id->p_encoder->fmt_out = id->p_encoder->fmt_in;
704     id->p_encoder->fmt_out.i_codec = id->f_dst.i_codec;
705     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
706
707     id->p_encoder->p_module =
708         module_Need( id->p_encoder, "encoder", NULL );
709     if( !id->p_encoder->p_module )
710     {
711         vlc_object_destroy( id->p_encoder );
712         msg_Err( p_stream, "cannot open encoder" );
713         return VLC_EGENERIC;
714     }
715
716     id->b_enc_inited = VLC_FALSE;
717
718     id->f_dst.i_extra = id->p_encoder->fmt_out.i_extra;
719     id->f_dst.p_extra = id->p_encoder->fmt_out.p_extra;
720
721     /* Hack for mp3 transcoding support */
722     if( id->f_dst.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
723     {
724         id->f_dst.i_codec = VLC_FOURCC( 'm','p','g','a' );
725     }
726
727     return VLC_SUCCESS;
728 }
729
730 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
731                                           sout_stream_id_t *id )
732 {
733     if( id->ff_dec )
734     {
735         avcodec_close( id->ff_dec_c );
736         free( id->ff_dec_c );
737     }
738
739     module_Unneed( id->p_encoder, id->p_encoder->p_module );
740     vlc_object_destroy( id->p_encoder );
741
742     free( id->p_buffer );
743 }
744
745 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
746                                            sout_stream_id_t *id,
747                                            sout_buffer_t *in,
748                                            sout_buffer_t **out )
749 {
750     aout_buffer_t aout_buf;
751     block_t *p_block;
752     int i_buffer = in->i_size;
753     char *p_buffer = in->p_buffer;
754     id->i_dts = in->i_dts;
755     *out = NULL;
756
757     while( i_buffer )
758     {
759         id->i_buffer_pos = 0;
760
761         /* decode as much data as possible */
762         if( id->ff_dec )
763         {
764             int i_used;
765
766             i_used = avcodec_decode_audio( id->ff_dec_c,
767                          (int16_t*)id->p_buffer, &id->i_buffer_pos,
768                          p_buffer, i_buffer );
769
770 #if 0
771             msg_Warn( p_stream, "avcodec_decode_audio: %d used on %d",
772                       i_used, i_buffer );
773 #endif
774             if( i_used < 0 )
775             {
776                 msg_Warn( p_stream, "error audio decoding");
777                 break;
778             }
779
780             i_buffer -= i_used;
781             p_buffer += i_used;
782         }
783         else
784         {
785             int16_t *sout = (int16_t*)id->p_buffer;
786
787             if( id->f_src.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
788                 id->f_src.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
789             {
790                 int8_t *sin = (int8_t*)p_buffer;
791                 int i_used = __MIN( id->i_buffer/2, i_buffer );
792                 int i_samples = i_used;
793
794                 if( id->f_src.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
795                     while( i_samples > 0 )
796                     {
797                         *sout++ = ( *sin++ ) << 8;
798                         i_samples--;
799                     }
800                 else
801                     while( i_samples > 0 )
802                     {
803                         *sout++ = ( *sin++ - 128 ) << 8;
804                         i_samples--;
805                     }
806
807                 i_buffer -= i_used;
808                 p_buffer += i_used;
809                 id->i_buffer_pos = i_used * 2;
810             }
811             else if( id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) ||
812                      id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'b' ) )
813             {
814                 int16_t *sin = (int16_t*)p_buffer;
815                 int i_used = __MIN( id->i_buffer, i_buffer );
816                 int i_samples = i_used / 2;
817                 int b_invert_indianness;
818
819                 if( id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
820 #ifdef WORDS_BIGENDIAN
821                     b_invert_indianness = 1;
822 #else
823                     b_invert_indianness = 0;
824 #endif
825                 else
826 #ifdef WORDS_BIGENDIAN
827                     b_invert_indianness = 0;
828 #else
829                     b_invert_indianness = 1;
830 #endif
831
832                 if( b_invert_indianness )
833                 {
834                     while( i_samples > 0 )
835                     {
836                         uint8_t tmp[2];
837
838                         tmp[1] = *sin++;
839                         tmp[0] = *sin++;
840                         *sout++ = *(int16_t*)tmp;
841                         i_samples--;
842                     }
843                 }
844                 else
845                 {
846                     memcpy( sout, sin, i_used );
847                     sout += i_samples;
848                 }
849
850                 i_buffer -= i_used;
851                 p_buffer += i_used;
852                 id->i_buffer_pos = i_used;
853             }
854         }
855
856         if( id->i_buffer_pos == 0 ) continue;
857
858         /* Encode as much data as possible */
859         if( !id->b_enc_inited && id->p_encoder->pf_header )
860         {
861             p_block = id->p_encoder->pf_header( id->p_encoder );
862             while( p_block )
863             {
864                 sout_buffer_t *p_out;
865                 block_t *p_prev_block = p_block;
866
867                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
868                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
869                 p_out->i_dts = p_out->i_pts = in->i_dts;
870                 p_out->i_length = 0;
871                 sout_BufferChain( out, p_out );
872
873                 p_block = p_block->p_next;
874                 block_Release( p_prev_block );
875             }
876
877             id->b_enc_inited = VLC_TRUE;
878         }
879
880         aout_buf.p_buffer = id->p_buffer;
881         aout_buf.i_nb_bytes = id->i_buffer_pos;
882         aout_buf.i_nb_samples = id->i_buffer_pos / 2 / id->f_src.audio.i_channels;
883         aout_buf.start_date = id->i_dts;
884         aout_buf.end_date = id->i_dts;
885
886         id->i_dts += ( I64C(1000000) * id->i_buffer_pos / 2 /
887             id->f_src.audio.i_channels / id->f_src.audio.i_rate );
888
889         if( id->f_src.audio.i_channels !=
890             id->p_encoder->fmt_in.audio.i_channels )
891         {
892             int i, j;
893
894             /* dumb downmixing */
895             for( i = 0; i < aout_buf.i_nb_samples; i++ )
896             {
897                 uint16_t *p_buffer = aout_buf.p_buffer;
898                 for( j = 0 ; j < id->p_encoder->fmt_in.audio.i_channels; j++ )
899                 {
900                     p_buffer[i*id->p_encoder->fmt_in.audio.i_channels+j] =
901                         p_buffer[i*id->f_src.audio.i_channels+j];
902                 }
903             }
904             aout_buf.i_nb_bytes = i*id->p_encoder->fmt_in.audio.i_channels * 2;
905         }
906
907         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf );
908         while( p_block )
909         {
910             sout_buffer_t *p_out;
911             block_t *p_prev_block = p_block;
912
913             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
914             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
915             p_out->i_dts = p_block->i_dts;
916             p_out->i_pts = p_block->i_pts;
917             p_out->i_length = p_block->i_length;
918             sout_BufferChain( out, p_out );
919
920             p_block = p_block->p_next;
921             block_Release( p_prev_block );
922         }
923     }
924
925     return VLC_SUCCESS;
926 }
927
928
929 /*
930  * video
931  */
932 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
933                                        sout_stream_id_t *id )
934 {
935     sout_stream_sys_t   *p_sys = p_stream->p_sys;
936
937     int i_ff_codec;
938
939     /* Open decoder */
940     if( id->f_src.i_codec == VLC_FOURCC( 'I', '4', '2', '0' ) ||
941         id->f_src.i_codec == VLC_FOURCC( 'I', '4', '2', '2' ) ||
942         id->f_src.i_codec == VLC_FOURCC( 'I', '4', '4', '4' ) ||
943         id->f_src.i_codec == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
944         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
945         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
946         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
947         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
948         id->f_src.i_codec == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
949     {
950         id->ff_dec              = NULL;
951         id->ff_dec_c            = avcodec_alloc_context();
952         id->ff_dec_c->width     = id->f_src.video.i_width;
953         id->ff_dec_c->height    = id->f_src.video.i_height;
954         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_codec );
955     }
956     else
957     {
958         /* find decoder */
959         i_ff_codec = get_ff_codec( id->f_src.i_codec );
960         if( i_ff_codec == 0 )
961         {
962             msg_Err( p_stream, "cannot find decoder" );
963             return VLC_EGENERIC;
964         }
965
966         id->ff_dec = avcodec_find_decoder( i_ff_codec );
967         if( !id->ff_dec )
968         {
969             msg_Err( p_stream, "cannot find decoder" );
970             return VLC_EGENERIC;
971         }
972
973         id->ff_dec_c = avcodec_alloc_context();
974         id->ff_dec_c->width         = id->f_src.video.i_width;
975         id->ff_dec_c->height        = id->f_src.video.i_height;
976         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
977         id->ff_dec_c->extradata_size= id->f_src.i_extra;
978         id->ff_dec_c->extradata     = id->f_src.p_extra;
979         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
980         id->ff_dec_c->error_resilience= -1;
981         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
982         id->ff_dec_c->opaque        = p_sys;
983
984         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
985         {
986             msg_Err( p_stream, "cannot open decoder" );
987             return VLC_EGENERIC;
988         }
989
990         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
991         {
992             int b_gotpicture;
993             AVFrame frame;
994             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
995                                      FF_INPUT_BUFFER_PADDING_SIZE );
996
997             memcpy( p_vol, id->ff_dec_c->extradata,
998                     id->ff_dec_c->extradata_size );
999             memset( p_vol + id->ff_dec_c->extradata_size, 0,
1000                     FF_INPUT_BUFFER_PADDING_SIZE );
1001
1002             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
1003                                   id->ff_dec_c->extradata,
1004                                   id->ff_dec_c->extradata_size );
1005             free( p_vol );
1006         }
1007     }
1008
1009     /* Open encoder */
1010     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
1011
1012     /* Initialization of encoder format structures */
1013     es_format_Init( &id->p_encoder->fmt_in,
1014                     id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
1015
1016     id->p_encoder->fmt_in.video.i_width = id->f_dst.video.i_width;
1017     id->p_encoder->fmt_in.video.i_height = id->f_dst.video.i_height;
1018
1019     if( id->p_encoder->fmt_in.video.i_width <= 0 )
1020     {
1021         id->p_encoder->fmt_in.video.i_width = id->f_dst.video.i_width =
1022             id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1023     }
1024     if( id->p_encoder->fmt_in.video.i_height <= 0 )
1025     {
1026         id->p_encoder->fmt_in.video.i_height = id->f_dst.video.i_height =
1027             id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1028     }
1029
1030     id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */
1031     id->p_encoder->fmt_in.video.i_frame_rate_base= 1;
1032     if( id->ff_dec )
1033     {
1034         id->p_encoder->fmt_in.video.i_frame_rate = id->ff_dec_c->frame_rate;
1035 #if LIBAVCODEC_BUILD >= 4662
1036         id->p_encoder->fmt_in.video.i_frame_rate_base =
1037             id->ff_dec_c->frame_rate_base;
1038 #endif
1039
1040 #if LIBAVCODEC_BUILD >= 4687
1041         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1042             ( av_q2d(id->ff_dec_c->sample_aspect_ratio) *
1043               id->ff_dec_c->width / id->ff_dec_c->height );
1044 #else
1045         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1046             id->ff_dec_c->aspect_ratio;
1047 #endif
1048
1049     }
1050
1051     id->p_encoder->fmt_out = id->p_encoder->fmt_in;
1052     id->p_encoder->fmt_out.i_codec = id->f_dst.i_codec;
1053     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
1054
1055     id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
1056     id->p_encoder->i_key_int = p_sys->i_key_int;
1057     id->p_encoder->i_b_frames = p_sys->i_b_frames;
1058     id->p_encoder->i_qmin = p_sys->i_qmin;
1059     id->p_encoder->i_qmax = p_sys->i_qmax;
1060     id->p_encoder->i_hq = p_sys->i_hq;
1061
1062     id->p_ff_pic         = avcodec_alloc_frame();
1063     id->p_ff_pic_tmp0    = NULL;
1064     id->p_ff_pic_tmp1    = NULL;
1065     id->p_ff_pic_tmp2    = NULL;
1066     id->p_vresample      = NULL;
1067
1068     id->p_encoder->p_module =
1069         module_Need( id->p_encoder, "encoder", NULL );
1070
1071     if( !id->p_encoder->p_module )
1072     {
1073         vlc_object_destroy( id->p_encoder );
1074         msg_Err( p_stream, "cannot find encoder" );
1075         return VLC_EGENERIC;
1076     }
1077
1078     /* Close the encoder.
1079      * We'll open it only when we have the first frame */
1080     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1081
1082     id->b_enc_inited = VLC_FALSE;
1083
1084     return VLC_SUCCESS;
1085 }
1086
1087 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream,
1088                                            sout_stream_id_t *id )
1089 {
1090     /* Close decoder */
1091     if( id->ff_dec )
1092     {
1093         avcodec_close( id->ff_dec_c );
1094         free( id->ff_dec_c );
1095     }
1096
1097     /* Close encoder */
1098     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1099     vlc_object_destroy( id->p_encoder );
1100
1101     /* Misc cleanup */
1102     if( id->p_ff_pic)
1103     {
1104         free( id->p_ff_pic );
1105     }
1106
1107     if( id->p_ff_pic_tmp0 )
1108     {
1109         free( id->p_ff_pic_tmp0->data[0] );
1110         free( id->p_ff_pic_tmp0 );
1111     }
1112     if( id->p_ff_pic_tmp1)
1113     {
1114         free( id->p_ff_pic_tmp1->data[0] );
1115         free( id->p_ff_pic_tmp1 );
1116     }
1117     if( id->p_ff_pic_tmp2)
1118     {
1119         free( id->p_ff_pic_tmp2->data[0] );
1120         free( id->p_ff_pic_tmp2 );
1121     }
1122     if( id->p_vresample )
1123     {
1124         free( id->p_vresample );
1125     }
1126 }
1127
1128 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1129                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1130 {
1131     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1132     int     i_used;
1133     int     b_gotpicture;
1134     AVFrame *frame;
1135
1136     int     i_data;
1137     uint8_t *p_data;
1138
1139     *out = NULL;
1140
1141     i_data = in->i_size;
1142     p_data = in->p_buffer;
1143  
1144     for( ;; )
1145     {
1146         block_t *p_block;
1147         picture_t pic;
1148         int i_plane;
1149
1150         /* decode frame */
1151         frame = id->p_ff_pic;
1152         p_sys->i_input_pts = in->i_pts;
1153        if( id->ff_dec )
1154         {
1155             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1156                                            &b_gotpicture,
1157                                            p_data, i_data );
1158         }
1159         else
1160         {
1161             /* raw video */
1162             avpicture_fill( (AVPicture*)frame,
1163                             p_data,
1164                             id->ff_dec_c->pix_fmt,
1165                             id->ff_dec_c->width, id->ff_dec_c->height );
1166             i_used = i_data;
1167             b_gotpicture = 1;
1168
1169             /* Set PTS */
1170             frame->pts = p_sys->i_input_pts;
1171         }
1172
1173         if( i_used < 0 )
1174         {
1175             msg_Warn( p_stream, "error");
1176             return VLC_EGENERIC;
1177         }
1178         i_data -= i_used;
1179         p_data += i_used;
1180
1181         if( !b_gotpicture )
1182         {
1183             return VLC_SUCCESS;
1184         }
1185
1186         /* Get the pts of the decoded frame if any, otherwise keep the
1187          * interpolated one */
1188         if( frame->pts > 0 )
1189         {
1190             p_sys->i_output_pts = frame->pts;
1191         }
1192
1193         if( !id->b_enc_inited )
1194         {
1195             /* XXX hack because of copy packetizer and mpeg4video that can fail
1196              * detecting size */
1197             if( id->p_encoder->fmt_in.video.i_width <= 0 )
1198             {
1199                 id->p_encoder->fmt_in.video.i_width =
1200                   id->p_encoder->fmt_out.video.i_width = id->f_dst.video.i_width =
1201                     id->ff_dec_c->width - p_sys->i_crop_left -
1202                       p_sys->i_crop_right;
1203             }
1204             if( id->p_encoder->fmt_in.video.i_height <= 0 )
1205             {
1206                 id->p_encoder->fmt_in.video.i_height =
1207                   id->p_encoder->fmt_out.video.i_height = id->f_dst.video.i_height =
1208                     id->ff_dec_c->height - p_sys->i_crop_top -
1209                       p_sys->i_crop_bottom;
1210             }
1211
1212             id->p_encoder->fmt_out.i_extra = 0;
1213             id->p_encoder->fmt_out.p_extra = NULL;
1214
1215             id->p_encoder->p_module =
1216                 module_Need( id->p_encoder, "encoder", NULL );
1217             if( !id->p_encoder->p_module )
1218             {
1219                 vlc_object_destroy( id->p_encoder );
1220                 msg_Err( p_stream, "cannot find encoder" );
1221                 return VLC_EGENERIC;
1222             }
1223
1224             id->f_dst.i_extra = id->p_encoder->fmt_out.i_extra;
1225             id->f_dst.p_extra = id->p_encoder->fmt_out.p_extra;
1226
1227             /* Hack for mp2v/mp1v transcoding support */
1228             if( id->f_dst.i_codec == VLC_FOURCC( 'm','p','1','v' ) ||
1229                 id->f_dst.i_codec == VLC_FOURCC( 'm','p','2','v' ) )
1230             {
1231                 id->f_dst.i_codec = VLC_FOURCC( 'm','p','g','v' );
1232             }
1233
1234             if( !( id->id =
1235                      p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1236                                                      &id->f_dst ) ) )
1237             {
1238                 msg_Err( p_stream, "cannot add this stream" );
1239                 transcode_video_ffmpeg_close( p_stream, id );
1240                 id->b_transcode = VLC_FALSE;
1241                 return VLC_EGENERIC;
1242             }
1243
1244             while( id->p_encoder->pf_header &&
1245                    (p_block = id->p_encoder->pf_header( id->p_encoder )) )
1246             {
1247                 sout_buffer_t *p_out;
1248                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1249                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1250                 p_out->i_dts = in->i_dts;
1251                 p_out->i_pts = in->i_dts;
1252                 p_out->i_length = 0;
1253                 sout_BufferChain( out, p_out );
1254             }
1255
1256             id->i_inter_pixfmt =
1257                 get_ff_chroma( id->p_encoder->fmt_in.i_codec );
1258
1259             id->b_enc_inited = VLC_TRUE;
1260         }
1261
1262         /* deinterlace */
1263         if( p_stream->p_sys->b_deinterlace )
1264         {
1265             if( id->p_ff_pic_tmp0 == NULL )
1266             {
1267                 int     i_size;
1268                 uint8_t *buf;
1269                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1270                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1271                                              id->ff_dec_c->width, id->ff_dec_c->height );
1272
1273                 buf = malloc( i_size );
1274
1275                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1276                                 id->i_inter_pixfmt,
1277                                 id->ff_dec_c->width, id->ff_dec_c->height );
1278             }
1279
1280             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1281                                    id->ff_dec_c->pix_fmt,
1282                                    id->ff_dec_c->width, id->ff_dec_c->height );
1283
1284             frame = id->p_ff_pic_tmp0;
1285         }
1286
1287         /* convert pix format */
1288         if( id->ff_dec_c->pix_fmt != id->i_inter_pixfmt )
1289         {
1290             if( id->p_ff_pic_tmp1 == NULL )
1291             {
1292                 int     i_size;
1293                 uint8_t *buf;
1294                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1295                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1296                                              id->ff_dec_c->width,
1297                                              id->ff_dec_c->height );
1298
1299                 buf = malloc( i_size );
1300
1301                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1302                                 id->i_inter_pixfmt,
1303                                 id->ff_dec_c->width, id->ff_dec_c->height );
1304             }
1305
1306             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->i_inter_pixfmt,
1307                          (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1308                          id->ff_dec_c->width, id->ff_dec_c->height );
1309
1310             frame = id->p_ff_pic_tmp1;
1311         }
1312
1313         /* convert size and crop */
1314         if( id->ff_dec_c->width  != id->f_dst.video.i_width ||
1315             id->ff_dec_c->height != id->f_dst.video.i_height ||
1316             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1317             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1318         {
1319             if( id->p_ff_pic_tmp2 == NULL )
1320             {
1321                 int     i_size;
1322                 uint8_t *buf;
1323                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1324                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1325                                              id->f_dst.video.i_width,
1326                                              id->f_dst.video.i_height );
1327
1328                 buf = malloc( i_size );
1329
1330                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1331                                 id->i_inter_pixfmt,
1332                                 id->f_dst.video.i_width, id->f_dst.video.i_height );
1333
1334                 id->p_vresample =
1335                     img_resample_full_init( id->f_dst.video.i_width,
1336                                             id->f_dst.video.i_height,
1337                                             id->ff_dec_c->width, id->ff_dec_c->height,
1338                                             p_stream->p_sys->i_crop_top,
1339                                             p_stream->p_sys->i_crop_bottom,
1340                                             p_stream->p_sys->i_crop_left,
1341                                             p_stream->p_sys->i_crop_right );
1342             }
1343
1344             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1345                           (AVPicture*)frame );
1346
1347             frame = id->p_ff_pic_tmp2;
1348         }
1349
1350         /* Encoding */
1351         vout_InitPicture( VLC_OBJECT(p_stream), &pic,
1352                           id->p_encoder->fmt_in.i_codec,
1353                           id->f_dst.video.i_width, id->f_dst.video.i_height,
1354                           id->f_dst.video.i_width * VOUT_ASPECT_FACTOR /
1355                           id->f_dst.video.i_height );
1356
1357         for( i_plane = 0; i_plane < pic.i_planes; i_plane++ )
1358         {
1359             pic.p[i_plane].p_pixels = frame->data[i_plane];
1360             pic.p[i_plane].i_pitch = frame->linesize[i_plane];
1361         }
1362
1363         /* Set the pts of the frame being encoded */
1364         pic.date = p_sys->i_output_pts;
1365
1366         /* Interpolate the next PTS
1367          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1368         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1369         {
1370             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1371               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1372         }
1373
1374         p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic );
1375         while( p_block )
1376         {
1377             sout_buffer_t *p_out;
1378             block_t *p_prev_block = p_block;
1379
1380             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1381             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1382             p_out->i_dts = p_block->i_dts;
1383             p_out->i_pts = p_block->i_pts;
1384             p_out->i_length = p_block->i_length;
1385             sout_BufferChain( out, p_out );
1386
1387             p_block = p_block->p_next;
1388             block_Release( p_prev_block );
1389         }
1390
1391         if( i_data <= 0 )
1392         {
1393             return VLC_SUCCESS;
1394         }
1395     }
1396
1397     return VLC_SUCCESS;
1398 }
1399
1400 /*****************************************************************************
1401  * transcode_video_ffmpeg_getframebuf:
1402  *
1403  * Callback used by ffmpeg to get a frame buffer.
1404  * We use it to get the right PTS for each decoded picture.
1405  *****************************************************************************/
1406 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1407                                               AVFrame *p_frame)
1408 {
1409     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1410
1411     /* Set PTS */
1412     p_frame->pts = p_sys->i_input_pts;
1413
1414     return avcodec_default_get_buffer( p_context, p_frame );
1415 }