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