]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
* include/vlc_codec.h: defines decoders/encoders related structures here.
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.35 2003/10/08 21:01: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 #include <vlc/vout.h>
34 #include <vlc/decoder.h>
35
36 /* ffmpeg header */
37 #ifdef HAVE_FFMPEG_AVCODEC_H
38 #   include <ffmpeg/avcodec.h>
39 #else
40 #   include <avcodec.h>
41 #endif
42
43 /* vorbis header */
44 #ifdef HAVE_VORBIS_VORBISENC_H
45 #   include <vorbis/vorbisenc.h>
46 #   ifndef OV_ECTL_RATEMANAGE_AVG
47 #       define OV_ECTL_RATEMANAGE_AVG 0x0
48 #   endif
49 #endif
50
51 /*****************************************************************************
52  * Exported prototypes
53  *****************************************************************************/
54 static int      Open    ( vlc_object_t * );
55 static void     Close   ( vlc_object_t * );
56
57 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
58 static int               Del ( sout_stream_t *, sout_stream_id_t * );
59 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
60
61 static int  transcode_audio_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
62 static void transcode_audio_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
63 static int  transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
64
65 static int  transcode_video_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
66 static void transcode_video_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
67 static int  transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
68
69 static int  transcode_video_ffmpeg_getframebuf( struct AVCodecContext *, AVFrame *);
70
71 /*****************************************************************************
72  * Module descriptor
73  *****************************************************************************/
74 vlc_module_begin();
75     set_description( _("Transcode stream") );
76     set_capability( "sout stream", 50 );
77     add_shortcut( "transcode" );
78     set_callbacks( Open, Close );
79 vlc_module_end();
80
81 struct sout_stream_sys_t
82 {
83     sout_stream_t   *p_out;
84
85     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
86     int             i_sample_rate;
87     int             i_channels;
88     int             i_abitrate;
89
90     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
91     int             i_vbitrate;
92     int             i_vtolerance;
93     int             i_width;
94     int             i_height;
95     int             i_b_frames;
96     int             i_key_int;
97     int             i_qmin;
98     int             i_qmax;
99     vlc_bool_t      i_hq;
100     vlc_bool_t      b_deinterlace;
101
102     int             i_crop_top;
103     int             i_crop_bottom;
104     int             i_crop_right;
105     int             i_crop_left;
106
107     mtime_t         i_input_pts;
108     mtime_t         i_output_pts;
109     mtime_t         i_last_ref_pts;
110
111     mtime_t         i_buggy_pts_detect;
112 };
113
114 /*****************************************************************************
115  * Open:
116  *****************************************************************************/
117 static int Open( vlc_object_t *p_this )
118 {
119     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
120     sout_stream_sys_t *p_sys;
121     char *codec;
122
123     p_sys = malloc( sizeof( sout_stream_sys_t ) );
124     p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
125
126     p_sys->i_acodec      = 0;
127     p_sys->i_sample_rate = 0;
128     p_sys->i_channels    = 0;
129     p_sys->i_abitrate    = 0;
130
131     p_sys->i_vcodec     = 0;
132     p_sys->i_vbitrate   = 0;
133     p_sys->i_vtolerance = -1;
134     p_sys->i_width      = 0;
135     p_sys->i_height     = 0;
136     p_sys->i_key_int    = -1;
137     p_sys->i_b_frames   = 0;
138     p_sys->i_qmin       = 2;
139     p_sys->i_qmax       = 31;
140 #if LIBAVCODEC_BUILD >= 4673
141     p_sys->i_hq         = FF_MB_DECISION_SIMPLE;
142 #else
143     p_sys->i_hq         = VLC_FALSE;
144 #endif
145     p_sys->b_deinterlace= VLC_FALSE;
146
147     p_sys->i_crop_top   = 0;
148     p_sys->i_crop_bottom= 0;
149     p_sys->i_crop_right = 0;
150     p_sys->i_crop_left  = 0;
151
152     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "acodec" ) ) )
153     {
154         char fcc[4] = "    ";
155         char *val;
156
157         memcpy( fcc, codec, strlen( codec ) );
158
159         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
160
161         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "samplerate" ) ) )
162         {
163             p_sys->i_sample_rate = atoi( val );
164         }
165         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "channels" ) ) )
166         {
167             p_sys->i_channels = atoi( val );
168         }
169         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
170         {
171             p_sys->i_abitrate = atoi( val );
172             if( p_sys->i_abitrate < 4000 )
173             {
174                 p_sys->i_abitrate *= 1000;
175             }
176         }
177
178         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", fcc,
179                  p_sys->i_sample_rate, p_sys->i_channels,
180                  p_sys->i_abitrate / 1024 );
181     }
182
183     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
184     {
185         char fcc[4] = "    ";
186         char *val;
187
188         memcpy( fcc, codec, strlen( codec ) );
189
190         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
191
192         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
193         {
194             p_sys->i_width = atoi( val );
195         }
196         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
197         {
198             p_sys->i_height = atoi( val );
199         }
200         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
201         {
202             p_sys->i_vbitrate = atoi( val );
203             if( p_sys->i_vbitrate < 16000 )
204             {
205                 p_sys->i_vbitrate *= 1000;
206             }
207         }
208         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
209         {
210             p_sys->i_vtolerance = atoi( val );
211         }
212         if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
213         {
214             p_sys->b_deinterlace = VLC_TRUE;
215         }
216         /* crop */
217         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
218         {
219             p_sys->i_crop_top = atoi( val );
220         }
221         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
222         {
223             p_sys->i_crop_bottom = atoi( val );
224         }
225         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
226         {
227             p_sys->i_crop_left = atoi( val );
228         }
229         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
230         {
231             p_sys->i_crop_right = atoi( val );
232         }
233         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
234         {
235             p_sys->i_key_int    = atoi( val );
236         }
237         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "bframes" ) ) )
238         {
239             p_sys->i_b_frames   = atoi( val );
240         }
241 #if LIBAVCODEC_BUILD >= 4673
242         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "hq" ) ) )
243         {
244             if( !strcmp( val, "rd" ) )
245             {
246                 p_sys->i_hq = FF_MB_DECISION_RD;
247             }
248             else if( !strcmp( val, "bits" ) )
249             {
250                 p_sys->i_hq = FF_MB_DECISION_BITS;
251             }
252             else if( !strcmp( val, "simple" ) )
253             {
254                 p_sys->i_hq = FF_MB_DECISION_SIMPLE;
255             }
256             else
257             {
258                 p_sys->i_hq = FF_MB_DECISION_RD;
259             }
260         }
261 #else
262         if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
263         {
264             p_sys->i_hq = VLC_TRUE;
265         }
266 #endif
267         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
268         {
269             p_sys->i_qmin   = atoi( val );
270         }
271         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
272         {
273             p_sys->i_qmax   = atoi( val );
274         }
275
276         msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
277                  fcc,
278                  p_sys->i_width, p_sys->i_height,
279                  p_sys->i_vbitrate / 1024 );
280     }
281
282     if( !p_sys->p_out )
283     {
284         msg_Err( p_stream, "cannot create chain" );
285         free( p_sys );
286         return VLC_EGENERIC;
287     }
288     p_stream->pf_add    = Add;
289     p_stream->pf_del    = Del;
290     p_stream->pf_send   = Send;
291
292     p_stream->p_sys     = p_sys;
293
294     avcodec_init();
295     avcodec_register_all();
296
297     /* ffmpeg needs some padding at the end of each buffer */
298     p_stream->p_sout->i_padding += FF_INPUT_BUFFER_PADDING_SIZE;
299
300     return VLC_SUCCESS;
301 }
302
303 /*****************************************************************************
304  * Close:
305  *****************************************************************************/
306
307 static void Close( vlc_object_t * p_this )
308 {
309     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
310     sout_stream_sys_t   *p_sys = p_stream->p_sys;
311
312     sout_stream_delete( p_sys->p_out );
313     free( p_sys );
314 }
315
316 struct sout_stream_id_t
317 {
318     vlc_fourcc_t  b_transcode;
319     sout_format_t f_src;        /* only if transcoding */
320     sout_format_t f_dst;        /*  "   "      " */
321
322     /* id of the out stream */
323     void *id;
324
325     /* Encoder */
326     encoder_t *p_encoder;
327
328     /* ffmpeg part */
329     AVCodec         *ff_dec;
330     AVCodecContext  *ff_dec_c;
331
332
333     vlc_fourcc_t    b_enc_inited;
334     AVCodec         *ff_enc;
335     AVCodecContext  *ff_enc_c;
336
337     mtime_t         i_dts;
338     mtime_t         i_length;
339
340     int             i_buffer_in;
341     int             i_buffer_in_pos;
342     uint8_t         *p_buffer_in;
343
344     int             i_buffer;
345     int             i_buffer_pos;
346     uint8_t         *p_buffer;
347
348     int             i_buffer_out;
349     int             i_buffer_out_pos;
350     uint8_t         *p_buffer_out;
351
352     AVFrame         *p_ff_pic;
353     AVFrame         *p_ff_pic_tmp0; /* to do deinterlace */
354     AVFrame         *p_ff_pic_tmp1; /* to do pix conversion */
355     AVFrame         *p_ff_pic_tmp2; /* to do resample */
356
357     ImgReSampleContext *p_vresample;
358
359 #ifdef HAVE_VORBIS_VORBISENC_H
360
361     /* Vorbis part */
362     vorbis_info      *p_vi;
363     vorbis_dsp_state *p_vd;
364     vorbis_block     *p_vb;
365     vorbis_comment   *p_vc;
366     int              i_last_block_size;
367     int              i_samples_delay;
368     vlc_bool_t       b_headers_sent;
369 #endif
370 };
371
372
373 static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
374 {
375     sout_stream_sys_t   *p_sys = p_stream->p_sys;
376     sout_stream_id_t    *id;
377
378     id = malloc( sizeof( sout_stream_id_t ) );
379     id->i_dts = 0;
380     id->id = NULL;
381     id->p_encoder = NULL;
382
383     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
384     {
385         msg_Dbg( p_stream,
386                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
387                  (char*)&p_fmt->i_fourcc,
388                  (char*)&p_sys->i_acodec );
389
390         /* src format */
391         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
392
393         /* create dst format */
394         id->f_dst.i_cat    = AUDIO_ES;
395         id->f_dst.i_fourcc = p_sys->i_acodec;
396         id->f_dst.i_sample_rate = p_sys->i_sample_rate  > 0 ? p_sys->i_sample_rate : id->f_src.i_sample_rate;
397         id->f_dst.i_channels    = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.i_channels;
398         id->f_dst.i_bitrate     = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
399         id->f_dst.i_block_align = 0;
400         id->f_dst.i_extra_data  = 0;
401         id->f_dst.p_extra_data  = NULL;
402
403         /* build decoder -> filter -> encoder */
404         if( transcode_audio_ffmpeg_new( p_stream, id ) )
405         {
406             msg_Err( p_stream, "cannot create audio chain" );
407             free( id );
408             return NULL;
409         }
410
411         /* open output stream */
412         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
413         id->b_transcode = VLC_TRUE;
414
415         if( id->id == NULL )
416         {
417             free( id );
418             return NULL;
419         }
420     }
421     else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
422     {
423         msg_Dbg( p_stream,
424                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
425                  (char*)&p_fmt->i_fourcc,
426                  (char*)&p_sys->i_vcodec );
427
428         memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
429
430         /* create dst format */
431         id->f_dst.i_cat         = VIDEO_ES;
432         id->f_dst.i_fourcc      = p_sys->i_vcodec;
433         id->f_dst.i_width       = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
434         id->f_dst.i_height      = p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
435         id->f_dst.i_bitrate     = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
436         id->f_dst.i_extra_data  = 0;
437         id->f_dst.p_extra_data  = NULL;
438
439         /* build decoder -> filter -> encoder */
440         if( transcode_video_ffmpeg_new( p_stream, id ) )
441         {
442             msg_Err( p_stream, "cannot create video chain" );
443             free( id );
444             return NULL;
445         }
446 #if 0
447         /* open output stream */
448         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
449 #endif
450         id->b_transcode = VLC_TRUE;
451     }
452     else
453     {
454         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_fourcc );
455         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
456         id->b_transcode = VLC_FALSE;
457
458         if( id->id == NULL )
459         {
460             free( id );
461             return NULL;
462         }
463     }
464
465     return id;
466 }
467
468 static int     Del      ( sout_stream_t *p_stream, sout_stream_id_t *id )
469 {
470     sout_stream_sys_t   *p_sys = p_stream->p_sys;
471
472     if( id->b_transcode )
473     {
474         if( id->f_src.i_cat == AUDIO_ES )
475         {
476             transcode_audio_ffmpeg_close( p_stream, id );
477         }
478         else if( id->f_src.i_cat == VIDEO_ES )
479         {
480             transcode_video_ffmpeg_close( p_stream, id );
481         }
482     }
483
484     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
485     free( id );
486
487     return VLC_SUCCESS;
488 }
489
490 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
491                  sout_buffer_t *p_buffer )
492 {
493     sout_stream_sys_t   *p_sys = p_stream->p_sys;
494
495     if( id->b_transcode )
496     {
497         sout_buffer_t *p_buffer_out;
498         if( id->f_src.i_cat == AUDIO_ES )
499         {
500             transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
501         }
502         else if( id->f_src.i_cat == VIDEO_ES )
503         {
504             transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
505         }
506         sout_BufferDelete( p_stream->p_sout, p_buffer );
507
508         if( p_buffer_out )
509         {
510             return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
511         }
512         return VLC_SUCCESS;
513     }
514     else if( id->id != NULL )
515     {
516         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
517     }
518     else
519     {
520         sout_BufferDelete( p_stream->p_sout, p_buffer );
521         return VLC_EGENERIC;
522     }
523 }
524
525 /****************************************************************************
526  * ffmpeg decoder reencocdr part
527  ****************************************************************************/
528
529 static struct
530 {
531     vlc_fourcc_t i_fcc;
532     int          i_ff_codec;
533 } fourcc_to_ff_code[] =
534 {
535     /* audio */
536     { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
537     { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
538     { VLC_FOURCC( 'm', 'p', '4', 'a' ), CODEC_ID_AAC },
539     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
540     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
541     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
542     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
543     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
544     { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
545
546     /* video */
547     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
548     { VLC_FOURCC( 'm', 'p', '1', 'v' ), CODEC_ID_MPEG1VIDEO },
549 #if LIBAVCODEC_BUILD >= 4676
550     { VLC_FOURCC( 'm', 'p', '2', 'v' ), CODEC_ID_MPEG2VIDEO },
551 #endif
552     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
553     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
554     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
555     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
556     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
557     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
558     { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
559     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
560     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
561     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
562     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
563     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
564     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
565 #if LIBAVCODEC_BUILD >= 4666
566     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
567 #endif
568
569     /* raw video code, only used for 'encoding' */
570     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
571     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
572     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
573     { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
574     { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
575     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
576     { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
577     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
578
579     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
580 };
581
582 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
583 {
584     int i;
585
586     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
587     {
588         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
589         {
590             return fourcc_to_ff_code[i].i_ff_codec;
591         }
592     }
593
594     return 0;
595 }
596
597 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
598 {
599     switch( i_chroma )
600     {
601         case VLC_FOURCC( 'I', '4', '2', '0' ):
602             return PIX_FMT_YUV420P;
603         case VLC_FOURCC( 'I', '4', '2', '2' ):
604             return PIX_FMT_YUV422P;
605         case VLC_FOURCC( 'I', '4', '4', '4' ):
606             return PIX_FMT_YUV444P;
607         case VLC_FOURCC( 'R', 'V', '1', '5' ):
608             return PIX_FMT_RGB555;
609         case VLC_FOURCC( 'R', 'V', '1', '6' ):
610             return PIX_FMT_RGB565;
611         case VLC_FOURCC( 'R', 'V', '2', '4' ):
612             return PIX_FMT_RGB24;
613         case VLC_FOURCC( 'R', 'V', '3', '2' ):
614             return PIX_FMT_RGBA32;
615         case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
616             return PIX_FMT_GRAY8;
617         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
618             return PIX_FMT_YUV422;
619         default:
620             return 0;
621     }
622 }
623
624 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
625                                        sout_stream_id_t *id )
626 {
627     int i_ff_codec;
628
629     if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
630         id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
631         id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
632         id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
633     {
634         id->ff_dec = NULL;
635
636         id->ff_dec_c = avcodec_alloc_context();
637         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
638         id->ff_dec_c->channels    = id->f_src.i_channels;
639         id->ff_dec_c->block_align = id->f_src.i_block_align;
640         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
641     }
642     else
643     {
644         /* find decoder */
645         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
646         if( i_ff_codec == 0 )
647         {
648             msg_Err( p_stream, "cannot find decoder id" );
649             return VLC_EGENERIC;
650         }
651
652         id->ff_dec = avcodec_find_decoder( i_ff_codec );
653         if( !id->ff_dec )
654         {
655             msg_Err( p_stream, "cannot find decoder (avcodec)" );
656             return VLC_EGENERIC;
657         }
658
659         id->ff_dec_c = avcodec_alloc_context();
660         id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
661         id->ff_dec_c->channels    = id->f_src.i_channels;
662         id->ff_dec_c->block_align = id->f_src.i_block_align;
663         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
664
665         id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
666         id->ff_dec_c->extradata      = id->f_src.p_extra_data;
667         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
668         {
669             msg_Err( p_stream, "cannot open decoder" );
670             return VLC_EGENERIC;
671         }
672     }
673
674     /* find encoder */
675     id->i_buffer_in      = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
676     id->i_buffer_in_pos = 0;
677     id->p_buffer_in      = malloc( id->i_buffer_in );
678
679     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
680     id->i_buffer_pos = 0;
681     id->p_buffer     = malloc( id->i_buffer );
682
683     id->i_buffer_out     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
684     id->i_buffer_out_pos = 0;
685     id->p_buffer_out     = malloc( id->i_buffer_out );
686
687     /* Sanity check for audio channels */
688     id->f_dst.i_channels = __MIN( id->f_dst.i_channels, id->f_src.i_channels );
689
690 #ifdef HAVE_VORBIS_VORBISENC_H
691     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
692     {
693         id->p_vi = (vorbis_info *)malloc( sizeof(vorbis_info) );
694         id->p_vd = (vorbis_dsp_state *)malloc( sizeof(vorbis_dsp_state) );
695         id->p_vb = (vorbis_block *)malloc( sizeof(vorbis_block) );
696         id->p_vc = (vorbis_comment *)malloc( sizeof(vorbis_comment) );
697
698         vorbis_info_init( id->p_vi );
699
700         if( vorbis_encode_setup_managed( id->p_vi, id->f_dst.i_channels,
701               id->f_dst.i_sample_rate, -1, id->f_dst.i_bitrate, -1 ) ||
702             vorbis_encode_ctl( id->p_vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
703              vorbis_encode_setup_init( id->p_vi ) ){}
704
705         /* add a comment */
706         vorbis_comment_init( id->p_vc);
707         vorbis_comment_add_tag( id->p_vc, "ENCODER", "VLC media player");
708
709         /* set up the analysis state and auxiliary encoding storage */
710         vorbis_analysis_init( id->p_vd, id->p_vi );
711         vorbis_block_init( id->p_vd, id->p_vb );
712
713         id->b_headers_sent = VLC_FALSE;
714         id->i_last_block_size = 0;
715         id->i_samples_delay = 0;
716
717         return VLC_SUCCESS;
718     }
719 #endif
720
721     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
722     if( i_ff_codec == 0 )
723     {
724         msg_Err( p_stream, "cannot find encoder id" );
725         return VLC_EGENERIC;
726     }
727
728     id->ff_enc = avcodec_find_encoder( i_ff_codec );
729     if( !id->ff_enc )
730     {
731         msg_Err( p_stream, "cannot find encoder (avcodec)" );
732         return VLC_EGENERIC;
733     }
734
735     /* Hack for mp3 transcoding support */
736     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
737     {
738         id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','a' );
739     }
740
741     id->ff_enc_c = avcodec_alloc_context();
742     id->ff_enc_c->bit_rate    = id->f_dst.i_bitrate;
743     id->ff_enc_c->sample_rate = id->f_dst.i_sample_rate;
744     id->ff_enc_c->channels    = id->f_dst.i_channels;
745
746     /* Make sure we get extradata filled by the encoder */
747     id->ff_enc_c->extradata_size = 0;
748     id->ff_enc_c->extradata = NULL;
749     id->ff_enc_c->flags |= CODEC_FLAG_GLOBAL_HEADER;
750
751     if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
752     {
753         if( id->ff_enc_c->channels > 2 )
754         {
755             id->ff_enc_c->channels = 2;
756             id->f_dst.i_channels   = 2;
757             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
758             {
759                 msg_Err( p_stream, "cannot open encoder" );
760                 return VLC_EGENERIC;
761             }
762             msg_Warn( p_stream, "stereo mode selected (codec limitation)" );
763         }
764         else
765         {
766             msg_Err( p_stream, "cannot open encoder" );
767             return VLC_EGENERIC;
768         }
769     }
770
771     id->f_dst.i_extra_data = id->ff_enc_c->extradata_size;
772     id->f_dst.p_extra_data = id->ff_enc_c->extradata;
773     id->ff_enc_c->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
774
775     return VLC_SUCCESS;
776 }
777
778 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
779                                           sout_stream_id_t *id )
780 {
781     if( id->ff_dec )
782     {
783         avcodec_close( id->ff_dec_c );
784     }
785
786 #ifdef HAVE_VORBIS_VORBISENC_H
787     if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
788     {
789         vorbis_block_clear( id->p_vb );
790         vorbis_dsp_clear( id->p_vd );
791         vorbis_comment_clear( id->p_vc );
792         vorbis_info_clear( id->p_vi );  /* must be called last */
793
794         free( id->p_vi );
795         free( id->p_vd );
796         free( id->p_vb );
797         free( id->p_vc );
798     }
799     else
800 #endif
801         avcodec_close( id->ff_enc_c );
802
803     free( id->ff_dec_c );
804     if( id->f_dst.i_fourcc != VLC_FOURCC('v','o','r','b') )
805         free( id->ff_enc_c );
806
807     free( id->p_buffer_in );
808     free( id->p_buffer );
809     free( id->p_buffer_out );
810 }
811
812 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
813                                            sout_stream_id_t *id,
814                                            sout_buffer_t *in,
815                                            sout_buffer_t **out )
816 {
817     vlc_bool_t b_again = VLC_FALSE;
818
819     *out = NULL;
820
821     /* gather data into p_buffer_in */
822 #ifdef HAVE_VORBIS_VORBISENC_H
823     if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
824     id->i_dts = in->i_dts -
825                 (mtime_t)1000000 * (mtime_t)id->i_samples_delay /
826                 (mtime_t)id->f_dst.i_sample_rate;
827     else
828 #endif
829     id->i_dts = in->i_dts -
830                 (mtime_t)1000000 *
831                 (mtime_t)(id->i_buffer_pos / 2 / id->ff_dec_c->channels )/
832                 (mtime_t)id->ff_dec_c->sample_rate;
833
834     if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
835     {
836         /* extend buffer_in */
837         id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
838         id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
839     }
840     memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
841             in->p_buffer, in->i_size );
842     id->i_buffer_in_pos += in->i_size;
843
844     do
845     {
846         int i_buffer_pos;
847
848         /* decode as much data as possible */
849         if( id->ff_dec )
850         {
851             for( ;; )
852             {
853                 int i_buffer_size;
854                 int i_used;
855
856                 i_buffer_size = id->i_buffer - id->i_buffer_pos;
857
858                 i_used = avcodec_decode_audio( id->ff_dec_c,
859                          (int16_t*)&id->p_buffer[id->i_buffer_pos],
860                          &i_buffer_size, id->p_buffer_in,
861                          id->i_buffer_in_pos );
862
863                 /* msg_Warn( p_stream, "avcodec_decode_audio: %d used",
864                              i_used ); */
865                 id->i_buffer_pos += i_buffer_size;
866
867                 if( i_used < 0 )
868                 {
869                     msg_Warn( p_stream, "error");
870                     id->i_buffer_in_pos = 0;
871                     break;
872                 }
873                 else if( i_used < id->i_buffer_in_pos )
874                 {
875                     memmove( id->p_buffer_in,
876                              &id->p_buffer_in[i_used],
877                              id->i_buffer_in - i_used );
878                     id->i_buffer_in_pos -= i_used;
879                 }
880                 else
881                 {
882                     id->i_buffer_in_pos = 0;
883                     break;
884                 }
885
886                 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
887                 {
888                     /* buffer full */
889                     b_again = VLC_TRUE;
890                     break;
891                 }
892             }
893         }
894         else
895         {
896             int16_t *sout  = (int16_t*)&id->p_buffer[id->i_buffer_pos];
897             int     i_used = 0;
898
899             if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
900             {
901                 int8_t *sin = (int8_t*)id->p_buffer_in;
902                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
903                                            / 2, id->i_buffer_in_pos );
904                 i_used = i_samples;
905                 while( i_samples > 0 )
906                 {
907                     *sout++ = ( *sin++ ) << 8;
908                     i_samples--;
909                 }
910             }
911             else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
912             {
913                 int8_t *sin = (int8_t*)id->p_buffer_in;
914                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
915                                            / 2, id->i_buffer_in_pos );
916                 i_used = i_samples;
917                 while( i_samples > 0 )
918                 {
919                     *sout++ = ( *sin++ - 128 ) << 8;
920                     i_samples--;
921                 }
922             }
923             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
924             {
925                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
926                                            / 2, id->i_buffer_in_pos / 2);
927 #ifdef WORDS_BIGENDIAN
928                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
929                 i_used = i_samples * 2;
930                 while( i_samples > 0 )
931                 {
932                     uint8_t tmp[2];
933
934                     tmp[1] = *sin++;
935                     tmp[0] = *sin++;
936                     *sout++ = *(int16_t*)tmp;
937                     i_samples--;
938                 }
939
940 #else
941                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
942                 sout += i_samples;
943                 i_used = i_samples * 2;
944 #endif
945             }
946             else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
947             {
948                 int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
949                                            / 2, id->i_buffer_in_pos / 2);
950 #ifdef WORDS_BIGENDIAN
951                 memcpy( sout, id->p_buffer_in, i_samples * 2 );
952                 sout += i_samples;
953                 i_used = i_samples * 2;
954 #else
955                 uint8_t *sin = (uint8_t*)id->p_buffer_in;
956                 i_used = i_samples * 2;
957                 while( i_samples > 0 )
958                 {
959                     uint8_t tmp[2];
960
961                     tmp[1] = *sin++;
962                     tmp[0] = *sin++;
963                     *sout++ = *(int16_t*)tmp;
964                     i_samples--;
965                 }
966 #endif
967             }
968
969             id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
970             if( i_used < id->i_buffer_in_pos )
971             {
972                 memmove( id->p_buffer_in,
973                          &id->p_buffer_in[i_used],
974                          id->i_buffer_in - i_used );
975             }
976             id->i_buffer_in_pos -= i_used;
977         }
978
979         i_buffer_pos = id->i_buffer_pos;
980
981         /* encode as much data as possible */
982
983 #ifdef HAVE_VORBIS_VORBISENC_H
984         if( id->i_buffer_pos == 0 );
985         else if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
986         {
987             float **buffer;
988             int i, j, i_samples;
989             sout_buffer_t *p_out;
990             ogg_packet op;
991
992             if( !id->b_headers_sent )
993             {
994                 ogg_packet header[3];
995                 vorbis_analysis_headerout( id->p_vd, id->p_vc,
996                                            &header[0], &header[1], &header[2]);
997                 for( i = 0; i < 3; i++ )
998                 {
999                     p_out = sout_BufferNew( p_stream->p_sout, header[i].bytes);
1000                     memcpy( p_out->p_buffer, header[i].packet,
1001                             header[i].bytes );
1002
1003                     p_out->i_size = header[i].bytes;
1004                     p_out->i_length = 0;
1005
1006                     p_out->i_dts = p_out->i_pts = 0;
1007
1008                     sout_BufferChain( out, p_out );
1009                 }
1010                 id->b_headers_sent = VLC_TRUE;
1011             }
1012
1013             i_samples = id->i_buffer_pos / id->f_src.i_channels / 2;
1014             id->i_samples_delay += i_samples;
1015             id->i_buffer_pos = 0;
1016
1017             buffer = vorbis_analysis_buffer( id->p_vd, i_samples );
1018
1019             /* convert samples to float and uninterleave */
1020             for( i = 0; i < id->f_dst.i_channels; i++ )
1021             {
1022                 for( j = 0 ; j < i_samples ; j++ )
1023                 {
1024                     buffer[i][j]= ((float)( ((int16_t *)id->p_buffer)
1025                                   [j*id->f_src.i_channels + i ] ))/ 32768.f;
1026                 }
1027             }
1028
1029             vorbis_analysis_wrote( id->p_vd, i_samples );
1030
1031             while( vorbis_analysis_blockout( id->p_vd, id->p_vb ) == 1 )
1032             {
1033                 vorbis_analysis( id->p_vb, NULL );
1034                 vorbis_bitrate_addblock( id->p_vb );
1035
1036                 while( vorbis_bitrate_flushpacket( id->p_vd, &op ) )
1037                 {
1038                     int i_block_size;
1039                     p_out = sout_BufferNew( p_stream->p_sout, op.bytes );
1040                     memcpy( p_out->p_buffer, op.packet, op.bytes );
1041
1042                     i_block_size = vorbis_packet_blocksize( id->p_vi, &op );
1043
1044                     if( i_block_size < 0 ) i_block_size = 0;
1045                     i_samples = ( id->i_last_block_size +
1046                                   i_block_size ) >> 2;
1047                     id->i_last_block_size = i_block_size;
1048
1049                     p_out->i_size = op.bytes;
1050                     p_out->i_length = (mtime_t)1000000 *
1051                       (mtime_t)i_samples /
1052                       (mtime_t)id->f_dst.i_sample_rate;
1053
1054                     //msg_Err( p_stream, "i_dts: %lld", id->i_dts );
1055
1056                     /* FIXME */
1057                     p_out->i_dts = id->i_dts;
1058                     p_out->i_pts = id->i_dts;
1059
1060                     id->i_samples_delay -= i_samples;
1061
1062                     /* update dts */
1063                     id->i_dts += p_out->i_length;
1064                     sout_BufferChain( out, p_out );
1065
1066                 }
1067             }
1068         }
1069         else
1070 #endif
1071
1072         for( ;; )
1073         {
1074             int i_frame_size = id->ff_enc_c->frame_size * 2 *
1075                                  id->ff_dec_c->channels;
1076             int i_out_size, i, j;
1077             sout_buffer_t *p_out;
1078             int16_t *p_buffer = (int16_t *)(id->p_buffer + i_buffer_pos -
1079                                             id->i_buffer_pos);
1080
1081             if( id->i_buffer_pos < i_frame_size )
1082             {
1083                 break;
1084             }
1085
1086             if( id->ff_dec_c->channels != id->ff_enc_c->channels )
1087             {
1088                 /* dumb downmixing */
1089                 for( i = 0; i < id->ff_enc_c->frame_size; i++ )
1090                 {
1091                     for( j = 0 ; j < id->f_dst.i_channels; j++ )
1092                     {
1093                         p_buffer[i*id->f_dst.i_channels+j] = p_buffer[i*id->f_src.i_channels+j];
1094                     }
1095                 }
1096             }
1097
1098             /* msg_Warn( p_stream, "avcodec_encode_audio: frame size%d",
1099                          i_frame_size); */
1100             i_out_size = avcodec_encode_audio( id->ff_enc_c,
1101                            id->p_buffer_out, id->i_buffer_out, p_buffer );
1102
1103             if( i_out_size <= 0 )
1104             {
1105                 break;
1106             }
1107
1108             id->i_buffer_pos -= i_frame_size;
1109
1110             p_out = sout_BufferNew( p_stream->p_sout, i_out_size );
1111             memcpy( p_out->p_buffer, id->p_buffer_out, i_out_size );
1112             p_out->i_size = i_out_size;
1113             p_out->i_length = (mtime_t)1000000 *
1114                               (mtime_t)id->ff_enc_c->frame_size /
1115                               (mtime_t)id->ff_enc_c->sample_rate;
1116
1117             /* FIXME */
1118             p_out->i_dts = id->i_dts;
1119             p_out->i_pts = id->i_dts;
1120
1121             /* update dts */
1122             id->i_dts += p_out->i_length;
1123
1124            /* msg_Warn( p_stream, "frame dts=%lld len %lld out=%d",
1125                         p_out->i_dts, p_out->i_length, i_out_size ); */
1126
1127             sout_BufferChain( out, p_out );
1128         }
1129
1130         /* Copy the remaining raw samples */
1131         if( id->i_buffer_pos != 0 )
1132         {
1133             memmove( id->p_buffer,
1134                      &id->p_buffer[i_buffer_pos - id->i_buffer_pos],
1135                      id->i_buffer_pos );
1136         }
1137
1138     } while( b_again );
1139
1140     return VLC_SUCCESS;
1141 }
1142
1143
1144 /*
1145  * video
1146  */
1147 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1148                                        sout_stream_id_t *id )
1149 {
1150     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1151
1152     int i_ff_codec;
1153
1154     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1155         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1156         id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1157         id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1158         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
1159         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
1160         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
1161         id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
1162         id->f_src.i_fourcc == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
1163     {
1164         id->ff_dec   = NULL;
1165         id->ff_dec_c            = avcodec_alloc_context();
1166         id->ff_dec_c->width     = id->f_src.i_width;
1167         id->ff_dec_c->height    = id->f_src.i_height;
1168         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_fourcc );
1169     }
1170     else
1171     {
1172         /* find decoder */
1173         i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
1174         if( i_ff_codec == 0 )
1175         {
1176             msg_Err( p_stream, "cannot find decoder" );
1177             return VLC_EGENERIC;
1178         }
1179
1180         id->ff_dec = avcodec_find_decoder( i_ff_codec );
1181         if( !id->ff_dec )
1182         {
1183             msg_Err( p_stream, "cannot find decoder" );
1184             return VLC_EGENERIC;
1185         }
1186
1187         id->ff_dec_c = avcodec_alloc_context();
1188         id->ff_dec_c->width         = id->f_src.i_width;
1189         id->ff_dec_c->height        = id->f_src.i_height;
1190         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
1191         id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
1192         id->ff_dec_c->extradata     = id->f_src.p_extra_data;
1193         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1194         id->ff_dec_c->error_resilience= -1;
1195         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
1196         id->ff_dec_c->opaque        = p_sys;
1197
1198         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1199         {
1200             msg_Err( p_stream, "cannot open decoder" );
1201             return VLC_EGENERIC;
1202         }
1203
1204         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1205         {
1206             int b_gotpicture;
1207             AVFrame frame;
1208             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
1209                                      FF_INPUT_BUFFER_PADDING_SIZE );
1210
1211             memcpy( p_vol, id->ff_dec_c->extradata,
1212                     id->ff_dec_c->extradata_size );
1213             memset( p_vol + id->ff_dec_c->extradata_size, 0,
1214                     FF_INPUT_BUFFER_PADDING_SIZE );
1215
1216             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
1217                                   id->ff_dec_c->extradata,
1218                                   id->ff_dec_c->extradata_size );
1219             free( p_vol );
1220         }
1221     }
1222
1223
1224     /* find encoder */
1225     id->ff_enc = NULL;
1226     i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
1227     if( i_ff_codec != 0 )
1228     {
1229         id->ff_enc = avcodec_find_encoder( i_ff_codec );
1230     }
1231
1232     /* Hack for external encoders */
1233     if( !id->ff_enc )
1234     {
1235         id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
1236         id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
1237         id->p_encoder->format.video.i_width = p_sys->i_width;
1238         id->p_encoder->format.video.i_height = p_sys->i_height;
1239         id->p_encoder->i_bitrate = p_sys->i_vbitrate;
1240
1241             if( id->p_encoder->format.video.i_width <= 0 )
1242             {
1243                 id->p_encoder->format.video.i_width = id->f_dst.i_width =
1244                     id->ff_dec_c->width - p_sys->i_crop_left -
1245                     p_sys->i_crop_right;
1246             }
1247             if( id->p_encoder->format.video.i_height <= 0 )
1248             {
1249                 id->p_encoder->format.video.i_height = id->f_dst.i_height =
1250                     id->ff_dec_c->height - p_sys->i_crop_top -
1251                     p_sys->i_crop_bottom;
1252             }
1253
1254         id->p_encoder->p_module =
1255             module_Need( id->p_encoder, "video encoder", NULL );
1256
1257         if( !id->p_encoder->p_module )
1258         {
1259             free( id->p_encoder );
1260             id->p_encoder = NULL;
1261         }
1262     }
1263     /* End hack for external encoders */
1264
1265     if( !id->ff_enc && !id->p_encoder )
1266     {
1267         msg_Err( p_stream, "cannot find encoder" );
1268         return VLC_EGENERIC;
1269     }
1270
1271     /* XXX open it only when we have the first frame */
1272     id->b_enc_inited     = VLC_FALSE;
1273     id->i_buffer_in      = 0;
1274     id->i_buffer_in_pos  = 0;
1275     id->p_buffer_in      = NULL;
1276
1277     id->i_buffer     = 3*1024*1024;
1278     id->i_buffer_pos = 0;
1279     id->p_buffer     = malloc( id->i_buffer );
1280
1281     id->i_buffer_out     = 0;
1282     id->i_buffer_out_pos = 0;
1283     id->p_buffer_out     = NULL;
1284
1285     id->p_ff_pic         = avcodec_alloc_frame();
1286     id->p_ff_pic_tmp0    = NULL;
1287     id->p_ff_pic_tmp1    = NULL;
1288     id->p_ff_pic_tmp2    = NULL;
1289     id->p_vresample      = NULL;
1290
1291     p_sys->i_last_ref_pts = 0;
1292     p_sys->i_buggy_pts_detect = 0;
1293
1294     /* This is enough for external encoders */
1295     if( id->p_encoder->p_module ) return VLC_SUCCESS;
1296
1297     if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' )||
1298         id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
1299     {
1300         id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','v' );
1301     }
1302
1303     id->ff_enc_c = avcodec_alloc_context();
1304     id->ff_enc_c->width          = id->f_dst.i_width;
1305     id->ff_enc_c->height         = id->f_dst.i_height;
1306     id->ff_enc_c->bit_rate       = id->f_dst.i_bitrate;
1307
1308     if( id->ff_dec )
1309     {
1310         id->ff_enc_c->frame_rate     = id->ff_dec_c->frame_rate;
1311 #if LIBAVCODEC_BUILD >= 4662
1312         id->ff_enc_c->frame_rate_base= id->ff_dec_c->frame_rate_base;
1313 #endif
1314     }
1315     else
1316     {
1317 #if LIBAVCODEC_BUILD >= 4662
1318         id->ff_enc_c->frame_rate     = 25 ; /* FIXME as it break mpeg */
1319         id->ff_enc_c->frame_rate_base= 1;
1320 #else
1321         id->ff_enc_c->frame_rate     = 25 * FRAME_RATE_BASE;
1322 #endif
1323     }
1324
1325     id->ff_enc_c->gop_size       = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
1326     id->ff_enc_c->max_b_frames   = __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES );
1327     id->ff_enc_c->b_frame_strategy = 0;
1328     id->ff_enc_c->b_quant_factor = 2.0;
1329
1330     if( p_sys->i_vtolerance >= 0 )
1331     {
1332         id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
1333     }
1334     id->ff_enc_c->qmin           = p_sys->i_qmin;
1335     id->ff_enc_c->qmax           = p_sys->i_qmax;
1336
1337 #if LIBAVCODEC_BUILD >= 4673
1338     id->ff_enc_c->mb_decision = p_sys->i_hq;
1339 #else
1340     if( p_sys->i_hq )
1341     {
1342         id->ff_enc_c->flags      |= CODEC_FLAG_HQ;
1343     }
1344 #endif
1345
1346     if( i_ff_codec == CODEC_ID_RAWVIDEO )
1347     {
1348         id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
1349     }
1350
1351     return VLC_SUCCESS;
1352 }
1353
1354 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
1355 {
1356     if( id->ff_dec )
1357     {
1358         avcodec_close( id->ff_dec_c );
1359     }
1360     if( id->p_encoder )
1361     {
1362         /* External encoding */
1363         module_Unneed( p_stream, id->p_encoder->p_module );
1364         vlc_object_destroy( id->p_encoder->p_module );
1365     }
1366     else if( id->b_enc_inited )
1367     {
1368         avcodec_close( id->ff_enc_c );
1369     }
1370
1371     if( id->p_ff_pic)
1372     {
1373         free( id->p_ff_pic );
1374     }
1375
1376     if( id->p_ff_pic_tmp0 )
1377     {
1378         free( id->p_ff_pic_tmp0->data[0] );
1379         free( id->p_ff_pic_tmp0 );
1380     }
1381     if( id->p_ff_pic_tmp1)
1382     {
1383         free( id->p_ff_pic_tmp1->data[0] );
1384         free( id->p_ff_pic_tmp1 );
1385     }
1386     if( id->p_ff_pic_tmp2)
1387     {
1388         free( id->p_ff_pic_tmp2->data[0] );
1389         free( id->p_ff_pic_tmp2 );
1390     }
1391     if( id->p_vresample )
1392     {
1393         free( id->p_vresample );
1394     }
1395
1396     free( id->ff_dec_c );
1397     free( id->ff_enc_c );
1398     free( id->p_buffer );
1399 }
1400
1401 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1402                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1403 {
1404     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1405     int     i_used;
1406     int     i_out;
1407     int     b_gotpicture;
1408     AVFrame *frame;
1409
1410     int     i_data;
1411     uint8_t *p_data;
1412
1413     *out = NULL;
1414
1415     i_data = in->i_size;
1416     p_data = in->p_buffer;
1417
1418     for( ;; )
1419     {
1420         /* decode frame */
1421         frame = id->p_ff_pic;
1422         p_sys->i_input_pts = in->i_pts;
1423         if( id->ff_dec )
1424         {
1425             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1426                                            &b_gotpicture,
1427                                            p_data, i_data );
1428         }
1429         else
1430         {
1431             /* raw video */
1432             avpicture_fill( (AVPicture*)frame,
1433                             p_data,
1434                             id->ff_dec_c->pix_fmt,
1435                             id->ff_dec_c->width, id->ff_dec_c->height );
1436             i_used = i_data;
1437             b_gotpicture = 1;
1438
1439             /* Set PTS */
1440             frame->pts = p_sys->i_input_pts;
1441         }
1442
1443         if( i_used < 0 )
1444         {
1445             msg_Warn( p_stream, "error");
1446             return VLC_EGENERIC;
1447         }
1448         i_data -= i_used;
1449         p_data += i_used;
1450
1451         if( !b_gotpicture )
1452         {
1453             return VLC_SUCCESS;
1454         }
1455
1456         /* Get the pts of the decoded frame if any, otherwise keep the
1457          * interpolated one */
1458         if( frame->pts > 0 )
1459         {
1460             p_sys->i_output_pts = frame->pts;
1461         }
1462
1463         if( !id->b_enc_inited && id->p_encoder )
1464         {
1465             block_t *p_block;
1466
1467             /* XXX hack because of copy packetizer and mpeg4video that can fail
1468              * detecting size */
1469 #if 0
1470             if( id->p_encoder->i_width <= 0 )
1471             {
1472                 id->p_encoder->i_width = id->f_dst.i_width =
1473                     id->ff_dec_c->width - p_sys->i_crop_left -
1474                     p_sys->i_crop_right;
1475             }
1476             if( id->p_encoder->i_height <= 0 )
1477             {
1478                 id->p_encoder->i_height = id->f_dst.i_height =
1479                     id->ff_dec_c->height - p_sys->i_crop_top -
1480                     p_sys->i_crop_bottom;
1481             }
1482 #endif
1483
1484             id->p_encoder->i_bitrate = p_sys->i_vbitrate;
1485
1486             if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1487             {
1488                 msg_Err( p_stream, "cannot add this stream" );
1489                 id->b_transcode = VLC_FALSE;
1490                 return VLC_EGENERIC;
1491             }
1492
1493             while( (p_block = id->p_encoder->pf_header( id->p_encoder )) )
1494             {
1495                 sout_buffer_t *p_out;
1496                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1497                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1498                 sout_BufferChain( out, p_out );
1499             }
1500
1501             id->b_enc_inited = VLC_TRUE;
1502         }
1503         else if( !id->b_enc_inited )
1504         {
1505             /* XXX hack because of copy packetizer and mpeg4video that can fail
1506              * detecting size */
1507             if( id->ff_enc_c->width <= 0 )
1508             {
1509                 id->ff_enc_c->width    =
1510                     id->f_dst.i_width  = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1511             }
1512             if( id->ff_enc_c->height <= 0 )
1513             {
1514                 id->ff_enc_c->height   =
1515                     id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1516             }
1517
1518             /* Make sure we get extradata filled by the encoder */
1519             id->ff_enc_c->extradata_size = 0;
1520             id->ff_enc_c->extradata = NULL;
1521             id->ff_enc_c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1522
1523             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
1524             {
1525                 msg_Err( p_stream, "cannot open encoder" );
1526                 return VLC_EGENERIC;
1527             }
1528
1529             id->f_dst.i_extra_data = id->ff_enc_c->extradata_size;
1530             id->f_dst.p_extra_data = id->ff_enc_c->extradata;
1531             id->ff_enc_c->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
1532
1533             if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1534             {
1535                 msg_Err( p_stream, "cannot add this stream" );
1536                 transcode_video_ffmpeg_close( p_stream, id );
1537                 id->b_transcode = VLC_FALSE;
1538                 return VLC_EGENERIC;
1539             }
1540             id->b_enc_inited = VLC_TRUE;
1541         }
1542
1543
1544         /* deinterlace */
1545         if( p_stream->p_sys->b_deinterlace )
1546         {
1547             if( id->p_ff_pic_tmp0 == NULL )
1548             {
1549                 int     i_size;
1550                 uint8_t *buf;
1551                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1552                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1553                                              id->ff_dec_c->width, id->ff_dec_c->height );
1554
1555                 buf = malloc( i_size );
1556
1557                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1558                                 id->ff_enc_c->pix_fmt,
1559                                 id->ff_dec_c->width, id->ff_dec_c->height );
1560             }
1561
1562             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1563                                    id->ff_dec_c->pix_fmt,
1564                                    id->ff_dec_c->width, id->ff_dec_c->height );
1565
1566             frame = id->p_ff_pic_tmp0;
1567         }
1568
1569         /* convert pix format */
1570         if( !id->p_encoder )
1571         if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
1572         {
1573             if( id->p_ff_pic_tmp1 == NULL )
1574             {
1575                 int     i_size;
1576                 uint8_t *buf;
1577                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1578                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1579                                              id->ff_dec_c->width, id->ff_dec_c->height );
1580
1581                 buf = malloc( i_size );
1582
1583                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1584                                 id->ff_enc_c->pix_fmt,
1585                                 id->ff_dec_c->width, id->ff_dec_c->height );
1586             }
1587
1588             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->ff_enc_c->pix_fmt,
1589                          (AVPicture*)frame,             id->ff_dec_c->pix_fmt,
1590                          id->ff_dec_c->width, id->ff_dec_c->height );
1591
1592             frame = id->p_ff_pic_tmp1;
1593         }
1594
1595         /* convert size and crop */
1596         if( !id->p_encoder )
1597         if( id->ff_dec_c->width  != id->ff_enc_c->width ||
1598             id->ff_dec_c->height != id->ff_enc_c->height ||
1599             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1600             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1601         {
1602             if( id->p_ff_pic_tmp2 == NULL )
1603             {
1604                 int     i_size;
1605                 uint8_t *buf;
1606                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1607                 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1608                                              id->ff_enc_c->width, id->ff_enc_c->height );
1609
1610                 buf = malloc( i_size );
1611
1612                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1613                                 id->ff_enc_c->pix_fmt,
1614                                 id->ff_enc_c->width, id->ff_enc_c->height );
1615
1616                 id->p_vresample =
1617                     img_resample_full_init( id->ff_enc_c->width, id->ff_enc_c->height,
1618                                             id->ff_dec_c->width, id->ff_dec_c->height,
1619                                             p_stream->p_sys->i_crop_top,
1620                                             p_stream->p_sys->i_crop_bottom,
1621                                             p_stream->p_sys->i_crop_left,
1622                                             p_stream->p_sys->i_crop_right );
1623             }
1624
1625             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1626                           (AVPicture*)frame );
1627
1628             frame = id->p_ff_pic_tmp2;
1629         }
1630
1631         /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
1632         if( id->f_dst.i_fourcc == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
1633             frame->pts = p_sys->i_output_pts;
1634         else
1635             frame->pts = 0;
1636
1637         /* Interpolate the next PTS
1638          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1639         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1640         {
1641             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1642               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1643         }
1644
1645         if( id->p_encoder )
1646         {
1647             /* External encoding */
1648             block_t *p_block;
1649             picture_t pic;
1650             int i_plane;
1651
1652             vout_InitPicture( VLC_OBJECT(p_stream), &pic,
1653                               id->ff_dec_c->width, id->ff_dec_c->height,
1654                               VLC_FOURCC('I','4','2','0') );
1655
1656             for( i_plane = 0; i_plane < pic.i_planes; i_plane++ )
1657             {
1658                 pic.p[i_plane].p_pixels = frame->data[i_plane];
1659                 pic.p[i_plane].i_pitch = frame->linesize[i_plane];
1660             }
1661
1662             pic.date = frame->pts;
1663
1664             p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic );
1665             if( p_block )
1666             {
1667                 sout_buffer_t *p_out;
1668                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1669                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1670                 sout_BufferChain( out, p_out );
1671             }
1672
1673             return VLC_SUCCESS;
1674         }
1675
1676         /* Let ffmpeg select the frame type */
1677         frame->pict_type = 0;
1678
1679         i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer,
1680                                       id->i_buffer, frame );
1681         if( i_out > 0 )
1682         {
1683             sout_buffer_t *p_out;
1684             p_out = sout_BufferNew( p_stream->p_sout, i_out );
1685
1686             memcpy( p_out->p_buffer, id->p_buffer, i_out );
1687
1688             p_out->i_size   = i_out;
1689
1690             if( id->ff_enc_c->coded_frame->pts != 0 &&
1691                 p_sys->i_buggy_pts_detect != id->ff_enc_c->coded_frame->pts )
1692             {
1693                 p_sys->i_buggy_pts_detect = id->ff_enc_c->coded_frame->pts;
1694
1695                 /* FIXME, 3-2 pulldown is not handled correctly */
1696                 p_out->i_length = in->i_length;
1697                 p_out->i_pts    = id->ff_enc_c->coded_frame->pts;
1698
1699                 if( !id->ff_enc_c->delay ||
1700                     ( id->ff_enc_c->coded_frame->pict_type != FF_I_TYPE &&
1701                       id->ff_enc_c->coded_frame->pict_type != FF_P_TYPE ) )
1702                 {
1703                     p_out->i_dts    = p_out->i_pts;
1704                 }
1705                 else
1706                 {
1707                     if( p_sys->i_last_ref_pts )
1708                     {
1709                         p_out->i_dts = p_sys->i_last_ref_pts;
1710                     }
1711                     else
1712                     {
1713                         /* Let's put something sensible */
1714                         p_out->i_dts = p_out->i_pts;
1715                     }
1716
1717                     p_sys->i_last_ref_pts = p_out->i_pts;
1718                 }
1719             }
1720             else
1721             {
1722                 /* Buggy libavcodec which doesn't update coded_frame->pts
1723                  * correctly */
1724                 p_out->i_length = in->i_length;
1725                 p_out->i_dts    = in->i_dts;
1726                 p_out->i_pts    = in->i_dts;
1727             }
1728
1729             sout_BufferChain( out, p_out );
1730         }
1731
1732         if( i_data <= 0 )
1733         {
1734             return VLC_SUCCESS;
1735         }
1736     }
1737
1738     return VLC_SUCCESS;
1739 }
1740
1741 /*****************************************************************************
1742  * transcode_video_ffmpeg_getframebuf:
1743  *
1744  * Callback used by ffmpeg to get a frame buffer.
1745  * We use it to get the right PTS for each decoded picture.
1746  *****************************************************************************/
1747 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1748                                               AVFrame *p_frame)
1749 {
1750     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1751
1752     /* Set PTS */
1753     p_frame->pts = p_sys->i_input_pts;
1754
1755     return avcodec_default_get_buffer( p_context, p_frame );
1756 }