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