d37c5c915b3d30033f5b0337be16b659dac23afe
[vlc.git] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.51 2003/11/17 02:55:22 fenrir 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;
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, sout_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_fourcc,
365                  (char*)&p_sys->i_acodec );
366
367         /* src format */
368         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
369
370         /* create dst format */
371         id->f_dst.i_cat    = AUDIO_ES;
372         id->f_dst.i_fourcc = p_sys->i_acodec;
373         id->f_dst.i_sample_rate = p_sys->i_sample_rate  > 0 ? p_sys->i_sample_rate : id->f_src.i_sample_rate;
374         id->f_dst.i_channels    = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.i_channels;
375         id->f_dst.i_bitrate     = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
376         id->f_dst.i_block_align = 0;
377         id->f_dst.i_extra_data  = 0;
378         id->f_dst.p_extra_data  = 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_fourcc,
403                  (char*)&p_sys->i_vcodec );
404
405         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
406
407         /* create dst format */
408         id->f_dst.i_cat         = VIDEO_ES;
409         id->f_dst.i_fourcc      = p_sys->i_vcodec;
410         id->f_dst.i_width       = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
411         id->f_dst.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_data  = 0;
414         id->f_dst.p_extra_data  = 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_fourcc );
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_fourcc == VLC_FOURCC('s','1','6','l') ||
640         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
641         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
642         id->f_src.i_fourcc == 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.i_sample_rate;
648         id->ff_dec_c->channels    = id->f_src.i_channels;
649         id->ff_dec_c->block_align = id->f_src.i_block_align;
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_fourcc );
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.i_sample_rate;
671         id->ff_dec_c->channels    = id->f_src.i_channels;
672         id->ff_dec_c->block_align = id->f_src.i_block_align;
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_data;
676         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
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.i_channels = __MIN( id->f_dst.i_channels, id->f_src.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.i_sample_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.i_channels];
701     id->p_encoder->fmt_in.audio.i_channels = id->f_dst.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_fourcc;
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_data = id->p_encoder->fmt_out.i_extra;
719     id->f_dst.p_extra_data = id->p_encoder->fmt_out.p_extra;
720
721     /* Hack for mp3 transcoding support */
722     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
723     {
724         id->f_dst.i_fourcc = 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_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
788                 id->f_src.i_fourcc == 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_fourcc == 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_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) ||
812                      id->f_src.i_fourcc == 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_fourcc == 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.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.i_channels / id->f_src.i_sample_rate );
888
889         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf );
890         while( p_block )
891         {
892             sout_buffer_t *p_out;
893             block_t *p_prev_block = p_block;
894
895             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
896             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
897             p_out->i_dts = p_block->i_dts;
898             p_out->i_pts = p_block->i_pts;
899             p_out->i_length = p_block->i_length;
900             sout_BufferChain( out, p_out );
901
902             p_block = p_block->p_next;
903             block_Release( p_prev_block );
904         }
905     }
906
907     return VLC_SUCCESS;
908 }
909
910
911 /*
912  * video
913  */
914 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
915                                        sout_stream_id_t *id )
916 {
917     sout_stream_sys_t   *p_sys = p_stream->p_sys;
918
919     int i_ff_codec;
920
921     /* Open decoder */
922     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
923         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
924         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
925         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
926         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
927         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
928         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
929         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
930         id->f_src.i_fourcc == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
931     {
932         id->ff_dec              = NULL;
933         id->ff_dec_c            = avcodec_alloc_context();
934         id->ff_dec_c->width     = id->f_src.i_width;
935         id->ff_dec_c->height    = id->f_src.i_height;
936         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
937     }
938     else
939     {
940         /* find decoder */
941         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
942         if( i_ff_codec == 0 )
943         {
944             msg_Err( p_stream, "cannot find decoder" );
945             return VLC_EGENERIC;
946         }
947
948         id->ff_dec = avcodec_find_decoder( i_ff_codec );
949         if( !id->ff_dec )
950         {
951             msg_Err( p_stream, "cannot find decoder" );
952             return VLC_EGENERIC;
953         }
954
955         id->ff_dec_c = avcodec_alloc_context();
956         id->ff_dec_c->width         = id->f_src.i_width;
957         id->ff_dec_c->height        = id->f_src.i_height;
958         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
959         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
960         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
961         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
962         id->ff_dec_c->error_resilience= -1;
963         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
964         id->ff_dec_c->opaque        = p_sys;
965
966         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
967         {
968             msg_Err( p_stream, "cannot open decoder" );
969             return VLC_EGENERIC;
970         }
971
972         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
973         {
974             int b_gotpicture;
975             AVFrame frame;
976             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
977                                      FF_INPUT_BUFFER_PADDING_SIZE );
978
979             memcpy( p_vol, id->ff_dec_c->extradata,
980                     id->ff_dec_c->extradata_size );
981             memset( p_vol + id->ff_dec_c->extradata_size, 0,
982                     FF_INPUT_BUFFER_PADDING_SIZE );
983
984             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
985                                   id->ff_dec_c->extradata,
986                                   id->ff_dec_c->extradata_size );
987             free( p_vol );
988         }
989     }
990
991     /* Open encoder */
992     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
993
994     /* Initialization of encoder format structures */
995     es_format_Init( &id->p_encoder->fmt_in,
996                     id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
997
998     id->p_encoder->fmt_in.video.i_width = id->f_dst.i_width;
999     id->p_encoder->fmt_in.video.i_height = id->f_dst.i_height;
1000
1001     if( id->p_encoder->fmt_in.video.i_width <= 0 )
1002     {
1003         id->p_encoder->fmt_in.video.i_width = id->f_dst.i_width =
1004             id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1005     }
1006     if( id->p_encoder->fmt_in.video.i_height <= 0 )
1007     {
1008         id->p_encoder->fmt_in.video.i_height = id->f_dst.i_height =
1009             id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1010     }
1011
1012     id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */
1013     id->p_encoder->fmt_in.video.i_frame_rate_base= 1;
1014     if( id->ff_dec )
1015     {
1016         id->p_encoder->fmt_in.video.i_frame_rate = id->ff_dec_c->frame_rate;
1017 #if LIBAVCODEC_BUILD >= 4662
1018         id->p_encoder->fmt_in.video.i_frame_rate_base =
1019             id->ff_dec_c->frame_rate_base;
1020 #endif
1021
1022 #if LIBAVCODEC_BUILD >= 4687
1023         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1024             ( av_q2d(id->ff_dec_c->sample_aspect_ratio) *
1025               id->ff_dec_c->width / id->ff_dec_c->height );
1026 #else
1027         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1028             id->ff_dec_c->aspect_ratio;
1029 #endif
1030
1031     }
1032
1033     id->p_encoder->fmt_out = id->p_encoder->fmt_in;
1034     id->p_encoder->fmt_out.i_codec = id->f_dst.i_fourcc;
1035     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
1036
1037     id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
1038     id->p_encoder->i_key_int = p_sys->i_key_int;
1039     id->p_encoder->i_b_frames = p_sys->i_b_frames;
1040     id->p_encoder->i_qmin = p_sys->i_qmin;
1041     id->p_encoder->i_qmax = p_sys->i_qmax;
1042     id->p_encoder->i_hq = p_sys->i_hq;
1043
1044     id->p_ff_pic         = avcodec_alloc_frame();
1045     id->p_ff_pic_tmp0    = NULL;
1046     id->p_ff_pic_tmp1    = NULL;
1047     id->p_ff_pic_tmp2    = NULL;
1048     id->p_vresample      = NULL;
1049
1050     id->p_encoder->p_module =
1051         module_Need( id->p_encoder, "encoder", NULL );
1052
1053     if( !id->p_encoder->p_module )
1054     {
1055         vlc_object_destroy( id->p_encoder );
1056         msg_Err( p_stream, "cannot find encoder" );
1057         return VLC_EGENERIC;
1058     }
1059
1060     /* Close the encoder.
1061      * We'll open it only when we have the first frame */
1062     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1063
1064     id->b_enc_inited = VLC_FALSE;
1065
1066     return VLC_SUCCESS;
1067 }
1068
1069 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream,
1070                                            sout_stream_id_t *id )
1071 {
1072     /* Close decoder */
1073     if( id->ff_dec )
1074     {
1075         avcodec_close( id->ff_dec_c );
1076         free( id->ff_dec_c );
1077     }
1078
1079     /* Close encoder */
1080     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1081     vlc_object_destroy( id->p_encoder );
1082
1083     /* Misc cleanup */
1084     if( id->p_ff_pic)
1085     {
1086         free( id->p_ff_pic );
1087     }
1088
1089     if( id->p_ff_pic_tmp0 )
1090     {
1091         free( id->p_ff_pic_tmp0->data[0] );
1092         free( id->p_ff_pic_tmp0 );
1093     }
1094     if( id->p_ff_pic_tmp1)
1095     {
1096         free( id->p_ff_pic_tmp1->data[0] );
1097         free( id->p_ff_pic_tmp1 );
1098     }
1099     if( id->p_ff_pic_tmp2)
1100     {
1101         free( id->p_ff_pic_tmp2->data[0] );
1102         free( id->p_ff_pic_tmp2 );
1103     }
1104     if( id->p_vresample )
1105     {
1106         free( id->p_vresample );
1107     }
1108 }
1109
1110 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1111                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1112 {
1113     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1114     int     i_used;
1115     int     b_gotpicture;
1116     AVFrame *frame;
1117
1118     int     i_data;
1119     uint8_t *p_data;
1120
1121     *out = NULL;
1122
1123     i_data = in->i_size;
1124     p_data = in->p_buffer;
1125  
1126     for( ;; )
1127     {
1128         block_t *p_block;
1129         picture_t pic;
1130         int i_plane;
1131
1132         /* decode frame */
1133         frame = id->p_ff_pic;
1134         p_sys->i_input_pts = in->i_pts;
1135        if( id->ff_dec )
1136         {
1137             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1138                                            &b_gotpicture,
1139                                            p_data, i_data );
1140         }
1141         else
1142         {
1143             /* raw video */
1144             avpicture_fill( (AVPicture*)frame,
1145                             p_data,
1146                             id->ff_dec_c->pix_fmt,
1147                             id->ff_dec_c->width, id->ff_dec_c->height );
1148             i_used = i_data;
1149             b_gotpicture = 1;
1150
1151             /* Set PTS */
1152             frame->pts = p_sys->i_input_pts;
1153         }
1154
1155         if( i_used < 0 )
1156         {
1157             msg_Warn( p_stream, "error");
1158             return VLC_EGENERIC;
1159         }
1160         i_data -= i_used;
1161         p_data += i_used;
1162
1163         if( !b_gotpicture )
1164         {
1165             return VLC_SUCCESS;
1166         }
1167
1168         /* Get the pts of the decoded frame if any, otherwise keep the
1169          * interpolated one */
1170         if( frame->pts > 0 )
1171         {
1172             p_sys->i_output_pts = frame->pts;
1173         }
1174
1175         if( !id->b_enc_inited )
1176         {
1177             /* XXX hack because of copy packetizer and mpeg4video that can fail
1178              * detecting size */
1179             if( id->p_encoder->fmt_in.video.i_width <= 0 )
1180             {
1181                 id->p_encoder->fmt_in.video.i_width =
1182                   id->p_encoder->fmt_out.video.i_width = id->f_dst.i_width =
1183                     id->ff_dec_c->width - p_sys->i_crop_left -
1184                       p_sys->i_crop_right;
1185             }
1186             if( id->p_encoder->fmt_in.video.i_height <= 0 )
1187             {
1188                 id->p_encoder->fmt_in.video.i_height =
1189                   id->p_encoder->fmt_out.video.i_height = id->f_dst.i_height =
1190                     id->ff_dec_c->height - p_sys->i_crop_top -
1191                       p_sys->i_crop_bottom;
1192             }
1193
1194             id->p_encoder->fmt_out.i_extra = 0;
1195             id->p_encoder->fmt_out.p_extra = NULL;
1196
1197             id->p_encoder->p_module =
1198                 module_Need( id->p_encoder, "encoder", NULL );
1199             if( !id->p_encoder->p_module )
1200             {
1201                 vlc_object_destroy( id->p_encoder );
1202                 msg_Err( p_stream, "cannot find encoder" );
1203                 return VLC_EGENERIC;
1204             }
1205
1206             id->f_dst.i_extra_data = id->p_encoder->fmt_out.i_extra;
1207             id->f_dst.p_extra_data = id->p_encoder->fmt_out.p_extra;
1208
1209             /* Hack for mp2v/mp1v transcoding support */
1210             if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' ) ||
1211                 id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
1212             {
1213                 id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','v' );
1214             }
1215
1216             if( !( id->id =
1217                      p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1218                                                      &id->f_dst ) ) )
1219             {
1220                 msg_Err( p_stream, "cannot add this stream" );
1221                 transcode_video_ffmpeg_close( p_stream, id );
1222                 id->b_transcode = VLC_FALSE;
1223                 return VLC_EGENERIC;
1224             }
1225
1226             while( id->p_encoder->pf_header &&
1227                    (p_block = id->p_encoder->pf_header( id->p_encoder )) )
1228             {
1229                 sout_buffer_t *p_out;
1230                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1231                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1232                 p_out->i_dts = in->i_dts;
1233                 p_out->i_pts = in->i_dts;
1234                 p_out->i_length = 0;
1235                 sout_BufferChain( out, p_out );
1236             }
1237
1238             id->i_inter_pixfmt =
1239                 get_ff_chroma( id->p_encoder->fmt_in.i_codec );
1240
1241             id->b_enc_inited = VLC_TRUE;
1242         }
1243
1244         /* deinterlace */
1245         if( p_stream->p_sys->b_deinterlace )
1246         {
1247             if( id->p_ff_pic_tmp0 == NULL )
1248             {
1249                 int     i_size;
1250                 uint8_t *buf;
1251                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1252                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1253                                              id->ff_dec_c->width, id->ff_dec_c->height );
1254
1255                 buf = malloc( i_size );
1256
1257                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1258                                 id->i_inter_pixfmt,
1259                                 id->ff_dec_c->width, id->ff_dec_c->height );
1260             }
1261
1262             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1263                                    id->ff_dec_c->pix_fmt,
1264                                    id->ff_dec_c->width, id->ff_dec_c->height );
1265
1266             frame = id->p_ff_pic_tmp0;
1267         }
1268
1269         /* convert pix format */
1270         if( id->ff_dec_c->pix_fmt != id->i_inter_pixfmt )
1271         {
1272             if( id->p_ff_pic_tmp1 == NULL )
1273             {
1274                 int     i_size;
1275                 uint8_t *buf;
1276                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1277                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1278                                              id->ff_dec_c->width,
1279                                              id->ff_dec_c->height );
1280
1281                 buf = malloc( i_size );
1282
1283                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1284                                 id->i_inter_pixfmt,
1285                                 id->ff_dec_c->width, id->ff_dec_c->height );
1286             }
1287
1288             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->i_inter_pixfmt,
1289                          (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1290                          id->ff_dec_c->width, id->ff_dec_c->height );
1291
1292             frame = id->p_ff_pic_tmp1;
1293         }
1294
1295         /* convert size and crop */
1296         if( id->ff_dec_c->width  != id->f_dst.i_width ||
1297             id->ff_dec_c->height != id->f_dst.i_height ||
1298             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1299             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1300         {
1301             if( id->p_ff_pic_tmp2 == NULL )
1302             {
1303                 int     i_size;
1304                 uint8_t *buf;
1305                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1306                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1307                                              id->f_dst.i_width,
1308                                              id->f_dst.i_height );
1309
1310                 buf = malloc( i_size );
1311
1312                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1313                                 id->i_inter_pixfmt,
1314                                 id->f_dst.i_width, id->f_dst.i_height );
1315
1316                 id->p_vresample =
1317                     img_resample_full_init( id->f_dst.i_width,
1318                                             id->f_dst.i_height,
1319                                             id->ff_dec_c->width, id->ff_dec_c->height,
1320                                             p_stream->p_sys->i_crop_top,
1321                                             p_stream->p_sys->i_crop_bottom,
1322                                             p_stream->p_sys->i_crop_left,
1323                                             p_stream->p_sys->i_crop_right );
1324             }
1325
1326             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1327                           (AVPicture*)frame );
1328
1329             frame = id->p_ff_pic_tmp2;
1330         }
1331
1332         /* Encoding */
1333         vout_InitPicture( VLC_OBJECT(p_stream), &pic,
1334                           id->p_encoder->fmt_in.i_codec,
1335                           id->f_dst.i_width, id->f_dst.i_height,
1336                           id->f_dst.i_width * VOUT_ASPECT_FACTOR /
1337                           id->f_dst.i_height );
1338
1339         for( i_plane = 0; i_plane < pic.i_planes; i_plane++ )
1340         {
1341             pic.p[i_plane].p_pixels = frame->data[i_plane];
1342             pic.p[i_plane].i_pitch = frame->linesize[i_plane];
1343         }
1344
1345         /* Set the pts of the frame being encoded */
1346         pic.date = p_sys->i_output_pts;
1347
1348         /* Interpolate the next PTS
1349          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1350         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1351         {
1352             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1353               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1354         }
1355
1356         p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic );
1357         while( p_block )
1358         {
1359             sout_buffer_t *p_out;
1360             block_t *p_prev_block = p_block;
1361
1362             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1363             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1364             p_out->i_dts = p_block->i_dts;
1365             p_out->i_pts = p_block->i_pts;
1366             p_out->i_length = p_block->i_length;
1367             sout_BufferChain( out, p_out );
1368
1369             p_block = p_block->p_next;
1370             block_Release( p_prev_block );
1371         }
1372
1373         if( i_data <= 0 )
1374         {
1375             return VLC_SUCCESS;
1376         }
1377     }
1378
1379     return VLC_SUCCESS;
1380 }
1381
1382 /*****************************************************************************
1383  * transcode_video_ffmpeg_getframebuf:
1384  *
1385  * Callback used by ffmpeg to get a frame buffer.
1386  * We use it to get the right PTS for each decoded picture.
1387  *****************************************************************************/
1388 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1389                                               AVFrame *p_frame)
1390 {
1391     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1392
1393     /* Set PTS */
1394     p_frame->pts = p_sys->i_input_pts;
1395
1396     return avcodec_default_get_buffer( p_context, p_frame );
1397 }