]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
* include/vlc_codec.h, modules/codec/ffmpeg/encoder.c, modules/stream_out/transcode...
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.49 2003/11/05 18:59:01 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/input.h>
33 #include <vlc/sout.h>
34 #include <vlc/vout.h>
35 #include <vlc/decoder.h>
36
37 /* ffmpeg header */
38 #ifdef HAVE_FFMPEG_AVCODEC_H
39 #   include <ffmpeg/avcodec.h>
40 #else
41 #   include <avcodec.h>
42 #endif
43
44 /*****************************************************************************
45  * Exported prototypes
46  *****************************************************************************/
47 static int      Open    ( vlc_object_t * );
48 static void     Close   ( vlc_object_t * );
49
50 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
51 static int               Del ( sout_stream_t *, sout_stream_id_t * );
52 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
53
54 static int  transcode_audio_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
55 static void transcode_audio_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
56 static int  transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
57
58 static int  transcode_video_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
59 static void transcode_video_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
60 static int  transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
61
62 static int  transcode_video_ffmpeg_getframebuf( struct AVCodecContext *, AVFrame *);
63
64 static int pi_channels_maps[6] =
65 {
66     0,
67     AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
68     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
69     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
70      | AOUT_CHAN_REARRIGHT,
71     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
72      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
73 };
74
75 /*****************************************************************************
76  * Module descriptor
77  *****************************************************************************/
78 vlc_module_begin();
79     set_description( _("Transcode stream") );
80     set_capability( "sout stream", 50 );
81     add_shortcut( "transcode" );
82     set_callbacks( Open, Close );
83 vlc_module_end();
84
85 struct sout_stream_sys_t
86 {
87     sout_stream_t   *p_out;
88
89     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
90     int             i_sample_rate;
91     int             i_channels;
92     int             i_abitrate;
93
94     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
95     int             i_vbitrate;
96     int             i_vtolerance;
97     int             i_width;
98     int             i_height;
99     int             i_b_frames;
100     int             i_key_int;
101     int             i_qmin;
102     int             i_qmax;
103     vlc_bool_t      i_hq;
104     vlc_bool_t      b_deinterlace;
105
106     int             i_crop_top;
107     int             i_crop_bottom;
108     int             i_crop_right;
109     int             i_crop_left;
110
111     mtime_t         i_input_pts;
112     mtime_t         i_output_pts;
113 };
114
115 /*****************************************************************************
116  * Open:
117  *****************************************************************************/
118 static int Open( vlc_object_t *p_this )
119 {
120     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
121     sout_stream_sys_t *p_sys;
122     char *codec;
123
124     p_sys = malloc( sizeof( sout_stream_sys_t ) );
125     p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
126
127     p_sys->i_acodec      = 0;
128     p_sys->i_sample_rate = 0;
129     p_sys->i_channels    = 0;
130     p_sys->i_abitrate    = 0;
131
132     p_sys->i_vcodec     = 0;
133     p_sys->i_vbitrate   = 0;
134     p_sys->i_vtolerance = -1;
135     p_sys->i_width      = 0;
136     p_sys->i_height     = 0;
137     p_sys->i_key_int    = -1;
138     p_sys->i_b_frames   = 0;
139     p_sys->i_qmin       = 2;
140     p_sys->i_qmax       = 31;
141 #if LIBAVCODEC_BUILD >= 4673
142     p_sys->i_hq         = FF_MB_DECISION_SIMPLE;
143 #else
144     p_sys->i_hq         = VLC_FALSE;
145 #endif
146     p_sys->b_deinterlace= VLC_FALSE;
147
148     p_sys->i_crop_top   = 0;
149     p_sys->i_crop_bottom= 0;
150     p_sys->i_crop_right = 0;
151     p_sys->i_crop_left  = 0;
152
153     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "acodec" ) ) )
154     {
155         char fcc[4] = "    ";
156         char *val;
157
158         memcpy( fcc, codec, strlen( codec ) );
159
160         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
161
162         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "samplerate" ) ) )
163         {
164             p_sys->i_sample_rate = atoi( val );
165         }
166         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "channels" ) ) )
167         {
168             p_sys->i_channels = atoi( val );
169         }
170         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
171         {
172             p_sys->i_abitrate = atoi( val );
173             if( p_sys->i_abitrate < 4000 )
174             {
175                 p_sys->i_abitrate *= 1000;
176             }
177         }
178
179         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", fcc,
180                  p_sys->i_sample_rate, p_sys->i_channels,
181                  p_sys->i_abitrate / 1024 );
182     }
183
184     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
185     {
186         char fcc[4] = "    ";
187         char *val;
188
189         memcpy( fcc, codec, strlen( codec ) );
190
191         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
192
193         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
194         {
195             p_sys->i_width = atoi( val );
196         }
197         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
198         {
199             p_sys->i_height = atoi( val );
200         }
201         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
202         {
203             p_sys->i_vbitrate = atoi( val );
204             if( p_sys->i_vbitrate < 16000 )
205             {
206                 p_sys->i_vbitrate *= 1000;
207             }
208         }
209         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
210         {
211             p_sys->i_vtolerance = atoi( val );
212         }
213         if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
214         {
215             p_sys->b_deinterlace = VLC_TRUE;
216         }
217         /* crop */
218         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
219         {
220             p_sys->i_crop_top = atoi( val );
221         }
222         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
223         {
224             p_sys->i_crop_bottom = atoi( val );
225         }
226         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
227         {
228             p_sys->i_crop_left = atoi( val );
229         }
230         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
231         {
232             p_sys->i_crop_right = atoi( val );
233         }
234         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
235         {
236             p_sys->i_key_int    = atoi( val );
237         }
238         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "bframes" ) ) )
239         {
240             p_sys->i_b_frames   = atoi( val );
241         }
242 #if LIBAVCODEC_BUILD >= 4673
243         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "hq" ) ) )
244         {
245             if( !strcmp( val, "rd" ) )
246             {
247                 p_sys->i_hq = FF_MB_DECISION_RD;
248             }
249             else if( !strcmp( val, "bits" ) )
250             {
251                 p_sys->i_hq = FF_MB_DECISION_BITS;
252             }
253             else if( !strcmp( val, "simple" ) )
254             {
255                 p_sys->i_hq = FF_MB_DECISION_SIMPLE;
256             }
257             else
258             {
259                 p_sys->i_hq = FF_MB_DECISION_RD;
260             }
261         }
262 #else
263         if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
264         {
265             p_sys->i_hq = VLC_TRUE;
266         }
267 #endif
268         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
269         {
270             p_sys->i_qmin   = atoi( val );
271         }
272         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
273         {
274             p_sys->i_qmax   = atoi( val );
275         }
276
277         msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
278                  fcc,
279                  p_sys->i_width, p_sys->i_height,
280                  p_sys->i_vbitrate / 1024 );
281     }
282
283     if( !p_sys->p_out )
284     {
285         msg_Err( p_stream, "cannot create chain" );
286         free( p_sys );
287         return VLC_EGENERIC;
288     }
289     p_stream->pf_add    = Add;
290     p_stream->pf_del    = Del;
291     p_stream->pf_send   = Send;
292
293     p_stream->p_sys     = p_sys;
294
295     avcodec_init();
296     avcodec_register_all();
297
298     /* ffmpeg needs some padding at the end of each buffer */
299     p_stream->p_sout->i_padding += FF_INPUT_BUFFER_PADDING_SIZE;
300
301     return VLC_SUCCESS;
302 }
303
304 /*****************************************************************************
305  * Close:
306  *****************************************************************************/
307 static void Close( vlc_object_t * p_this )
308 {
309     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
310     sout_stream_sys_t   *p_sys = p_stream->p_sys;
311
312     sout_stream_delete( p_sys->p_out );
313     free( p_sys );
314 }
315
316 struct sout_stream_id_t
317 {
318     vlc_fourcc_t  b_transcode;
319     sout_format_t f_src;        /* only if transcoding */
320     sout_format_t f_dst;        /*  "   "      " */
321     unsigned int  i_inter_pixfmt; /* intermediary format when transcoding */
322
323     /* id of the out stream */
324     void *id;
325
326     /* Encoder */
327     encoder_t       *p_encoder;
328     vlc_fourcc_t    b_enc_inited;
329
330     /* ffmpeg part */
331     AVCodec         *ff_dec;
332     AVCodecContext  *ff_dec_c;
333
334     mtime_t         i_dts;
335     mtime_t         i_length;
336
337     int             i_buffer;
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 int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
602                                        sout_stream_id_t *id )
603 {
604     int i_ff_codec;
605
606     if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
607         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
608         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
609         id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
610     {
611         id->ff_dec = NULL;
612
613         id->ff_dec_c = avcodec_alloc_context();
614         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
615         id->ff_dec_c->channels    = id->f_src.i_channels;
616         id->ff_dec_c->block_align = id->f_src.i_block_align;
617         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
618     }
619     else
620     {
621         /* find decoder */
622         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
623         if( i_ff_codec == 0 )
624         {
625             msg_Err( p_stream, "cannot find decoder id" );
626             return VLC_EGENERIC;
627         }
628
629         id->ff_dec = avcodec_find_decoder( i_ff_codec );
630         if( !id->ff_dec )
631         {
632             msg_Err( p_stream, "cannot find decoder (avcodec)" );
633             return VLC_EGENERIC;
634         }
635
636         id->ff_dec_c = avcodec_alloc_context();
637         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
638         id->ff_dec_c->channels    = id->f_src.i_channels;
639         id->ff_dec_c->block_align = id->f_src.i_block_align;
640         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
641
642         id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
643         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
644         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
645         {
646             msg_Err( p_stream, "cannot open decoder" );
647             return VLC_EGENERIC;
648         }
649     }
650
651     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
652     id->i_buffer_pos = 0;
653     id->p_buffer     = malloc( id->i_buffer );
654
655     /* Sanity check for audio channels */
656     id->f_dst.i_channels = __MIN( id->f_dst.i_channels, id->f_src.i_channels );
657
658     /* find encoder */
659     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
660     id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
661     id->p_encoder->format.audio.i_format = AOUT_FMT_S16_NE;
662     id->p_encoder->format.audio.i_rate = id->f_dst.i_sample_rate;
663     id->p_encoder->format.audio.i_physical_channels =
664         id->p_encoder->format.audio.i_original_channels =
665             pi_channels_maps[id->f_dst.i_channels];
666     id->p_encoder->i_bitrate = id->f_dst.i_bitrate;
667     id->p_encoder->i_extra_data = 0;
668     id->p_encoder->p_extra_data = NULL;
669
670     id->p_encoder->p_module =
671         module_Need( id->p_encoder, "audio encoder", NULL );
672     if( !id->p_encoder->p_module )
673     {
674         vlc_object_destroy( id->p_encoder );
675         msg_Err( p_stream, "cannot open encoder" );
676         return VLC_EGENERIC;
677     }
678
679     id->b_enc_inited = VLC_FALSE;
680
681     id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
682     id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
683
684     /* Hack for mp3 transcoding support */
685     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
686     {
687         id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','a' );
688     }
689
690     return VLC_SUCCESS;
691 }
692
693 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
694                                           sout_stream_id_t *id )
695 {
696     if( id->ff_dec )
697     {
698         avcodec_close( id->ff_dec_c );
699         free( id->ff_dec_c );
700     }
701
702     module_Unneed( id->p_encoder, id->p_encoder->p_module );
703     vlc_object_destroy( id->p_encoder );
704
705     free( id->p_buffer );
706 }
707
708 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
709                                            sout_stream_id_t *id,
710                                            sout_buffer_t *in,
711                                            sout_buffer_t **out )
712 {
713     aout_buffer_t aout_buf;
714     block_t *p_block;
715     int i_buffer = in->i_size;
716     char *p_buffer = in->p_buffer;
717     id->i_dts = in->i_dts;
718     *out = NULL;
719
720     while( i_buffer )
721     {
722         id->i_buffer_pos = 0;
723
724         /* decode as much data as possible */
725         if( id->ff_dec )
726         {
727             int i_used;
728
729             i_used = avcodec_decode_audio( id->ff_dec_c,
730                          (int16_t*)id->p_buffer, &id->i_buffer_pos,
731                          p_buffer, i_buffer );
732
733 #if 0
734             msg_Warn( p_stream, "avcodec_decode_audio: %d used on %d",
735                       i_used, i_buffer );
736 #endif
737             if( i_used < 0 )
738             {
739                 msg_Warn( p_stream, "error audio decoding");
740                 break;
741             }
742
743             i_buffer -= i_used;
744             p_buffer += i_used;
745         }
746         else
747         {
748             int16_t *sout = (int16_t*)id->p_buffer;
749
750             if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
751                 id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
752             {
753                 int8_t *sin = (int8_t*)p_buffer;
754                 int i_used = __MIN( id->i_buffer/2, i_buffer );
755                 int i_samples = i_used;
756
757                 if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
758                     while( i_samples > 0 )
759                     {
760                         *sout++ = ( *sin++ ) << 8;
761                         i_samples--;
762                     }
763                 else
764                     while( i_samples > 0 )
765                     {
766                         *sout++ = ( *sin++ - 128 ) << 8;
767                         i_samples--;
768                     }
769
770                 i_buffer -= i_used;
771                 p_buffer += i_used;
772                 id->i_buffer_pos = i_used * 2;
773             }
774             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) ||
775                      id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
776             {
777                 int16_t *sin = (int16_t*)p_buffer;
778                 int i_used = __MIN( id->i_buffer, i_buffer );
779                 int i_samples = i_used / 2;
780                 int b_invert_indianness;
781
782                 if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
783 #ifdef WORDS_BIGENDIAN
784                     b_invert_indianness = 1;
785 #else
786                     b_invert_indianness = 0;
787 #endif
788                 else
789 #ifdef WORDS_BIGENDIAN
790                     b_invert_indianness = 0;
791 #else
792                     b_invert_indianness = 1;
793 #endif
794
795                 if( b_invert_indianness )
796                 {
797                     while( i_samples > 0 )
798                     {
799                         uint8_t tmp[2];
800
801                         tmp[1] = *sin++;
802                         tmp[0] = *sin++;
803                         *sout++ = *(int16_t*)tmp;
804                         i_samples--;
805                     }
806                 }
807                 else
808                 {
809                     memcpy( sout, sin, i_used );
810                     sout += i_samples;
811                 }
812
813                 i_buffer -= i_used;
814                 p_buffer += i_used;
815                 id->i_buffer_pos = i_used;
816             }
817         }
818
819         if( id->i_buffer_pos == 0 ) continue;
820
821         /* Encode as much data as possible */
822         if( !id->b_enc_inited && id->p_encoder->pf_header )
823         {
824             p_block = id->p_encoder->pf_header( id->p_encoder );
825             while( p_block )
826             {
827                 sout_buffer_t *p_out;
828                 block_t *p_prev_block = p_block;
829
830                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
831                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
832                 p_out->i_dts = p_out->i_pts = in->i_dts;
833                 p_out->i_length = 0;
834                 sout_BufferChain( out, p_out );
835
836                 p_block = p_block->p_next;
837                 block_Release( p_prev_block );
838             }
839
840             id->b_enc_inited = VLC_TRUE;
841         }
842
843         aout_buf.p_buffer = id->p_buffer;
844         aout_buf.i_nb_bytes = id->i_buffer_pos;
845         aout_buf.i_nb_samples = id->i_buffer_pos / 2 / id->f_src.i_channels;
846         aout_buf.start_date = id->i_dts;
847         aout_buf.end_date = id->i_dts;
848
849         id->i_dts += ( I64C(1000000) * id->i_buffer_pos / 2 /
850             id->f_src.i_channels / id->f_src.i_sample_rate );
851
852         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf );
853         while( p_block )
854         {
855             sout_buffer_t *p_out;
856             block_t *p_prev_block = p_block;
857
858             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
859             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
860             p_out->i_dts = p_block->i_dts;
861             p_out->i_pts = p_block->i_pts;
862             p_out->i_length = p_block->i_length;
863             sout_BufferChain( out, p_out );
864
865             p_block = p_block->p_next;
866             block_Release( p_prev_block );
867         }
868     }
869
870     return VLC_SUCCESS;
871 }
872
873
874 /*
875  * video
876  */
877 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
878                                        sout_stream_id_t *id )
879 {
880     sout_stream_sys_t   *p_sys = p_stream->p_sys;
881
882     int i_ff_codec;
883
884     /* Open decoder */
885     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
886         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
887         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
888         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
889         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
890         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
891         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
892         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
893         id->f_src.i_fourcc == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
894     {
895         id->ff_dec              = NULL;
896         id->ff_dec_c            = avcodec_alloc_context();
897         id->ff_dec_c->width     = id->f_src.i_width;
898         id->ff_dec_c->height    = id->f_src.i_height;
899         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
900     }
901     else
902     {
903         /* find decoder */
904         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
905         if( i_ff_codec == 0 )
906         {
907             msg_Err( p_stream, "cannot find decoder" );
908             return VLC_EGENERIC;
909         }
910
911         id->ff_dec = avcodec_find_decoder( i_ff_codec );
912         if( !id->ff_dec )
913         {
914             msg_Err( p_stream, "cannot find decoder" );
915             return VLC_EGENERIC;
916         }
917
918         id->ff_dec_c = avcodec_alloc_context();
919         id->ff_dec_c->width         = id->f_src.i_width;
920         id->ff_dec_c->height        = id->f_src.i_height;
921         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
922         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
923         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
924         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
925         id->ff_dec_c->error_resilience= -1;
926         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
927         id->ff_dec_c->opaque        = p_sys;
928
929         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
930         {
931             msg_Err( p_stream, "cannot open decoder" );
932             return VLC_EGENERIC;
933         }
934
935         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
936         {
937             int b_gotpicture;
938             AVFrame frame;
939             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
940                                      FF_INPUT_BUFFER_PADDING_SIZE );
941
942             memcpy( p_vol, id->ff_dec_c->extradata,
943                     id->ff_dec_c->extradata_size );
944             memset( p_vol + id->ff_dec_c->extradata_size, 0,
945                     FF_INPUT_BUFFER_PADDING_SIZE );
946
947             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
948                                   id->ff_dec_c->extradata,
949                                   id->ff_dec_c->extradata_size );
950             free( p_vol );
951         }
952     }
953
954     /* Open encoder */
955     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
956     id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
957     id->p_encoder->format.video.i_width = p_sys->i_width;
958     id->p_encoder->format.video.i_height = p_sys->i_height;
959     id->p_encoder->i_bitrate = p_sys->i_vbitrate;
960
961     id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
962     id->p_encoder->i_key_int = p_sys->i_key_int;
963     id->p_encoder->i_b_frames = p_sys->i_b_frames;
964     id->p_encoder->i_qmin = p_sys->i_qmin;
965     id->p_encoder->i_qmax = p_sys->i_qmax;
966     id->p_encoder->i_hq = p_sys->i_hq;
967
968     if( id->p_encoder->format.video.i_width <= 0 )
969     {
970         id->p_encoder->format.video.i_width = id->f_dst.i_width =
971             id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
972     }
973     if( id->p_encoder->format.video.i_height <= 0 )
974     {
975         id->p_encoder->format.video.i_height = id->f_dst.i_height =
976             id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
977     }
978
979     id->p_ff_pic         = avcodec_alloc_frame();
980     id->p_ff_pic_tmp0    = NULL;
981     id->p_ff_pic_tmp1    = NULL;
982     id->p_ff_pic_tmp2    = NULL;
983     id->p_vresample      = NULL;
984
985     if( id->ff_dec )
986     {
987         id->p_encoder->i_frame_rate = id->ff_dec_c->frame_rate;
988 #if LIBAVCODEC_BUILD >= 4662
989         id->p_encoder->i_frame_rate_base= id->ff_dec_c->frame_rate_base;
990 #endif
991
992 #if LIBAVCODEC_BUILD >= 4687
993         id->p_encoder->i_aspect = VOUT_ASPECT_FACTOR *
994             ( av_q2d(id->ff_dec_c->sample_aspect_ratio) *
995               id->ff_dec_c->width / id->ff_dec_c->height );
996 #else
997         id->p_encoder->i_aspect = VOUT_ASPECT_FACTOR *
998             id->ff_dec_c->aspect_ratio;
999 #endif
1000
1001     }
1002     else
1003     {
1004 #if LIBAVCODEC_BUILD >= 4662
1005         id->p_encoder->i_frame_rate     = 25 ; /* FIXME as it break mpeg */
1006         id->p_encoder->i_frame_rate_base= 1;
1007 #else
1008         id->p_encoder->i_frame_rate     = 25 * FRAME_RATE_BASE;
1009 #endif
1010     }
1011
1012     id->p_encoder->p_module =
1013         module_Need( id->p_encoder, "video encoder", NULL );
1014
1015     if( !id->p_encoder->p_module )
1016     {
1017         vlc_object_destroy( id->p_encoder );
1018         msg_Err( p_stream, "cannot find encoder" );
1019         return VLC_EGENERIC;
1020     }
1021
1022     /* Close the encoder.
1023      * We'll open it only when we have the first frame */
1024     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1025
1026     id->b_enc_inited = VLC_FALSE;
1027
1028     return VLC_SUCCESS;
1029 }
1030
1031 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream,
1032                                            sout_stream_id_t *id )
1033 {
1034     /* Close decoder */
1035     if( id->ff_dec )
1036     {
1037         avcodec_close( id->ff_dec_c );
1038         free( id->ff_dec_c );
1039     }
1040
1041     /* Close encoder */
1042     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1043     vlc_object_destroy( id->p_encoder );
1044
1045     /* Misc cleanup */
1046     if( id->p_ff_pic)
1047     {
1048         free( id->p_ff_pic );
1049     }
1050
1051     if( id->p_ff_pic_tmp0 )
1052     {
1053         free( id->p_ff_pic_tmp0->data[0] );
1054         free( id->p_ff_pic_tmp0 );
1055     }
1056     if( id->p_ff_pic_tmp1)
1057     {
1058         free( id->p_ff_pic_tmp1->data[0] );
1059         free( id->p_ff_pic_tmp1 );
1060     }
1061     if( id->p_ff_pic_tmp2)
1062     {
1063         free( id->p_ff_pic_tmp2->data[0] );
1064         free( id->p_ff_pic_tmp2 );
1065     }
1066     if( id->p_vresample )
1067     {
1068         free( id->p_vresample );
1069     }
1070 }
1071
1072 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1073                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1074 {
1075     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1076     int     i_used;
1077     int     b_gotpicture;
1078     AVFrame *frame;
1079
1080     int     i_data;
1081     uint8_t *p_data;
1082
1083     *out = NULL;
1084
1085     i_data = in->i_size;
1086     p_data = in->p_buffer;
1087  
1088     for( ;; )
1089     {
1090         block_t *p_block;
1091         picture_t pic;
1092         int i_plane;
1093
1094         /* decode frame */
1095         frame = id->p_ff_pic;
1096         p_sys->i_input_pts = in->i_pts;
1097        if( id->ff_dec )
1098         {
1099             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1100                                            &b_gotpicture,
1101                                            p_data, i_data );
1102         }
1103         else
1104         {
1105             /* raw video */
1106             avpicture_fill( (AVPicture*)frame,
1107                             p_data,
1108                             id->ff_dec_c->pix_fmt,
1109                             id->ff_dec_c->width, id->ff_dec_c->height );
1110             i_used = i_data;
1111             b_gotpicture = 1;
1112
1113             /* Set PTS */
1114             frame->pts = p_sys->i_input_pts;
1115         }
1116
1117         if( i_used < 0 )
1118         {
1119             msg_Warn( p_stream, "error");
1120             return VLC_EGENERIC;
1121         }
1122         i_data -= i_used;
1123         p_data += i_used;
1124
1125         if( !b_gotpicture )
1126         {
1127             return VLC_SUCCESS;
1128         }
1129
1130         /* Get the pts of the decoded frame if any, otherwise keep the
1131          * interpolated one */
1132         if( frame->pts > 0 )
1133         {
1134             p_sys->i_output_pts = frame->pts;
1135         }
1136
1137         if( !id->b_enc_inited )
1138         {
1139             /* XXX hack because of copy packetizer and mpeg4video that can fail
1140              * detecting size */
1141             if( id->p_encoder->format.video.i_width <= 0 )
1142             {
1143                 id->p_encoder->format.video.i_width = id->f_dst.i_width =
1144                     id->ff_dec_c->width - p_sys->i_crop_left -
1145                     p_sys->i_crop_right;
1146             }
1147             if( id->p_encoder->format.video.i_height <= 0 )
1148             {
1149                 id->p_encoder->format.video.i_height = id->f_dst.i_height =
1150                     id->ff_dec_c->height - p_sys->i_crop_top -
1151                     p_sys->i_crop_bottom;
1152             }
1153
1154             id->p_encoder->i_bitrate = p_sys->i_vbitrate;
1155
1156             id->p_encoder->i_extra_data = 0;
1157             id->p_encoder->p_extra_data = NULL;
1158
1159             id->p_encoder->p_module =
1160                 module_Need( id->p_encoder, "video encoder", NULL );
1161             if( !id->p_encoder->p_module )
1162             {
1163                 vlc_object_destroy( id->p_encoder );
1164                 msg_Err( p_stream, "cannot find encoder" );
1165                 return VLC_EGENERIC;
1166             }
1167
1168             id->f_dst.i_extra_data = id->p_encoder->i_extra_data;
1169             id->f_dst.p_extra_data = id->p_encoder->p_extra_data;
1170
1171             /* Hack for mp2v/mp1v transcoding support */
1172             if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' ) ||
1173                 id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
1174             {
1175                 id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','v' );
1176             }
1177
1178             if( !( id->id =
1179                      p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1180                                                      &id->f_dst ) ) )
1181             {
1182                 msg_Err( p_stream, "cannot add this stream" );
1183                 transcode_video_ffmpeg_close( p_stream, id );
1184                 id->b_transcode = VLC_FALSE;
1185                 return VLC_EGENERIC;
1186             }
1187
1188             while( id->p_encoder->pf_header &&
1189                    (p_block = id->p_encoder->pf_header( id->p_encoder )) )
1190             {
1191                 sout_buffer_t *p_out;
1192                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1193                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1194                 p_out->i_dts = in->i_dts;
1195                 p_out->i_pts = in->i_dts;
1196                 p_out->i_length = 0;
1197                 sout_BufferChain( out, p_out );
1198             }
1199
1200             id->i_inter_pixfmt =
1201                 get_ff_chroma( id->p_encoder->format.video.i_chroma );
1202
1203             id->b_enc_inited = VLC_TRUE;
1204         }
1205
1206         /* deinterlace */
1207         if( p_stream->p_sys->b_deinterlace )
1208         {
1209             if( id->p_ff_pic_tmp0 == NULL )
1210             {
1211                 int     i_size;
1212                 uint8_t *buf;
1213                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1214                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1215                                              id->ff_dec_c->width, id->ff_dec_c->height );
1216
1217                 buf = malloc( i_size );
1218
1219                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1220                                 id->i_inter_pixfmt,
1221                                 id->ff_dec_c->width, id->ff_dec_c->height );
1222             }
1223
1224             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1225                                    id->ff_dec_c->pix_fmt,
1226                                    id->ff_dec_c->width, id->ff_dec_c->height );
1227
1228             frame = id->p_ff_pic_tmp0;
1229         }
1230
1231         /* convert pix format */
1232         if( id->ff_dec_c->pix_fmt != id->i_inter_pixfmt )
1233         {
1234             if( id->p_ff_pic_tmp1 == NULL )
1235             {
1236                 int     i_size;
1237                 uint8_t *buf;
1238                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1239                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1240                                              id->ff_dec_c->width,
1241                                              id->ff_dec_c->height );
1242
1243                 buf = malloc( i_size );
1244
1245                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1246                                 id->i_inter_pixfmt,
1247                                 id->ff_dec_c->width, id->ff_dec_c->height );
1248             }
1249
1250             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->i_inter_pixfmt,
1251                          (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1252                          id->ff_dec_c->width, id->ff_dec_c->height );
1253
1254             frame = id->p_ff_pic_tmp1;
1255         }
1256
1257         /* convert size and crop */
1258         if( id->ff_dec_c->width  != id->f_dst.i_width ||
1259             id->ff_dec_c->height != id->f_dst.i_height ||
1260             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1261             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1262         {
1263             if( id->p_ff_pic_tmp2 == NULL )
1264             {
1265                 int     i_size;
1266                 uint8_t *buf;
1267                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1268                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1269                                              id->f_dst.i_width,
1270                                              id->f_dst.i_height );
1271
1272                 buf = malloc( i_size );
1273
1274                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1275                                 id->i_inter_pixfmt,
1276                                 id->f_dst.i_width, id->f_dst.i_height );
1277
1278                 id->p_vresample =
1279                     img_resample_full_init( id->f_dst.i_width,
1280                                             id->f_dst.i_height,
1281                                             id->ff_dec_c->width, id->ff_dec_c->height,
1282                                             p_stream->p_sys->i_crop_top,
1283                                             p_stream->p_sys->i_crop_bottom,
1284                                             p_stream->p_sys->i_crop_left,
1285                                             p_stream->p_sys->i_crop_right );
1286             }
1287
1288             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1289                           (AVPicture*)frame );
1290
1291             frame = id->p_ff_pic_tmp2;
1292         }
1293
1294         /* Encoding */
1295         vout_InitPicture( VLC_OBJECT(p_stream), &pic,
1296                           id->p_encoder->format.video.i_chroma,
1297                           id->f_dst.i_width, id->f_dst.i_height,
1298                           id->f_dst.i_width * VOUT_ASPECT_FACTOR /
1299                           id->f_dst.i_height );
1300
1301         for( i_plane = 0; i_plane < pic.i_planes; i_plane++ )
1302         {
1303             pic.p[i_plane].p_pixels = frame->data[i_plane];
1304             pic.p[i_plane].i_pitch = frame->linesize[i_plane];
1305         }
1306
1307         /* Set the pts of the frame being encoded */
1308         pic.date = p_sys->i_output_pts;
1309
1310         /* Interpolate the next PTS
1311          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1312         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1313         {
1314             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1315               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1316         }
1317
1318         p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic );
1319         while( p_block )
1320         {
1321             sout_buffer_t *p_out;
1322             block_t *p_prev_block = p_block;
1323
1324             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1325             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1326             p_out->i_dts = p_block->i_dts;
1327             p_out->i_pts = p_block->i_pts;
1328             p_out->i_length = p_block->i_length;
1329             sout_BufferChain( out, p_out );
1330
1331             p_block = p_block->p_next;
1332             block_Release( p_prev_block );
1333         }
1334
1335         if( i_data <= 0 )
1336         {
1337             return VLC_SUCCESS;
1338         }
1339     }
1340
1341     return VLC_SUCCESS;
1342 }
1343
1344 /*****************************************************************************
1345  * transcode_video_ffmpeg_getframebuf:
1346  *
1347  * Callback used by ffmpeg to get a frame buffer.
1348  * We use it to get the right PTS for each decoded picture.
1349  *****************************************************************************/
1350 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1351                                               AVFrame *p_frame)
1352 {
1353     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1354
1355     /* Set PTS */
1356     p_frame->pts = p_sys->i_input_pts;
1357
1358     return avcodec_default_get_buffer( p_context, p_frame );
1359 }