1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: transcode.c,v 1.23 2003/07/06 16:22:15 gbazin Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc/input.h>
35 #ifdef HAVE_FFMPEG_AVCODEC_H
36 # include <ffmpeg/avcodec.h>
42 #ifdef HAVE_VORBIS_VORBISENC_H
43 # include <vorbis/vorbisenc.h>
44 # ifndef OV_ECTL_RATEMANAGE_AVG
45 # define OV_ECTL_RATEMANAGE_AVG 0x0
49 /*****************************************************************************
51 *****************************************************************************/
52 static int Open ( vlc_object_t * );
53 static void Close ( vlc_object_t * );
55 static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
56 static int Del ( sout_stream_t *, sout_stream_id_t * );
57 static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
59 static int transcode_audio_ffmpeg_new ( sout_stream_t *, sout_stream_id_t * );
60 static void transcode_audio_ffmpeg_close ( sout_stream_t *, sout_stream_id_t * );
61 static int transcode_audio_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
63 static int transcode_video_ffmpeg_new ( sout_stream_t *, sout_stream_id_t * );
64 static void transcode_video_ffmpeg_close ( sout_stream_t *, sout_stream_id_t * );
65 static int transcode_video_ffmpeg_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** );
67 /*****************************************************************************
69 *****************************************************************************/
71 set_description( _("Transcode stream") );
72 set_capability( "sout stream", 50 );
73 add_shortcut( "transcode" );
74 set_callbacks( Open, Close );
77 struct sout_stream_sys_t
81 vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
86 vlc_fourcc_t i_vcodec; /* " video " " " " */
95 vlc_bool_t b_deinterlace;
103 /*****************************************************************************
105 *****************************************************************************/
106 static int Open( vlc_object_t *p_this )
108 sout_stream_t *p_stream = (sout_stream_t*)p_this;
109 sout_stream_sys_t *p_sys;
112 p_sys = malloc( sizeof( sout_stream_sys_t ) );
113 p_sys->p_out = sout_stream_new( p_stream->p_sout, p_stream->psz_next );
116 p_sys->i_sample_rate = 0;
117 p_sys->i_channels = 0;
118 p_sys->i_abitrate = 0;
121 p_sys->i_vbitrate = 0;
122 p_sys->i_vtolerance = -1;
125 p_sys->i_key_int = -1;
128 p_sys->b_hq = VLC_FALSE;
129 p_sys->b_deinterlace= VLC_FALSE;
131 p_sys->i_crop_top = 0;
132 p_sys->i_crop_bottom= 0;
133 p_sys->i_crop_right = 0;
134 p_sys->i_crop_left = 0;
136 if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "acodec" ) ) )
141 memcpy( fcc, codec, strlen( codec ) );
143 p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
145 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "samplerate" ) ) )
147 p_sys->i_sample_rate = atoi( val );
149 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "channels" ) ) )
151 p_sys->i_channels = atoi( val );
153 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
155 p_sys->i_abitrate = atoi( val );
156 if( p_sys->i_abitrate < 4000 )
158 p_sys->i_abitrate *= 1000;
162 msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
164 p_sys->i_sample_rate, p_sys->i_channels,
165 p_sys->i_abitrate / 1024 );
168 if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
173 memcpy( fcc, codec, strlen( codec ) );
175 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
177 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
179 p_sys->i_width = atoi( val );
181 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
183 p_sys->i_height = atoi( val );
185 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
187 p_sys->i_vbitrate = atoi( val );
188 if( p_sys->i_vbitrate < 16000 )
190 p_sys->i_vbitrate *= 1000;
193 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
195 p_sys->i_vtolerance = atoi( val );
197 if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
199 p_sys->b_deinterlace = VLC_TRUE;
202 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
204 p_sys->i_crop_top = atoi( val );
206 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
208 p_sys->i_crop_bottom = atoi( val );
210 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
212 p_sys->i_crop_left = atoi( val );
214 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
216 p_sys->i_crop_right = atoi( val );
218 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
220 p_sys->i_key_int = atoi( val );
222 if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
224 p_sys->b_hq = VLC_TRUE;
226 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
228 p_sys->i_qmin = atoi( val );
230 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
232 p_sys->i_qmax = atoi( val );
235 msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
237 p_sys->i_width, p_sys->i_height,
238 p_sys->i_vbitrate / 1024 );
243 msg_Err( p_stream, "cannot create chain" );
247 p_stream->pf_add = Add;
248 p_stream->pf_del = Del;
249 p_stream->pf_send = Send;
251 p_stream->p_sys = p_sys;
254 avcodec_register_all();
259 /*****************************************************************************
261 *****************************************************************************/
263 static void Close( vlc_object_t * p_this )
265 sout_stream_t *p_stream = (sout_stream_t*)p_this;
266 sout_stream_sys_t *p_sys = p_stream->p_sys;
268 sout_stream_delete( p_sys->p_out );
272 struct sout_stream_id_t
274 vlc_fourcc_t b_transcode;
275 sout_format_t f_src; /* only if transcoding */
276 sout_format_t f_dst; /* " " " */
278 /* id of the out stream */
283 AVCodecContext *ff_dec_c;
286 vlc_fourcc_t b_enc_inited;
288 AVCodecContext *ff_enc_c;
295 uint8_t *p_buffer_in;
302 int i_buffer_out_pos;
303 uint8_t *p_buffer_out;
306 AVFrame *p_ff_pic_tmp0; /* to do deinterlace */
307 AVFrame *p_ff_pic_tmp1; /* to do pix conversion */
308 AVFrame *p_ff_pic_tmp2; /* to do resample */
310 ImgReSampleContext *p_vresample;
312 #ifdef HAVE_VORBIS_VORBISENC_H
316 vorbis_dsp_state *p_vd;
318 vorbis_comment *p_vc;
319 int i_last_block_size;
321 vlc_bool_t b_headers_sent;
326 static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
328 sout_stream_sys_t *p_sys = p_stream->p_sys;
329 sout_stream_id_t *id;
331 id = malloc( sizeof( sout_stream_id_t ) );
334 if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
337 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
338 (char*)&p_fmt->i_fourcc,
339 (char*)&p_sys->i_acodec );
342 memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
344 /* create dst format */
345 id->f_dst.i_cat = AUDIO_ES;
346 id->f_dst.i_fourcc = p_sys->i_acodec;
347 id->f_dst.i_sample_rate = p_sys->i_sample_rate > 0 ? p_sys->i_sample_rate : id->f_src.i_sample_rate;
348 id->f_dst.i_channels = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.i_channels;
349 id->f_dst.i_bitrate = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
350 id->f_dst.i_block_align = 0;
351 id->f_dst.i_extra_data = 0;
352 id->f_dst.p_extra_data = NULL;
354 /* build decoder -> filter -> encoder */
355 if( transcode_audio_ffmpeg_new( p_stream, id ) )
357 msg_Err( p_stream, "cannot create audio chain" );
362 /* open output stream */
363 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
364 id->b_transcode = VLC_TRUE;
366 else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
369 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
370 (char*)&p_fmt->i_fourcc,
371 (char*)&p_sys->i_vcodec );
373 memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
375 /* create dst format */
376 id->f_dst.i_cat = VIDEO_ES;
377 id->f_dst.i_fourcc = p_sys->i_vcodec;
378 id->f_dst.i_width = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
379 id->f_dst.i_height = p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
380 id->f_dst.i_bitrate = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
381 id->f_dst.i_extra_data = 0;
382 id->f_dst.p_extra_data = NULL;
384 /* build decoder -> filter -> encoder */
385 if( transcode_video_ffmpeg_new( p_stream, id ) )
387 msg_Err( p_stream, "cannot create video chain" );
392 /* open output stream */
393 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
395 id->b_transcode = VLC_TRUE;
399 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_fourcc );
400 id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
401 id->b_transcode = VLC_FALSE;
413 static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id )
415 sout_stream_sys_t *p_sys = p_stream->p_sys;
417 if( id->b_transcode )
419 if( id->f_src.i_cat == AUDIO_ES )
421 transcode_audio_ffmpeg_close( p_stream, id );
423 else if( id->f_src.i_cat == VIDEO_ES )
425 transcode_video_ffmpeg_close( p_stream, id );
429 if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
435 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
436 sout_buffer_t *p_buffer )
438 sout_stream_sys_t *p_sys = p_stream->p_sys;
440 if( id->b_transcode )
442 sout_buffer_t *p_buffer_out;
443 if( id->f_src.i_cat == AUDIO_ES )
445 transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
447 else if( id->f_src.i_cat == VIDEO_ES )
449 transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
451 sout_BufferDelete( p_stream->p_sout, p_buffer );
455 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
459 else if( id->id != NULL )
461 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
465 sout_BufferDelete( p_stream->p_sout, p_buffer );
470 /****************************************************************************
471 * ffmpeg decoder reencocdr part
472 ****************************************************************************/
478 } fourcc_to_ff_code[] =
481 { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
482 { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
483 { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
484 { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
485 { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
486 { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
487 { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
490 { VLC_FOURCC( 'm', 'p', '4', 'v'), CODEC_ID_MPEG4 },
491 { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
492 { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
493 { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
494 { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
495 { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
496 { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
497 { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
498 { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
499 { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
500 { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
501 { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
502 { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
503 #if LIBAVCODEC_BUILD >= 4666
504 { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
507 /* raw video code, only used for 'encoding' */
508 { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
509 { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
510 { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
511 { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
512 { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
514 { VLC_FOURCC( 0, 0, 0, 0 ), 0 }
517 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
521 for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
523 if( fourcc_to_ff_code[i].i_fcc == i_fcc )
525 return fourcc_to_ff_code[i].i_ff_codec;
532 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
536 case VLC_FOURCC( 'I', '4', '2', '0' ):
537 return PIX_FMT_YUV420P;
538 case VLC_FOURCC( 'I', '4', '2', '2' ):
539 return PIX_FMT_YUV422P;
540 case VLC_FOURCC( 'I', '4', '4', '4' ):
541 return PIX_FMT_YUV444P;
542 case VLC_FOURCC( 'R', 'V', '2', '4' ):
543 return PIX_FMT_RGB24;
544 case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
545 return PIX_FMT_YUV422;
551 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
552 sout_stream_id_t *id )
556 if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
557 id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
558 id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
559 id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
563 id->ff_dec_c = avcodec_alloc_context();
564 id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
565 id->ff_dec_c->channels = id->f_src.i_channels;
566 id->ff_dec_c->block_align = id->f_src.i_block_align;
567 id->ff_dec_c->bit_rate = id->f_src.i_bitrate;
572 i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
573 if( i_ff_codec == 0 )
575 msg_Err( p_stream, "cannot find decoder" );
579 id->ff_dec = avcodec_find_decoder( i_ff_codec );
582 msg_Err( p_stream, "cannot find decoder" );
586 id->ff_dec_c = avcodec_alloc_context();
587 id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
588 id->ff_dec_c->channels = id->f_src.i_channels;
589 id->ff_dec_c->block_align = id->f_src.i_block_align;
590 id->ff_dec_c->bit_rate = id->f_src.i_bitrate;
592 id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
593 id->ff_dec_c->extradata = id->f_src.p_extra_data;
594 if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
596 msg_Err( p_stream, "cannot open decoder" );
602 id->i_buffer_in = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
603 id->i_buffer_in_pos = 0;
604 id->p_buffer_in = malloc( id->i_buffer_in );
606 id->i_buffer = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
607 id->i_buffer_pos = 0;
608 id->p_buffer = malloc( id->i_buffer );
610 id->i_buffer_out = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
611 id->i_buffer_out_pos = 0;
612 id->p_buffer_out = malloc( id->i_buffer_out );
614 #ifdef HAVE_VORBIS_VORBISENC_H
615 if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
617 id->p_vi = (vorbis_info *)malloc( sizeof(vorbis_info) );
618 id->p_vd = (vorbis_dsp_state *)malloc( sizeof(vorbis_dsp_state) );
619 id->p_vb = (vorbis_block *)malloc( sizeof(vorbis_block) );
620 id->p_vc = (vorbis_comment *)malloc( sizeof(vorbis_comment) );
622 vorbis_info_init( id->p_vi );
624 if( vorbis_encode_setup_managed( id->p_vi, id->f_dst.i_channels,
625 id->f_dst.i_sample_rate, -1, id->f_dst.i_bitrate, -1 ) ||
626 vorbis_encode_ctl( id->p_vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
627 vorbis_encode_setup_init( id->p_vi ) ){}
630 vorbis_comment_init( id->p_vc);
631 vorbis_comment_add_tag( id->p_vc, "ENCODER", "VLC media player");
633 /* set up the analysis state and auxiliary encoding storage */
634 vorbis_analysis_init( id->p_vd, id->p_vi );
635 vorbis_block_init( id->p_vd, id->p_vb );
637 id->b_headers_sent = VLC_FALSE;
638 id->i_last_block_size = 0;
639 id->i_samples_delay = 0;
645 i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
646 if( i_ff_codec == 0 )
648 msg_Err( p_stream, "cannot find encoder" );
652 id->ff_enc = avcodec_find_encoder( i_ff_codec );
655 msg_Err( p_stream, "cannot find encoder" );
659 id->ff_enc_c = avcodec_alloc_context();
660 id->ff_enc_c->bit_rate = id->f_dst.i_bitrate;
661 id->ff_enc_c->sample_rate = id->f_dst.i_sample_rate;
662 id->ff_enc_c->channels = id->f_dst.i_channels;
664 if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
666 msg_Err( p_stream, "cannot open encoder" );
673 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
674 sout_stream_id_t *id )
678 avcodec_close( id->ff_dec_c );
681 #ifdef HAVE_VORBIS_VORBISENC_H
682 if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
684 vorbis_block_clear( id->p_vb );
685 vorbis_dsp_clear( id->p_vd );
686 vorbis_comment_clear( id->p_vc );
687 vorbis_info_clear( id->p_vi ); /* must be called last */
696 avcodec_close( id->ff_enc_c );
698 free( id->ff_dec_c );
699 if( id->f_dst.i_fourcc != VLC_FOURCC('v','o','r','b') )
700 free( id->ff_enc_c );
702 free( id->p_buffer_in );
703 free( id->p_buffer );
704 free( id->p_buffer_out );
707 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
708 sout_stream_id_t *id,
710 sout_buffer_t **out )
712 vlc_bool_t b_again = VLC_FALSE;
716 /* gather data into p_buffer_in */
717 #ifdef HAVE_VORBIS_VORBISENC_H
718 if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
719 id->i_dts = in->i_dts -
720 (mtime_t)1000000 * (mtime_t)id->i_samples_delay /
721 (mtime_t)id->f_dst.i_sample_rate;
724 id->i_dts = in->i_dts -
726 (mtime_t)(id->i_buffer_pos / 2 / id->ff_enc_c->channels )/
727 (mtime_t)id->ff_enc_c->sample_rate;
729 if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
731 /* extend buffer_in */
732 id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
733 id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
735 memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
736 in->p_buffer, in->i_size );
737 id->i_buffer_in_pos += in->i_size;
741 /* decode as much data as possible */
749 i_buffer_size = id->i_buffer - id->i_buffer_pos;
751 i_used = avcodec_decode_audio( id->ff_dec_c,
752 (int16_t*)&id->p_buffer[id->i_buffer_pos],
753 &i_buffer_size, id->p_buffer_in,
754 id->i_buffer_in_pos );
756 /* msg_Warn( p_stream, "avcodec_decode_audio: %d used",
758 id->i_buffer_pos += i_buffer_size;
762 msg_Warn( p_stream, "error");
763 id->i_buffer_in_pos = 0;
766 else if( i_used < id->i_buffer_in_pos )
768 memmove( id->p_buffer_in,
769 &id->p_buffer_in[i_used],
770 id->i_buffer_in - i_used );
771 id->i_buffer_in_pos -= i_used;
775 id->i_buffer_in_pos = 0;
779 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
789 int16_t *sout = (int16_t*)&id->p_buffer[id->i_buffer_pos];
792 if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
794 int8_t *sin = (int8_t*)id->p_buffer_in;
795 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
796 / 2, id->i_buffer_in_pos );
798 while( i_samples > 0 )
800 *sout++ = ( *sin++ ) << 8;
804 else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
806 int8_t *sin = (int8_t*)id->p_buffer_in;
807 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
808 / 2, id->i_buffer_in_pos );
810 while( i_samples > 0 )
812 *sout++ = ( *sin++ - 128 ) << 8;
816 else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
818 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
819 / 2, id->i_buffer_in_pos / 2);
820 #ifdef WORDS_BIGENDIAN
821 uint8_t *sin = (uint8_t*)id->p_buffer_in;
822 i_used = i_samples * 2;
823 while( i_samples > 0 )
829 *sout++ = *(int16_t*)tmp;
834 memcpy( sout, id->p_buffer_in, i_samples * 2 );
836 i_used = i_samples * 2;
839 else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
841 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
842 / 2, id->i_buffer_in_pos / 2);
843 #ifdef WORDS_BIGENDIAN
844 memcpy( sout, id->p_buffer_in, i_samples * 2 );
846 i_used = i_samples * 2;
848 uint8_t *sin = (uint8_t*)id->p_buffer_in;
849 i_used = i_samples * 2;
850 while( i_samples > 0 )
856 *sout++ = *(int16_t*)tmp;
862 id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
863 if( i_used < id->i_buffer_in_pos )
865 memmove( id->p_buffer_in,
866 &id->p_buffer_in[i_used],
867 id->i_buffer_in - i_used );
869 id->i_buffer_in_pos -= i_used;
872 /* encode as much data as possible */
874 #ifdef HAVE_VORBIS_VORBISENC_H
875 if( id->i_buffer_pos == 0 );
876 else if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
880 sout_buffer_t *p_out;
883 if( id->i_buffer_pos == 0 )
888 if( !id->b_headers_sent )
890 ogg_packet header[3];
891 vorbis_analysis_headerout( id->p_vd, id->p_vc,
892 &header[0], &header[1], &header[2]);
893 for( i = 0; i < 3; i++ )
895 p_out = sout_BufferNew( p_stream->p_sout, header[i].bytes);
896 memcpy( p_out->p_buffer, header[i].packet,
899 p_out->i_size = header[i].bytes;
902 p_out->i_dts = p_out->i_pts = 0;
904 sout_BufferChain( out, p_out );
906 id->b_headers_sent = VLC_TRUE;
909 i_samples = id->i_buffer_pos / id->f_dst.i_channels / 2;
910 id->i_samples_delay += i_samples;
911 id->i_buffer_pos = 0;
913 buffer = vorbis_analysis_buffer( id->p_vd, i_samples );
915 /* convert samples to float and uninterleave */
916 for( i = 0; i < id->f_dst.i_channels; i++ )
918 for( j = 0 ; j < i_samples ; j++ )
920 buffer[i][j]= ((float)( ((int16_t *)id->p_buffer)
921 [j*id->f_dst.i_channels + i ] ))/ 32768.f;
925 vorbis_analysis_wrote( id->p_vd, i_samples );
927 while( vorbis_analysis_blockout( id->p_vd, id->p_vb ) == 1 )
929 vorbis_analysis( id->p_vb, NULL );
930 vorbis_bitrate_addblock( id->p_vb );
932 while( vorbis_bitrate_flushpacket( id->p_vd, &op ) )
935 p_out = sout_BufferNew( p_stream->p_sout, op.bytes );
936 memcpy( p_out->p_buffer, op.packet, op.bytes );
938 i_block_size = vorbis_packet_blocksize( id->p_vi, &op );
940 if( i_block_size < 0 ) i_block_size = 0;
941 i_samples = ( id->i_last_block_size +
943 id->i_last_block_size = i_block_size;
945 p_out->i_size = op.bytes;
946 p_out->i_length = (mtime_t)1000000 *
948 (mtime_t)id->f_dst.i_sample_rate;
950 //msg_Err( p_stream, "i_dts: %lld", id->i_dts );
953 p_out->i_dts = id->i_dts;
954 p_out->i_pts = id->i_dts;
956 id->i_samples_delay -= i_samples;
959 id->i_dts += p_out->i_length;
960 sout_BufferChain( out, p_out );
970 int i_frame_size = id->ff_enc_c->frame_size * 2 *
971 id->ff_enc_c->channels;
973 sout_buffer_t *p_out;
975 if( id->i_buffer_pos < i_frame_size )
980 /* msg_Warn( p_stream, "avcodec_encode_audio: frame size%d",
982 i_out_size = avcodec_encode_audio( id->ff_enc_c,
983 id->p_buffer_out, id->i_buffer_out,
984 (int16_t*)id->p_buffer );
986 if( i_out_size <= 0 )
990 memmove( id->p_buffer,
991 &id->p_buffer[i_frame_size],
992 id->i_buffer - i_frame_size );
993 id->i_buffer_pos -= i_frame_size;
995 p_out = sout_BufferNew( p_stream->p_sout, i_out_size );
996 memcpy( p_out->p_buffer, id->p_buffer_out, i_out_size );
997 p_out->i_size = i_out_size;
998 p_out->i_length = (mtime_t)1000000 *
999 (mtime_t)id->ff_enc_c->frame_size /
1000 (mtime_t)id->ff_enc_c->sample_rate;
1003 p_out->i_dts = id->i_dts;
1004 p_out->i_pts = id->i_dts;
1007 id->i_dts += p_out->i_length;
1009 /* msg_Warn( p_stream, "frame dts=%lld len %lld out=%d",
1010 p_out->i_dts, p_out->i_length, i_out_size ); */
1012 sout_BufferChain( out, p_out );
1024 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1025 sout_stream_id_t *id )
1027 sout_stream_sys_t *p_sys = p_stream->p_sys;
1031 if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1032 id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1033 id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1034 id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1035 id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) )
1038 id->ff_dec_c = avcodec_alloc_context();
1039 id->ff_dec_c->width = id->f_src.i_width;
1040 id->ff_dec_c->height = id->f_src.i_height;
1041 id->ff_dec_c->pix_fmt = get_ff_chroma( id->f_src.i_fourcc );
1046 i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
1047 if( i_ff_codec == 0 )
1049 msg_Err( p_stream, "cannot find decoder" );
1050 return VLC_EGENERIC;
1053 id->ff_dec = avcodec_find_decoder( i_ff_codec );
1056 msg_Err( p_stream, "cannot find decoder" );
1057 return VLC_EGENERIC;
1060 id->ff_dec_c = avcodec_alloc_context();
1061 id->ff_dec_c->width = id->f_src.i_width;
1062 id->ff_dec_c->height = id->f_src.i_height;
1063 /* id->ff_dec_c->bit_rate = id->f_src.i_bitrate; */
1064 id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
1065 id->ff_dec_c->extradata = id->f_src.p_extra_data;
1066 id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1067 id->ff_dec_c->error_resilience= -1;
1068 if( id->ff_dec->capabilities & CODEC_CAP_TRUNCATED )
1070 id->ff_dec_c->flags |= CODEC_FLAG_TRUNCATED;
1073 if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1075 msg_Err( p_stream, "cannot open decoder" );
1076 return VLC_EGENERIC;
1079 if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1084 avcodec_decode_video( id->ff_dec_c, &frame,
1086 id->ff_dec_c->extradata, id->ff_dec_c->extradata_size );
1092 i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
1093 if( i_ff_codec == 0 )
1095 msg_Err( p_stream, "cannot find encoder" );
1096 return VLC_EGENERIC;
1099 id->ff_enc = avcodec_find_encoder( i_ff_codec );
1102 msg_Err( p_stream, "cannot find encoder" );
1103 return VLC_EGENERIC;
1106 id->ff_enc_c = avcodec_alloc_context();
1107 id->ff_enc_c->width = id->f_dst.i_width;
1108 id->ff_enc_c->height = id->f_dst.i_height;
1109 id->ff_enc_c->bit_rate = id->f_dst.i_bitrate;
1110 #if LIBAVCODEC_BUILD >= 4662
1111 id->ff_enc_c->frame_rate = 25 ; /* FIXME as it break mpeg */
1112 id->ff_enc_c->frame_rate_base= 1;
1114 id->ff_enc_c->frame_rate = 25 * FRAME_RATE_BASE;
1116 id->ff_enc_c->gop_size = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
1118 if( p_sys->i_vtolerance >= 0 )
1120 id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
1122 id->ff_enc_c->qmin = p_sys->i_qmin;
1123 id->ff_enc_c->qmax = p_sys->i_qmax;
1126 id->ff_enc_c->flags |= CODEC_FLAG_HQ;
1129 if( i_ff_codec == CODEC_ID_RAWVIDEO )
1131 id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
1133 /* XXX open it only when we have the first frame */
1134 id->b_enc_inited = VLC_FALSE;
1135 id->i_buffer_in = 0;
1136 id->i_buffer_in_pos = 0;
1137 id->p_buffer_in = NULL;
1139 id->i_buffer = 3*1024*1024;
1140 id->i_buffer_pos = 0;
1141 id->p_buffer = malloc( id->i_buffer );
1143 id->i_buffer_out = 0;
1144 id->i_buffer_out_pos = 0;
1145 id->p_buffer_out = NULL;
1147 id->p_ff_pic = avcodec_alloc_frame();
1148 id->p_ff_pic_tmp0 = NULL;
1149 id->p_ff_pic_tmp1 = NULL;
1150 id->p_ff_pic_tmp2 = NULL;
1151 id->p_vresample = NULL;
1155 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
1159 avcodec_close( id->ff_dec_c );
1161 if( id->b_enc_inited )
1163 avcodec_close( id->ff_enc_c );
1168 free( id->p_ff_pic );
1171 if( id->p_ff_pic_tmp0 )
1173 free( id->p_ff_pic_tmp0->data[0] );
1174 free( id->p_ff_pic_tmp0 );
1176 if( id->p_ff_pic_tmp1)
1178 free( id->p_ff_pic_tmp1->data[0] );
1179 free( id->p_ff_pic_tmp1 );
1181 if( id->p_ff_pic_tmp2)
1183 free( id->p_ff_pic_tmp2->data[0] );
1184 free( id->p_ff_pic_tmp2 );
1186 if( id->p_vresample )
1188 free( id->p_vresample );
1191 free( id->ff_dec_c );
1192 free( id->ff_enc_c );
1194 free( id->p_buffer );
1197 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_id_t *id,
1198 sout_buffer_t *in, sout_buffer_t **out )
1200 sout_stream_sys_t *p_sys = p_stream->p_sys;
1211 i_data = in->i_size;
1212 p_data = in->p_buffer;
1217 frame = id->p_ff_pic;
1220 i_used = avcodec_decode_video( id->ff_dec_c, frame,
1227 avpicture_fill( (AVPicture*)frame,
1229 id->ff_dec_c->pix_fmt,
1230 id->ff_dec_c->width, id->ff_dec_c->height );
1237 msg_Warn( p_stream, "error");
1238 return VLC_EGENERIC;
1248 if( !id->b_enc_inited )
1250 /* XXX hack because of copy packetizer and mpeg4video that can failed
1252 if( id->ff_enc_c->width <= 0 )
1254 id->ff_enc_c->width =
1255 id->f_dst.i_width = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1257 if( id->ff_enc_c->height <= 0 )
1259 id->ff_enc_c->height =
1260 id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1263 if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
1265 msg_Err( p_stream, "cannot open encoder" );
1266 return VLC_EGENERIC;
1269 if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1271 msg_Err( p_stream, "cannot add this stream" );
1272 transcode_video_ffmpeg_close( p_stream, id );
1273 id->b_transcode = VLC_FALSE;
1274 return VLC_EGENERIC;
1276 id->b_enc_inited = VLC_TRUE;
1281 if( p_stream->p_sys->b_deinterlace )
1283 if( id->p_ff_pic_tmp0 == NULL )
1287 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1288 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1289 id->ff_dec_c->width, id->ff_dec_c->height );
1291 buf = malloc( i_size );
1293 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1294 id->ff_enc_c->pix_fmt,
1295 id->ff_dec_c->width, id->ff_dec_c->height );
1298 avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1299 id->ff_dec_c->pix_fmt,
1300 id->ff_dec_c->width, id->ff_dec_c->height );
1302 frame = id->p_ff_pic_tmp0;
1305 /* convert pix format */
1306 if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
1308 if( id->p_ff_pic_tmp1 == NULL )
1312 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1313 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1314 id->ff_dec_c->width, id->ff_dec_c->height );
1316 buf = malloc( i_size );
1318 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1319 id->ff_enc_c->pix_fmt,
1320 id->ff_dec_c->width, id->ff_dec_c->height );
1323 img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->ff_enc_c->pix_fmt,
1324 (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1325 id->ff_dec_c->width, id->ff_dec_c->height );
1327 frame = id->p_ff_pic_tmp1;
1330 /* convert size and crop */
1331 if( id->ff_dec_c->width != id->ff_enc_c->width ||
1332 id->ff_dec_c->height != id->ff_enc_c->height ||
1333 p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1334 p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1336 if( id->p_ff_pic_tmp2 == NULL )
1340 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1341 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1342 id->ff_enc_c->width, id->ff_enc_c->height );
1344 buf = malloc( i_size );
1346 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1347 id->ff_enc_c->pix_fmt,
1348 id->ff_enc_c->width, id->ff_enc_c->height );
1351 img_resample_full_init( id->ff_enc_c->width, id->ff_enc_c->height,
1352 id->ff_dec_c->width, id->ff_dec_c->height,
1353 p_stream->p_sys->i_crop_top,
1354 p_stream->p_sys->i_crop_bottom,
1355 p_stream->p_sys->i_crop_left,
1356 p_stream->p_sys->i_crop_right );
1359 img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2, (AVPicture*)frame );
1361 frame = id->p_ff_pic_tmp2;
1364 i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer, id->i_buffer, frame );
1367 sout_buffer_t *p_out;
1368 p_out = sout_BufferNew( p_stream->p_sout, i_out );
1370 memcpy( p_out->p_buffer, id->p_buffer, i_out );
1372 p_out->i_size = i_out;
1373 p_out->i_length = in->i_length;
1374 p_out->i_dts = in->i_dts;
1375 p_out->i_pts = in->i_dts; /* FIXME */
1377 sout_BufferChain( out, p_out );