]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
f22b262541b9567d245fe98c321300e8bd00602b
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.23 2003/07/06 16:22:15 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <vlc/vlc.h>
31 #include <vlc/input.h>
32 #include <vlc/sout.h>
33
34 /* ffmpeg header */
35 #ifdef HAVE_FFMPEG_AVCODEC_H
36 #   include <ffmpeg/avcodec.h>
37 #else
38 #   include <avcodec.h>
39 #endif
40
41 /* vorbis header */
42 #ifdef HAVE_VORBIS_VORBISENC_H
43 #   include <vorbis/vorbisenc.h>
44 #   ifndef OV_ECTL_RATEMANAGE_AVG
45 #       define OV_ECTL_RATEMANAGE_AVG 0x0
46 #   endif
47 #endif
48
49 /*****************************************************************************
50  * Exported prototypes
51  *****************************************************************************/
52 static int      Open    ( vlc_object_t * );
53 static void     Close   ( vlc_object_t * );
54
55 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
56 static int               Del ( sout_stream_t *, sout_stream_id_t * );
57 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
58
59 static int  transcode_audio_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
60 static void transcode_audio_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
61 static int  transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
62
63 static int  transcode_video_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
64 static void transcode_video_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
65 static int  transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
66
67 /*****************************************************************************
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( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
483     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
484     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
485     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
486     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
487     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
488
489     /* video */
490     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
491     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
492     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
493     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
494     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
495     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
496     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
497     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
498     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
499     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
500     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
501     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
502     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
503 #if LIBAVCODEC_BUILD >= 4666
504     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
505 #endif
506
507     /* raw video code, only used for 'encoding' */
508     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
509     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
510     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
511     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
512     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
513
514     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
515 };
516
517 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
518 {
519     int i;
520
521     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
522     {
523         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
524         {
525             return fourcc_to_ff_code[i].i_ff_codec;
526         }
527     }
528
529     return 0;
530 }
531
532 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
533 {
534     switch( i_chroma )
535     {
536         case VLC_FOURCC( 'I', '4', '2', '0' ):
537             return PIX_FMT_YUV420P;
538         case VLC_FOURCC( 'I', '4', '2', '2' ):
539             return PIX_FMT_YUV422P;
540         case VLC_FOURCC( 'I', '4', '4', '4' ):
541             return PIX_FMT_YUV444P;
542         case VLC_FOURCC( 'R', 'V', '2', '4' ):
543             return PIX_FMT_RGB24;
544         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
545             return PIX_FMT_YUV422;
546         default:
547             return 0;
548     }
549 }
550
551 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
552                                        sout_stream_id_t *id )
553 {
554     int i_ff_codec;
555
556     if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
557         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
558         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
559         id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
560     {
561         id->ff_dec = NULL;
562
563         id->ff_dec_c = avcodec_alloc_context();
564         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
565         id->ff_dec_c->channels    = id->f_src.i_channels;
566         id->ff_dec_c->block_align = id->f_src.i_block_align;
567         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
568     }
569     else
570     {
571         /* find decoder */
572         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
573         if( i_ff_codec == 0 )
574         {
575             msg_Err( p_stream, "cannot find decoder" );
576             return VLC_EGENERIC;
577         }
578
579         id->ff_dec = avcodec_find_decoder( i_ff_codec );
580         if( !id->ff_dec )
581         {
582             msg_Err( p_stream, "cannot find decoder" );
583             return VLC_EGENERIC;
584         }
585
586         id->ff_dec_c = avcodec_alloc_context();
587         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
588         id->ff_dec_c->channels    = id->f_src.i_channels;
589         id->ff_dec_c->block_align = id->f_src.i_block_align;
590         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
591
592         id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
593         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
594         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
595         {
596             msg_Err( p_stream, "cannot open decoder" );
597             return VLC_EGENERIC;
598         }
599     }
600
601     /* find encoder */
602     id->i_buffer_in      = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
603     id->i_buffer_in_pos = 0;
604     id->p_buffer_in      = malloc( id->i_buffer_in );
605
606     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
607     id->i_buffer_pos = 0;
608     id->p_buffer     = malloc( id->i_buffer );
609
610     id->i_buffer_out     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
611     id->i_buffer_out_pos = 0;
612     id->p_buffer_out     = malloc( id->i_buffer_out );
613
614 #ifdef HAVE_VORBIS_VORBISENC_H
615     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
616     {
617         id->p_vi = (vorbis_info *)malloc( sizeof(vorbis_info) );
618         id->p_vd = (vorbis_dsp_state *)malloc( sizeof(vorbis_dsp_state) );
619         id->p_vb = (vorbis_block *)malloc( sizeof(vorbis_block) );
620         id->p_vc = (vorbis_comment *)malloc( sizeof(vorbis_comment) );
621
622         vorbis_info_init( id->p_vi );
623
624         if( vorbis_encode_setup_managed( id->p_vi, id->f_dst.i_channels,
625               id->f_dst.i_sample_rate, -1, id->f_dst.i_bitrate, -1 ) ||
626             vorbis_encode_ctl( id->p_vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
627              vorbis_encode_setup_init( id->p_vi ) ){}
628
629         /* add a comment */
630         vorbis_comment_init( id->p_vc);
631         vorbis_comment_add_tag( id->p_vc, "ENCODER", "VLC media player");
632
633         /* set up the analysis state and auxiliary encoding storage */
634         vorbis_analysis_init( id->p_vd, id->p_vi );
635         vorbis_block_init( id->p_vd, id->p_vb );
636
637         id->b_headers_sent = VLC_FALSE;
638         id->i_last_block_size = 0;
639         id->i_samples_delay = 0;
640
641         return VLC_SUCCESS;
642     }
643 #endif
644
645     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
646     if( i_ff_codec == 0 )
647     {
648         msg_Err( p_stream, "cannot find encoder" );
649         return VLC_EGENERIC;
650     }
651
652     id->ff_enc = avcodec_find_encoder( i_ff_codec );
653     if( !id->ff_enc )
654     {
655         msg_Err( p_stream, "cannot find encoder" );
656         return VLC_EGENERIC;
657     }
658
659     id->ff_enc_c = avcodec_alloc_context();
660     id->ff_enc_c->bit_rate    = id->f_dst.i_bitrate;
661     id->ff_enc_c->sample_rate = id->f_dst.i_sample_rate;
662     id->ff_enc_c->channels    = id->f_dst.i_channels;
663
664     if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
665     {
666         msg_Err( p_stream, "cannot open encoder" );
667         return VLC_EGENERIC;
668     }
669
670     return VLC_SUCCESS;
671 }
672
673 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
674                                           sout_stream_id_t *id )
675 {
676     if( id->ff_dec )
677     {
678         avcodec_close( id->ff_dec_c );
679     }
680
681 #ifdef HAVE_VORBIS_VORBISENC_H
682     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
683     {
684         vorbis_block_clear( id->p_vb );
685         vorbis_dsp_clear( id->p_vd );
686         vorbis_comment_clear( id->p_vc );
687         vorbis_info_clear( id->p_vi );  /* must be called last */
688
689         free( id->p_vi );
690         free( id->p_vd );
691         free( id->p_vb );
692         free( id->p_vc );
693     }
694     else
695 #endif
696         avcodec_close( id->ff_enc_c );
697
698     free( id->ff_dec_c );
699     if( id->f_dst.i_fourcc != VLC_FOURCC('v','o','r','b') )
700         free( id->ff_enc_c );
701
702     free( id->p_buffer_in );
703     free( id->p_buffer );
704     free( id->p_buffer_out );
705 }
706
707 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
708                                            sout_stream_id_t *id,
709                                            sout_buffer_t *in,
710                                            sout_buffer_t **out )
711 {
712     vlc_bool_t b_again = VLC_FALSE;
713
714     *out = NULL;
715
716     /* gather data into p_buffer_in */
717 #ifdef HAVE_VORBIS_VORBISENC_H
718     if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
719     id->i_dts = in->i_dts -
720                 (mtime_t)1000000 * (mtime_t)id->i_samples_delay /
721                 (mtime_t)id->f_dst.i_sample_rate;
722     else
723 #endif
724     id->i_dts = in->i_dts -
725                 (mtime_t)1000000 *
726                 (mtime_t)(id->i_buffer_pos / 2 / id->ff_enc_c->channels )/
727                 (mtime_t)id->ff_enc_c->sample_rate;
728
729     if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
730     {
731         /* extend buffer_in */
732         id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
733         id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
734     }
735     memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
736             in->p_buffer, in->i_size );
737     id->i_buffer_in_pos += in->i_size;
738
739     do
740     {
741         /* decode as much data as possible */
742         if( id->ff_dec )
743         {
744             for( ;; )
745             {
746                 int i_buffer_size;
747                 int i_used;
748
749                 i_buffer_size = id->i_buffer - id->i_buffer_pos;
750
751                 i_used = avcodec_decode_audio( id->ff_dec_c,
752                          (int16_t*)&id->p_buffer[id->i_buffer_pos],
753                          &i_buffer_size, id->p_buffer_in,
754                          id->i_buffer_in_pos );
755
756                 /* msg_Warn( p_stream, "avcodec_decode_audio: %d used",
757                              i_used ); */
758                 id->i_buffer_pos += i_buffer_size;
759
760                 if( i_used < 0 )
761                 {
762                     msg_Warn( p_stream, "error");
763                     id->i_buffer_in_pos = 0;
764                     break;
765                 }
766                 else if( i_used < id->i_buffer_in_pos )
767                 {
768                     memmove( id->p_buffer_in,
769                              &id->p_buffer_in[i_used],
770                              id->i_buffer_in - i_used );
771                     id->i_buffer_in_pos -= i_used;
772                 }
773                 else
774                 {
775                     id->i_buffer_in_pos = 0;
776                     break;
777                 }
778
779                 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
780                 {
781                     /* buffer full */
782                     b_again = VLC_TRUE;
783                     break;
784                 }
785             }
786         }
787         else
788         {
789             int16_t *sout  = (int16_t*)&id->p_buffer[id->i_buffer_pos];
790             int     i_used = 0;
791
792             if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
793             {
794                 int8_t *sin = (int8_t*)id->p_buffer_in;
795                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
796                                            / 2, id->i_buffer_in_pos );
797                 i_used = i_samples;
798                 while( i_samples > 0 )
799                 {
800                     *sout++ = ( *sin++ ) << 8;
801                     i_samples--;
802                 }
803             }
804             else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
805             {
806                 int8_t *sin = (int8_t*)id->p_buffer_in;
807                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
808                                            / 2, id->i_buffer_in_pos );
809                 i_used = i_samples;
810                 while( i_samples > 0 )
811                 {
812                     *sout++ = ( *sin++ - 128 ) << 8;
813                     i_samples--;
814                 }
815             }
816             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
817             {
818                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
819                                            / 2, id->i_buffer_in_pos / 2);
820 #ifdef WORDS_BIGENDIAN
821                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
822                 i_used = i_samples * 2;
823                 while( i_samples > 0 )
824                 {
825                     uint8_t tmp[2];
826
827                     tmp[1] = *sin++;
828                     tmp[0] = *sin++;
829                     *sout++ = *(int16_t*)tmp;
830                     i_samples--;
831                 }
832
833 #else
834                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
835                 sout += i_samples;
836                 i_used = i_samples * 2;
837 #endif
838             }
839             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
840             {
841                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
842                                            / 2, id->i_buffer_in_pos / 2);
843 #ifdef WORDS_BIGENDIAN
844                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
845                 sout += i_samples;
846                 i_used = i_samples * 2;
847 #else
848                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
849                 i_used = i_samples * 2;
850                 while( i_samples > 0 )
851                 {
852                     uint8_t tmp[2];
853
854                     tmp[1] = *sin++;
855                     tmp[0] = *sin++;
856                     *sout++ = *(int16_t*)tmp;
857                     i_samples--;
858                 }
859 #endif
860             }
861
862             id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
863             if( i_used < id->i_buffer_in_pos )
864             {
865                 memmove( id->p_buffer_in,
866                          &id->p_buffer_in[i_used],
867                          id->i_buffer_in - i_used );
868             }
869             id->i_buffer_in_pos -= i_used;
870         }
871
872         /* encode as much data as possible */
873
874 #ifdef HAVE_VORBIS_VORBISENC_H
875         if( id->i_buffer_pos == 0 );
876         else if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
877         {
878             float **buffer;
879             int i, j, i_samples;
880             sout_buffer_t *p_out;
881             ogg_packet op;
882
883             if( id->i_buffer_pos == 0 )
884             {
885                 break;
886             }
887
888             if( !id->b_headers_sent )
889             {
890                 ogg_packet header[3];
891                 vorbis_analysis_headerout( id->p_vd, id->p_vc,
892                                            &header[0], &header[1], &header[2]);
893                 for( i = 0; i < 3; i++ )
894                 {
895                     p_out = sout_BufferNew( p_stream->p_sout, header[i].bytes);
896                     memcpy( p_out->p_buffer, header[i].packet,
897                             header[i].bytes );
898
899                     p_out->i_size = header[i].bytes;
900                     p_out->i_length = 0;
901
902                     p_out->i_dts = p_out->i_pts = 0;
903
904                     sout_BufferChain( out, p_out );
905                 }
906                 id->b_headers_sent = VLC_TRUE;
907             }
908
909             i_samples = id->i_buffer_pos / id->f_dst.i_channels / 2;
910             id->i_samples_delay += i_samples;
911             id->i_buffer_pos = 0;
912
913             buffer = vorbis_analysis_buffer( id->p_vd, i_samples );
914
915             /* convert samples to float and uninterleave */
916             for( i = 0; i < id->f_dst.i_channels; i++ )
917             {
918                 for( j = 0 ; j < i_samples ; j++ )
919                 {
920                     buffer[i][j]= ((float)( ((int16_t *)id->p_buffer)
921                                   [j*id->f_dst.i_channels + i ] ))/ 32768.f;
922                 }
923             }
924
925             vorbis_analysis_wrote( id->p_vd, i_samples );
926
927             while( vorbis_analysis_blockout( id->p_vd, id->p_vb ) == 1 )
928             {
929                 vorbis_analysis( id->p_vb, NULL );
930                 vorbis_bitrate_addblock( id->p_vb );
931
932                 while( vorbis_bitrate_flushpacket( id->p_vd, &op ) )
933                 {
934                     int i_block_size;
935                     p_out = sout_BufferNew( p_stream->p_sout, op.bytes );
936                     memcpy( p_out->p_buffer, op.packet, op.bytes );
937
938                     i_block_size = vorbis_packet_blocksize( id->p_vi, &op );
939
940                     if( i_block_size < 0 ) i_block_size = 0;
941                     i_samples = ( id->i_last_block_size +
942                                   i_block_size ) >> 2;
943                     id->i_last_block_size = i_block_size;
944
945                     p_out->i_size = op.bytes;
946                     p_out->i_length = (mtime_t)1000000 *
947                       (mtime_t)i_samples /
948                       (mtime_t)id->f_dst.i_sample_rate;
949
950                     //msg_Err( p_stream, "i_dts: %lld", id->i_dts );
951
952                     /* FIXME */
953                     p_out->i_dts = id->i_dts;
954                     p_out->i_pts = id->i_dts;
955
956                     id->i_samples_delay -= i_samples;
957
958                     /* update dts */
959                     id->i_dts += p_out->i_length;
960                     sout_BufferChain( out, p_out );
961
962                 }
963             }
964         }
965         else
966 #endif
967
968         for( ;; )
969         {
970             int i_frame_size = id->ff_enc_c->frame_size * 2 *
971                                  id->ff_enc_c->channels;
972             int i_out_size;
973             sout_buffer_t *p_out;
974
975             if( id->i_buffer_pos < i_frame_size )
976             {
977                 break;
978             }
979
980             /* msg_Warn( p_stream, "avcodec_encode_audio: frame size%d",
981                          i_frame_size); */
982             i_out_size = avcodec_encode_audio( id->ff_enc_c,
983                            id->p_buffer_out, id->i_buffer_out,
984                            (int16_t*)id->p_buffer );
985
986             if( i_out_size <= 0 )
987             {
988                 break;
989             }
990             memmove( id->p_buffer,
991                      &id->p_buffer[i_frame_size],
992                      id->i_buffer - i_frame_size );
993             id->i_buffer_pos -= i_frame_size;
994
995             p_out = sout_BufferNew( p_stream->p_sout, i_out_size );
996             memcpy( p_out->p_buffer, id->p_buffer_out, i_out_size );
997             p_out->i_size = i_out_size;
998             p_out->i_length = (mtime_t)1000000 *
999                               (mtime_t)id->ff_enc_c->frame_size /
1000                               (mtime_t)id->ff_enc_c->sample_rate;
1001
1002             /* FIXME */
1003             p_out->i_dts = id->i_dts;
1004             p_out->i_pts = id->i_dts;
1005
1006             /* update dts */
1007             id->i_dts += p_out->i_length;
1008
1009            /* msg_Warn( p_stream, "frame dts=%lld len %lld out=%d",
1010                         p_out->i_dts, p_out->i_length, i_out_size ); */
1011
1012             sout_BufferChain( out, p_out );
1013         }
1014
1015     } while( b_again );
1016
1017     return VLC_SUCCESS;
1018 }
1019
1020
1021 /*
1022  * video
1023  */
1024 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1025                                        sout_stream_id_t *id )
1026 {
1027     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1028
1029     int i_ff_codec;
1030
1031     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1032         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1033         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1034         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1035         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) )
1036     {
1037         id->ff_dec   = NULL;
1038         id->ff_dec_c            = avcodec_alloc_context();
1039         id->ff_dec_c->width     = id->f_src.i_width;
1040         id->ff_dec_c->height    = id->f_src.i_height;
1041         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
1042     }
1043     else
1044     {
1045         /* find decoder */
1046         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
1047         if( i_ff_codec == 0 )
1048         {
1049             msg_Err( p_stream, "cannot find decoder" );
1050             return VLC_EGENERIC;
1051         }
1052
1053         id->ff_dec = avcodec_find_decoder( i_ff_codec );
1054         if( !id->ff_dec )
1055         {
1056             msg_Err( p_stream, "cannot find decoder" );
1057             return VLC_EGENERIC;
1058         }
1059
1060         id->ff_dec_c = avcodec_alloc_context();
1061         id->ff_dec_c->width         = id->f_src.i_width;
1062         id->ff_dec_c->height        = id->f_src.i_height;
1063         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
1064         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
1065         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
1066         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1067         id->ff_dec_c->error_resilience= -1;
1068         if( id->ff_dec->capabilities & CODEC_CAP_TRUNCATED )
1069         {
1070             id->ff_dec_c->flags |= CODEC_FLAG_TRUNCATED;
1071         }
1072
1073         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1074         {
1075             msg_Err( p_stream, "cannot open decoder" );
1076             return VLC_EGENERIC;
1077         }
1078
1079         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1080         {
1081             int b_gotpicture;
1082             AVFrame frame;
1083
1084             avcodec_decode_video( id->ff_dec_c, &frame,
1085                                   &b_gotpicture,
1086                                   id->ff_dec_c->extradata, id->ff_dec_c->extradata_size );
1087         }
1088     }
1089
1090
1091     /* find encoder */
1092     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
1093     if( i_ff_codec == 0 )
1094     {
1095         msg_Err( p_stream, "cannot find encoder" );
1096         return VLC_EGENERIC;
1097     }
1098
1099     id->ff_enc = avcodec_find_encoder( i_ff_codec );
1100     if( !id->ff_enc )
1101     {
1102         msg_Err( p_stream, "cannot find encoder" );
1103         return VLC_EGENERIC;
1104     }
1105
1106     id->ff_enc_c = avcodec_alloc_context();
1107     id->ff_enc_c->width          = id->f_dst.i_width;
1108     id->ff_enc_c->height         = id->f_dst.i_height;
1109     id->ff_enc_c->bit_rate       = id->f_dst.i_bitrate;
1110 #if LIBAVCODEC_BUILD >= 4662
1111     id->ff_enc_c->frame_rate     = 25 ; /* FIXME as it break mpeg */
1112     id->ff_enc_c->frame_rate_base= 1;
1113 #else
1114     id->ff_enc_c->frame_rate     = 25 * FRAME_RATE_BASE;
1115 #endif
1116     id->ff_enc_c->gop_size       = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
1117
1118     if( p_sys->i_vtolerance >= 0 )
1119     {
1120         id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
1121     }
1122     id->ff_enc_c->qmin           = p_sys->i_qmin;
1123     id->ff_enc_c->qmax           = p_sys->i_qmax;
1124     if( p_sys->b_hq )
1125     {
1126         id->ff_enc_c->flags      |= CODEC_FLAG_HQ;
1127     }
1128
1129     if( i_ff_codec == CODEC_ID_RAWVIDEO )
1130     {
1131         id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
1132     }
1133     /* XXX open it only when we have the first frame */
1134     id->b_enc_inited     = VLC_FALSE;
1135     id->i_buffer_in      = 0;
1136     id->i_buffer_in_pos  = 0;
1137     id->p_buffer_in      = NULL;
1138
1139     id->i_buffer     = 3*1024*1024;
1140     id->i_buffer_pos = 0;
1141     id->p_buffer     = malloc( id->i_buffer );
1142
1143     id->i_buffer_out     = 0;
1144     id->i_buffer_out_pos = 0;
1145     id->p_buffer_out     = NULL;
1146
1147     id->p_ff_pic         = avcodec_alloc_frame();
1148     id->p_ff_pic_tmp0    = NULL;
1149     id->p_ff_pic_tmp1    = NULL;
1150     id->p_ff_pic_tmp2    = NULL;
1151     id->p_vresample      = NULL;
1152     return VLC_SUCCESS;
1153 }
1154
1155 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
1156 {
1157     if( id->ff_dec )
1158     {
1159         avcodec_close( id->ff_dec_c );
1160     }
1161     if( id->b_enc_inited )
1162     {
1163         avcodec_close( id->ff_enc_c );
1164     }
1165
1166     if( id->p_ff_pic)
1167     {
1168         free( id->p_ff_pic );
1169     }
1170
1171     if( id->p_ff_pic_tmp0 )
1172     {
1173         free( id->p_ff_pic_tmp0->data[0] );
1174         free( id->p_ff_pic_tmp0 );
1175     }
1176     if( id->p_ff_pic_tmp1)
1177     {
1178         free( id->p_ff_pic_tmp1->data[0] );
1179         free( id->p_ff_pic_tmp1 );
1180     }
1181     if( id->p_ff_pic_tmp2)
1182     {
1183         free( id->p_ff_pic_tmp2->data[0] );
1184         free( id->p_ff_pic_tmp2 );
1185     }
1186     if( id->p_vresample )
1187     {
1188         free( id->p_vresample );
1189     }
1190
1191     free( id->ff_dec_c );
1192     free( id->ff_enc_c );
1193
1194     free( id->p_buffer );
1195 }
1196
1197 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_id_t *id,
1198                                            sout_buffer_t *in, sout_buffer_t **out )
1199 {
1200     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1201     int     i_used;
1202     int     i_out;
1203     int     b_gotpicture;
1204     AVFrame *frame;
1205
1206     int     i_data;
1207     uint8_t *p_data;
1208
1209     *out = NULL;
1210
1211     i_data = in->i_size;
1212     p_data = in->p_buffer;
1213
1214     for( ;; )
1215     {
1216         /* decode frame */
1217         frame = id->p_ff_pic;
1218         if( id->ff_dec )
1219         {
1220             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1221                                            &b_gotpicture,
1222                                            p_data, i_data );
1223         }
1224         else
1225         {
1226             /* raw video */
1227             avpicture_fill( (AVPicture*)frame,
1228                             p_data,
1229                             id->ff_dec_c->pix_fmt,
1230                             id->ff_dec_c->width, id->ff_dec_c->height );
1231             i_used = i_data;
1232             b_gotpicture = 1;
1233         }
1234
1235         if( i_used < 0 )
1236         {
1237             msg_Warn( p_stream, "error");
1238             return VLC_EGENERIC;
1239         }
1240         i_data -= i_used;
1241         p_data += i_used;
1242
1243         if( !b_gotpicture )
1244         {
1245             return VLC_SUCCESS;
1246         }
1247
1248         if( !id->b_enc_inited )
1249         {
1250             /* XXX hack because of copy packetizer and mpeg4video that can failed
1251                detecting size */
1252             if( id->ff_enc_c->width <= 0 )
1253             {
1254                 id->ff_enc_c->width    =
1255                     id->f_dst.i_width  = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1256             }
1257             if( id->ff_enc_c->height <= 0 )
1258             {
1259                 id->ff_enc_c->height   =
1260                     id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1261             }
1262
1263             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
1264             {
1265                 msg_Err( p_stream, "cannot open encoder" );
1266                 return VLC_EGENERIC;
1267             }
1268
1269             if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1270             {
1271                 msg_Err( p_stream, "cannot add this stream" );
1272                 transcode_video_ffmpeg_close( p_stream, id );
1273                 id->b_transcode = VLC_FALSE;
1274                 return VLC_EGENERIC;
1275             }
1276             id->b_enc_inited = VLC_TRUE;
1277         }
1278
1279
1280         /* deinterlace */
1281         if( p_stream->p_sys->b_deinterlace )
1282         {
1283             if( id->p_ff_pic_tmp0 == NULL )
1284             {
1285                 int     i_size;
1286                 uint8_t *buf;
1287                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1288                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1289                                              id->ff_dec_c->width, id->ff_dec_c->height );
1290
1291                 buf = malloc( i_size );
1292
1293                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1294                                 id->ff_enc_c->pix_fmt,
1295                                 id->ff_dec_c->width, id->ff_dec_c->height );
1296             }
1297
1298             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1299                                    id->ff_dec_c->pix_fmt,
1300                                    id->ff_dec_c->width, id->ff_dec_c->height );
1301
1302             frame = id->p_ff_pic_tmp0;
1303         }
1304
1305         /* convert pix format */
1306         if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
1307         {
1308             if( id->p_ff_pic_tmp1 == NULL )
1309             {
1310                 int     i_size;
1311                 uint8_t *buf;
1312                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1313                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1314                                              id->ff_dec_c->width, id->ff_dec_c->height );
1315
1316                 buf = malloc( i_size );
1317
1318                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1319                                 id->ff_enc_c->pix_fmt,
1320                                 id->ff_dec_c->width, id->ff_dec_c->height );
1321             }
1322
1323             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->ff_enc_c->pix_fmt,
1324                          (AVPicture*)frame,             id->ff_dec_c->pix_fmt,
1325                          id->ff_dec_c->width, id->ff_dec_c->height );
1326
1327             frame = id->p_ff_pic_tmp1;
1328         }
1329
1330         /* convert size and crop */
1331         if( id->ff_dec_c->width  != id->ff_enc_c->width ||
1332             id->ff_dec_c->height != id->ff_enc_c->height ||
1333             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1334             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1335         {
1336             if( id->p_ff_pic_tmp2 == NULL )
1337             {
1338                 int     i_size;
1339                 uint8_t *buf;
1340                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1341                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1342                                              id->ff_enc_c->width, id->ff_enc_c->height );
1343
1344                 buf = malloc( i_size );
1345
1346                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1347                                 id->ff_enc_c->pix_fmt,
1348                                 id->ff_enc_c->width, id->ff_enc_c->height );
1349
1350                 id->p_vresample =
1351                     img_resample_full_init( id->ff_enc_c->width, id->ff_enc_c->height,
1352                                             id->ff_dec_c->width, id->ff_dec_c->height,
1353                                             p_stream->p_sys->i_crop_top,
1354                                             p_stream->p_sys->i_crop_bottom,
1355                                             p_stream->p_sys->i_crop_left,
1356                                             p_stream->p_sys->i_crop_right );
1357             }
1358
1359             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2, (AVPicture*)frame );
1360
1361             frame = id->p_ff_pic_tmp2;
1362         }
1363
1364         i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer, id->i_buffer, frame );
1365         if( i_out > 0 )
1366         {
1367             sout_buffer_t *p_out;
1368             p_out = sout_BufferNew( p_stream->p_sout, i_out );
1369
1370             memcpy( p_out->p_buffer, id->p_buffer, i_out );
1371
1372             p_out->i_size   = i_out;
1373             p_out->i_length = in->i_length;
1374             p_out->i_dts    = in->i_dts;
1375             p_out->i_pts    = in->i_dts; /* FIXME */
1376
1377             sout_BufferChain( out, p_out );
1378         }
1379
1380         if( i_data <= 0 )
1381         {
1382             return VLC_SUCCESS;
1383         }
1384     }
1385
1386     return VLC_SUCCESS;
1387 }