]> git.sesse.net Git - vlc/blob - modules/stream_out/transcode.c
321e5d6b73f7d9b9031c3ef46de1d895319a0a0c
[vlc] / modules / stream_out / transcode.c
1 /*****************************************************************************
2  * transcode.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: transcode.c,v 1.59 2003/12/06 22:53:07 jpsaman Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/input.h>
33 #include <vlc/sout.h>
34 #include <vlc/vout.h>
35 #include <vlc/decoder.h>
36
37 /* ffmpeg header */
38 #ifdef HAVE_FFMPEG_AVCODEC_H
39 #   include <ffmpeg/avcodec.h>
40 #else
41 #   include <avcodec.h>
42 #endif
43
44 /*****************************************************************************
45  * Exported prototypes
46  *****************************************************************************/
47 static int      Open    ( vlc_object_t * );
48 static void     Close   ( vlc_object_t * );
49
50 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
51 static int               Del ( sout_stream_t *, sout_stream_id_t * );
52 static int               Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
53
54 static int  transcode_audio_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
55 static void transcode_audio_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
56 static int  transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
57
58 static int  transcode_video_ffmpeg_new    ( sout_stream_t *, sout_stream_id_t * );
59 static void transcode_video_ffmpeg_close  ( sout_stream_t *, sout_stream_id_t * );
60 static int  transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
61
62 static int  transcode_video_ffmpeg_getframebuf( struct AVCodecContext *, AVFrame *);
63
64 static int pi_channels_maps[6] =
65 {
66     0,
67     AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
68     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
69     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
70      | AOUT_CHAN_REARRIGHT,
71     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
72      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
73 };
74
75 /*****************************************************************************
76  * Module descriptor
77  *****************************************************************************/
78 vlc_module_begin();
79     set_description( _("Transcode stream") );
80     set_capability( "sout stream", 50 );
81     add_shortcut( "transcode" );
82     set_callbacks( Open, Close );
83 vlc_module_end();
84
85 struct sout_stream_sys_t
86 {
87     sout_stream_t   *p_out;
88
89     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
90     int             i_sample_rate;
91     int             i_channels;
92     int             i_abitrate;
93
94     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
95     int             i_vbitrate;
96     int             i_vtolerance;
97     int             i_width;
98     int             i_height;
99     int             i_b_frames;
100     int             i_key_int;
101     int             i_qmin;
102     int             i_qmax;
103     vlc_bool_t      i_hq;
104     vlc_bool_t      b_deinterlace;
105     vlc_bool_t      b_strict_rc;
106     vlc_bool_t      b_pre_me;
107     vlc_bool_t      b_hurry_up;
108
109     int             i_crop_top;
110     int             i_crop_bottom;
111     int             i_crop_right;
112     int             i_crop_left;
113
114     mtime_t         i_input_pts;
115     mtime_t         i_output_pts;
116 };
117
118 /*****************************************************************************
119  * Open:
120  *****************************************************************************/
121 static int Open( vlc_object_t *p_this )
122 {
123     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
124     sout_stream_sys_t *p_sys;
125     char *codec;
126
127     p_sys = malloc( sizeof( sout_stream_sys_t ) );
128     memset( p_sys, 0, sizeof(struct sout_stream_sys_t) );
129     p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
130
131     p_sys->i_vtolerance = -1;
132     p_sys->i_key_int    = -1;
133     p_sys->i_qmin       = 2;
134     p_sys->i_qmax       = 31;
135 #if LIBAVCODEC_BUILD >= 4673
136     p_sys->i_hq         = FF_MB_DECISION_SIMPLE;
137 #else
138     p_sys->i_hq         = VLC_FALSE;
139 #endif
140
141     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "acodec" ) ) )
142     {
143         char fcc[4] = "    ";
144         char *val;
145
146         memcpy( fcc, codec, __MIN( strlen( codec ), 4 ) );
147
148         p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
149
150         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "samplerate" ) ) )
151         {
152             p_sys->i_sample_rate = atoi( val );
153         }
154         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "channels" ) ) )
155         {
156             p_sys->i_channels = atoi( val );
157         }
158         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
159         {
160             p_sys->i_abitrate = atoi( val );
161             if( p_sys->i_abitrate < 4000 )
162             {
163                 p_sys->i_abitrate *= 1000;
164             }
165         }
166
167         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", fcc,
168                  p_sys->i_sample_rate, p_sys->i_channels,
169                  p_sys->i_abitrate / 1024 );
170     }
171
172     if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
173     {
174         char fcc[4] = "    ";
175         char *val;
176
177         memcpy( fcc, codec, __MIN( strlen( codec ), 4 ) );
178
179         p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
180
181         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
182         {
183             p_sys->i_width = atoi( val );
184         }
185         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
186         {
187             p_sys->i_height = atoi( val );
188         }
189         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
190         {
191             p_sys->i_vbitrate = atoi( val );
192             if( p_sys->i_vbitrate < 16000 )
193             {
194                 p_sys->i_vbitrate *= 1000;
195             }
196         }
197         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
198         {
199             p_sys->i_vtolerance = atoi( val );
200         }
201         if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
202         {
203             p_sys->b_deinterlace = VLC_TRUE;
204         }
205         if( sout_cfg_find( p_stream->p_cfg, "strict_rc" ) )
206         {
207             p_sys->b_strict_rc = VLC_TRUE;
208         }
209         if( sout_cfg_find( p_stream->p_cfg, "pre_me" ) )
210         {
211             p_sys->b_pre_me = VLC_TRUE;
212         }
213         if( sout_cfg_find( p_stream->p_cfg, "hurry_up" ) )
214         {
215             p_sys->b_hurry_up = VLC_TRUE;
216         }
217         /* crop */
218         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
219         {
220             p_sys->i_crop_top = atoi( val );
221         }
222         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
223         {
224             p_sys->i_crop_bottom = atoi( val );
225         }
226         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
227         {
228             p_sys->i_crop_left = atoi( val );
229         }
230         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
231         {
232             p_sys->i_crop_right = atoi( val );
233         }
234         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
235         {
236             p_sys->i_key_int    = atoi( val );
237         }
238         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "bframes" ) ) )
239         {
240             p_sys->i_b_frames   = atoi( val );
241         }
242 #if LIBAVCODEC_BUILD >= 4673
243         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "hq" ) ) )
244         {
245             if( !strcmp( val, "rd" ) )
246             {
247                 p_sys->i_hq = FF_MB_DECISION_RD;
248             }
249             else if( !strcmp( val, "bits" ) )
250             {
251                 p_sys->i_hq = FF_MB_DECISION_BITS;
252             }
253             else if( !strcmp( val, "simple" ) )
254             {
255                 p_sys->i_hq = FF_MB_DECISION_SIMPLE;
256             }
257             else
258             {
259                 p_sys->i_hq = FF_MB_DECISION_RD;
260             }
261         }
262 #else
263         if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
264         {
265             p_sys->i_hq = VLC_TRUE;
266         }
267 #endif
268         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
269         {
270             p_sys->i_qmin   = atoi( val );
271         }
272         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
273         {
274             p_sys->i_qmax   = atoi( val );
275         }
276
277         msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
278                  fcc,
279                  p_sys->i_width, p_sys->i_height,
280                  p_sys->i_vbitrate / 1024 );
281     }
282
283     if( !p_sys->p_out )
284     {
285         msg_Err( p_stream, "cannot create chain" );
286         free( p_sys );
287         return VLC_EGENERIC;
288     }
289     p_stream->pf_add    = Add;
290     p_stream->pf_del    = Del;
291     p_stream->pf_send   = Send;
292
293     p_stream->p_sys     = p_sys;
294
295     avcodec_init();
296     avcodec_register_all();
297
298     /* ffmpeg needs some padding at the end of each buffer */
299     p_stream->p_sout->i_padding += FF_INPUT_BUFFER_PADDING_SIZE;
300
301     return VLC_SUCCESS;
302 }
303
304 /*****************************************************************************
305  * Close:
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     es_format_t f_src;        /* only if transcoding */
320     es_format_t f_dst;        /*  "   "      " */
321     unsigned int  i_inter_pixfmt; /* intermediary format when transcoding */
322
323     /* id of the out stream */
324     void *id;
325
326     /* Encoder */
327     encoder_t       *p_encoder;
328     vlc_fourcc_t    b_enc_inited;
329
330     /* ffmpeg part */
331     AVCodec         *ff_dec;
332     AVCodecContext  *ff_dec_c;
333
334     mtime_t         i_dts;
335     mtime_t         i_length;
336
337     int             i_buffer;
338     int             i_buffer_pos;
339     uint8_t         *p_buffer;
340
341     AVFrame         *p_ff_pic;
342     AVFrame         *p_ff_pic_tmp0; /* to do deinterlace */
343     AVFrame         *p_ff_pic_tmp1; /* to do pix conversion */
344     AVFrame         *p_ff_pic_tmp2; /* to do resample */
345
346     ImgReSampleContext *p_vresample;
347 };
348
349
350 static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
351 {
352     sout_stream_sys_t   *p_sys = p_stream->p_sys;
353     sout_stream_id_t    *id;
354
355     id = malloc( sizeof( sout_stream_id_t ) );
356     id->i_dts = 0;
357     id->id = NULL;
358     id->p_encoder = NULL;
359
360     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
361     {
362         msg_Dbg( p_stream,
363                  "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
364                  (char*)&p_fmt->i_codec,
365                  (char*)&p_sys->i_acodec );
366
367         /* src format */
368         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
369
370         /* create dst format */
371         id->f_dst.i_cat    = AUDIO_ES;
372         id->f_dst.i_codec = p_sys->i_acodec;
373         id->f_dst.audio.i_rate = p_sys->i_sample_rate  > 0 ? p_sys->i_sample_rate : id->f_src.audio.i_rate;
374         id->f_dst.audio.i_channels    = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.audio.i_channels;
375         id->f_dst.i_bitrate     = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
376         id->f_dst.audio.i_blockalign = 0;
377         id->f_dst.i_extra  = 0;
378         id->f_dst.p_extra  = NULL;
379
380         /* build decoder -> filter -> encoder */
381         if( transcode_audio_ffmpeg_new( p_stream, id ) )
382         {
383             msg_Err( p_stream, "cannot create audio chain" );
384             free( id );
385             return NULL;
386         }
387
388         /* open output stream */
389         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
390         id->b_transcode = VLC_TRUE;
391
392         if( id->id == NULL )
393         {
394             free( id );
395             return NULL;
396         }
397     }
398     else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
399     {
400         msg_Dbg( p_stream,
401                  "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
402                  (char*)&p_fmt->i_codec,
403                  (char*)&p_sys->i_vcodec );
404
405         memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
406
407         /* create dst format */
408         id->f_dst.i_cat         = VIDEO_ES;
409         id->f_dst.i_codec       = p_sys->i_vcodec;
410         id->f_dst.video.i_width = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
411         id->f_dst.video.i_height= p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
412         id->f_dst.i_bitrate     = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
413         id->f_dst.i_extra       = 0;
414         id->f_dst.p_extra       = NULL;
415
416         /* build decoder -> filter -> encoder */
417         if( transcode_video_ffmpeg_new( p_stream, id ) )
418         {
419             msg_Err( p_stream, "cannot create video chain" );
420             free( id );
421             return NULL;
422         }
423 #if 0
424         /* open output stream */
425         id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
426 #endif
427         id->b_transcode = VLC_TRUE;
428     }
429     else
430     {
431         msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_codec );
432         id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
433         id->b_transcode = VLC_FALSE;
434
435         if( id->id == NULL )
436         {
437             free( id );
438             return NULL;
439         }
440     }
441
442     return id;
443 }
444
445 static int     Del      ( sout_stream_t *p_stream, sout_stream_id_t *id )
446 {
447     sout_stream_sys_t   *p_sys = p_stream->p_sys;
448
449     if( id->b_transcode )
450     {
451         if( id->f_src.i_cat == AUDIO_ES )
452         {
453             transcode_audio_ffmpeg_close( p_stream, id );
454         }
455         else if( id->f_src.i_cat == VIDEO_ES )
456         {
457             transcode_video_ffmpeg_close( p_stream, id );
458         }
459     }
460
461     if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
462     free( id );
463
464     return VLC_SUCCESS;
465 }
466
467 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
468                  sout_buffer_t *p_buffer )
469 {
470     sout_stream_sys_t   *p_sys = p_stream->p_sys;
471
472     if( id->b_transcode )
473     {
474         sout_buffer_t *p_buffer_out;
475         if( id->f_src.i_cat == AUDIO_ES )
476         {
477             transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
478         }
479         else if( id->f_src.i_cat == VIDEO_ES )
480         {
481             transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
482         }
483         sout_BufferDelete( p_stream->p_sout, p_buffer );
484
485         if( p_buffer_out )
486         {
487             return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
488         }
489         return VLC_SUCCESS;
490     }
491     else if( id->id != NULL )
492     {
493         return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
494     }
495     else
496     {
497         sout_BufferDelete( p_stream->p_sout, p_buffer );
498         return VLC_EGENERIC;
499     }
500 }
501
502 /****************************************************************************
503  * ffmpeg decoder reencocdr part
504  ****************************************************************************/
505
506 static struct
507 {
508     vlc_fourcc_t i_fcc;
509     int          i_ff_codec;
510 } fourcc_to_ff_code[] =
511 {
512     /* audio */
513     { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
514     { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
515     { VLC_FOURCC( 'm', 'p', '4', 'a' ), CODEC_ID_AAC },
516     { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
517     { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
518     { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
519     { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
520     { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
521     { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
522
523     /* video */
524     { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
525     { VLC_FOURCC( 'm', 'p', '1', 'v' ), CODEC_ID_MPEG1VIDEO },
526 #if LIBAVCODEC_BUILD >= 4676
527     { VLC_FOURCC( 'm', 'p', '2', 'v' ), CODEC_ID_MPEG2VIDEO },
528 #endif
529     { VLC_FOURCC( 'm', 'p', '4', 'v'),  CODEC_ID_MPEG4 },
530     { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
531     { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
532     { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
533     { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
534     { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
535     { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
536     { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
537     { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
538     { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
539     { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
540     { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
541     { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
542 #if LIBAVCODEC_BUILD >= 4666
543     { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
544 #endif
545
546     /* raw video code, only used for 'encoding' */
547     { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
548     { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
549     { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
550     { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
551     { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
552     { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
553     { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
554     { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
555
556     { VLC_FOURCC(   0,   0,   0,   0 ), 0 }
557 };
558
559 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
560 {
561     int i;
562
563     for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
564     {
565         if( fourcc_to_ff_code[i].i_fcc == i_fcc )
566         {
567             return fourcc_to_ff_code[i].i_ff_codec;
568         }
569     }
570
571     return 0;
572 }
573
574 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
575 {
576     switch( i_chroma )
577     {
578         case VLC_FOURCC( 'I', '4', '2', '0' ):
579             return PIX_FMT_YUV420P;
580         case VLC_FOURCC( 'I', '4', '2', '2' ):
581             return PIX_FMT_YUV422P;
582         case VLC_FOURCC( 'I', '4', '4', '4' ):
583             return PIX_FMT_YUV444P;
584         case VLC_FOURCC( 'R', 'V', '1', '5' ):
585             return PIX_FMT_RGB555;
586         case VLC_FOURCC( 'R', 'V', '1', '6' ):
587             return PIX_FMT_RGB565;
588         case VLC_FOURCC( 'R', 'V', '2', '4' ):
589             return PIX_FMT_RGB24;
590         case VLC_FOURCC( 'R', 'V', '3', '2' ):
591             return PIX_FMT_RGBA32;
592         case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
593             return PIX_FMT_GRAY8;
594         case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
595             return PIX_FMT_YUV422;
596         default:
597             return 0;
598     }
599 }
600
601 static inline vlc_fourcc_t get_vlc_chroma( int i_pix_fmt )
602 {
603     switch( i_pix_fmt )
604     {
605     case PIX_FMT_YUV420P:
606         return VLC_FOURCC('I','4','2','0');
607     case PIX_FMT_YUV422P:
608         return VLC_FOURCC('I','4','2','2');
609     case PIX_FMT_YUV444P:
610         return VLC_FOURCC('I','4','4','4');
611
612     case PIX_FMT_YUV422:
613         return VLC_FOURCC('Y','U','Y','2');
614
615     case PIX_FMT_RGB555:
616         return VLC_FOURCC('R','V','1','5');
617     case PIX_FMT_RGB565:
618         return VLC_FOURCC('R','V','1','6');
619     case PIX_FMT_RGB24:
620         return VLC_FOURCC('R','V','2','4');
621     case PIX_FMT_RGBA32:
622         return VLC_FOURCC('R','V','3','2');
623     case PIX_FMT_GRAY8:
624         return VLC_FOURCC('G','R','E','Y');
625
626     case PIX_FMT_YUV410P:
627     case PIX_FMT_YUV411P:
628     case PIX_FMT_BGR24:
629     default:
630         return 0;
631     }
632 }
633
634 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
635                                        sout_stream_id_t *id )
636 {
637     int i_ff_codec;
638
639     if( id->f_src.i_codec == VLC_FOURCC('s','1','6','l') ||
640         id->f_src.i_codec == VLC_FOURCC('s','1','6','b') ||
641         id->f_src.i_codec == VLC_FOURCC('s','8',' ',' ') ||
642         id->f_src.i_codec == VLC_FOURCC('u','8',' ',' ') )
643     {
644         id->ff_dec = NULL;
645
646         id->ff_dec_c = avcodec_alloc_context();
647         id->ff_dec_c->sample_rate = id->f_src.audio.i_rate;
648         id->ff_dec_c->channels    = id->f_src.audio.i_channels;
649         id->ff_dec_c->block_align = id->f_src.audio.i_blockalign;
650         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
651     }
652     else
653     {
654         /* find decoder */
655         i_ff_codec = get_ff_codec( id->f_src.i_codec );
656         if( i_ff_codec == 0 )
657         {
658             msg_Err( p_stream, "cannot find decoder id" );
659             return VLC_EGENERIC;
660         }
661
662         id->ff_dec = avcodec_find_decoder( i_ff_codec );
663         if( !id->ff_dec )
664         {
665             msg_Err( p_stream, "cannot find decoder (avcodec)" );
666             return VLC_EGENERIC;
667         }
668
669         id->ff_dec_c = avcodec_alloc_context();
670         id->ff_dec_c->sample_rate = id->f_src.audio.i_rate;
671         id->ff_dec_c->channels    = id->f_src.audio.i_channels;
672         id->ff_dec_c->block_align = id->f_src.audio.i_blockalign;
673         id->ff_dec_c->bit_rate    = id->f_src.i_bitrate;
674
675         id->ff_dec_c->extradata_size = id->f_src.i_extra;
676         id->ff_dec_c->extradata      = id->f_src.p_extra;
677         if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
678         {
679             msg_Err( p_stream, "cannot open decoder" );
680             return VLC_EGENERIC;
681         }
682     }
683
684     id->i_buffer     = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
685     id->i_buffer_pos = 0;
686     id->p_buffer     = malloc( id->i_buffer );
687
688     /* Sanity check for audio channels */
689     id->f_dst.audio.i_channels = __MIN( id->f_dst.audio.i_channels, id->f_src.audio.i_channels );
690
691     /* find encoder */
692     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
693
694     /* Initialization of encoder format structures */
695     es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, AOUT_FMT_S16_NE );
696     id->p_encoder->fmt_in.audio.i_format = AOUT_FMT_S16_NE;
697     id->p_encoder->fmt_in.audio.i_rate = id->f_dst.audio.i_rate;
698     id->p_encoder->fmt_in.audio.i_physical_channels =
699         id->p_encoder->fmt_in.audio.i_original_channels =
700             pi_channels_maps[id->f_dst.audio.i_channels];
701     id->p_encoder->fmt_in.audio.i_channels = id->f_dst.audio.i_channels;
702
703     id->p_encoder->fmt_out = id->p_encoder->fmt_in;
704     id->p_encoder->fmt_out.i_codec = id->f_dst.i_codec;
705     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
706
707     id->p_encoder->p_module =
708         module_Need( id->p_encoder, "encoder", NULL );
709     if( !id->p_encoder->p_module )
710     {
711         vlc_object_destroy( id->p_encoder );
712         msg_Err( p_stream, "cannot open encoder" );
713         return VLC_EGENERIC;
714     }
715
716     id->b_enc_inited = VLC_FALSE;
717
718     id->f_dst.i_extra = id->p_encoder->fmt_out.i_extra;
719     id->f_dst.p_extra = id->p_encoder->fmt_out.p_extra;
720
721     /* Hack for mp3 transcoding support */
722     if( id->f_dst.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
723     {
724         id->f_dst.i_codec = VLC_FOURCC( 'm','p','g','a' );
725     }
726
727     return VLC_SUCCESS;
728 }
729
730 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
731                                           sout_stream_id_t *id )
732 {
733     if( id->ff_dec )
734     {
735         avcodec_close( id->ff_dec_c );
736         free( id->ff_dec_c );
737     }
738
739     module_Unneed( id->p_encoder, id->p_encoder->p_module );
740     vlc_object_destroy( id->p_encoder );
741
742     free( id->p_buffer );
743 }
744
745 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
746                                            sout_stream_id_t *id,
747                                            sout_buffer_t *in,
748                                            sout_buffer_t **out )
749 {
750     aout_buffer_t aout_buf;
751     block_t *p_block;
752     int i_buffer = in->i_size;
753     char *p_buffer = in->p_buffer;
754     id->i_dts = in->i_dts;
755     *out = NULL;
756
757     while( i_buffer )
758     {
759         id->i_buffer_pos = 0;
760
761         /* decode as much data as possible */
762         if( id->ff_dec )
763         {
764             int i_used;
765
766             i_used = avcodec_decode_audio( id->ff_dec_c,
767                          (int16_t*)id->p_buffer, &id->i_buffer_pos,
768                          p_buffer, i_buffer );
769
770 #if 0
771             msg_Warn( p_stream, "avcodec_decode_audio: %d used on %d",
772                       i_used, i_buffer );
773 #endif
774             if( i_used < 0 )
775             {
776                 msg_Warn( p_stream, "error audio decoding");
777                 break;
778             }
779
780             i_buffer -= i_used;
781             p_buffer += i_used;
782         }
783         else
784         {
785             int16_t *sout = (int16_t*)id->p_buffer;
786
787             if( id->f_src.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
788                 id->f_src.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
789             {
790                 int8_t *sin = (int8_t*)p_buffer;
791                 int i_used = __MIN( id->i_buffer/2, i_buffer );
792                 int i_samples = i_used;
793
794                 if( id->f_src.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
795                     while( i_samples > 0 )
796                     {
797                         *sout++ = ( *sin++ ) << 8;
798                         i_samples--;
799                     }
800                 else
801                     while( i_samples > 0 )
802                     {
803                         *sout++ = ( *sin++ - 128 ) << 8;
804                         i_samples--;
805                     }
806
807                 i_buffer -= i_used;
808                 p_buffer += i_used;
809                 id->i_buffer_pos = i_used * 2;
810             }
811             else if( id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) ||
812                      id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'b' ) )
813             {
814                 int16_t *sin = (int16_t*)p_buffer;
815                 int i_used = __MIN( id->i_buffer, i_buffer );
816                 int i_samples = i_used / 2;
817                 int b_invert_indianness;
818
819                 if( id->f_src.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
820 #ifdef WORDS_BIGENDIAN
821                     b_invert_indianness = 1;
822 #else
823                     b_invert_indianness = 0;
824 #endif
825                 else
826 #ifdef WORDS_BIGENDIAN
827                     b_invert_indianness = 0;
828 #else
829                     b_invert_indianness = 1;
830 #endif
831
832                 if( b_invert_indianness )
833                 {
834                     while( i_samples > 0 )
835                     {
836                         uint8_t tmp[2];
837
838                         tmp[1] = *sin++;
839                         tmp[0] = *sin++;
840                         *sout++ = *(int16_t*)tmp;
841                         i_samples--;
842                     }
843                 }
844                 else
845                 {
846                     memcpy( sout, sin, i_used );
847                     sout += i_samples;
848                 }
849
850                 i_buffer -= i_used;
851                 p_buffer += i_used;
852                 id->i_buffer_pos = i_used;
853             }
854         }
855
856         if( id->i_buffer_pos == 0 ) continue;
857
858         /* Encode as much data as possible */
859         if( !id->b_enc_inited && id->p_encoder->pf_header )
860         {
861             p_block = id->p_encoder->pf_header( id->p_encoder );
862             while( p_block )
863             {
864                 sout_buffer_t *p_out;
865                 block_t *p_prev_block = p_block;
866
867                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
868                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
869                 p_out->i_dts = p_out->i_pts = in->i_dts;
870                 p_out->i_length = 0;
871                 sout_BufferChain( out, p_out );
872
873                 p_block = p_block->p_next;
874                 block_Release( p_prev_block );
875             }
876
877             id->b_enc_inited = VLC_TRUE;
878         }
879
880         aout_buf.p_buffer = id->p_buffer;
881         aout_buf.i_nb_bytes = id->i_buffer_pos;
882         aout_buf.i_nb_samples = id->i_buffer_pos / 2 / id->f_src.audio.i_channels;
883         aout_buf.start_date = id->i_dts;
884         aout_buf.end_date = id->i_dts;
885
886         id->i_dts += ( I64C(1000000) * id->i_buffer_pos / 2 /
887             id->f_src.audio.i_channels / id->f_src.audio.i_rate );
888
889         if( id->f_src.audio.i_channels !=
890             id->p_encoder->fmt_in.audio.i_channels )
891         {
892             unsigned int i;
893             int j;
894
895             /* This is for liba52 which is what ffmpeg uses to decode ac3 */
896             static const int translation[7][6] =
897             {{ 0, 0, 0, 0, 0, 0 },      /* 0 channels (rarely used) */
898              { 0, 0, 0, 0, 0, 0 },       /* 1 ch */
899              { 0, 1, 0, 0, 0, 0 },       /* 2 */
900              { 1, 2, 0, 0, 0, 0 },       /* 3 */
901              { 1, 3, 2, 0, 0, 0 },       /* 4 */
902              { 1, 3, 4, 2, 0, 0 },       /* 5 */
903              { 1, 3, 4, 5, 2, 0 }};      /* 6 */
904
905             /* dumb downmixing */
906             for( i = 0; i < aout_buf.i_nb_samples; i++ )
907             {
908                 uint16_t *p_buffer = (uint16_t *)aout_buf.p_buffer;
909                 for( j = 0 ; j < id->p_encoder->fmt_in.audio.i_channels; j++ )
910                 {
911                     p_buffer[i*id->p_encoder->fmt_in.audio.i_channels+j] =
912                         p_buffer[i*id->f_src.audio.i_channels+
913                                  translation[id->f_src.audio.i_channels][j]];
914                 }
915             }
916             aout_buf.i_nb_bytes = i*id->p_encoder->fmt_in.audio.i_channels * 2;
917         }
918
919         p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf );
920         while( p_block )
921         {
922             sout_buffer_t *p_out;
923             block_t *p_prev_block = p_block;
924
925             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
926             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
927             p_out->i_dts = p_block->i_dts;
928             p_out->i_pts = p_block->i_pts;
929             p_out->i_length = p_block->i_length;
930             sout_BufferChain( out, p_out );
931
932             p_block = p_block->p_next;
933             block_Release( p_prev_block );
934         }
935     }
936
937     return VLC_SUCCESS;
938 }
939
940
941 /*
942  * video
943  */
944 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
945                                        sout_stream_id_t *id )
946 {
947     sout_stream_sys_t   *p_sys = p_stream->p_sys;
948
949     int i_ff_codec;
950
951     /* Open decoder */
952     if( id->f_src.i_codec == VLC_FOURCC( 'I', '4', '2', '0' ) ||
953         id->f_src.i_codec == VLC_FOURCC( 'I', '4', '2', '2' ) ||
954         id->f_src.i_codec == VLC_FOURCC( 'I', '4', '4', '4' ) ||
955         id->f_src.i_codec == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
956         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
957         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
958         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
959         id->f_src.i_codec == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
960         id->f_src.i_codec == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
961     {
962         id->ff_dec              = NULL;
963         id->ff_dec_c            = avcodec_alloc_context();
964         id->ff_dec_c->width     = id->f_src.video.i_width;
965         id->ff_dec_c->height    = id->f_src.video.i_height;
966         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_codec );
967     }
968     else
969     {
970         /* find decoder */
971         i_ff_codec = get_ff_codec( id->f_src.i_codec );
972         if( i_ff_codec == 0 )
973         {
974             msg_Err( p_stream, "cannot find decoder" );
975             return VLC_EGENERIC;
976         }
977
978         id->ff_dec = avcodec_find_decoder( i_ff_codec );
979         if( !id->ff_dec )
980         {
981             msg_Err( p_stream, "cannot find decoder" );
982             return VLC_EGENERIC;
983         }
984
985         id->ff_dec_c = avcodec_alloc_context();
986         id->ff_dec_c->width         = id->f_src.video.i_width;
987         id->ff_dec_c->height        = id->f_src.video.i_height;
988         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
989         id->ff_dec_c->extradata_size= id->f_src.i_extra;
990         id->ff_dec_c->extradata     = id->f_src.p_extra;
991         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
992         id->ff_dec_c->error_resilience= -1;
993         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
994         id->ff_dec_c->opaque        = p_sys;
995
996         if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
997         {
998             msg_Err( p_stream, "cannot open decoder" );
999             return VLC_EGENERIC;
1000         }
1001
1002         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1003         {
1004             int b_gotpicture;
1005             AVFrame frame;
1006             uint8_t *p_vol = malloc( id->ff_dec_c->extradata_size +
1007                                      FF_INPUT_BUFFER_PADDING_SIZE );
1008
1009             memcpy( p_vol, id->ff_dec_c->extradata,
1010                     id->ff_dec_c->extradata_size );
1011             memset( p_vol + id->ff_dec_c->extradata_size, 0,
1012                     FF_INPUT_BUFFER_PADDING_SIZE );
1013
1014             avcodec_decode_video( id->ff_dec_c, &frame, &b_gotpicture,
1015                                   id->ff_dec_c->extradata,
1016                                   id->ff_dec_c->extradata_size );
1017             free( p_vol );
1018         }
1019     }
1020
1021     /* Open encoder */
1022     id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
1023
1024     /* Initialization of encoder format structures */
1025     es_format_Init( &id->p_encoder->fmt_in,
1026                     id->f_src.i_cat, get_vlc_chroma(id->ff_dec_c->pix_fmt) );
1027
1028     id->p_encoder->fmt_in.video.i_width = id->f_dst.video.i_width;
1029     id->p_encoder->fmt_in.video.i_height = id->f_dst.video.i_height;
1030
1031     if( id->p_encoder->fmt_in.video.i_width <= 0 )
1032     {
1033         id->p_encoder->fmt_in.video.i_width = id->f_dst.video.i_width =
1034             id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1035     }
1036     if( id->p_encoder->fmt_in.video.i_height <= 0 )
1037     {
1038         id->p_encoder->fmt_in.video.i_height = id->f_dst.video.i_height =
1039             id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1040     }
1041
1042     id->p_encoder->fmt_in.video.i_frame_rate = 25; /* FIXME as it break mpeg */
1043     id->p_encoder->fmt_in.video.i_frame_rate_base= 1;
1044     if( id->ff_dec )
1045     {
1046         id->p_encoder->fmt_in.video.i_frame_rate = id->ff_dec_c->frame_rate;
1047 #if LIBAVCODEC_BUILD >= 4662
1048         id->p_encoder->fmt_in.video.i_frame_rate_base =
1049             id->ff_dec_c->frame_rate_base;
1050 #endif
1051
1052 #if LIBAVCODEC_BUILD >= 4687
1053         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1054             ( av_q2d(id->ff_dec_c->sample_aspect_ratio) *
1055               id->ff_dec_c->width / id->ff_dec_c->height );
1056 #else
1057         id->p_encoder->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR *
1058             id->ff_dec_c->aspect_ratio;
1059 #endif
1060
1061     }
1062
1063     id->p_encoder->fmt_out = id->p_encoder->fmt_in;
1064     id->p_encoder->fmt_out.i_codec = id->f_dst.i_codec;
1065     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
1066
1067     id->p_encoder->i_vtolerance = p_sys->i_vtolerance;
1068     id->p_encoder->i_key_int = p_sys->i_key_int;
1069     id->p_encoder->i_b_frames = p_sys->i_b_frames;
1070     id->p_encoder->i_qmin = p_sys->i_qmin;
1071     id->p_encoder->i_qmax = p_sys->i_qmax;
1072     id->p_encoder->i_hq = p_sys->i_hq;
1073     id->p_encoder->b_strict_rc = p_sys->b_strict_rc;
1074     id->p_encoder->b_pre_me = p_sys->b_pre_me;
1075     id->p_encoder->b_hurry_up = p_sys->b_hurry_up;
1076
1077     id->p_ff_pic         = avcodec_alloc_frame();
1078     id->p_ff_pic_tmp0    = NULL;
1079     id->p_ff_pic_tmp1    = NULL;
1080     id->p_ff_pic_tmp2    = NULL;
1081     id->p_vresample      = NULL;
1082
1083     id->p_encoder->p_module =
1084         module_Need( id->p_encoder, "encoder", NULL );
1085
1086     if( !id->p_encoder->p_module )
1087     {
1088         vlc_object_destroy( id->p_encoder );
1089         msg_Err( p_stream, "cannot find encoder" );
1090         return VLC_EGENERIC;
1091     }
1092
1093     /* Close the encoder.
1094      * We'll open it only when we have the first frame */
1095     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1096
1097     id->b_enc_inited = VLC_FALSE;
1098
1099     return VLC_SUCCESS;
1100 }
1101
1102 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream,
1103                                            sout_stream_id_t *id )
1104 {
1105     /* Close decoder */
1106     if( id->ff_dec )
1107     {
1108         avcodec_close( id->ff_dec_c );
1109         free( id->ff_dec_c );
1110     }
1111
1112     /* Close encoder */
1113     module_Unneed( id->p_encoder, id->p_encoder->p_module );
1114     vlc_object_destroy( id->p_encoder );
1115
1116     /* Misc cleanup */
1117     if( id->p_ff_pic)
1118     {
1119         free( id->p_ff_pic );
1120     }
1121
1122     if( id->p_ff_pic_tmp0 )
1123     {
1124         free( id->p_ff_pic_tmp0->data[0] );
1125         free( id->p_ff_pic_tmp0 );
1126     }
1127     if( id->p_ff_pic_tmp1)
1128     {
1129         free( id->p_ff_pic_tmp1->data[0] );
1130         free( id->p_ff_pic_tmp1 );
1131     }
1132     if( id->p_ff_pic_tmp2)
1133     {
1134         free( id->p_ff_pic_tmp2->data[0] );
1135         free( id->p_ff_pic_tmp2 );
1136     }
1137     if( id->p_vresample )
1138     {
1139         free( id->p_vresample );
1140     }
1141 }
1142
1143 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
1144                sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out )
1145 {
1146     sout_stream_sys_t   *p_sys = p_stream->p_sys;
1147     int     i_used;
1148     int     b_gotpicture;
1149     AVFrame *frame;
1150
1151     int     i_data;
1152     uint8_t *p_data;
1153
1154     *out = NULL;
1155
1156     i_data = in->i_size;
1157     p_data = in->p_buffer;
1158  
1159     for( ;; )
1160     {
1161         block_t *p_block;
1162         picture_t pic;
1163         int i_plane;
1164
1165         /* decode frame */
1166         frame = id->p_ff_pic;
1167         p_sys->i_input_pts = in->i_pts;
1168         if( id->ff_dec )
1169         {
1170             i_used = avcodec_decode_video( id->ff_dec_c, frame,
1171                                            &b_gotpicture,
1172                                            p_data, i_data );
1173         }
1174         else
1175         {
1176             /* raw video */
1177             avpicture_fill( (AVPicture*)frame, p_data,
1178                             id->ff_dec_c->pix_fmt,
1179                             id->ff_dec_c->width, id->ff_dec_c->height );
1180             i_used = i_data;
1181             b_gotpicture = 1;
1182
1183             /* Set PTS */
1184             frame->pts = p_sys->i_input_pts;
1185         }
1186
1187         if( i_used < 0 )
1188         {
1189             msg_Warn( p_stream, "error");
1190             return VLC_EGENERIC;
1191         }
1192         i_data -= i_used;
1193         p_data += i_used;
1194
1195         if( !b_gotpicture )
1196         {
1197             return VLC_SUCCESS;
1198         }
1199
1200         /* Get the pts of the decoded frame if any, otherwise keep the
1201          * interpolated one */
1202         if( frame->pts > 0 )
1203         {
1204             p_sys->i_output_pts = frame->pts;
1205         }
1206
1207         if( !id->b_enc_inited )
1208         {
1209             /* XXX hack because of copy packetizer and mpeg4video that can fail
1210              * detecting size */
1211             if( id->p_encoder->fmt_in.video.i_width <= 0 )
1212             {
1213                 id->p_encoder->fmt_in.video.i_width =
1214                   id->p_encoder->fmt_out.video.i_width = id->f_dst.video.i_width =
1215                     id->ff_dec_c->width - p_sys->i_crop_left -
1216                       p_sys->i_crop_right;
1217             }
1218             if( id->p_encoder->fmt_in.video.i_height <= 0 )
1219             {
1220                 id->p_encoder->fmt_in.video.i_height =
1221                   id->p_encoder->fmt_out.video.i_height = id->f_dst.video.i_height =
1222                     id->ff_dec_c->height - p_sys->i_crop_top -
1223                       p_sys->i_crop_bottom;
1224             }
1225
1226             id->p_encoder->fmt_out.i_extra = 0;
1227             id->p_encoder->fmt_out.p_extra = NULL;
1228
1229             id->p_encoder->p_module =
1230                 module_Need( id->p_encoder, "encoder", NULL );
1231             if( !id->p_encoder->p_module )
1232             {
1233                 vlc_object_destroy( id->p_encoder );
1234                 msg_Err( p_stream, "cannot find encoder" );
1235                 return VLC_EGENERIC;
1236             }
1237
1238             id->f_dst.i_extra = id->p_encoder->fmt_out.i_extra;
1239             id->f_dst.p_extra = id->p_encoder->fmt_out.p_extra;
1240
1241             /* Hack for mp2v/mp1v transcoding support */
1242             if( id->f_dst.i_codec == VLC_FOURCC( 'm','p','1','v' ) ||
1243                 id->f_dst.i_codec == VLC_FOURCC( 'm','p','2','v' ) )
1244             {
1245                 id->f_dst.i_codec = VLC_FOURCC( 'm','p','g','v' );
1246             }
1247
1248             if( !( id->id =
1249                      p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1250                                                      &id->f_dst ) ) )
1251             {
1252                 msg_Err( p_stream, "cannot add this stream" );
1253                 transcode_video_ffmpeg_close( p_stream, id );
1254                 id->b_transcode = VLC_FALSE;
1255                 return VLC_EGENERIC;
1256             }
1257
1258             while( id->p_encoder->pf_header &&
1259                    (p_block = id->p_encoder->pf_header( id->p_encoder )) )
1260             {
1261                 sout_buffer_t *p_out;
1262                 p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1263                 memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1264                 p_out->i_dts = in->i_dts;
1265                 p_out->i_pts = in->i_dts;
1266                 p_out->i_length = 0;
1267                 sout_BufferChain( out, p_out );
1268             }
1269
1270             id->i_inter_pixfmt =
1271                 get_ff_chroma( id->p_encoder->fmt_in.i_codec );
1272
1273             id->b_enc_inited = VLC_TRUE;
1274         }
1275
1276         /* deinterlace */
1277         if( p_stream->p_sys->b_deinterlace )
1278         {
1279             if( id->p_ff_pic_tmp0 == NULL )
1280             {
1281                 int     i_size;
1282                 uint8_t *buf;
1283                 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1284                 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1285                                              id->ff_dec_c->width, id->ff_dec_c->height );
1286
1287                 buf = malloc( i_size );
1288
1289                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1290                                 id->i_inter_pixfmt,
1291                                 id->ff_dec_c->width, id->ff_dec_c->height );
1292             }
1293
1294             avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1295                                    id->ff_dec_c->pix_fmt,
1296                                    id->ff_dec_c->width, id->ff_dec_c->height );
1297
1298             frame = id->p_ff_pic_tmp0;
1299         }
1300
1301         /* convert pix format */
1302         if( id->ff_dec_c->pix_fmt != id->i_inter_pixfmt )
1303         {
1304             if( id->p_ff_pic_tmp1 == NULL )
1305             {
1306                 int     i_size;
1307                 uint8_t *buf;
1308                 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1309                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1310                                              id->ff_dec_c->width,
1311                                              id->ff_dec_c->height );
1312
1313                 buf = malloc( i_size );
1314
1315                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1316                                 id->i_inter_pixfmt,
1317                                 id->ff_dec_c->width, id->ff_dec_c->height );
1318             }
1319
1320             img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->i_inter_pixfmt,
1321                          (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1322                          id->ff_dec_c->width, id->ff_dec_c->height );
1323
1324             frame = id->p_ff_pic_tmp1;
1325         }
1326
1327         /* convert size and crop */
1328         if( id->ff_dec_c->width  != id->f_dst.video.i_width ||
1329             id->ff_dec_c->height != id->f_dst.video.i_height ||
1330             p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1331             p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1332         {
1333             if( id->p_ff_pic_tmp2 == NULL )
1334             {
1335                 int     i_size;
1336                 uint8_t *buf;
1337                 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1338                 i_size = avpicture_get_size( id->i_inter_pixfmt,
1339                                              id->f_dst.video.i_width,
1340                                              id->f_dst.video.i_height );
1341
1342                 buf = malloc( i_size );
1343
1344                 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1345                                 id->i_inter_pixfmt,
1346                                 id->f_dst.video.i_width, id->f_dst.video.i_height );
1347
1348                 id->p_vresample =
1349                     img_resample_full_init( id->f_dst.video.i_width,
1350                                             id->f_dst.video.i_height,
1351                                             id->ff_dec_c->width, id->ff_dec_c->height,
1352                                             p_stream->p_sys->i_crop_top,
1353                                             p_stream->p_sys->i_crop_bottom,
1354                                             p_stream->p_sys->i_crop_left,
1355                                             p_stream->p_sys->i_crop_right );
1356             }
1357
1358             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
1359                           (AVPicture*)frame );
1360
1361             frame = id->p_ff_pic_tmp2;
1362         }
1363
1364         /* Encoding */
1365         vout_InitPicture( VLC_OBJECT(p_stream), &pic,
1366                           id->p_encoder->fmt_in.i_codec,
1367                           id->f_dst.video.i_width, id->f_dst.video.i_height,
1368                           id->f_dst.video.i_width * VOUT_ASPECT_FACTOR /
1369                           id->f_dst.video.i_height );
1370
1371         for( i_plane = 0; i_plane < pic.i_planes; i_plane++ )
1372         {
1373             pic.p[i_plane].p_pixels = frame->data[i_plane];
1374             pic.p[i_plane].i_pitch = frame->linesize[i_plane];
1375         }
1376
1377         /* Set the pts of the frame being encoded */
1378         pic.date = p_sys->i_output_pts;
1379
1380         pic.b_progressive = 1; /* ffmpeg doesn't support interlaced encoding */
1381         pic.i_nb_fields = frame->repeat_pict;
1382 #if LIBAVCODEC_BUILD >= 4684
1383         pic.b_top_field_first = frame->top_field_first;
1384 #endif
1385
1386         /* Interpolate the next PTS
1387          * (needed by the mpeg video packetizer which can send pts <= 0 ) */
1388         if( id->ff_dec_c && id->ff_dec_c->frame_rate > 0 )
1389         {
1390             p_sys->i_output_pts += I64C(1000000) * (2 + frame->repeat_pict) *
1391               id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate);
1392         }
1393
1394         p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic );
1395         while( p_block )
1396         {
1397             sout_buffer_t *p_out;
1398             block_t *p_prev_block = p_block;
1399
1400             p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
1401             memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
1402             p_out->i_dts = p_block->i_dts;
1403             p_out->i_pts = p_block->i_pts;
1404             p_out->i_length = p_block->i_length;
1405             sout_BufferChain( out, p_out );
1406
1407             p_block = p_block->p_next;
1408             block_Release( p_prev_block );
1409         }
1410
1411         if( i_data <= 0 )
1412         {
1413             return VLC_SUCCESS;
1414         }
1415     }
1416
1417     return VLC_SUCCESS;
1418 }
1419
1420 /*****************************************************************************
1421  * transcode_video_ffmpeg_getframebuf:
1422  *
1423  * Callback used by ffmpeg to get a frame buffer.
1424  * We use it to get the right PTS for each decoded picture.
1425  *****************************************************************************/
1426 static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
1427                                               AVFrame *p_frame)
1428 {
1429     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
1430
1431     /* Set PTS */
1432     p_frame->pts = p_sys->i_input_pts;
1433
1434     return avcodec_default_get_buffer( p_context, p_frame );
1435 }