]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
718d5de069aac3a1c7f7a87c3e85ac12e6c0649e
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.34 2003/10/04 10:54:45 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( 'm', 'p', '4', 'a' ), CODEC_ID_AAC },
532     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
533     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
534     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
535     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
536     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
537     { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
538
539     /* video */
540     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
541     { VLC_FOURCC( 'm', 'p', '1', 'v' ), CODEC_ID_MPEG1VIDEO },
542 #if LIBAVCODEC_BUILD >= 4676
543     { VLC_FOURCC( 'm', 'p', '2', 'v' ), CODEC_ID_MPEG2VIDEO },
544 #endif
545     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
546     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
547     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
548     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
549     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
550     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
551     { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
552     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
553     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
554     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
555     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
556     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
557     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
558 #if LIBAVCODEC_BUILD >= 4666
559     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
560 #endif
561
562     /* raw video code, only used for 'encoding' */
563     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
564     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
565     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
566     { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
567     { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
568     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
569     { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
570     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
571
572     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
573 };
574
575 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
576 {
577     int i;
578
579     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
580     {
581         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
582         {
583             return fourcc_to_ff_code[i].i_ff_codec;
584         }
585     }
586
587     return 0;
588 }
589
590 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
591 {
592     switch( i_chroma )
593     {
594         case VLC_FOURCC( 'I', '4', '2', '0' ):
595             return PIX_FMT_YUV420P;
596         case VLC_FOURCC( 'I', '4', '2', '2' ):
597             return PIX_FMT_YUV422P;
598         case VLC_FOURCC( 'I', '4', '4', '4' ):
599             return PIX_FMT_YUV444P;
600         case VLC_FOURCC( 'R', 'V', '1', '5' ):
601             return PIX_FMT_RGB555;
602         case VLC_FOURCC( 'R', 'V', '1', '6' ):
603             return PIX_FMT_RGB565;
604         case VLC_FOURCC( 'R', 'V', '2', '4' ):
605             return PIX_FMT_RGB24;
606         case VLC_FOURCC( 'R', 'V', '3', '2' ):
607             return PIX_FMT_RGBA32;
608         case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
609             return PIX_FMT_GRAY8;
610         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
611             return PIX_FMT_YUV422;
612         default:
613             return 0;
614     }
615 }
616
617 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
618                                        sout_stream_id_t *id )
619 {
620     int i_ff_codec;
621
622     if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
623         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
624         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
625         id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
626     {
627         id->ff_dec = NULL;
628
629         id->ff_dec_c = avcodec_alloc_context();
630         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
631         id->ff_dec_c->channels    = id->f_src.i_channels;
632         id->ff_dec_c->block_align = id->f_src.i_block_align;
633         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
634     }
635     else
636     {
637         /* find decoder */
638         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
639         if( i_ff_codec == 0 )
640         {
641             msg_Err( p_stream, "cannot find decoder id" );
642             return VLC_EGENERIC;
643         }
644
645         id->ff_dec = avcodec_find_decoder( i_ff_codec );
646         if( !id->ff_dec )
647         {
648             msg_Err( p_stream, "cannot find decoder (avcodec)" );
649             return VLC_EGENERIC;
650         }
651
652         id->ff_dec_c = avcodec_alloc_context();
653         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
654         id->ff_dec_c->channels    = id->f_src.i_channels;
655         id->ff_dec_c->block_align = id->f_src.i_block_align;
656         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
657
658         id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
659         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
660         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
661         {
662             msg_Err( p_stream, "cannot open decoder" );
663             return VLC_EGENERIC;
664         }
665     }
666
667     /* find encoder */
668     id->i_buffer_in      = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
669     id->i_buffer_in_pos = 0;
670     id->p_buffer_in      = malloc( id->i_buffer_in );
671
672     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
673     id->i_buffer_pos = 0;
674     id->p_buffer     = malloc( id->i_buffer );
675
676     id->i_buffer_out     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
677     id->i_buffer_out_pos = 0;
678     id->p_buffer_out     = malloc( id->i_buffer_out );
679
680     /* Sanity check for audio channels */
681     id->f_dst.i_channels = __MIN( id->f_dst.i_channels, id->f_src.i_channels );
682
683 #ifdef HAVE_VORBIS_VORBISENC_H
684     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
685     {
686         id->p_vi = (vorbis_info *)malloc( sizeof(vorbis_info) );
687         id->p_vd = (vorbis_dsp_state *)malloc( sizeof(vorbis_dsp_state) );
688         id->p_vb = (vorbis_block *)malloc( sizeof(vorbis_block) );
689         id->p_vc = (vorbis_comment *)malloc( sizeof(vorbis_comment) );
690
691         vorbis_info_init( id->p_vi );
692
693         if( vorbis_encode_setup_managed( id->p_vi, id->f_dst.i_channels,
694               id->f_dst.i_sample_rate, -1, id->f_dst.i_bitrate, -1 ) ||
695             vorbis_encode_ctl( id->p_vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
696              vorbis_encode_setup_init( id->p_vi ) ){}
697
698         /* add a comment */
699         vorbis_comment_init( id->p_vc);
700         vorbis_comment_add_tag( id->p_vc, "ENCODER", "VLC media player");
701
702         /* set up the analysis state and auxiliary encoding storage */
703         vorbis_analysis_init( id->p_vd, id->p_vi );
704         vorbis_block_init( id->p_vd, id->p_vb );
705
706         id->b_headers_sent = VLC_FALSE;
707         id->i_last_block_size = 0;
708         id->i_samples_delay = 0;
709
710         return VLC_SUCCESS;
711     }
712 #endif
713
714     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
715     if( i_ff_codec == 0 )
716     {
717         msg_Err( p_stream, "cannot find encoder id" );
718         return VLC_EGENERIC;
719     }
720
721     id->ff_enc = avcodec_find_encoder( i_ff_codec );
722     if( !id->ff_enc )
723     {
724         msg_Err( p_stream, "cannot find encoder (avcodec)" );
725         return VLC_EGENERIC;
726     }
727
728     /* Hack for mp3 transcoding support */
729     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
730     {
731         id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','a' );
732     }
733
734     id->ff_enc_c = avcodec_alloc_context();
735     id->ff_enc_c->bit_rate    = id->f_dst.i_bitrate;
736     id->ff_enc_c->sample_rate = id->f_dst.i_sample_rate;
737     id->ff_enc_c->channels    = id->f_dst.i_channels;
738
739     /* Make sure we get extradata filled by the encoder */
740     id->ff_enc_c->extradata_size = 0;
741     id->ff_enc_c->extradata = NULL;
742     id->ff_enc_c->flags |= CODEC_FLAG_GLOBAL_HEADER;
743
744     if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
745     {
746         if( id->ff_enc_c->channels > 2 )
747         {
748             id->ff_enc_c->channels = 2;
749             id->f_dst.i_channels   = 2;
750             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
751             {
752                 msg_Err( p_stream, "cannot open encoder" );
753                 return VLC_EGENERIC;
754             }
755             msg_Warn( p_stream, "stereo mode selected (codec limitation)" );
756         }
757         else
758         {
759             msg_Err( p_stream, "cannot open encoder" );
760             return VLC_EGENERIC;
761         }
762     }
763
764     id->f_dst.i_extra_data = id->ff_enc_c->extradata_size;
765     id->f_dst.p_extra_data = id->ff_enc_c->extradata;
766     id->ff_enc_c->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
767
768     return VLC_SUCCESS;
769 }
770
771 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
772                                           sout_stream_id_t *id )
773 {
774     if( id->ff_dec )
775     {
776         avcodec_close( id->ff_dec_c );
777     }
778
779 #ifdef HAVE_VORBIS_VORBISENC_H
780     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
781     {
782         vorbis_block_clear( id->p_vb );
783         vorbis_dsp_clear( id->p_vd );
784         vorbis_comment_clear( id->p_vc );
785         vorbis_info_clear( id->p_vi );  /* must be called last */
786
787         free( id->p_vi );
788         free( id->p_vd );
789         free( id->p_vb );
790         free( id->p_vc );
791     }
792     else
793 #endif
794         avcodec_close( id->ff_enc_c );
795
796     free( id->ff_dec_c );
797     if( id->f_dst.i_fourcc != VLC_FOURCC('v','o','r','b') )
798         free( id->ff_enc_c );
799
800     free( id->p_buffer_in );
801     free( id->p_buffer );
802     free( id->p_buffer_out );
803 }
804
805 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
806                                            sout_stream_id_t *id,
807                                            sout_buffer_t *in,
808                                            sout_buffer_t **out )
809 {
810     vlc_bool_t b_again = VLC_FALSE;
811
812     *out = NULL;
813
814     /* gather data into p_buffer_in */
815 #ifdef HAVE_VORBIS_VORBISENC_H
816     if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
817     id->i_dts = in->i_dts -
818                 (mtime_t)1000000 * (mtime_t)id->i_samples_delay /
819                 (mtime_t)id->f_dst.i_sample_rate;
820     else
821 #endif
822     id->i_dts = in->i_dts -
823                 (mtime_t)1000000 *
824                 (mtime_t)(id->i_buffer_pos / 2 / id->ff_dec_c->channels )/
825                 (mtime_t)id->ff_dec_c->sample_rate;
826
827     if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
828     {
829         /* extend buffer_in */
830         id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
831         id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
832     }
833     memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
834             in->p_buffer, in->i_size );
835     id->i_buffer_in_pos += in->i_size;
836
837     do
838     {
839         int i_buffer_pos;
840
841         /* decode as much data as possible */
842         if( id->ff_dec )
843         {
844             for( ;; )
845             {
846                 int i_buffer_size;
847                 int i_used;
848
849                 i_buffer_size = id->i_buffer - id->i_buffer_pos;
850
851                 i_used = avcodec_decode_audio( id->ff_dec_c,
852                          (int16_t*)&id->p_buffer[id->i_buffer_pos],
853                          &i_buffer_size, id->p_buffer_in,
854                          id->i_buffer_in_pos );
855
856                 /* msg_Warn( p_stream, "avcodec_decode_audio: %d used",
857                              i_used ); */
858                 id->i_buffer_pos += i_buffer_size;
859
860                 if( i_used < 0 )
861                 {
862                     msg_Warn( p_stream, "error");
863                     id->i_buffer_in_pos = 0;
864                     break;
865                 }
866                 else if( i_used < id->i_buffer_in_pos )
867                 {
868                     memmove( id->p_buffer_in,
869                              &id->p_buffer_in[i_used],
870                              id->i_buffer_in - i_used );
871                     id->i_buffer_in_pos -= i_used;
872                 }
873                 else
874                 {
875                     id->i_buffer_in_pos = 0;
876                     break;
877                 }
878
879                 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
880                 {
881                     /* buffer full */
882                     b_again = VLC_TRUE;
883                     break;
884                 }
885             }
886         }
887         else
888         {
889             int16_t *sout  = (int16_t*)&id->p_buffer[id->i_buffer_pos];
890             int     i_used = 0;
891
892             if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
893             {
894                 int8_t *sin = (int8_t*)id->p_buffer_in;
895                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
896                                            / 2, id->i_buffer_in_pos );
897                 i_used = i_samples;
898                 while( i_samples > 0 )
899                 {
900                     *sout++ = ( *sin++ ) << 8;
901                     i_samples--;
902                 }
903             }
904             else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
905             {
906                 int8_t *sin = (int8_t*)id->p_buffer_in;
907                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
908                                            / 2, id->i_buffer_in_pos );
909                 i_used = i_samples;
910                 while( i_samples > 0 )
911                 {
912                     *sout++ = ( *sin++ - 128 ) << 8;
913                     i_samples--;
914                 }
915             }
916             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
917             {
918                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
919                                            / 2, id->i_buffer_in_pos / 2);
920 #ifdef WORDS_BIGENDIAN
921                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
922                 i_used = i_samples * 2;
923                 while( i_samples > 0 )
924                 {
925                     uint8_t tmp[2];
926
927                     tmp[1] = *sin++;
928                     tmp[0] = *sin++;
929                     *sout++ = *(int16_t*)tmp;
930                     i_samples--;
931                 }
932
933 #else
934                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
935                 sout += i_samples;
936                 i_used = i_samples * 2;
937 #endif
938             }
939             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
940             {
941                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
942                                            / 2, id->i_buffer_in_pos / 2);
943 #ifdef WORDS_BIGENDIAN
944                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
945                 sout += i_samples;
946                 i_used = i_samples * 2;
947 #else
948                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
949                 i_used = i_samples * 2;
950                 while( i_samples > 0 )
951                 {
952                     uint8_t tmp[2];
953
954                     tmp[1] = *sin++;
955                     tmp[0] = *sin++;
956                     *sout++ = *(int16_t*)tmp;
957                     i_samples--;
958                 }
959 #endif
960             }
961
962             id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
963             if( i_used < id->i_buffer_in_pos )
964             {
965                 memmove( id->p_buffer_in,
966                          &id->p_buffer_in[i_used],
967                          id->i_buffer_in - i_used );
968             }
969             id->i_buffer_in_pos -= i_used;
970         }
971
972         i_buffer_pos = id->i_buffer_pos;
973
974         /* encode as much data as possible */
975
976 #ifdef HAVE_VORBIS_VORBISENC_H
977         if( id->i_buffer_pos == 0 );
978         else if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
979         {
980             float **buffer;
981             int i, j, i_samples;
982             sout_buffer_t *p_out;
983             ogg_packet op;
984
985             if( !id->b_headers_sent )
986             {
987                 ogg_packet header[3];
988                 vorbis_analysis_headerout( id->p_vd, id->p_vc,
989                                            &header[0], &header[1], &header[2]);
990                 for( i = 0; i < 3; i++ )
991                 {
992                     p_out = sout_BufferNew( p_stream->p_sout, header[i].bytes);
993                     memcpy( p_out->p_buffer, header[i].packet,
994                             header[i].bytes );
995
996                     p_out->i_size = header[i].bytes;
997                     p_out->i_length = 0;
998
999                     p_out->i_dts = p_out->i_pts = 0;
1000
1001                     sout_BufferChain( out, p_out );
1002                 }
1003                 id->b_headers_sent = VLC_TRUE;
1004             }
1005
1006             i_samples = id->i_buffer_pos / id->f_src.i_channels / 2;
1007             id->i_samples_delay += i_samples;
1008             id->i_buffer_pos = 0;
1009
1010             buffer = vorbis_analysis_buffer( id->p_vd, i_samples );
1011
1012             /* convert samples to float and uninterleave */
1013             for( i = 0; i < id->f_dst.i_channels; i++ )
1014             {
1015                 for( j = 0 ; j < i_samples ; j++ )
1016                 {
1017                     buffer[i][j]= ((float)( ((int16_t *)id->p_buffer)
1018                                   [j*id->f_src.i_channels + i ] ))/ 32768.f;
1019                 }
1020             }
1021
1022             vorbis_analysis_wrote( id->p_vd, i_samples );
1023
1024             while( vorbis_analysis_blockout( id->p_vd, id->p_vb ) == 1 )
1025             {
1026                 vorbis_analysis( id->p_vb, NULL );
1027                 vorbis_bitrate_addblock( id->p_vb );
1028
1029                 while( vorbis_bitrate_flushpacket( id->p_vd, &op ) )
1030                 {
1031                     int i_block_size;
1032                     p_out = sout_BufferNew( p_stream->p_sout, op.bytes );
1033                     memcpy( p_out->p_buffer, op.packet, op.bytes );
1034
1035                     i_block_size = vorbis_packet_blocksize( id->p_vi, &op );
1036
1037                     if( i_block_size < 0 ) i_block_size = 0;
1038                     i_samples = ( id->i_last_block_size +
1039                                   i_block_size ) >> 2;
1040                     id->i_last_block_size = i_block_size;
1041
1042                     p_out->i_size = op.bytes;
1043                     p_out->i_length = (mtime_t)1000000 *
1044                       (mtime_t)i_samples /
1045                       (mtime_t)id->f_dst.i_sample_rate;
1046
1047                     //msg_Err( p_stream, "i_dts: %lld", id->i_dts );
1048
1049                     /* FIXME */
1050                     p_out->i_dts = id->i_dts;
1051                     p_out->i_pts = id->i_dts;
1052
1053                     id->i_samples_delay -= i_samples;
1054
1055                     /* update dts */
1056                     id->i_dts += p_out->i_length;
1057                     sout_BufferChain( out, p_out );
1058
1059                 }
1060             }
1061         }
1062         else
1063 #endif
1064
1065         for( ;; )
1066         {
1067             int i_frame_size = id->ff_enc_c->frame_size * 2 *
1068                                  id->ff_dec_c->channels;
1069             int i_out_size, i, j;
1070             sout_buffer_t *p_out;
1071             int16_t *p_buffer = (int16_t *)(id->p_buffer + i_buffer_pos -
1072                                             id->i_buffer_pos);
1073
1074             if( id->i_buffer_pos < i_frame_size )
1075             {
1076                 break;
1077             }
1078
1079             if( id->ff_dec_c->channels != id->ff_enc_c->channels )
1080             {
1081                 /* dumb downmixing */
1082                 for( i = 0; i < id->ff_enc_c->frame_size; i++ )
1083                 {
1084                     for( j = 0 ; j < id->f_dst.i_channels; j++ )
1085                     {
1086                         p_buffer[i*id->f_dst.i_channels+j] = p_buffer[i*id->f_src.i_channels+j];
1087                     }
1088                 }
1089             }
1090
1091             /* msg_Warn( p_stream, "avcodec_encode_audio: frame size%d",
1092                          i_frame_size); */
1093             i_out_size = avcodec_encode_audio( id->ff_enc_c,
1094                            id->p_buffer_out, id->i_buffer_out, p_buffer );
1095
1096             if( i_out_size <= 0 )
1097             {
1098                 break;
1099             }
1100
1101             id->i_buffer_pos -= i_frame_size;
1102
1103             p_out = sout_BufferNew( p_stream->p_sout, i_out_size );
1104             memcpy( p_out->p_buffer, id->p_buffer_out, i_out_size );
1105             p_out->i_size = i_out_size;
1106             p_out->i_length = (mtime_t)1000000 *
1107                               (mtime_t)id->ff_enc_c->frame_size /
1108                               (mtime_t)id->ff_enc_c->sample_rate;
1109
1110             /* FIXME */
1111             p_out->i_dts = id->i_dts;
1112             p_out->i_pts = id->i_dts;
1113
1114             /* update dts */
1115             id->i_dts += p_out->i_length;
1116
1117            /* msg_Warn( p_stream, "frame dts=%lld len %lld out=%d",
1118                         p_out->i_dts, p_out->i_length, i_out_size ); */
1119
1120             sout_BufferChain( out, p_out );
1121         }
1122
1123         /* Copy the remaining raw samples */
1124         if( id->i_buffer_pos != 0 )
1125         {
1126             memmove( id->p_buffer,
1127                      &id->p_buffer[i_buffer_pos - id->i_buffer_pos],
1128                      id->i_buffer_pos );
1129         }
1130
1131     } while( b_again );
1132
1133     return VLC_SUCCESS;
1134 }
1135
1136
1137 /*
1138  * video
1139  */
1140 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1141                                        sout_stream_id_t *id )
1142 {
1143     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1144
1145     int i_ff_codec;
1146
1147     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1148         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1149         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1150         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1151         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
1152         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
1153         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
1154         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
1155         id->f_src.i_fourcc == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
1156     {
1157         id->ff_dec   = NULL;
1158         id->ff_dec_c            = avcodec_alloc_context();
1159         id->ff_dec_c->width     = id->f_src.i_width;
1160         id->ff_dec_c->height    = id->f_src.i_height;
1161         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
1162     }
1163     else
1164     {
1165         /* find decoder */
1166         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
1167         if( i_ff_codec == 0 )
1168         {
1169             msg_Err( p_stream, "cannot find decoder" );
1170             return VLC_EGENERIC;
1171         }
1172
1173         id->ff_dec = avcodec_find_decoder( i_ff_codec );
1174         if( !id->ff_dec )
1175         {
1176             msg_Err( p_stream, "cannot find decoder" );
1177             return VLC_EGENERIC;
1178         }
1179
1180         id->ff_dec_c = avcodec_alloc_context();
1181         id->ff_dec_c->width         = id->f_src.i_width;
1182         id->ff_dec_c->height        = id->f_src.i_height;
1183         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
1184         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
1185         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
1186         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1187         id->ff_dec_c->error_resilience= -1;
1188         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
1189         id->ff_dec_c->opaque        = p_sys;
1190
1191         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1192         {
1193             msg_Err( p_stream, "cannot open decoder" );
1194             return VLC_EGENERIC;
1195         }
1196
1197         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1198         {
1199             int b_gotpicture;
1200             AVFrame frame;
1201             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
1202                                      FF_INPUT_BUFFER_PADDING_SIZE );
1203
1204             memcpy( p_vol, id->ff_dec_c->extradata,
1205                     id->ff_dec_c->extradata_size );
1206             memset( p_vol + id->ff_dec_c->extradata_size, 0,
1207                     FF_INPUT_BUFFER_PADDING_SIZE );
1208
1209             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
1210                                   id->ff_dec_c->extradata,
1211                                   id->ff_dec_c->extradata_size );
1212             free( p_vol );
1213         }
1214     }
1215
1216
1217     /* find encoder */
1218     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
1219     if( i_ff_codec == 0 )
1220     {
1221         msg_Err( p_stream, "cannot find encoder" );
1222         return VLC_EGENERIC;
1223     }
1224
1225     id->ff_enc = avcodec_find_encoder( i_ff_codec );
1226     if( !id->ff_enc )
1227     {
1228         msg_Err( p_stream, "cannot find encoder" );
1229         return VLC_EGENERIC;
1230     }
1231
1232     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' )||
1233         id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
1234     {
1235         id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','v' );
1236     }
1237
1238     id->ff_enc_c = avcodec_alloc_context();
1239     id->ff_enc_c->width          = id->f_dst.i_width;
1240     id->ff_enc_c->height         = id->f_dst.i_height;
1241     id->ff_enc_c->bit_rate       = id->f_dst.i_bitrate;
1242
1243     if( id->ff_dec )
1244     {
1245         id->ff_enc_c->frame_rate     = id->ff_dec_c->frame_rate;
1246 #if LIBAVCODEC_BUILD >= 4662
1247         id->ff_enc_c->frame_rate_base= id->ff_dec_c->frame_rate_base;
1248 #endif
1249     }
1250     else
1251     {
1252 #if LIBAVCODEC_BUILD >= 4662
1253         id->ff_enc_c->frame_rate     = 25 ; /* FIXME as it break mpeg */
1254         id->ff_enc_c->frame_rate_base= 1;
1255 #else
1256         id->ff_enc_c->frame_rate     = 25 * FRAME_RATE_BASE;
1257 #endif
1258     }
1259
1260     id->ff_enc_c->gop_size       = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
1261     id->ff_enc_c->max_b_frames   = __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES );
1262     id->ff_enc_c->b_frame_strategy = 0;
1263     id->ff_enc_c->b_quant_factor = 2.0;
1264
1265     if( p_sys->i_vtolerance >= 0 )
1266     {
1267         id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
1268     }
1269     id->ff_enc_c->qmin           = p_sys->i_qmin;
1270     id->ff_enc_c->qmax           = p_sys->i_qmax;
1271
1272 #if LIBAVCODEC_BUILD >= 4673
1273     id->ff_enc_c->mb_decision = p_sys->i_hq;
1274 #else
1275     if( p_sys->i_hq )
1276     {
1277         id->ff_enc_c->flags      |= CODEC_FLAG_HQ;
1278     }
1279 #endif
1280
1281     if( i_ff_codec == CODEC_ID_RAWVIDEO )
1282     {
1283         id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
1284     }
1285     /* XXX open it only when we have the first frame */
1286     id->b_enc_inited     = VLC_FALSE;
1287     id->i_buffer_in      = 0;
1288     id->i_buffer_in_pos  = 0;
1289     id->p_buffer_in      = NULL;
1290
1291     id->i_buffer     = 3*1024*1024;
1292     id->i_buffer_pos = 0;
1293     id->p_buffer     = malloc( id->i_buffer );
1294
1295     id->i_buffer_out     = 0;
1296     id->i_buffer_out_pos = 0;
1297     id->p_buffer_out     = NULL;
1298
1299     id->p_ff_pic         = avcodec_alloc_frame();
1300     id->p_ff_pic_tmp0    = NULL;
1301     id->p_ff_pic_tmp1    = NULL;
1302     id->p_ff_pic_tmp2    = NULL;
1303     id->p_vresample      = NULL;
1304
1305     p_sys->i_last_ref_pts = 0;
1306     p_sys->i_buggy_pts_detect = 0;
1307
1308     return VLC_SUCCESS;
1309 }
1310
1311 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
1312 {
1313     if( id->ff_dec )
1314     {
1315         avcodec_close( id->ff_dec_c );
1316     }
1317     if( id->b_enc_inited )
1318     {
1319         avcodec_close( id->ff_enc_c );
1320     }
1321
1322     if( id->p_ff_pic)
1323     {
1324         free( id->p_ff_pic );
1325     }
1326
1327     if( id->p_ff_pic_tmp0 )
1328     {
1329         free( id->p_ff_pic_tmp0->data[0] );
1330         free( id->p_ff_pic_tmp0 );
1331     }
1332     if( id->p_ff_pic_tmp1)
1333     {
1334         free( id->p_ff_pic_tmp1->data[0] );
1335         free( id->p_ff_pic_tmp1 );
1336     }
1337     if( id->p_ff_pic_tmp2)
1338     {
1339         free( id->p_ff_pic_tmp2->data[0] );
1340         free( id->p_ff_pic_tmp2 );
1341     }
1342     if( id->p_vresample )
1343     {
1344         free( id->p_vresample );
1345     }
1346
1347     free( id->ff_dec_c );
1348     free( id->ff_enc_c );
1349
1350     free( id->p_buffer );
1351 }
1352
1353 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1354                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1355 {
1356     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1357     int     i_used;
1358     int     i_out;
1359     int     b_gotpicture;
1360     AVFrame *frame;
1361
1362     int     i_data;
1363     uint8_t *p_data;
1364
1365     *out = NULL;
1366
1367     i_data = in->i_size;
1368     p_data = in->p_buffer;
1369
1370     for( ;; )
1371     {
1372         /* decode frame */
1373         frame = id->p_ff_pic;
1374         p_sys->i_input_pts = in->i_pts;
1375         if( id->ff_dec )
1376         {
1377             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1378                                            &b_gotpicture,
1379                                            p_data, i_data );
1380         }
1381         else
1382         {
1383             /* raw video */
1384             avpicture_fill( (AVPicture*)frame,
1385                             p_data,
1386                             id->ff_dec_c->pix_fmt,
1387                             id->ff_dec_c->width, id->ff_dec_c->height );
1388             i_used = i_data;
1389             b_gotpicture = 1;
1390
1391             /* Set PTS */
1392             frame->pts = p_sys->i_input_pts;
1393         }
1394
1395         if( i_used < 0 )
1396         {
1397             msg_Warn( p_stream, "error");
1398             return VLC_EGENERIC;
1399         }
1400         i_data -= i_used;
1401         p_data += i_used;
1402
1403         if( !b_gotpicture )
1404         {
1405             return VLC_SUCCESS;
1406         }
1407
1408         /* Get the pts of the decoded frame if any, otherwise keep the
1409          * interpolated one */
1410         if( frame->pts > 0 )
1411         {
1412             p_sys->i_output_pts = frame->pts;
1413         }
1414
1415         if( !id->b_enc_inited )
1416         {
1417             /* XXX hack because of copy packetizer and mpeg4video that can failed
1418                detecting size */
1419             if( id->ff_enc_c->width <= 0 )
1420             {
1421                 id->ff_enc_c->width    =
1422                     id->f_dst.i_width  = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1423             }
1424             if( id->ff_enc_c->height <= 0 )
1425             {
1426                 id->ff_enc_c->height   =
1427                     id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1428             }
1429
1430             /* Make sure we get extradata filled by the encoder */
1431             id->ff_enc_c->extradata_size = 0;
1432             id->ff_enc_c->extradata = NULL;
1433             id->ff_enc_c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1434
1435             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
1436             {
1437                 msg_Err( p_stream, "cannot open encoder" );
1438                 return VLC_EGENERIC;
1439             }
1440
1441             id->f_dst.i_extra_data = id->ff_enc_c->extradata_size;
1442             id->f_dst.p_extra_data = id->ff_enc_c->extradata;
1443             id->ff_enc_c->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
1444
1445             if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1446             {
1447                 msg_Err( p_stream, "cannot add this stream" );
1448                 transcode_video_ffmpeg_close( p_stream, id );
1449                 id->b_transcode = VLC_FALSE;
1450                 return VLC_EGENERIC;
1451             }
1452             id->b_enc_inited = VLC_TRUE;
1453         }
1454
1455
1456         /* deinterlace */
1457         if( p_stream->p_sys->b_deinterlace )
1458         {
1459             if( id->p_ff_pic_tmp0 == NULL )
1460             {
1461                 int     i_size;
1462                 uint8_t *buf;
1463                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1464                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1465                                              id->ff_dec_c->width, id->ff_dec_c->height );
1466
1467                 buf = malloc( i_size );
1468
1469                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1470                                 id->ff_enc_c->pix_fmt,
1471                                 id->ff_dec_c->width, id->ff_dec_c->height );
1472             }
1473
1474             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1475                                    id->ff_dec_c->pix_fmt,
1476                                    id->ff_dec_c->width, id->ff_dec_c->height );
1477
1478             frame = id->p_ff_pic_tmp0;
1479         }
1480
1481         /* convert pix format */
1482         if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
1483         {
1484             if( id->p_ff_pic_tmp1 == NULL )
1485             {
1486                 int     i_size;
1487                 uint8_t *buf;
1488                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1489                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1490                                              id->ff_dec_c->width, id->ff_dec_c->height );
1491
1492                 buf = malloc( i_size );
1493
1494                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1495                                 id->ff_enc_c->pix_fmt,
1496                                 id->ff_dec_c->width, id->ff_dec_c->height );
1497             }
1498
1499             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->ff_enc_c->pix_fmt,
1500                          (AVPicture*)frame,             id->ff_dec_c->pix_fmt,
1501                          id->ff_dec_c->width, id->ff_dec_c->height );
1502
1503             frame = id->p_ff_pic_tmp1;
1504         }
1505
1506         /* convert size and crop */
1507         if( id->ff_dec_c->width  != id->ff_enc_c->width ||
1508             id->ff_dec_c->height != id->ff_enc_c->height ||
1509             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1510             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1511         {
1512             if( id->p_ff_pic_tmp2 == NULL )
1513             {
1514                 int     i_size;
1515                 uint8_t *buf;
1516                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1517                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1518                                              id->ff_enc_c->width, id->ff_enc_c->height );
1519
1520                 buf = malloc( i_size );
1521
1522                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1523                                 id->ff_enc_c->pix_fmt,
1524                                 id->ff_enc_c->width, id->ff_enc_c->height );
1525
1526                 id->p_vresample =
1527                     img_resample_full_init( id->ff_enc_c->width, id->ff_enc_c->height,
1528                                             id->ff_dec_c->width, id->ff_dec_c->height,
1529                                             p_stream->p_sys->i_crop_top,
1530                                             p_stream->p_sys->i_crop_bottom,
1531                                             p_stream->p_sys->i_crop_left,
1532                                             p_stream->p_sys->i_crop_right );
1533             }
1534
1535             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1536                           (AVPicture*)frame );
1537
1538             frame = id->p_ff_pic_tmp2;
1539         }
1540
1541         /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
1542         if( id->f_dst.i_fourcc == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
1543             frame->pts = p_sys->i_output_pts;
1544         else
1545             frame->pts = 0;
1546
1547         /* Interpolate the next PTS
1548          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1549         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1550         {
1551             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1552               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1553         }
1554
1555         /* Let ffmpeg select the frame type */
1556         frame->pict_type = 0;
1557
1558         i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer,
1559                                       id->i_buffer, frame );
1560         if( i_out > 0 )
1561         {
1562             sout_buffer_t *p_out;
1563             p_out = sout_BufferNew( p_stream->p_sout, i_out );
1564
1565             memcpy( p_out->p_buffer, id->p_buffer, i_out );
1566
1567             p_out->i_size   = i_out;
1568
1569             if( id->ff_enc_c->coded_frame->pts != 0 &&
1570                 p_sys->i_buggy_pts_detect != id->ff_enc_c->coded_frame->pts )
1571             {
1572                 p_sys->i_buggy_pts_detect = id->ff_enc_c->coded_frame->pts;
1573
1574                 /* FIXME, 3-2 pulldown is not handled correctly */
1575                 p_out->i_length = in->i_length;
1576                 p_out->i_pts    = id->ff_enc_c->coded_frame->pts;
1577
1578                 if( !id->ff_enc_c->delay ||
1579                     ( id->ff_enc_c->coded_frame->pict_type != FF_I_TYPE &&
1580                       id->ff_enc_c->coded_frame->pict_type != FF_P_TYPE ) )
1581                 {
1582                     p_out->i_dts    = p_out->i_pts;
1583                 }
1584                 else
1585                 {
1586                     if( p_sys->i_last_ref_pts )
1587                     {
1588                         p_out->i_dts = p_sys->i_last_ref_pts;
1589                     }
1590                     else
1591                     {
1592                         /* Let's put something sensible */
1593                         p_out->i_dts = p_out->i_pts;
1594                     }
1595
1596                     p_sys->i_last_ref_pts = p_out->i_pts;
1597                 }
1598             }
1599             else
1600             {
1601                 /* Buggy libavcodec which doesn't update coded_frame->pts
1602                  * correctly */
1603                 p_out->i_length = in->i_length;
1604                 p_out->i_dts    = in->i_dts;
1605                 p_out->i_pts    = in->i_dts;
1606             }
1607
1608             sout_BufferChain( out, p_out );
1609         }
1610
1611         if( i_data <= 0 )
1612         {
1613             return VLC_SUCCESS;
1614         }
1615     }
1616
1617     return VLC_SUCCESS;
1618 }
1619
1620 /*****************************************************************************
1621  * transcode_video_ffmpeg_getframebuf:
1622  *
1623  * Callback used by ffmpeg to get a frame buffer.
1624  * We use it to get the right PTS for each decoded picture.
1625  *****************************************************************************/
1626 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1627                                               AVFrame *p_frame)
1628 {
1629     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1630
1631     /* Set PTS */
1632     p_frame->pts = p_sys->i_input_pts;
1633
1634     return avcodec_default_get_buffer( p_context, p_frame );
1635 }