]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
1a4a19382e5f38e8c85905f4f10b7de3e7423677
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.29 2003/08/09 14:59:24 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <vlc/vlc.h>
31 #include <vlc/input.h>
32 #include <vlc/sout.h>
33
34 /* ffmpeg header */
35 #ifdef HAVE_FFMPEG_AVCODEC_H
36 #   include <ffmpeg/avcodec.h>
37 #else
38 #   include <avcodec.h>
39 #endif
40
41 /* vorbis header */
42 #ifdef HAVE_VORBIS_VORBISENC_H
43 #   include <vorbis/vorbisenc.h>
44 #   ifndef OV_ECTL_RATEMANAGE_AVG
45 #       define OV_ECTL_RATEMANAGE_AVG 0x0
46 #   endif
47 #endif
48
49 /*****************************************************************************
50  * Exported prototypes
51  *****************************************************************************/
52 static int      Open    ( vlc_object_t * );
53 static void     Close   ( vlc_object_t * );
54
55 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
56 static int               Del ( sout_stream_t *, sout_stream_id_t * );
57 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
58
59 static int  transcode_audio_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
60 static void transcode_audio_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
61 static int  transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
62
63 static int  transcode_video_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
64 static void transcode_video_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
65 static int  transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
66
67 static int  transcode_video_ffmpeg_getframebuf( struct AVCodecContext *, AVFrame *);
68
69 /*****************************************************************************
70  * Module descriptor
71  *****************************************************************************/
72 vlc_module_begin();
73     set_description( _("Transcode stream") );
74     set_capability( "sout stream", 50 );
75     add_shortcut( "transcode" );
76     set_callbacks( Open, Close );
77 vlc_module_end();
78
79 struct sout_stream_sys_t
80 {
81     sout_stream_t   *p_out;
82
83     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
84     int             i_sample_rate;
85     int             i_channels;
86     int             i_abitrate;
87
88     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
89     int             i_vbitrate;
90     int             i_vtolerance;
91     int             i_width;
92     int             i_height;
93     int             i_b_frames;
94     int             i_key_int;
95     int             i_qmin;
96     int             i_qmax;
97     vlc_bool_t      i_hq;
98     vlc_bool_t      b_deinterlace;
99
100     int             i_crop_top;
101     int             i_crop_bottom;
102     int             i_crop_right;
103     int             i_crop_left;
104
105     mtime_t         i_input_pts;
106     mtime_t         i_output_pts;
107     mtime_t         i_last_ref_pts;
108
109     mtime_t         i_buggy_pts_detect;
110 };
111
112 /*****************************************************************************
113  * Open:
114  *****************************************************************************/
115 static int Open( vlc_object_t *p_this )
116 {
117     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
118     sout_stream_sys_t *p_sys;
119     char *codec;
120
121     p_sys = malloc( sizeof( sout_stream_sys_t ) );
122     p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
123
124     p_sys->i_acodec      = 0;
125     p_sys->i_sample_rate = 0;
126     p_sys->i_channels    = 0;
127     p_sys->i_abitrate    = 0;
128
129     p_sys->i_vcodec     = 0;
130     p_sys->i_vbitrate   = 0;
131     p_sys->i_vtolerance = -1;
132     p_sys->i_width      = 0;
133     p_sys->i_height     = 0;
134     p_sys->i_key_int    = -1;
135     p_sys->i_b_frames   = 0;
136     p_sys->i_qmin       = 2;
137     p_sys->i_qmax       = 31;
138 #if LIBAVCODEC_BUILD >= 4673
139     p_sys->i_hq         = FF_MB_DECISION_SIMPLE;
140 #else
141     p_sys->i_hq         = VLC_FALSE;
142 #endif
143     p_sys->b_deinterlace= VLC_FALSE;
144
145     p_sys->i_crop_top   = 0;
146     p_sys->i_crop_bottom= 0;
147     p_sys->i_crop_right = 0;
148     p_sys->i_crop_left  = 0;
149
150     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "acodec" ) ) )
151     {
152         char fcc[4] = "    ";
153         char *val;
154
155         memcpy( fcc, codec, strlen( codec ) );
156
157         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
158
159         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "samplerate" ) ) )
160         {
161             p_sys->i_sample_rate = atoi( val );
162         }
163         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "channels" ) ) )
164         {
165             p_sys->i_channels = atoi( val );
166         }
167         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
168         {
169             p_sys->i_abitrate = atoi( val );
170             if( p_sys->i_abitrate < 4000 )
171             {
172                 p_sys->i_abitrate *= 1000;
173             }
174         }
175
176         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", fcc,
177                  p_sys->i_sample_rate, p_sys->i_channels,
178                  p_sys->i_abitrate / 1024 );
179     }
180
181     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
182     {
183         char fcc[4] = "    ";
184         char *val;
185
186         memcpy( fcc, codec, strlen( codec ) );
187
188         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
189
190         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
191         {
192             p_sys->i_width = atoi( val );
193         }
194         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
195         {
196             p_sys->i_height = atoi( val );
197         }
198         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
199         {
200             p_sys->i_vbitrate = atoi( val );
201             if( p_sys->i_vbitrate < 16000 )
202             {
203                 p_sys->i_vbitrate *= 1000;
204             }
205         }
206         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
207         {
208             p_sys->i_vtolerance = atoi( val );
209         }
210         if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
211         {
212             p_sys->b_deinterlace = VLC_TRUE;
213         }
214         /* crop */
215         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
216         {
217             p_sys->i_crop_top = atoi( val );
218         }
219         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
220         {
221             p_sys->i_crop_bottom = atoi( val );
222         }
223         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
224         {
225             p_sys->i_crop_left = atoi( val );
226         }
227         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
228         {
229             p_sys->i_crop_right = atoi( val );
230         }
231         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
232         {
233             p_sys->i_key_int    = atoi( val );
234         }
235         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "bframes" ) ) )
236         {
237             p_sys->i_b_frames   = atoi( val );
238         }
239 #if LIBAVCODEC_BUILD >= 4673
240         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "hq" ) ) )
241         {
242             if( !strcmp( val, "rd" ) )
243             {
244                 p_sys->i_hq = FF_MB_DECISION_RD;
245             }
246             else if( !strcmp( val, "bits" ) )
247             {
248                 p_sys->i_hq = FF_MB_DECISION_BITS;
249             }
250             else if( !strcmp( val, "simple" ) )
251             {
252                 p_sys->i_hq = FF_MB_DECISION_SIMPLE;
253             }
254             else
255             {
256                 p_sys->i_hq = FF_MB_DECISION_RD;
257             }
258         }
259 #else
260         if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
261         {
262             p_sys->i_hq = VLC_TRUE;
263         }
264 #endif
265         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
266         {
267             p_sys->i_qmin   = atoi( val );
268         }
269         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
270         {
271             p_sys->i_qmax   = atoi( val );
272         }
273
274         msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
275                  fcc,
276                  p_sys->i_width, p_sys->i_height,
277                  p_sys->i_vbitrate / 1024 );
278     }
279
280     if( !p_sys->p_out )
281     {
282         msg_Err( p_stream, "cannot create chain" );
283         free( p_sys );
284         return VLC_EGENERIC;
285     }
286     p_stream->pf_add    = Add;
287     p_stream->pf_del    = Del;
288     p_stream->pf_send   = Send;
289
290     p_stream->p_sys     = p_sys;
291
292     avcodec_init();
293     avcodec_register_all();
294
295     /* ffmpeg needs some padding at the end of each buffer */
296     p_stream->p_sout->i_padding += FF_INPUT_BUFFER_PADDING_SIZE;
297
298     return VLC_SUCCESS;
299 }
300
301 /*****************************************************************************
302  * Close:
303  *****************************************************************************/
304
305 static void Close( vlc_object_t * p_this )
306 {
307     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
308     sout_stream_sys_t   *p_sys = p_stream->p_sys;
309
310     sout_stream_delete( p_sys->p_out );
311     free( p_sys );
312 }
313
314 struct sout_stream_id_t
315 {
316     vlc_fourcc_t  b_transcode;
317     sout_format_t f_src;        /* only if transcoding */
318     sout_format_t f_dst;        /*  "   "      " */
319
320     /* id of the out stream */
321     void *id;
322
323     /* ffmpeg part */
324     AVCodec         *ff_dec;
325     AVCodecContext  *ff_dec_c;
326
327
328     vlc_fourcc_t    b_enc_inited;
329     AVCodec         *ff_enc;
330     AVCodecContext  *ff_enc_c;
331
332     mtime_t         i_dts;
333     mtime_t         i_length;
334
335     int             i_buffer_in;
336     int             i_buffer_in_pos;
337     uint8_t         *p_buffer_in;
338
339     int             i_buffer;
340     int             i_buffer_pos;
341     uint8_t         *p_buffer;
342
343     int             i_buffer_out;
344     int             i_buffer_out_pos;
345     uint8_t         *p_buffer_out;
346
347     AVFrame         *p_ff_pic;
348     AVFrame         *p_ff_pic_tmp0; /* to do deinterlace */
349     AVFrame         *p_ff_pic_tmp1; /* to do pix conversion */
350     AVFrame         *p_ff_pic_tmp2; /* to do resample */
351
352     ImgReSampleContext *p_vresample;
353
354 #ifdef HAVE_VORBIS_VORBISENC_H
355
356     /* Vorbis part */
357     vorbis_info      *p_vi;
358     vorbis_dsp_state *p_vd;
359     vorbis_block     *p_vb;
360     vorbis_comment   *p_vc;
361     int              i_last_block_size;
362     int              i_samples_delay;
363     vlc_bool_t       b_headers_sent;
364 #endif
365 };
366
367
368 static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
369 {
370     sout_stream_sys_t   *p_sys = p_stream->p_sys;
371     sout_stream_id_t    *id;
372
373     id = malloc( sizeof( sout_stream_id_t ) );
374     id->i_dts = 0;
375     id->id = NULL;
376     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
377     {
378         msg_Dbg( p_stream,
379                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
380                  (char*)&p_fmt->i_fourcc,
381                  (char*)&p_sys->i_acodec );
382
383         /* src format */
384         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
385
386         /* create dst format */
387         id->f_dst.i_cat    = AUDIO_ES;
388         id->f_dst.i_fourcc = p_sys->i_acodec;
389         id->f_dst.i_sample_rate = p_sys->i_sample_rate  > 0 ? p_sys->i_sample_rate : id->f_src.i_sample_rate;
390         id->f_dst.i_channels    = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.i_channels;
391         id->f_dst.i_bitrate     = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
392         id->f_dst.i_block_align = 0;
393         id->f_dst.i_extra_data  = 0;
394         id->f_dst.p_extra_data  = NULL;
395
396         /* build decoder -> filter -> encoder */
397         if( transcode_audio_ffmpeg_new( p_stream, id ) )
398         {
399             msg_Err( p_stream, "cannot create audio chain" );
400             free( id );
401             return NULL;
402         }
403
404         /* open output stream */
405         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
406         id->b_transcode = VLC_TRUE;
407
408         if( id->id == NULL )
409         {
410             free( id );
411             return NULL;
412         }
413     }
414     else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
415     {
416         msg_Dbg( p_stream,
417                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
418                  (char*)&p_fmt->i_fourcc,
419                  (char*)&p_sys->i_vcodec );
420
421         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
422
423         /* create dst format */
424         id->f_dst.i_cat         = VIDEO_ES;
425         id->f_dst.i_fourcc      = p_sys->i_vcodec;
426         id->f_dst.i_width       = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
427         id->f_dst.i_height      = p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
428         id->f_dst.i_bitrate     = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
429         id->f_dst.i_extra_data  = 0;
430         id->f_dst.p_extra_data  = NULL;
431
432         /* build decoder -> filter -> encoder */
433         if( transcode_video_ffmpeg_new( p_stream, id ) )
434         {
435             msg_Err( p_stream, "cannot create video chain" );
436             free( id );
437             return NULL;
438         }
439 #if 0
440         /* open output stream */
441         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
442 #endif
443         id->b_transcode = VLC_TRUE;
444     }
445     else
446     {
447         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_fourcc );
448         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
449         id->b_transcode = VLC_FALSE;
450
451         if( id->id == NULL )
452         {
453             free( id );
454             return NULL;
455         }
456     }
457
458     return id;
459 }
460
461 static int     Del      ( sout_stream_t *p_stream, sout_stream_id_t *id )
462 {
463     sout_stream_sys_t   *p_sys = p_stream->p_sys;
464
465     if( id->b_transcode )
466     {
467         if( id->f_src.i_cat == AUDIO_ES )
468         {
469             transcode_audio_ffmpeg_close( p_stream, id );
470         }
471         else if( id->f_src.i_cat == VIDEO_ES )
472         {
473             transcode_video_ffmpeg_close( p_stream, id );
474         }
475     }
476
477     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
478     free( id );
479
480     return VLC_SUCCESS;
481 }
482
483 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
484                  sout_buffer_t *p_buffer )
485 {
486     sout_stream_sys_t   *p_sys = p_stream->p_sys;
487
488     if( id->b_transcode )
489     {
490         sout_buffer_t *p_buffer_out;
491         if( id->f_src.i_cat == AUDIO_ES )
492         {
493             transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
494         }
495         else if( id->f_src.i_cat == VIDEO_ES )
496         {
497             transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
498         }
499         sout_BufferDelete( p_stream->p_sout, p_buffer );
500
501         if( p_buffer_out )
502         {
503             return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
504         }
505         return VLC_SUCCESS;
506     }
507     else if( id->id != NULL )
508     {
509         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
510     }
511     else
512     {
513         sout_BufferDelete( p_stream->p_sout, p_buffer );
514         return VLC_EGENERIC;
515     }
516 }
517
518 /****************************************************************************
519  * ffmpeg decoder reencocdr part
520  ****************************************************************************/
521
522 static struct
523 {
524     vlc_fourcc_t i_fcc;
525     int          i_ff_codec;
526 } fourcc_to_ff_code[] =
527 {
528     /* audio */
529     { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
530     { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
531     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
532     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
533     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
534     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
535     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
536     { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
537
538     /* video */
539     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
540     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
541     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
542     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
543     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
544     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
545     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
546     { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
547     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
548     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
549     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
550     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
551     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
552     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
553 #if LIBAVCODEC_BUILD >= 4666
554     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
555 #endif
556
557     /* raw video code, only used for 'encoding' */
558     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
559     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
560     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
561     { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
562     { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
563     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
564     { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
565     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
566
567     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
568 };
569
570 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
571 {
572     int i;
573
574     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
575     {
576         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
577         {
578             return fourcc_to_ff_code[i].i_ff_codec;
579         }
580     }
581
582     return 0;
583 }
584
585 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
586 {
587     switch( i_chroma )
588     {
589         case VLC_FOURCC( 'I', '4', '2', '0' ):
590             return PIX_FMT_YUV420P;
591         case VLC_FOURCC( 'I', '4', '2', '2' ):
592             return PIX_FMT_YUV422P;
593         case VLC_FOURCC( 'I', '4', '4', '4' ):
594             return PIX_FMT_YUV444P;
595         case VLC_FOURCC( 'R', 'V', '1', '5' ):
596             return PIX_FMT_RGB555;
597         case VLC_FOURCC( 'R', 'V', '1', '6' ):
598             return PIX_FMT_RGB565;
599         case VLC_FOURCC( 'R', 'V', '2', '4' ):
600             return PIX_FMT_RGB24;
601         case VLC_FOURCC( 'R', 'V', '3', '2' ):
602             return PIX_FMT_RGBA32;
603         case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
604             return PIX_FMT_GRAY8;
605         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
606             return PIX_FMT_YUV422;
607         default:
608             return 0;
609     }
610 }
611
612 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
613                                        sout_stream_id_t *id )
614 {
615     int i_ff_codec;
616
617     if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
618         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
619         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
620         id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
621     {
622         id->ff_dec = NULL;
623
624         id->ff_dec_c = avcodec_alloc_context();
625         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
626         id->ff_dec_c->channels    = id->f_src.i_channels;
627         id->ff_dec_c->block_align = id->f_src.i_block_align;
628         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
629     }
630     else
631     {
632         /* find decoder */
633         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
634         if( i_ff_codec == 0 )
635         {
636             msg_Err( p_stream, "cannot find decoder id" );
637             return VLC_EGENERIC;
638         }
639
640         id->ff_dec = avcodec_find_decoder( i_ff_codec );
641         if( !id->ff_dec )
642         {
643             msg_Err( p_stream, "cannot find decoder (avcodec)" );
644             return VLC_EGENERIC;
645         }
646
647         id->ff_dec_c = avcodec_alloc_context();
648         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
649         id->ff_dec_c->channels    = id->f_src.i_channels;
650         id->ff_dec_c->block_align = id->f_src.i_block_align;
651         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
652
653         id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
654         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
655         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
656         {
657             msg_Err( p_stream, "cannot open decoder" );
658             return VLC_EGENERIC;
659         }
660     }
661
662     /* find encoder */
663     id->i_buffer_in      = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
664     id->i_buffer_in_pos = 0;
665     id->p_buffer_in      = malloc( id->i_buffer_in );
666
667     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
668     id->i_buffer_pos = 0;
669     id->p_buffer     = malloc( id->i_buffer );
670
671     id->i_buffer_out     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
672     id->i_buffer_out_pos = 0;
673     id->p_buffer_out     = malloc( id->i_buffer_out );
674
675     /* Sanity check for audio channels */
676     id->f_dst.i_channels = __MIN( id->f_dst.i_channels, id->f_src.i_channels );
677
678 #ifdef HAVE_VORBIS_VORBISENC_H
679     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
680     {
681         id->p_vi = (vorbis_info *)malloc( sizeof(vorbis_info) );
682         id->p_vd = (vorbis_dsp_state *)malloc( sizeof(vorbis_dsp_state) );
683         id->p_vb = (vorbis_block *)malloc( sizeof(vorbis_block) );
684         id->p_vc = (vorbis_comment *)malloc( sizeof(vorbis_comment) );
685
686         vorbis_info_init( id->p_vi );
687
688         if( vorbis_encode_setup_managed( id->p_vi, id->f_dst.i_channels,
689               id->f_dst.i_sample_rate, -1, id->f_dst.i_bitrate, -1 ) ||
690             vorbis_encode_ctl( id->p_vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
691              vorbis_encode_setup_init( id->p_vi ) ){}
692
693         /* add a comment */
694         vorbis_comment_init( id->p_vc);
695         vorbis_comment_add_tag( id->p_vc, "ENCODER", "VLC media player");
696
697         /* set up the analysis state and auxiliary encoding storage */
698         vorbis_analysis_init( id->p_vd, id->p_vi );
699         vorbis_block_init( id->p_vd, id->p_vb );
700
701         id->b_headers_sent = VLC_FALSE;
702         id->i_last_block_size = 0;
703         id->i_samples_delay = 0;
704
705         return VLC_SUCCESS;
706     }
707 #endif
708
709     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
710     if( i_ff_codec == 0 )
711     {
712         msg_Err( p_stream, "cannot find encoder id" );
713         return VLC_EGENERIC;
714     }
715
716     id->ff_enc = avcodec_find_encoder( i_ff_codec );
717     if( !id->ff_enc )
718     {
719         msg_Err( p_stream, "cannot find encoder (avcodec)" );
720         return VLC_EGENERIC;
721     }
722
723     /* Hack for mp3 transcoding support */
724     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
725     {
726         id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','a' );
727     }
728
729     id->ff_enc_c = avcodec_alloc_context();
730     id->ff_enc_c->bit_rate    = id->f_dst.i_bitrate;
731     id->ff_enc_c->sample_rate = id->f_dst.i_sample_rate;
732     id->ff_enc_c->channels    = id->f_dst.i_channels;
733
734     if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
735     {
736         if( id->ff_enc_c->channels > 2 )
737         {
738             id->ff_enc_c->channels = 2;
739             id->f_dst.i_channels   = 2;
740             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
741             {
742                 msg_Err( p_stream, "cannot open encoder" );
743                 return VLC_EGENERIC;
744             }
745             msg_Warn( p_stream, "stereo mode selected (codec limitation)" );
746         }
747         else
748         {
749             msg_Err( p_stream, "cannot open encoder" );
750             return VLC_EGENERIC;
751         }
752     }
753
754     return VLC_SUCCESS;
755 }
756
757 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
758                                           sout_stream_id_t *id )
759 {
760     if( id->ff_dec )
761     {
762         avcodec_close( id->ff_dec_c );
763     }
764
765 #ifdef HAVE_VORBIS_VORBISENC_H
766     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
767     {
768         vorbis_block_clear( id->p_vb );
769         vorbis_dsp_clear( id->p_vd );
770         vorbis_comment_clear( id->p_vc );
771         vorbis_info_clear( id->p_vi );  /* must be called last */
772
773         free( id->p_vi );
774         free( id->p_vd );
775         free( id->p_vb );
776         free( id->p_vc );
777     }
778     else
779 #endif
780         avcodec_close( id->ff_enc_c );
781
782     free( id->ff_dec_c );
783     if( id->f_dst.i_fourcc != VLC_FOURCC('v','o','r','b') )
784         free( id->ff_enc_c );
785
786     free( id->p_buffer_in );
787     free( id->p_buffer );
788     free( id->p_buffer_out );
789 }
790
791 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
792                                            sout_stream_id_t *id,
793                                            sout_buffer_t *in,
794                                            sout_buffer_t **out )
795 {
796     vlc_bool_t b_again = VLC_FALSE;
797
798     *out = NULL;
799
800     /* gather data into p_buffer_in */
801 #ifdef HAVE_VORBIS_VORBISENC_H
802     if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
803     id->i_dts = in->i_dts -
804                 (mtime_t)1000000 * (mtime_t)id->i_samples_delay /
805                 (mtime_t)id->f_dst.i_sample_rate;
806     else
807 #endif
808     id->i_dts = in->i_dts -
809                 (mtime_t)1000000 *
810                 (mtime_t)(id->i_buffer_pos / 2 / id->ff_dec_c->channels )/
811                 (mtime_t)id->ff_dec_c->sample_rate;
812
813     if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
814     {
815         /* extend buffer_in */
816         id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
817         id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
818     }
819     memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
820             in->p_buffer, in->i_size );
821     id->i_buffer_in_pos += in->i_size;
822
823     do
824     {
825         int i_buffer_pos;
826
827         /* decode as much data as possible */
828         if( id->ff_dec )
829         {
830             for( ;; )
831             {
832                 int i_buffer_size;
833                 int i_used;
834
835                 i_buffer_size = id->i_buffer - id->i_buffer_pos;
836
837                 i_used = avcodec_decode_audio( id->ff_dec_c,
838                          (int16_t*)&id->p_buffer[id->i_buffer_pos],
839                          &i_buffer_size, id->p_buffer_in,
840                          id->i_buffer_in_pos );
841
842                 /* msg_Warn( p_stream, "avcodec_decode_audio: %d used",
843                              i_used ); */
844                 id->i_buffer_pos += i_buffer_size;
845
846                 if( i_used < 0 )
847                 {
848                     msg_Warn( p_stream, "error");
849                     id->i_buffer_in_pos = 0;
850                     break;
851                 }
852                 else if( i_used < id->i_buffer_in_pos )
853                 {
854                     memmove( id->p_buffer_in,
855                              &id->p_buffer_in[i_used],
856                              id->i_buffer_in - i_used );
857                     id->i_buffer_in_pos -= i_used;
858                 }
859                 else
860                 {
861                     id->i_buffer_in_pos = 0;
862                     break;
863                 }
864
865                 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
866                 {
867                     /* buffer full */
868                     b_again = VLC_TRUE;
869                     break;
870                 }
871             }
872         }
873         else
874         {
875             int16_t *sout  = (int16_t*)&id->p_buffer[id->i_buffer_pos];
876             int     i_used = 0;
877
878             if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
879             {
880                 int8_t *sin = (int8_t*)id->p_buffer_in;
881                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
882                                            / 2, id->i_buffer_in_pos );
883                 i_used = i_samples;
884                 while( i_samples > 0 )
885                 {
886                     *sout++ = ( *sin++ ) << 8;
887                     i_samples--;
888                 }
889             }
890             else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
891             {
892                 int8_t *sin = (int8_t*)id->p_buffer_in;
893                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
894                                            / 2, id->i_buffer_in_pos );
895                 i_used = i_samples;
896                 while( i_samples > 0 )
897                 {
898                     *sout++ = ( *sin++ - 128 ) << 8;
899                     i_samples--;
900                 }
901             }
902             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
903             {
904                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
905                                            / 2, id->i_buffer_in_pos / 2);
906 #ifdef WORDS_BIGENDIAN
907                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
908                 i_used = i_samples * 2;
909                 while( i_samples > 0 )
910                 {
911                     uint8_t tmp[2];
912
913                     tmp[1] = *sin++;
914                     tmp[0] = *sin++;
915                     *sout++ = *(int16_t*)tmp;
916                     i_samples--;
917                 }
918
919 #else
920                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
921                 sout += i_samples;
922                 i_used = i_samples * 2;
923 #endif
924             }
925             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
926             {
927                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
928                                            / 2, id->i_buffer_in_pos / 2);
929 #ifdef WORDS_BIGENDIAN
930                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
931                 sout += i_samples;
932                 i_used = i_samples * 2;
933 #else
934                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
935                 i_used = i_samples * 2;
936                 while( i_samples > 0 )
937                 {
938                     uint8_t tmp[2];
939
940                     tmp[1] = *sin++;
941                     tmp[0] = *sin++;
942                     *sout++ = *(int16_t*)tmp;
943                     i_samples--;
944                 }
945 #endif
946             }
947
948             id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
949             if( i_used < id->i_buffer_in_pos )
950             {
951                 memmove( id->p_buffer_in,
952                          &id->p_buffer_in[i_used],
953                          id->i_buffer_in - i_used );
954             }
955             id->i_buffer_in_pos -= i_used;
956         }
957
958         i_buffer_pos = id->i_buffer_pos;
959
960         /* encode as much data as possible */
961
962 #ifdef HAVE_VORBIS_VORBISENC_H
963         if( id->i_buffer_pos == 0 );
964         else if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
965         {
966             float **buffer;
967             int i, j, i_samples;
968             sout_buffer_t *p_out;
969             ogg_packet op;
970
971             if( !id->b_headers_sent )
972             {
973                 ogg_packet header[3];
974                 vorbis_analysis_headerout( id->p_vd, id->p_vc,
975                                            &header[0], &header[1], &header[2]);
976                 for( i = 0; i < 3; i++ )
977                 {
978                     p_out = sout_BufferNew( p_stream->p_sout, header[i].bytes);
979                     memcpy( p_out->p_buffer, header[i].packet,
980                             header[i].bytes );
981
982                     p_out->i_size = header[i].bytes;
983                     p_out->i_length = 0;
984
985                     p_out->i_dts = p_out->i_pts = 0;
986
987                     sout_BufferChain( out, p_out );
988                 }
989                 id->b_headers_sent = VLC_TRUE;
990             }
991
992             i_samples = id->i_buffer_pos / id->f_src.i_channels / 2;
993             id->i_samples_delay += i_samples;
994             id->i_buffer_pos = 0;
995
996             buffer = vorbis_analysis_buffer( id->p_vd, i_samples );
997
998             /* convert samples to float and uninterleave */
999             for( i = 0; i < id->f_dst.i_channels; i++ )
1000             {
1001                 for( j = 0 ; j < i_samples ; j++ )
1002                 {
1003                     buffer[i][j]= ((float)( ((int16_t *)id->p_buffer)
1004                                   [j*id->f_src.i_channels + i ] ))/ 32768.f;
1005                 }
1006             }
1007
1008             vorbis_analysis_wrote( id->p_vd, i_samples );
1009
1010             while( vorbis_analysis_blockout( id->p_vd, id->p_vb ) == 1 )
1011             {
1012                 vorbis_analysis( id->p_vb, NULL );
1013                 vorbis_bitrate_addblock( id->p_vb );
1014
1015                 while( vorbis_bitrate_flushpacket( id->p_vd, &op ) )
1016                 {
1017                     int i_block_size;
1018                     p_out = sout_BufferNew( p_stream->p_sout, op.bytes );
1019                     memcpy( p_out->p_buffer, op.packet, op.bytes );
1020
1021                     i_block_size = vorbis_packet_blocksize( id->p_vi, &op );
1022
1023                     if( i_block_size < 0 ) i_block_size = 0;
1024                     i_samples = ( id->i_last_block_size +
1025                                   i_block_size ) >> 2;
1026                     id->i_last_block_size = i_block_size;
1027
1028                     p_out->i_size = op.bytes;
1029                     p_out->i_length = (mtime_t)1000000 *
1030                       (mtime_t)i_samples /
1031                       (mtime_t)id->f_dst.i_sample_rate;
1032
1033                     //msg_Err( p_stream, "i_dts: %lld", id->i_dts );
1034
1035                     /* FIXME */
1036                     p_out->i_dts = id->i_dts;
1037                     p_out->i_pts = id->i_dts;
1038
1039                     id->i_samples_delay -= i_samples;
1040
1041                     /* update dts */
1042                     id->i_dts += p_out->i_length;
1043                     sout_BufferChain( out, p_out );
1044
1045                 }
1046             }
1047         }
1048         else
1049 #endif
1050
1051         for( ;; )
1052         {
1053             int i_frame_size = id->ff_enc_c->frame_size * 2 *
1054                                  id->ff_dec_c->channels;
1055             int i_out_size, i, j;
1056             sout_buffer_t *p_out;
1057             int16_t *p_buffer = (int16_t *)(id->p_buffer + i_buffer_pos -
1058                                             id->i_buffer_pos);
1059
1060             if( id->i_buffer_pos < i_frame_size )
1061             {
1062                 break;
1063             }
1064
1065             if( id->ff_dec_c->channels != id->ff_enc_c->channels )
1066             {
1067                 /* dumb downmixing */
1068                 for( i = 0; i < id->ff_enc_c->frame_size; i++ )
1069                 {
1070                     for( j = 0 ; j < id->f_dst.i_channels; j++ )
1071                     {
1072                         p_buffer[i*id->f_dst.i_channels+j] = p_buffer[i*id->f_src.i_channels+j];
1073                     }
1074                 }
1075             }
1076
1077             /* msg_Warn( p_stream, "avcodec_encode_audio: frame size%d",
1078                          i_frame_size); */
1079             i_out_size = avcodec_encode_audio( id->ff_enc_c,
1080                            id->p_buffer_out, id->i_buffer_out, p_buffer );
1081
1082             if( i_out_size <= 0 )
1083             {
1084                 break;
1085             }
1086
1087             id->i_buffer_pos -= i_frame_size;
1088
1089             p_out = sout_BufferNew( p_stream->p_sout, i_out_size );
1090             memcpy( p_out->p_buffer, id->p_buffer_out, i_out_size );
1091             p_out->i_size = i_out_size;
1092             p_out->i_length = (mtime_t)1000000 *
1093                               (mtime_t)id->ff_enc_c->frame_size /
1094                               (mtime_t)id->ff_enc_c->sample_rate;
1095
1096             /* FIXME */
1097             p_out->i_dts = id->i_dts;
1098             p_out->i_pts = id->i_dts;
1099
1100             /* update dts */
1101             id->i_dts += p_out->i_length;
1102
1103            /* msg_Warn( p_stream, "frame dts=%lld len %lld out=%d",
1104                         p_out->i_dts, p_out->i_length, i_out_size ); */
1105
1106             sout_BufferChain( out, p_out );
1107         }
1108
1109         /* Copy the remaining raw samples */
1110         if( id->i_buffer_pos != 0 )
1111         {
1112             memmove( id->p_buffer,
1113                      &id->p_buffer[i_buffer_pos - id->i_buffer_pos],
1114                      id->i_buffer_pos );
1115         }
1116
1117     } while( b_again );
1118
1119     return VLC_SUCCESS;
1120 }
1121
1122
1123 /*
1124  * video
1125  */
1126 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1127                                        sout_stream_id_t *id )
1128 {
1129     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1130
1131     int i_ff_codec;
1132
1133     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1134         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1135         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1136         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1137         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
1138         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
1139         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
1140         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
1141         id->f_src.i_fourcc == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
1142     {
1143         id->ff_dec   = NULL;
1144         id->ff_dec_c            = avcodec_alloc_context();
1145         id->ff_dec_c->width     = id->f_src.i_width;
1146         id->ff_dec_c->height    = id->f_src.i_height;
1147         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
1148     }
1149     else
1150     {
1151         /* find decoder */
1152         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
1153         if( i_ff_codec == 0 )
1154         {
1155             msg_Err( p_stream, "cannot find decoder" );
1156             return VLC_EGENERIC;
1157         }
1158
1159         id->ff_dec = avcodec_find_decoder( i_ff_codec );
1160         if( !id->ff_dec )
1161         {
1162             msg_Err( p_stream, "cannot find decoder" );
1163             return VLC_EGENERIC;
1164         }
1165
1166         id->ff_dec_c = avcodec_alloc_context();
1167         id->ff_dec_c->width         = id->f_src.i_width;
1168         id->ff_dec_c->height        = id->f_src.i_height;
1169         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
1170         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
1171         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
1172         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1173         id->ff_dec_c->error_resilience= -1;
1174         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
1175         id->ff_dec_c->opaque        = p_sys;
1176
1177         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1178         {
1179             msg_Err( p_stream, "cannot open decoder" );
1180             return VLC_EGENERIC;
1181         }
1182
1183         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1184         {
1185             int b_gotpicture;
1186             AVFrame frame;
1187             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
1188                                      FF_INPUT_BUFFER_PADDING_SIZE );
1189
1190             memcpy( p_vol, id->ff_dec_c->extradata,
1191                     id->ff_dec_c->extradata_size );
1192             memset( p_vol + id->ff_dec_c->extradata_size, 0,
1193                     FF_INPUT_BUFFER_PADDING_SIZE );
1194
1195             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
1196                                   id->ff_dec_c->extradata,
1197                                   id->ff_dec_c->extradata_size );
1198             free( p_vol );
1199         }
1200     }
1201
1202
1203     /* find encoder */
1204     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
1205     if( i_ff_codec == 0 )
1206     {
1207         msg_Err( p_stream, "cannot find encoder" );
1208         return VLC_EGENERIC;
1209     }
1210
1211     id->ff_enc = avcodec_find_encoder( i_ff_codec );
1212     if( !id->ff_enc )
1213     {
1214         msg_Err( p_stream, "cannot find encoder" );
1215         return VLC_EGENERIC;
1216     }
1217
1218     id->ff_enc_c = avcodec_alloc_context();
1219     id->ff_enc_c->width          = id->f_dst.i_width;
1220     id->ff_enc_c->height         = id->f_dst.i_height;
1221     id->ff_enc_c->bit_rate       = id->f_dst.i_bitrate;
1222
1223     if( id->ff_dec )
1224     {
1225         id->ff_enc_c->frame_rate     = id->ff_dec_c->frame_rate;
1226 #if LIBAVCODEC_BUILD >= 4662
1227         id->ff_enc_c->frame_rate_base= id->ff_dec_c->frame_rate_base;
1228 #endif
1229     }
1230     else
1231     {
1232 #if LIBAVCODEC_BUILD >= 4662
1233         id->ff_enc_c->frame_rate     = 25 ; /* FIXME as it break mpeg */
1234         id->ff_enc_c->frame_rate_base= 1;
1235 #else
1236         id->ff_enc_c->frame_rate     = 25 * FRAME_RATE_BASE;
1237 #endif
1238     }
1239
1240     id->ff_enc_c->gop_size       = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
1241     id->ff_enc_c->max_b_frames   = __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES );
1242     id->ff_enc_c->b_frame_strategy = 0;
1243     id->ff_enc_c->b_quant_factor = 2.0;
1244
1245     if( p_sys->i_vtolerance >= 0 )
1246     {
1247         id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
1248     }
1249     id->ff_enc_c->qmin           = p_sys->i_qmin;
1250     id->ff_enc_c->qmax           = p_sys->i_qmax;
1251
1252 #if LIBAVCODEC_BUILD >= 4673
1253     id->ff_enc_c->mb_decision = p_sys->i_hq;
1254 #else
1255     if( p_sys->i_hq )
1256     {
1257         id->ff_enc_c->flags      |= CODEC_FLAG_HQ;
1258     }
1259 #endif
1260
1261     if( i_ff_codec == CODEC_ID_RAWVIDEO )
1262     {
1263         id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
1264     }
1265     /* XXX open it only when we have the first frame */
1266     id->b_enc_inited     = VLC_FALSE;
1267     id->i_buffer_in      = 0;
1268     id->i_buffer_in_pos  = 0;
1269     id->p_buffer_in      = NULL;
1270
1271     id->i_buffer     = 3*1024*1024;
1272     id->i_buffer_pos = 0;
1273     id->p_buffer     = malloc( id->i_buffer );
1274
1275     id->i_buffer_out     = 0;
1276     id->i_buffer_out_pos = 0;
1277     id->p_buffer_out     = NULL;
1278
1279     id->p_ff_pic         = avcodec_alloc_frame();
1280     id->p_ff_pic_tmp0    = NULL;
1281     id->p_ff_pic_tmp1    = NULL;
1282     id->p_ff_pic_tmp2    = NULL;
1283     id->p_vresample      = NULL;
1284
1285     p_sys->i_last_ref_pts = 0;
1286     p_sys->i_buggy_pts_detect = 0;
1287
1288     return VLC_SUCCESS;
1289 }
1290
1291 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
1292 {
1293     if( id->ff_dec )
1294     {
1295         avcodec_close( id->ff_dec_c );
1296     }
1297     if( id->b_enc_inited )
1298     {
1299         avcodec_close( id->ff_enc_c );
1300     }
1301
1302     if( id->p_ff_pic)
1303     {
1304         free( id->p_ff_pic );
1305     }
1306
1307     if( id->p_ff_pic_tmp0 )
1308     {
1309         free( id->p_ff_pic_tmp0->data[0] );
1310         free( id->p_ff_pic_tmp0 );
1311     }
1312     if( id->p_ff_pic_tmp1)
1313     {
1314         free( id->p_ff_pic_tmp1->data[0] );
1315         free( id->p_ff_pic_tmp1 );
1316     }
1317     if( id->p_ff_pic_tmp2)
1318     {
1319         free( id->p_ff_pic_tmp2->data[0] );
1320         free( id->p_ff_pic_tmp2 );
1321     }
1322     if( id->p_vresample )
1323     {
1324         free( id->p_vresample );
1325     }
1326
1327     free( id->ff_dec_c );
1328     free( id->ff_enc_c );
1329
1330     free( id->p_buffer );
1331 }
1332
1333 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1334                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1335 {
1336     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1337     int     i_used;
1338     int     i_out;
1339     int     b_gotpicture;
1340     AVFrame *frame;
1341
1342     int     i_data;
1343     uint8_t *p_data;
1344
1345     *out = NULL;
1346
1347     i_data = in->i_size;
1348     p_data = in->p_buffer;
1349
1350     for( ;; )
1351     {
1352         /* decode frame */
1353         frame = id->p_ff_pic;
1354         p_sys->i_input_pts = in->i_pts;
1355         if( id->ff_dec )
1356         {
1357             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1358                                            &b_gotpicture,
1359                                            p_data, i_data );
1360         }
1361         else
1362         {
1363             /* raw video */
1364             avpicture_fill( (AVPicture*)frame,
1365                             p_data,
1366                             id->ff_dec_c->pix_fmt,
1367                             id->ff_dec_c->width, id->ff_dec_c->height );
1368             i_used = i_data;
1369             b_gotpicture = 1;
1370
1371             /* Set PTS */
1372             frame->pts = p_sys->i_input_pts;
1373         }
1374
1375         if( i_used < 0 )
1376         {
1377             msg_Warn( p_stream, "error");
1378             return VLC_EGENERIC;
1379         }
1380         i_data -= i_used;
1381         p_data += i_used;
1382
1383         if( !b_gotpicture )
1384         {
1385             return VLC_SUCCESS;
1386         }
1387
1388         /* Get the pts of the decoded frame if any, otherwise keep the
1389          * interpolated one */
1390         if( frame->pts > 0 )
1391         {
1392             p_sys->i_output_pts = frame->pts;
1393         }
1394
1395         if( !id->b_enc_inited )
1396         {
1397             /* XXX hack because of copy packetizer and mpeg4video that can failed
1398                detecting size */
1399             if( id->ff_enc_c->width <= 0 )
1400             {
1401                 id->ff_enc_c->width    =
1402                     id->f_dst.i_width  = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1403             }
1404             if( id->ff_enc_c->height <= 0 )
1405             {
1406                 id->ff_enc_c->height   =
1407                     id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1408             }
1409
1410             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
1411             {
1412                 msg_Err( p_stream, "cannot open encoder" );
1413                 return VLC_EGENERIC;
1414             }
1415
1416             if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1417             {
1418                 msg_Err( p_stream, "cannot add this stream" );
1419                 transcode_video_ffmpeg_close( p_stream, id );
1420                 id->b_transcode = VLC_FALSE;
1421                 return VLC_EGENERIC;
1422             }
1423             id->b_enc_inited = VLC_TRUE;
1424         }
1425
1426
1427         /* deinterlace */
1428         if( p_stream->p_sys->b_deinterlace )
1429         {
1430             if( id->p_ff_pic_tmp0 == NULL )
1431             {
1432                 int     i_size;
1433                 uint8_t *buf;
1434                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1435                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1436                                              id->ff_dec_c->width, id->ff_dec_c->height );
1437
1438                 buf = malloc( i_size );
1439
1440                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1441                                 id->ff_enc_c->pix_fmt,
1442                                 id->ff_dec_c->width, id->ff_dec_c->height );
1443             }
1444
1445             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1446                                    id->ff_dec_c->pix_fmt,
1447                                    id->ff_dec_c->width, id->ff_dec_c->height );
1448
1449             frame = id->p_ff_pic_tmp0;
1450         }
1451
1452         /* convert pix format */
1453         if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
1454         {
1455             if( id->p_ff_pic_tmp1 == NULL )
1456             {
1457                 int     i_size;
1458                 uint8_t *buf;
1459                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1460                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1461                                              id->ff_dec_c->width, id->ff_dec_c->height );
1462
1463                 buf = malloc( i_size );
1464
1465                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1466                                 id->ff_enc_c->pix_fmt,
1467                                 id->ff_dec_c->width, id->ff_dec_c->height );
1468             }
1469
1470             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->ff_enc_c->pix_fmt,
1471                          (AVPicture*)frame,             id->ff_dec_c->pix_fmt,
1472                          id->ff_dec_c->width, id->ff_dec_c->height );
1473
1474             frame = id->p_ff_pic_tmp1;
1475         }
1476
1477         /* convert size and crop */
1478         if( id->ff_dec_c->width  != id->ff_enc_c->width ||
1479             id->ff_dec_c->height != id->ff_enc_c->height ||
1480             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1481             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1482         {
1483             if( id->p_ff_pic_tmp2 == NULL )
1484             {
1485                 int     i_size;
1486                 uint8_t *buf;
1487                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1488                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1489                                              id->ff_enc_c->width, id->ff_enc_c->height );
1490
1491                 buf = malloc( i_size );
1492
1493                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1494                                 id->ff_enc_c->pix_fmt,
1495                                 id->ff_enc_c->width, id->ff_enc_c->height );
1496
1497                 id->p_vresample =
1498                     img_resample_full_init( id->ff_enc_c->width, id->ff_enc_c->height,
1499                                             id->ff_dec_c->width, id->ff_dec_c->height,
1500                                             p_stream->p_sys->i_crop_top,
1501                                             p_stream->p_sys->i_crop_bottom,
1502                                             p_stream->p_sys->i_crop_left,
1503                                             p_stream->p_sys->i_crop_right );
1504             }
1505
1506             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1507                           (AVPicture*)frame );
1508
1509             frame = id->p_ff_pic_tmp2;
1510         }
1511
1512         /* Set the pts of the frame being encoded */
1513         frame->pts = p_sys->i_output_pts;
1514
1515         /* Interpolate the next PTS
1516          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1517         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1518         {
1519             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1520               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1521         }
1522
1523         /* Let ffmpeg select the frame type */
1524         frame->pict_type = 0;
1525
1526         i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer,
1527                                       id->i_buffer, frame );
1528         if( i_out > 0 )
1529         {
1530             sout_buffer_t *p_out;
1531             p_out = sout_BufferNew( p_stream->p_sout, i_out );
1532
1533             memcpy( p_out->p_buffer, id->p_buffer, i_out );
1534
1535             p_out->i_size   = i_out;
1536
1537             if( id->ff_enc_c->coded_frame->pts != 0 &&
1538                 p_sys->i_buggy_pts_detect != id->ff_enc_c->coded_frame->pts )
1539             {
1540                 p_sys->i_buggy_pts_detect = id->ff_enc_c->coded_frame->pts;
1541
1542                 /* FIXME, 3-2 pulldown is not handled correctly */
1543                 p_out->i_length = in->i_length;
1544                 p_out->i_pts    = id->ff_enc_c->coded_frame->pts;
1545
1546                 if( !id->ff_enc_c->delay ||
1547                     ( id->ff_enc_c->coded_frame->pict_type != FF_I_TYPE &&
1548                       id->ff_enc_c->coded_frame->pict_type != FF_P_TYPE ) )
1549                 {
1550                     p_out->i_dts    = p_out->i_pts;
1551                 }
1552                 else
1553                 {
1554                     if( p_sys->i_last_ref_pts )
1555                     {
1556                         p_out->i_dts = p_sys->i_last_ref_pts;
1557                     }
1558                     else
1559                     {
1560                         /* Let's put something sensible */
1561                         p_out->i_dts = p_out->i_pts;
1562                     }
1563
1564                     p_sys->i_last_ref_pts = p_out->i_pts;
1565                 }
1566             }
1567             else
1568             {
1569                 /* Buggy libavcodec which doesn't update coded_frame->pts
1570                  * correctly */
1571                 p_out->i_length = in->i_length;
1572                 p_out->i_dts    = in->i_dts;
1573                 p_out->i_pts    = in->i_dts;
1574             }
1575
1576             sout_BufferChain( out, p_out );
1577         }
1578
1579         if( i_data <= 0 )
1580         {
1581             return VLC_SUCCESS;
1582         }
1583     }
1584
1585     return VLC_SUCCESS;
1586 }
1587
1588 /*****************************************************************************
1589  * transcode_video_ffmpeg_getframebuf:
1590  *
1591  * Callback used by ffmpeg to get a frame buffer.
1592  * We use it to get the right PTS for each decoded picture.
1593  *****************************************************************************/
1594 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1595                                               AVFrame *p_frame)
1596 {
1597     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1598
1599     /* Set PTS */
1600     p_frame->pts = p_sys->i_input_pts;
1601
1602     return avcodec_default_get_buffer( p_context, p_frame );
1603 }