* debian/changelog: Changelog for the forthcoming 0.6.0+cvs-20030704-1 Debian
[vlc.git] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.22 2003/07/04 16:35:20 sam 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 /*****************************************************************************
68  * Module descriptor
69  *****************************************************************************/
70 vlc_module_begin();
71     set_description( _("Transcode stream") );
72     set_capability( "sout stream", 50 );
73     add_shortcut( "transcode" );
74     set_callbacks( Open, Close );
75 vlc_module_end();
76
77 struct sout_stream_sys_t
78 {
79     sout_stream_t   *p_out;
80
81     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
82     int             i_sample_rate;
83     int             i_channels;
84     int             i_abitrate;
85
86     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
87     int             i_vbitrate;
88     int             i_vtolerance;
89     int             i_width;
90     int             i_height;
91     int             i_key_int;
92     int             i_qmin;
93     int             i_qmax;
94     vlc_bool_t      b_hq;
95     vlc_bool_t      b_deinterlace;
96
97     int             i_crop_top;
98     int             i_crop_bottom;
99     int             i_crop_right;
100     int             i_crop_left;
101 };
102
103 /*****************************************************************************
104  * Open:
105  *****************************************************************************/
106 static int Open( vlc_object_t *p_this )
107 {
108     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
109     sout_stream_sys_t *p_sys;
110     char *codec;
111
112     p_sys = malloc( sizeof( sout_stream_sys_t ) );
113     p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
114
115     p_sys->i_acodec      = 0;
116     p_sys->i_sample_rate = 0;
117     p_sys->i_channels    = 0;
118     p_sys->i_abitrate    = 0;
119
120     p_sys->i_vcodec     = 0;
121     p_sys->i_vbitrate   = 0;
122     p_sys->i_vtolerance = -1;
123     p_sys->i_width      = 0;
124     p_sys->i_height     = 0;
125     p_sys->i_key_int    = -1;
126     p_sys->i_qmin       = 2;
127     p_sys->i_qmax       = 31;
128     p_sys->b_hq         = VLC_FALSE;
129     p_sys->b_deinterlace= VLC_FALSE;
130
131     p_sys->i_crop_top   = 0;
132     p_sys->i_crop_bottom= 0;
133     p_sys->i_crop_right = 0;
134     p_sys->i_crop_left  = 0;
135
136     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "acodec" ) ) )
137     {
138         char fcc[4] = "    ";
139         char *val;
140
141         memcpy( fcc, codec, strlen( codec ) );
142
143         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
144
145         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "samplerate" ) ) )
146         {
147             p_sys->i_sample_rate = atoi( val );
148         }
149         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "channels" ) ) )
150         {
151             p_sys->i_channels = atoi( val );
152         }
153         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
154         {
155             p_sys->i_abitrate = atoi( val );
156             if( p_sys->i_abitrate < 4000 )
157             {
158                 p_sys->i_abitrate *= 1000;
159             }
160         }
161
162         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
163                  fcc,
164                  p_sys->i_sample_rate, p_sys->i_channels,
165                  p_sys->i_abitrate / 1024 );
166     }
167
168     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
169     {
170         char fcc[4] = "    ";
171         char *val;
172
173         memcpy( fcc, codec, strlen( codec ) );
174
175         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
176
177         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
178         {
179             p_sys->i_width = atoi( val );
180         }
181         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
182         {
183             p_sys->i_height = atoi( val );
184         }
185         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
186         {
187             p_sys->i_vbitrate = atoi( val );
188             if( p_sys->i_vbitrate < 16000 )
189             {
190                 p_sys->i_vbitrate *= 1000;
191             }
192         }
193         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
194         {
195             p_sys->i_vtolerance = atoi( val );
196         }
197         if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
198         {
199             p_sys->b_deinterlace = VLC_TRUE;
200         }
201         /* crop */
202         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
203         {
204             p_sys->i_crop_top = atoi( val );
205         }
206         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
207         {
208             p_sys->i_crop_bottom = atoi( val );
209         }
210         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
211         {
212             p_sys->i_crop_left = atoi( val );
213         }
214         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
215         {
216             p_sys->i_crop_right = atoi( val );
217         }
218         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
219         {
220             p_sys->i_key_int    = atoi( val );
221         }
222         if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
223         {
224             p_sys->b_hq = VLC_TRUE;
225         }
226         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
227         {
228             p_sys->i_qmin   = atoi( val );
229         }
230         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
231         {
232             p_sys->i_qmax   = atoi( val );
233         }
234
235         msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
236                  fcc,
237                  p_sys->i_width, p_sys->i_height,
238                  p_sys->i_vbitrate / 1024 );
239     }
240
241     if( !p_sys->p_out )
242     {
243         msg_Err( p_stream, "cannot create chain" );
244         free( p_sys );
245         return VLC_EGENERIC;
246     }
247     p_stream->pf_add    = Add;
248     p_stream->pf_del    = Del;
249     p_stream->pf_send   = Send;
250
251     p_stream->p_sys     = p_sys;
252
253     avcodec_init();
254     avcodec_register_all();
255
256     return VLC_SUCCESS;
257 }
258
259 /*****************************************************************************
260  * Close:
261  *****************************************************************************/
262
263 static void Close( vlc_object_t * p_this )
264 {
265     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
266     sout_stream_sys_t   *p_sys = p_stream->p_sys;
267
268     sout_stream_delete( p_sys->p_out );
269     free( p_sys );
270 }
271
272 struct sout_stream_id_t
273 {
274     vlc_fourcc_t  b_transcode;
275     sout_format_t f_src;        /* only if transcoding */
276     sout_format_t f_dst;        /*  "   "      " */
277
278     /* id of the out stream */
279     void *id;
280
281     /* ffmpeg part */
282     AVCodec         *ff_dec;
283     AVCodecContext  *ff_dec_c;
284
285
286     vlc_fourcc_t    b_enc_inited;
287     AVCodec         *ff_enc;
288     AVCodecContext  *ff_enc_c;
289
290     mtime_t         i_dts;
291     mtime_t         i_length;
292
293     int             i_buffer_in;
294     int             i_buffer_in_pos;
295     uint8_t         *p_buffer_in;
296
297     int             i_buffer;
298     int             i_buffer_pos;
299     uint8_t         *p_buffer;
300
301     int             i_buffer_out;
302     int             i_buffer_out_pos;
303     uint8_t         *p_buffer_out;
304
305     AVFrame         *p_ff_pic;
306     AVFrame         *p_ff_pic_tmp0; /* to do deinterlace */
307     AVFrame         *p_ff_pic_tmp1; /* to do pix conversion */
308     AVFrame         *p_ff_pic_tmp2; /* to do resample */
309
310     ImgReSampleContext *p_vresample;
311
312 #ifdef HAVE_VORBIS_VORBISENC_H
313
314     /* Vorbis part */
315     vorbis_info      *p_vi;
316     vorbis_dsp_state *p_vd;
317     vorbis_block     *p_vb;
318     vorbis_comment   *p_vc;
319     int              i_last_block_size;
320     int              i_samples_delay;
321     vlc_bool_t       b_headers_sent;
322 #endif
323 };
324
325
326 static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
327 {
328     sout_stream_sys_t   *p_sys = p_stream->p_sys;
329     sout_stream_id_t    *id;
330
331     id = malloc( sizeof( sout_stream_id_t ) );
332     id->i_dts = 0;
333     id->id = NULL;
334     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
335     {
336         msg_Dbg( p_stream,
337                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
338                  (char*)&p_fmt->i_fourcc,
339                  (char*)&p_sys->i_acodec );
340
341         /* src format */
342         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
343
344         /* create dst format */
345         id->f_dst.i_cat    = AUDIO_ES;
346         id->f_dst.i_fourcc = p_sys->i_acodec;
347         id->f_dst.i_sample_rate = p_sys->i_sample_rate  > 0 ? p_sys->i_sample_rate : id->f_src.i_sample_rate;
348         id->f_dst.i_channels    = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.i_channels;
349         id->f_dst.i_bitrate     = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
350         id->f_dst.i_block_align = 0;
351         id->f_dst.i_extra_data  = 0;
352         id->f_dst.p_extra_data  = NULL;
353
354         /* build decoder -> filter -> encoder */
355         if( transcode_audio_ffmpeg_new( p_stream, id ) )
356         {
357             msg_Err( p_stream, "cannot create audio chain" );
358             free( id );
359             return NULL;
360         }
361
362         /* open output stream */
363         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
364         id->b_transcode = VLC_TRUE;
365     }
366     else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
367     {
368         msg_Dbg( p_stream,
369                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
370                  (char*)&p_fmt->i_fourcc,
371                  (char*)&p_sys->i_vcodec );
372
373         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
374
375         /* create dst format */
376         id->f_dst.i_cat         = VIDEO_ES;
377         id->f_dst.i_fourcc      = p_sys->i_vcodec;
378         id->f_dst.i_width       = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
379         id->f_dst.i_height      = p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
380         id->f_dst.i_bitrate     = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
381         id->f_dst.i_extra_data  = 0;
382         id->f_dst.p_extra_data  = NULL;
383
384         /* build decoder -> filter -> encoder */
385         if( transcode_video_ffmpeg_new( p_stream, id ) )
386         {
387             msg_Err( p_stream, "cannot create video chain" );
388             free( id );
389             return NULL;
390         }
391 #if 0
392         /* open output stream */
393         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
394 #endif
395         id->b_transcode = VLC_TRUE;
396     }
397     else
398     {
399         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_fourcc );
400         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
401         id->b_transcode = VLC_FALSE;
402
403         if( id->id == NULL )
404         {
405             free( id );
406             return NULL;
407         }
408     }
409
410     return id;
411 }
412
413 static int     Del      ( sout_stream_t *p_stream, sout_stream_id_t *id )
414 {
415     sout_stream_sys_t   *p_sys = p_stream->p_sys;
416
417     if( id->b_transcode )
418     {
419         if( id->f_src.i_cat == AUDIO_ES )
420         {
421             transcode_audio_ffmpeg_close( p_stream, id );
422         }
423         else if( id->f_src.i_cat == VIDEO_ES )
424         {
425             transcode_video_ffmpeg_close( p_stream, id );
426         }
427     }
428
429     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
430     free( id );
431
432     return VLC_SUCCESS;
433 }
434
435 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
436                  sout_buffer_t *p_buffer )
437 {
438     sout_stream_sys_t   *p_sys = p_stream->p_sys;
439
440     if( id->b_transcode )
441     {
442         sout_buffer_t *p_buffer_out;
443         if( id->f_src.i_cat == AUDIO_ES )
444         {
445             transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
446         }
447         else if( id->f_src.i_cat == VIDEO_ES )
448         {
449             transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
450         }
451         sout_BufferDelete( p_stream->p_sout, p_buffer );
452
453         if( p_buffer_out )
454         {
455             return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
456         }
457         return VLC_SUCCESS;
458     }
459     else if( id->id != NULL )
460     {
461         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
462     }
463     else
464     {
465         sout_BufferDelete( p_stream->p_sout, p_buffer );
466         return VLC_EGENERIC;
467     }
468 }
469
470 /****************************************************************************
471  * ffmpeg decoder reencocdr part
472  ****************************************************************************/
473
474 static struct
475 {
476     vlc_fourcc_t i_fcc;
477     int          i_ff_codec;
478 } fourcc_to_ff_code[] =
479 {
480     /* audio */
481     { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
482     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
483     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
484     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
485     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
486     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
487
488     /* video */
489     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
490     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
491     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
492     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
493     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
494     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
495     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
496     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
497     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
498     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
499     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
500     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
501     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
502 #if LIBAVCODEC_BUILD >= 4666
503     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
504 #endif
505
506     /* raw video code, only used for 'encoding' */
507     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
508     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
509     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
510     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
511     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
512
513     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
514 };
515
516 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
517 {
518     int i;
519
520     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
521     {
522         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
523         {
524             return fourcc_to_ff_code[i].i_ff_codec;
525         }
526     }
527
528     return 0;
529 }
530
531 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
532 {
533     switch( i_chroma )
534     {
535         case VLC_FOURCC( 'I', '4', '2', '0' ):
536             return PIX_FMT_YUV420P;
537         case VLC_FOURCC( 'I', '4', '2', '2' ):
538             return PIX_FMT_YUV422P;
539         case VLC_FOURCC( 'I', '4', '4', '4' ):
540             return PIX_FMT_YUV444P;
541         case VLC_FOURCC( 'R', 'V', '2', '4' ):
542             return PIX_FMT_RGB24;
543         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
544             return PIX_FMT_YUV422;
545         default:
546             return 0;
547     }
548 }
549
550 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
551                                        sout_stream_id_t *id )
552 {
553     int i_ff_codec;
554
555     if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
556         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
557         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
558         id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
559     {
560         id->ff_dec = NULL;
561
562         id->ff_dec_c = avcodec_alloc_context();
563         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
564         id->ff_dec_c->channels    = id->f_src.i_channels;
565         id->ff_dec_c->block_align = id->f_src.i_block_align;
566         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
567     }
568     else
569     {
570         /* find decoder */
571         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
572         if( i_ff_codec == 0 )
573         {
574             msg_Err( p_stream, "cannot find decoder" );
575             return VLC_EGENERIC;
576         }
577
578         id->ff_dec = avcodec_find_decoder( i_ff_codec );
579         if( !id->ff_dec )
580         {
581             msg_Err( p_stream, "cannot find decoder" );
582             return VLC_EGENERIC;
583         }
584
585         id->ff_dec_c = avcodec_alloc_context();
586         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
587         id->ff_dec_c->channels    = id->f_src.i_channels;
588         id->ff_dec_c->block_align = id->f_src.i_block_align;
589         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
590
591         id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
592         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
593         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
594         {
595             msg_Err( p_stream, "cannot open decoder" );
596             return VLC_EGENERIC;
597         }
598     }
599
600     /* find encoder */
601     id->i_buffer_in      = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
602     id->i_buffer_in_pos = 0;
603     id->p_buffer_in      = malloc( id->i_buffer_in );
604
605     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
606     id->i_buffer_pos = 0;
607     id->p_buffer     = malloc( id->i_buffer );
608
609     id->i_buffer_out     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
610     id->i_buffer_out_pos = 0;
611     id->p_buffer_out     = malloc( id->i_buffer_out );
612
613 #ifdef HAVE_VORBIS_VORBISENC_H
614     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
615     {
616         id->p_vi = (vorbis_info *)malloc( sizeof(vorbis_info) );
617         id->p_vd = (vorbis_dsp_state *)malloc( sizeof(vorbis_dsp_state) );
618         id->p_vb = (vorbis_block *)malloc( sizeof(vorbis_block) );
619         id->p_vc = (vorbis_comment *)malloc( sizeof(vorbis_comment) );
620
621         vorbis_info_init( id->p_vi );
622
623         if( vorbis_encode_setup_managed( id->p_vi, id->f_dst.i_channels,
624               id->f_dst.i_sample_rate, -1, id->f_dst.i_bitrate, -1 ) ||
625             vorbis_encode_ctl( id->p_vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
626              vorbis_encode_setup_init( id->p_vi ) ){}
627
628         /* add a comment */
629         vorbis_comment_init( id->p_vc);
630         vorbis_comment_add_tag( id->p_vc, "ENCODER", "VLC media player");
631
632         /* set up the analysis state and auxiliary encoding storage */
633         vorbis_analysis_init( id->p_vd, id->p_vi );
634         vorbis_block_init( id->p_vd, id->p_vb );
635
636         id->b_headers_sent = VLC_FALSE;
637         id->i_last_block_size = 0;
638         id->i_samples_delay = 0;
639
640         return VLC_SUCCESS;
641     }
642 #endif
643
644     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
645     if( i_ff_codec == 0 )
646     {
647         msg_Err( p_stream, "cannot find encoder" );
648         return VLC_EGENERIC;
649     }
650
651     id->ff_enc = avcodec_find_encoder( i_ff_codec );
652     if( !id->ff_enc )
653     {
654         msg_Err( p_stream, "cannot find encoder" );
655         return VLC_EGENERIC;
656     }
657
658     id->ff_enc_c = avcodec_alloc_context();
659     id->ff_enc_c->bit_rate    = id->f_dst.i_bitrate;
660     id->ff_enc_c->sample_rate = id->f_dst.i_sample_rate;
661     id->ff_enc_c->channels    = id->f_dst.i_channels;
662
663     if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
664     {
665         msg_Err( p_stream, "cannot open encoder" );
666         return VLC_EGENERIC;
667     }
668
669     return VLC_SUCCESS;
670 }
671
672 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
673                                           sout_stream_id_t *id )
674 {
675     if( id->ff_dec )
676     {
677         avcodec_close( id->ff_dec_c );
678     }
679
680 #ifdef HAVE_VORBIS_VORBISENC_H
681     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
682     {
683         vorbis_block_clear( id->p_vb );
684         vorbis_dsp_clear( id->p_vd );
685         vorbis_comment_clear( id->p_vc );
686         vorbis_info_clear( id->p_vi );  /* must be called last */
687
688         free( id->p_vi );
689         free( id->p_vd );
690         free( id->p_vb );
691         free( id->p_vc );
692     }
693     else
694 #endif
695         avcodec_close( id->ff_enc_c );
696
697     free( id->ff_dec_c );
698     if( id->f_dst.i_fourcc != VLC_FOURCC('v','o','r','b') )
699         free( id->ff_enc_c );
700
701     free( id->p_buffer_in );
702     free( id->p_buffer );
703     free( id->p_buffer_out );
704 }
705
706 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
707                                            sout_stream_id_t *id,
708                                            sout_buffer_t *in,
709                                            sout_buffer_t **out )
710 {
711     vlc_bool_t b_again = VLC_FALSE;
712
713     *out = NULL;
714
715     /* gather data into p_buffer_in */
716 #ifdef HAVE_VORBIS_VORBISENC_H
717     if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
718     id->i_dts = in->i_dts -
719                 (mtime_t)1000000 * (mtime_t)id->i_samples_delay /
720                 (mtime_t)id->f_dst.i_sample_rate;
721     else
722 #endif
723     id->i_dts = in->i_dts -
724                 (mtime_t)1000000 *
725                 (mtime_t)(id->i_buffer_pos / 2 / id->ff_enc_c->channels )/
726                 (mtime_t)id->ff_enc_c->sample_rate;
727
728     if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
729     {
730         /* extend buffer_in */
731         id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
732         id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
733     }
734     memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
735             in->p_buffer, in->i_size );
736     id->i_buffer_in_pos += in->i_size;
737
738     do
739     {
740         /* decode as much data as possible */
741         if( id->ff_dec )
742         {
743             for( ;; )
744             {
745                 int i_buffer_size;
746                 int i_used;
747
748                 i_buffer_size = id->i_buffer - id->i_buffer_pos;
749
750                 i_used = avcodec_decode_audio( id->ff_dec_c,
751                          (int16_t*)&id->p_buffer[id->i_buffer_pos],
752                          &i_buffer_size, id->p_buffer_in,
753                          id->i_buffer_in_pos );
754
755                 /* msg_Warn( p_stream, "avcodec_decode_audio: %d used",
756                              i_used ); */
757                 id->i_buffer_pos += i_buffer_size;
758
759                 if( i_used < 0 )
760                 {
761                     msg_Warn( p_stream, "error");
762                     id->i_buffer_in_pos = 0;
763                     break;
764                 }
765                 else if( i_used < id->i_buffer_in_pos )
766                 {
767                     memmove( id->p_buffer_in,
768                              &id->p_buffer_in[i_used],
769                              id->i_buffer_in - i_used );
770                     id->i_buffer_in_pos -= i_used;
771                 }
772                 else
773                 {
774                     id->i_buffer_in_pos = 0;
775                     break;
776                 }
777
778                 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
779                 {
780                     /* buffer full */
781                     b_again = VLC_TRUE;
782                     break;
783                 }
784             }
785         }
786         else
787         {
788             int16_t *sout  = (int16_t*)&id->p_buffer[id->i_buffer_pos];
789             int     i_used = 0;
790
791             if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
792             {
793                 int8_t *sin = (int8_t*)id->p_buffer_in;
794                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
795                                            / 2, id->i_buffer_in_pos );
796                 i_used = i_samples;
797                 while( i_samples > 0 )
798                 {
799                     *sout++ = ( *sin++ ) << 8;
800                     i_samples--;
801                 }
802             }
803             else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
804             {
805                 int8_t *sin = (int8_t*)id->p_buffer_in;
806                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
807                                            / 2, id->i_buffer_in_pos );
808                 i_used = i_samples;
809                 while( i_samples > 0 )
810                 {
811                     *sout++ = ( *sin++ - 128 ) << 8;
812                     i_samples--;
813                 }
814             }
815             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
816             {
817                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
818                                            / 2, id->i_buffer_in_pos / 2);
819 #ifdef WORDS_BIGENDIAN
820                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
821                 i_used = i_samples * 2;
822                 while( i_samples > 0 )
823                 {
824                     uint8_t tmp[2];
825
826                     tmp[1] = *sin++;
827                     tmp[0] = *sin++;
828                     *sout++ = *(int16_t*)tmp;
829                     i_samples--;
830                 }
831
832 #else
833                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
834                 sout += i_samples;
835                 i_used = i_samples * 2;
836 #endif
837             }
838             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
839             {
840                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
841                                            / 2, id->i_buffer_in_pos / 2);
842 #ifdef WORDS_BIGENDIAN
843                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
844                 sout += i_samples;
845                 i_used = i_samples * 2;
846 #else
847                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
848                 i_used = i_samples * 2;
849                 while( i_samples > 0 )
850                 {
851                     uint8_t tmp[2];
852
853                     tmp[1] = *sin++;
854                     tmp[0] = *sin++;
855                     *sout++ = *(int16_t*)tmp;
856                     i_samples--;
857                 }
858 #endif
859             }
860
861             id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
862             if( i_used < id->i_buffer_in_pos )
863             {
864                 memmove( id->p_buffer_in,
865                          &id->p_buffer_in[i_used],
866                          id->i_buffer_in - i_used );
867             }
868             id->i_buffer_in_pos -= i_used;
869         }
870
871         /* encode as much data as possible */
872
873 #ifdef HAVE_VORBIS_VORBISENC_H
874         if( id->i_buffer_pos == 0 );
875         else if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
876         {
877             float **buffer;
878             int i, j, i_samples;
879             sout_buffer_t *p_out;
880             ogg_packet op;
881
882             if( id->i_buffer_pos == 0 )
883             {
884                 break;
885             }
886
887             if( !id->b_headers_sent )
888             {
889                 ogg_packet header[3];
890                 vorbis_analysis_headerout( id->p_vd, id->p_vc,
891                                            &header[0], &header[1], &header[2]);
892                 for( i = 0; i < 3; i++ )
893                 {
894                     p_out = sout_BufferNew( p_stream->p_sout, header[i].bytes);
895                     memcpy( p_out->p_buffer, header[i].packet,
896                             header[i].bytes );
897
898                     p_out->i_size = header[i].bytes;
899                     p_out->i_length = 0;
900
901                     p_out->i_dts = p_out->i_pts = 0;
902
903                     sout_BufferChain( out, p_out );
904                 }
905                 id->b_headers_sent = VLC_TRUE;
906             }
907
908             i_samples = id->i_buffer_pos / id->f_dst.i_channels / 2;
909             id->i_samples_delay += i_samples;
910             id->i_buffer_pos = 0;
911
912             buffer = vorbis_analysis_buffer( id->p_vd, i_samples );
913
914             /* convert samples to float and uninterleave */
915             for( i = 0; i < id->f_dst.i_channels; i++ )
916             {
917                 for( j = 0 ; j < i_samples ; j++ )
918                 {
919                     buffer[i][j]= ((float)( ((int16_t *)id->p_buffer)
920                                   [j*id->f_dst.i_channels + i ] ))/ 32768.f;
921                 }
922             }
923
924             vorbis_analysis_wrote( id->p_vd, i_samples );
925
926             while( vorbis_analysis_blockout( id->p_vd, id->p_vb ) == 1 )
927             {
928                 vorbis_analysis( id->p_vb, NULL );
929                 vorbis_bitrate_addblock( id->p_vb );
930
931                 while( vorbis_bitrate_flushpacket( id->p_vd, &op ) )
932                 {
933                     int i_block_size;
934                     p_out = sout_BufferNew( p_stream->p_sout, op.bytes );
935                     memcpy( p_out->p_buffer, op.packet, op.bytes );
936
937                     i_block_size = vorbis_packet_blocksize( id->p_vi, &op );
938
939                     if( i_block_size < 0 ) i_block_size = 0;
940                     i_samples = ( id->i_last_block_size +
941                                   i_block_size ) >> 2;
942                     id->i_last_block_size = i_block_size;
943
944                     p_out->i_size = op.bytes;
945                     p_out->i_length = (mtime_t)1000000 *
946                       (mtime_t)i_samples /
947                       (mtime_t)id->f_dst.i_sample_rate;
948
949                     //msg_Err( p_stream, "i_dts: %lld", id->i_dts );
950
951                     /* FIXME */
952                     p_out->i_dts = id->i_dts;
953                     p_out->i_pts = id->i_dts;
954
955                     id->i_samples_delay -= i_samples;
956
957                     /* update dts */
958                     id->i_dts += p_out->i_length;
959                     sout_BufferChain( out, p_out );
960
961                 }
962             }
963         }
964         else
965 #endif
966
967         for( ;; )
968         {
969             int i_frame_size = id->ff_enc_c->frame_size * 2 *
970                                  id->ff_enc_c->channels;
971             int i_out_size;
972             sout_buffer_t *p_out;
973
974             if( id->i_buffer_pos < i_frame_size )
975             {
976                 break;
977             }
978
979             /* msg_Warn( p_stream, "avcodec_encode_audio: frame size%d",
980                          i_frame_size); */
981             i_out_size = avcodec_encode_audio( id->ff_enc_c,
982                            id->p_buffer_out, id->i_buffer_out,
983                            (int16_t*)id->p_buffer );
984
985             if( i_out_size <= 0 )
986             {
987                 break;
988             }
989             memmove( id->p_buffer,
990                      &id->p_buffer[i_frame_size],
991                      id->i_buffer - i_frame_size );
992             id->i_buffer_pos -= i_frame_size;
993
994             p_out = sout_BufferNew( p_stream->p_sout, i_out_size );
995             memcpy( p_out->p_buffer, id->p_buffer_out, i_out_size );
996             p_out->i_size = i_out_size;
997             p_out->i_length = (mtime_t)1000000 *
998                               (mtime_t)id->ff_enc_c->frame_size /
999                               (mtime_t)id->ff_enc_c->sample_rate;
1000
1001             /* FIXME */
1002             p_out->i_dts = id->i_dts;
1003             p_out->i_pts = id->i_dts;
1004
1005             /* update dts */
1006             id->i_dts += p_out->i_length;
1007
1008            /* msg_Warn( p_stream, "frame dts=%lld len %lld out=%d",
1009                         p_out->i_dts, p_out->i_length, i_out_size ); */
1010
1011             sout_BufferChain( out, p_out );
1012         }
1013
1014     } while( b_again );
1015
1016     return VLC_SUCCESS;
1017 }
1018
1019
1020 /*
1021  * video
1022  */
1023 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1024                                        sout_stream_id_t *id )
1025 {
1026     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1027
1028     int i_ff_codec;
1029
1030     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1031         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1032         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1033         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1034         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) )
1035     {
1036         id->ff_dec   = NULL;
1037         id->ff_dec_c            = avcodec_alloc_context();
1038         id->ff_dec_c->width     = id->f_src.i_width;
1039         id->ff_dec_c->height    = id->f_src.i_height;
1040         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
1041     }
1042     else
1043     {
1044         /* find decoder */
1045         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
1046         if( i_ff_codec == 0 )
1047         {
1048             msg_Err( p_stream, "cannot find decoder" );
1049             return VLC_EGENERIC;
1050         }
1051
1052         id->ff_dec = avcodec_find_decoder( i_ff_codec );
1053         if( !id->ff_dec )
1054         {
1055             msg_Err( p_stream, "cannot find decoder" );
1056             return VLC_EGENERIC;
1057         }
1058
1059         id->ff_dec_c = avcodec_alloc_context();
1060         id->ff_dec_c->width         = id->f_src.i_width;
1061         id->ff_dec_c->height        = id->f_src.i_height;
1062         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
1063         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
1064         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
1065         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1066         id->ff_dec_c->error_resilience= -1;
1067         if( id->ff_dec->capabilities & CODEC_CAP_TRUNCATED )
1068         {
1069             id->ff_dec_c->flags |= CODEC_FLAG_TRUNCATED;
1070         }
1071
1072         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1073         {
1074             msg_Err( p_stream, "cannot open decoder" );
1075             return VLC_EGENERIC;
1076         }
1077
1078         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1079         {
1080             int b_gotpicture;
1081             AVFrame frame;
1082
1083             avcodec_decode_video( id->ff_dec_c, &frame,
1084                                   &b_gotpicture,
1085                                   id->ff_dec_c->extradata, id->ff_dec_c->extradata_size );
1086         }
1087     }
1088
1089
1090     /* find encoder */
1091     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
1092     if( i_ff_codec == 0 )
1093     {
1094         msg_Err( p_stream, "cannot find encoder" );
1095         return VLC_EGENERIC;
1096     }
1097
1098     id->ff_enc = avcodec_find_encoder( i_ff_codec );
1099     if( !id->ff_enc )
1100     {
1101         msg_Err( p_stream, "cannot find encoder" );
1102         return VLC_EGENERIC;
1103     }
1104
1105     id->ff_enc_c = avcodec_alloc_context();
1106     id->ff_enc_c->width          = id->f_dst.i_width;
1107     id->ff_enc_c->height         = id->f_dst.i_height;
1108     id->ff_enc_c->bit_rate       = id->f_dst.i_bitrate;
1109 #if LIBAVCODEC_BUILD >= 4662
1110     id->ff_enc_c->frame_rate     = 25 ; /* FIXME as it break mpeg */
1111     id->ff_enc_c->frame_rate_base= 1;
1112 #else
1113     id->ff_enc_c->frame_rate     = 25 * FRAME_RATE_BASE;
1114 #endif
1115     id->ff_enc_c->gop_size       = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
1116
1117     if( p_sys->i_vtolerance >= 0 )
1118     {
1119         id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
1120     }
1121     id->ff_enc_c->qmin           = p_sys->i_qmin;
1122     id->ff_enc_c->qmax           = p_sys->i_qmax;
1123     if( p_sys->b_hq )
1124     {
1125         id->ff_enc_c->flags      |= CODEC_FLAG_HQ;
1126     }
1127
1128     if( i_ff_codec == CODEC_ID_RAWVIDEO )
1129     {
1130         id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
1131     }
1132     /* XXX open it only when we have the first frame */
1133     id->b_enc_inited     = VLC_FALSE;
1134     id->i_buffer_in      = 0;
1135     id->i_buffer_in_pos  = 0;
1136     id->p_buffer_in      = NULL;
1137
1138     id->i_buffer     = 3*1024*1024;
1139     id->i_buffer_pos = 0;
1140     id->p_buffer     = malloc( id->i_buffer );
1141
1142     id->i_buffer_out     = 0;
1143     id->i_buffer_out_pos = 0;
1144     id->p_buffer_out     = NULL;
1145
1146     id->p_ff_pic         = avcodec_alloc_frame();
1147     id->p_ff_pic_tmp0    = NULL;
1148     id->p_ff_pic_tmp1    = NULL;
1149     id->p_ff_pic_tmp2    = NULL;
1150     id->p_vresample      = NULL;
1151     return VLC_SUCCESS;
1152 }
1153
1154 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
1155 {
1156     if( id->ff_dec )
1157     {
1158         avcodec_close( id->ff_dec_c );
1159     }
1160     if( id->b_enc_inited )
1161     {
1162         avcodec_close( id->ff_enc_c );
1163     }
1164
1165     if( id->p_ff_pic)
1166     {
1167         free( id->p_ff_pic );
1168     }
1169
1170     if( id->p_ff_pic_tmp0 )
1171     {
1172         free( id->p_ff_pic_tmp0->data[0] );
1173         free( id->p_ff_pic_tmp0 );
1174     }
1175     if( id->p_ff_pic_tmp1)
1176     {
1177         free( id->p_ff_pic_tmp1->data[0] );
1178         free( id->p_ff_pic_tmp1 );
1179     }
1180     if( id->p_ff_pic_tmp2)
1181     {
1182         free( id->p_ff_pic_tmp2->data[0] );
1183         free( id->p_ff_pic_tmp2 );
1184     }
1185     if( id->p_vresample )
1186     {
1187         free( id->p_vresample );
1188     }
1189
1190     free( id->ff_dec_c );
1191     free( id->ff_enc_c );
1192
1193     free( id->p_buffer );
1194 }
1195
1196 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_id_t *id,
1197                                            sout_buffer_t *in, sout_buffer_t **out )
1198 {
1199     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1200     int     i_used;
1201     int     i_out;
1202     int     b_gotpicture;
1203     AVFrame *frame;
1204
1205     int     i_data;
1206     uint8_t *p_data;
1207
1208     *out = NULL;
1209
1210     i_data = in->i_size;
1211     p_data = in->p_buffer;
1212
1213     for( ;; )
1214     {
1215         /* decode frame */
1216         frame = id->p_ff_pic;
1217         if( id->ff_dec )
1218         {
1219             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1220                                            &b_gotpicture,
1221                                            p_data, i_data );
1222         }
1223         else
1224         {
1225             /* raw video */
1226             avpicture_fill( (AVPicture*)frame,
1227                             p_data,
1228                             id->ff_dec_c->pix_fmt,
1229                             id->ff_dec_c->width, id->ff_dec_c->height );
1230             i_used = i_data;
1231             b_gotpicture = 1;
1232         }
1233
1234         if( i_used < 0 )
1235         {
1236             msg_Warn( p_stream, "error");
1237             return VLC_EGENERIC;
1238         }
1239         i_data -= i_used;
1240         p_data += i_used;
1241
1242         if( !b_gotpicture )
1243         {
1244             return VLC_SUCCESS;
1245         }
1246
1247         if( !id->b_enc_inited )
1248         {
1249             /* XXX hack because of copy packetizer and mpeg4video that can failed
1250                detecting size */
1251             if( id->ff_enc_c->width <= 0 )
1252             {
1253                 id->ff_enc_c->width    =
1254                     id->f_dst.i_width  = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1255             }
1256             if( id->ff_enc_c->height <= 0 )
1257             {
1258                 id->ff_enc_c->height   =
1259                     id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1260             }
1261
1262             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
1263             {
1264                 msg_Err( p_stream, "cannot open encoder" );
1265                 return VLC_EGENERIC;
1266             }
1267
1268             if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1269             {
1270                 msg_Err( p_stream, "cannot add this stream" );
1271                 transcode_video_ffmpeg_close( p_stream, id );
1272                 id->b_transcode = VLC_FALSE;
1273                 return VLC_EGENERIC;
1274             }
1275             id->b_enc_inited = VLC_TRUE;
1276         }
1277
1278
1279         /* deinterlace */
1280         if( p_stream->p_sys->b_deinterlace )
1281         {
1282             if( id->p_ff_pic_tmp0 == NULL )
1283             {
1284                 int     i_size;
1285                 uint8_t *buf;
1286                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1287                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1288                                              id->ff_dec_c->width, id->ff_dec_c->height );
1289
1290                 buf = malloc( i_size );
1291
1292                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1293                                 id->ff_enc_c->pix_fmt,
1294                                 id->ff_dec_c->width, id->ff_dec_c->height );
1295             }
1296
1297             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1298                                    id->ff_dec_c->pix_fmt,
1299                                    id->ff_dec_c->width, id->ff_dec_c->height );
1300
1301             frame = id->p_ff_pic_tmp0;
1302         }
1303
1304         /* convert pix format */
1305         if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
1306         {
1307             if( id->p_ff_pic_tmp1 == NULL )
1308             {
1309                 int     i_size;
1310                 uint8_t *buf;
1311                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1312                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1313                                              id->ff_dec_c->width, id->ff_dec_c->height );
1314
1315                 buf = malloc( i_size );
1316
1317                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1318                                 id->ff_enc_c->pix_fmt,
1319                                 id->ff_dec_c->width, id->ff_dec_c->height );
1320             }
1321
1322             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->ff_enc_c->pix_fmt,
1323                          (AVPicture*)frame,             id->ff_dec_c->pix_fmt,
1324                          id->ff_dec_c->width, id->ff_dec_c->height );
1325
1326             frame = id->p_ff_pic_tmp1;
1327         }
1328
1329         /* convert size and crop */
1330         if( id->ff_dec_c->width  != id->ff_enc_c->width ||
1331             id->ff_dec_c->height != id->ff_enc_c->height ||
1332             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1333             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1334         {
1335             if( id->p_ff_pic_tmp2 == NULL )
1336             {
1337                 int     i_size;
1338                 uint8_t *buf;
1339                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1340                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1341                                              id->ff_enc_c->width, id->ff_enc_c->height );
1342
1343                 buf = malloc( i_size );
1344
1345                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1346                                 id->ff_enc_c->pix_fmt,
1347                                 id->ff_enc_c->width, id->ff_enc_c->height );
1348
1349                 id->p_vresample =
1350                     img_resample_full_init( id->ff_enc_c->width, id->ff_enc_c->height,
1351                                             id->ff_dec_c->width, id->ff_dec_c->height,
1352                                             p_stream->p_sys->i_crop_top,
1353                                             p_stream->p_sys->i_crop_bottom,
1354                                             p_stream->p_sys->i_crop_left,
1355                                             p_stream->p_sys->i_crop_right );
1356             }
1357
1358             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2, (AVPicture*)frame );
1359
1360             frame = id->p_ff_pic_tmp2;
1361         }
1362
1363         i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer, id->i_buffer, frame );
1364         if( i_out > 0 )
1365         {
1366             sout_buffer_t *p_out;
1367             p_out = sout_BufferNew( p_stream->p_sout, i_out );
1368
1369             memcpy( p_out->p_buffer, id->p_buffer, i_out );
1370
1371             p_out->i_size   = i_out;
1372             p_out->i_length = in->i_length;
1373             p_out->i_dts    = in->i_dts;
1374             p_out->i_pts    = in->i_dts; /* FIXME */
1375
1376             sout_BufferChain( out, p_out );
1377         }
1378
1379         if( i_data <= 0 )
1380         {
1381             return VLC_SUCCESS;
1382         }
1383     }
1384
1385     return VLC_SUCCESS;
1386 }