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