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