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