1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: transcode.c,v 1.27 2003/07/28 20:25:30 jpsaman 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", fcc,
163 p_sys->i_sample_rate, p_sys->i_channels,
164 p_sys->i_abitrate / 1024 );
167 if( ( codec = sout_cfg_find_value( p_stream->p_cfg, "vcodec" ) ) )
172 memcpy( fcc, codec, strlen( codec ) );
174 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
176 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "width" ) ) )
178 p_sys->i_width = atoi( val );
180 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "height" ) ) )
182 p_sys->i_height = atoi( val );
184 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
186 p_sys->i_vbitrate = atoi( val );
187 if( p_sys->i_vbitrate < 16000 )
189 p_sys->i_vbitrate *= 1000;
192 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
194 p_sys->i_vtolerance = atoi( val );
196 if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
198 p_sys->b_deinterlace = VLC_TRUE;
201 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "croptop" ) ) )
203 p_sys->i_crop_top = atoi( val );
205 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropbottom" ) ) )
207 p_sys->i_crop_bottom = atoi( val );
209 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropleft" ) ) )
211 p_sys->i_crop_left = atoi( val );
213 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "cropright" ) ) )
215 p_sys->i_crop_right = atoi( val );
217 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
219 p_sys->i_key_int = atoi( val );
221 if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
223 p_sys->b_hq = VLC_TRUE;
225 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
227 p_sys->i_qmin = atoi( val );
229 if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
231 p_sys->i_qmax = atoi( val );
234 msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
236 p_sys->i_width, p_sys->i_height,
237 p_sys->i_vbitrate / 1024 );
242 msg_Err( p_stream, "cannot create chain" );
246 p_stream->pf_add = Add;
247 p_stream->pf_del = Del;
248 p_stream->pf_send = Send;
250 p_stream->p_sys = p_sys;
253 avcodec_register_all();
258 /*****************************************************************************
260 *****************************************************************************/
262 static void Close( vlc_object_t * p_this )
264 sout_stream_t *p_stream = (sout_stream_t*)p_this;
265 sout_stream_sys_t *p_sys = p_stream->p_sys;
267 sout_stream_delete( p_sys->p_out );
271 struct sout_stream_id_t
273 vlc_fourcc_t b_transcode;
274 sout_format_t f_src; /* only if transcoding */
275 sout_format_t f_dst; /* " " " */
277 /* id of the out stream */
282 AVCodecContext *ff_dec_c;
285 vlc_fourcc_t b_enc_inited;
287 AVCodecContext *ff_enc_c;
294 uint8_t *p_buffer_in;
301 int i_buffer_out_pos;
302 uint8_t *p_buffer_out;
305 AVFrame *p_ff_pic_tmp0; /* to do deinterlace */
306 AVFrame *p_ff_pic_tmp1; /* to do pix conversion */
307 AVFrame *p_ff_pic_tmp2; /* to do resample */
309 ImgReSampleContext *p_vresample;
311 #ifdef HAVE_VORBIS_VORBISENC_H
315 vorbis_dsp_state *p_vd;
317 vorbis_comment *p_vc;
318 int i_last_block_size;
320 vlc_bool_t b_headers_sent;
325 static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
327 sout_stream_sys_t *p_sys = p_stream->p_sys;
328 sout_stream_id_t *id;
330 id = malloc( sizeof( sout_stream_id_t ) );
333 if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
336 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
337 (char*)&p_fmt->i_fourcc,
338 (char*)&p_sys->i_acodec );
341 memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
343 /* create dst format */
344 id->f_dst.i_cat = AUDIO_ES;
345 id->f_dst.i_fourcc = p_sys->i_acodec;
346 id->f_dst.i_sample_rate = p_sys->i_sample_rate > 0 ? p_sys->i_sample_rate : id->f_src.i_sample_rate;
347 id->f_dst.i_channels = p_sys->i_channels > 0 ? p_sys->i_channels : id->f_src.i_channels;
348 id->f_dst.i_bitrate = p_sys->i_abitrate > 0 ? p_sys->i_abitrate : 64000;
349 id->f_dst.i_block_align = 0;
350 id->f_dst.i_extra_data = 0;
351 id->f_dst.p_extra_data = NULL;
353 /* build decoder -> filter -> encoder */
354 if( transcode_audio_ffmpeg_new( p_stream, id ) )
356 msg_Err( p_stream, "cannot create audio chain" );
361 /* open output stream */
362 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
363 id->b_transcode = VLC_TRUE;
371 else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_vcodec != 0 )
374 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
375 (char*)&p_fmt->i_fourcc,
376 (char*)&p_sys->i_vcodec );
378 memcpy( &id->f_src, p_fmt, sizeof( sout_format_t ) );
380 /* create dst format */
381 id->f_dst.i_cat = VIDEO_ES;
382 id->f_dst.i_fourcc = p_sys->i_vcodec;
383 id->f_dst.i_width = p_sys->i_width ; /* > 0 ? p_sys->i_width : id->f_src.i_width; */
384 id->f_dst.i_height = p_sys->i_height; /* > 0 ? p_sys->i_height: id->f_src.i_height; */
385 id->f_dst.i_bitrate = p_sys->i_vbitrate > 0 ? p_sys->i_vbitrate : 800*1000;
386 id->f_dst.i_extra_data = 0;
387 id->f_dst.p_extra_data = NULL;
389 /* build decoder -> filter -> encoder */
390 if( transcode_video_ffmpeg_new( p_stream, id ) )
392 msg_Err( p_stream, "cannot create video chain" );
397 /* open output stream */
398 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
400 id->b_transcode = VLC_TRUE;
404 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_fourcc );
405 id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
406 id->b_transcode = VLC_FALSE;
418 static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id )
420 sout_stream_sys_t *p_sys = p_stream->p_sys;
422 if( id->b_transcode )
424 if( id->f_src.i_cat == AUDIO_ES )
426 transcode_audio_ffmpeg_close( p_stream, id );
428 else if( id->f_src.i_cat == VIDEO_ES )
430 transcode_video_ffmpeg_close( p_stream, id );
434 if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
440 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
441 sout_buffer_t *p_buffer )
443 sout_stream_sys_t *p_sys = p_stream->p_sys;
445 if( id->b_transcode )
447 sout_buffer_t *p_buffer_out;
448 if( id->f_src.i_cat == AUDIO_ES )
450 transcode_audio_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
452 else if( id->f_src.i_cat == VIDEO_ES )
454 transcode_video_ffmpeg_process( p_stream, id, p_buffer, &p_buffer_out );
456 sout_BufferDelete( p_stream->p_sout, p_buffer );
460 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer_out );
464 else if( id->id != NULL )
466 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
470 sout_BufferDelete( p_stream->p_sout, p_buffer );
475 /****************************************************************************
476 * ffmpeg decoder reencocdr part
477 ****************************************************************************/
483 } fourcc_to_ff_code[] =
486 { VLC_FOURCC( 'm', 'p', 'g', 'a' ), CODEC_ID_MP2 },
487 { VLC_FOURCC( 'm', 'p', '3', ' ' ), CODEC_ID_MP3LAME },
488 { VLC_FOURCC( 'a', '5', '2', ' ' ), CODEC_ID_AC3 },
489 { VLC_FOURCC( 'a', 'c', '3', ' ' ), CODEC_ID_AC3 },
490 { VLC_FOURCC( 'w', 'm', 'a', '1' ), CODEC_ID_WMAV1 },
491 { VLC_FOURCC( 'w', 'm', 'a', '2' ), CODEC_ID_WMAV2 },
492 { VLC_FOURCC( 'v', 'o', 'r', 'b' ), CODEC_ID_VORBIS },
493 { VLC_FOURCC( 'a', 'l', 'a', 'w' ), CODEC_ID_PCM_ALAW },
496 { VLC_FOURCC( 'm', 'p', '4', 'v'), CODEC_ID_MPEG4 },
497 { VLC_FOURCC( 'm', 'p', 'g', 'v' ), CODEC_ID_MPEG1VIDEO },
498 { VLC_FOURCC( 'D', 'I', 'V', '1' ), CODEC_ID_MSMPEG4V1 },
499 { VLC_FOURCC( 'D', 'I', 'V', '2' ), CODEC_ID_MSMPEG4V2 },
500 { VLC_FOURCC( 'D', 'I', 'V', '3' ), CODEC_ID_MSMPEG4V3 },
501 { VLC_FOURCC( 'H', '2', '6', '3' ), CODEC_ID_H263 },
502 { VLC_FOURCC( 'I', '2', '6', '3' ), CODEC_ID_H263I },
503 { VLC_FOURCC( 'h', 'u', 'f', 'f' ), CODEC_ID_HUFFYUV },
504 { VLC_FOURCC( 'W', 'M', 'V', '1' ), CODEC_ID_WMV1 },
505 { VLC_FOURCC( 'W', 'M', 'V', '2' ), CODEC_ID_WMV2 },
506 { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG },
507 { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB },
508 { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
509 { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
510 #if LIBAVCODEC_BUILD >= 4666
511 { VLC_FOURCC( 'S', 'V', 'Q', '3' ), CODEC_ID_SVQ3 },
514 /* raw video code, only used for 'encoding' */
515 { VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
516 { VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
517 { VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
518 { VLC_FOURCC( 'R', 'V', '1', '5' ), CODEC_ID_RAWVIDEO },
519 { VLC_FOURCC( 'R', 'V', '1', '6' ), CODEC_ID_RAWVIDEO },
520 { VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
521 { VLC_FOURCC( 'R', 'V', '3', '2' ), CODEC_ID_RAWVIDEO },
522 { VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
524 { VLC_FOURCC( 0, 0, 0, 0 ), 0 }
527 static inline int get_ff_codec( vlc_fourcc_t i_fcc )
531 for( i = 0; fourcc_to_ff_code[i].i_fcc != 0; i++ )
533 if( fourcc_to_ff_code[i].i_fcc == i_fcc )
535 return fourcc_to_ff_code[i].i_ff_codec;
542 static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
546 case VLC_FOURCC( 'I', '4', '2', '0' ):
547 return PIX_FMT_YUV420P;
548 case VLC_FOURCC( 'I', '4', '2', '2' ):
549 return PIX_FMT_YUV422P;
550 case VLC_FOURCC( 'I', '4', '4', '4' ):
551 return PIX_FMT_YUV444P;
552 case VLC_FOURCC( 'R', 'V', '1', '5' ):
553 return PIX_FMT_RGB555;
554 case VLC_FOURCC( 'R', 'V', '1', '6' ):
555 return PIX_FMT_RGB565;
556 case VLC_FOURCC( 'R', 'V', '2', '4' ):
557 return PIX_FMT_RGB24;
558 case VLC_FOURCC( 'R', 'V', '3', '2' ):
559 return PIX_FMT_RGBA32;
560 case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
561 return PIX_FMT_GRAY8;
562 case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
563 return PIX_FMT_YUV422;
569 static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
570 sout_stream_id_t *id )
574 if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
575 id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
576 id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
577 id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
581 id->ff_dec_c = avcodec_alloc_context();
582 id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
583 id->ff_dec_c->channels = id->f_src.i_channels;
584 id->ff_dec_c->block_align = id->f_src.i_block_align;
585 id->ff_dec_c->bit_rate = id->f_src.i_bitrate;
590 i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
591 if( i_ff_codec == 0 )
593 msg_Err( p_stream, "cannot find decoder" );
597 id->ff_dec = avcodec_find_decoder( i_ff_codec );
600 msg_Err( p_stream, "cannot find decoder" );
604 id->ff_dec_c = avcodec_alloc_context();
605 id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
606 id->ff_dec_c->channels = id->f_src.i_channels;
607 id->ff_dec_c->block_align = id->f_src.i_block_align;
608 id->ff_dec_c->bit_rate = id->f_src.i_bitrate;
610 id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
611 id->ff_dec_c->extradata = id->f_src.p_extra_data;
612 if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
614 msg_Err( p_stream, "cannot open decoder" );
620 id->i_buffer_in = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
621 id->i_buffer_in_pos = 0;
622 id->p_buffer_in = malloc( id->i_buffer_in );
624 id->i_buffer = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
625 id->i_buffer_pos = 0;
626 id->p_buffer = malloc( id->i_buffer );
628 id->i_buffer_out = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
629 id->i_buffer_out_pos = 0;
630 id->p_buffer_out = malloc( id->i_buffer_out );
632 /* Sanity check for audio channels */
633 id->f_dst.i_channels = __MIN( id->f_dst.i_channels, id->f_src.i_channels );
635 #ifdef HAVE_VORBIS_VORBISENC_H
636 if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
638 id->p_vi = (vorbis_info *)malloc( sizeof(vorbis_info) );
639 id->p_vd = (vorbis_dsp_state *)malloc( sizeof(vorbis_dsp_state) );
640 id->p_vb = (vorbis_block *)malloc( sizeof(vorbis_block) );
641 id->p_vc = (vorbis_comment *)malloc( sizeof(vorbis_comment) );
643 vorbis_info_init( id->p_vi );
645 if( vorbis_encode_setup_managed( id->p_vi, id->f_dst.i_channels,
646 id->f_dst.i_sample_rate, -1, id->f_dst.i_bitrate, -1 ) ||
647 vorbis_encode_ctl( id->p_vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
648 vorbis_encode_setup_init( id->p_vi ) ){}
651 vorbis_comment_init( id->p_vc);
652 vorbis_comment_add_tag( id->p_vc, "ENCODER", "VLC media player");
654 /* set up the analysis state and auxiliary encoding storage */
655 vorbis_analysis_init( id->p_vd, id->p_vi );
656 vorbis_block_init( id->p_vd, id->p_vb );
658 id->b_headers_sent = VLC_FALSE;
659 id->i_last_block_size = 0;
660 id->i_samples_delay = 0;
666 i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
667 if( i_ff_codec == 0 )
669 msg_Err( p_stream, "cannot find encoder" );
673 id->ff_enc = avcodec_find_encoder( i_ff_codec );
676 msg_Err( p_stream, "cannot find encoder" );
680 /* Hack for mp3 transcoding support */
681 if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
682 id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','a' );
684 id->ff_enc_c = avcodec_alloc_context();
685 id->ff_enc_c->bit_rate = id->f_dst.i_bitrate;
686 id->ff_enc_c->sample_rate = id->f_dst.i_sample_rate;
687 id->ff_enc_c->channels = id->f_dst.i_channels;
689 if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
691 msg_Err( p_stream, "cannot open encoder" );
698 static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream,
699 sout_stream_id_t *id )
703 avcodec_close( id->ff_dec_c );
706 #ifdef HAVE_VORBIS_VORBISENC_H
707 if( id->f_dst.i_fourcc == VLC_FOURCC('v','o','r','b') )
709 vorbis_block_clear( id->p_vb );
710 vorbis_dsp_clear( id->p_vd );
711 vorbis_comment_clear( id->p_vc );
712 vorbis_info_clear( id->p_vi ); /* must be called last */
721 avcodec_close( id->ff_enc_c );
723 free( id->ff_dec_c );
724 if( id->f_dst.i_fourcc != VLC_FOURCC('v','o','r','b') )
725 free( id->ff_enc_c );
727 free( id->p_buffer_in );
728 free( id->p_buffer );
729 free( id->p_buffer_out );
732 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream,
733 sout_stream_id_t *id,
735 sout_buffer_t **out )
737 vlc_bool_t b_again = VLC_FALSE;
741 /* gather data into p_buffer_in */
742 #ifdef HAVE_VORBIS_VORBISENC_H
743 if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
744 id->i_dts = in->i_dts -
745 (mtime_t)1000000 * (mtime_t)id->i_samples_delay /
746 (mtime_t)id->f_dst.i_sample_rate;
749 id->i_dts = in->i_dts -
751 (mtime_t)(id->i_buffer_pos / 2 / id->ff_dec_c->channels )/
752 (mtime_t)id->ff_dec_c->sample_rate;
754 if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in )
756 /* extend buffer_in */
757 id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
758 id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
760 memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
761 in->p_buffer, in->i_size );
762 id->i_buffer_in_pos += in->i_size;
768 /* decode as much data as possible */
776 i_buffer_size = id->i_buffer - id->i_buffer_pos;
778 i_used = avcodec_decode_audio( id->ff_dec_c,
779 (int16_t*)&id->p_buffer[id->i_buffer_pos],
780 &i_buffer_size, id->p_buffer_in,
781 id->i_buffer_in_pos );
783 /* msg_Warn( p_stream, "avcodec_decode_audio: %d used",
785 id->i_buffer_pos += i_buffer_size;
789 msg_Warn( p_stream, "error");
790 id->i_buffer_in_pos = 0;
793 else if( i_used < id->i_buffer_in_pos )
795 memmove( id->p_buffer_in,
796 &id->p_buffer_in[i_used],
797 id->i_buffer_in - i_used );
798 id->i_buffer_in_pos -= i_used;
802 id->i_buffer_in_pos = 0;
806 if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE )
816 int16_t *sout = (int16_t*)&id->p_buffer[id->i_buffer_pos];
819 if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
821 int8_t *sin = (int8_t*)id->p_buffer_in;
822 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
823 / 2, id->i_buffer_in_pos );
825 while( i_samples > 0 )
827 *sout++ = ( *sin++ ) << 8;
831 else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
833 int8_t *sin = (int8_t*)id->p_buffer_in;
834 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
835 / 2, id->i_buffer_in_pos );
837 while( i_samples > 0 )
839 *sout++ = ( *sin++ - 128 ) << 8;
843 else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
845 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
846 / 2, id->i_buffer_in_pos / 2);
847 #ifdef WORDS_BIGENDIAN
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;
861 memcpy( sout, id->p_buffer_in, i_samples * 2 );
863 i_used = i_samples * 2;
866 else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
868 int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos )
869 / 2, id->i_buffer_in_pos / 2);
870 #ifdef WORDS_BIGENDIAN
871 memcpy( sout, id->p_buffer_in, i_samples * 2 );
873 i_used = i_samples * 2;
875 uint8_t *sin = (uint8_t*)id->p_buffer_in;
876 i_used = i_samples * 2;
877 while( i_samples > 0 )
883 *sout++ = *(int16_t*)tmp;
889 id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
890 if( i_used < id->i_buffer_in_pos )
892 memmove( id->p_buffer_in,
893 &id->p_buffer_in[i_used],
894 id->i_buffer_in - i_used );
896 id->i_buffer_in_pos -= i_used;
899 i_buffer_pos = id->i_buffer_pos;
901 /* encode as much data as possible */
903 #ifdef HAVE_VORBIS_VORBISENC_H
904 if( id->i_buffer_pos == 0 );
905 else if( id->f_dst.i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
909 sout_buffer_t *p_out;
912 if( !id->b_headers_sent )
914 ogg_packet header[3];
915 vorbis_analysis_headerout( id->p_vd, id->p_vc,
916 &header[0], &header[1], &header[2]);
917 for( i = 0; i < 3; i++ )
919 p_out = sout_BufferNew( p_stream->p_sout, header[i].bytes);
920 memcpy( p_out->p_buffer, header[i].packet,
923 p_out->i_size = header[i].bytes;
926 p_out->i_dts = p_out->i_pts = 0;
928 sout_BufferChain( out, p_out );
930 id->b_headers_sent = VLC_TRUE;
933 i_samples = id->i_buffer_pos / id->f_src.i_channels / 2;
934 id->i_samples_delay += i_samples;
935 id->i_buffer_pos = 0;
937 buffer = vorbis_analysis_buffer( id->p_vd, i_samples );
939 /* convert samples to float and uninterleave */
940 for( i = 0; i < id->f_dst.i_channels; i++ )
942 for( j = 0 ; j < i_samples ; j++ )
944 buffer[i][j]= ((float)( ((int16_t *)id->p_buffer)
945 [j*id->f_src.i_channels + i ] ))/ 32768.f;
949 vorbis_analysis_wrote( id->p_vd, i_samples );
951 while( vorbis_analysis_blockout( id->p_vd, id->p_vb ) == 1 )
953 vorbis_analysis( id->p_vb, NULL );
954 vorbis_bitrate_addblock( id->p_vb );
956 while( vorbis_bitrate_flushpacket( id->p_vd, &op ) )
959 p_out = sout_BufferNew( p_stream->p_sout, op.bytes );
960 memcpy( p_out->p_buffer, op.packet, op.bytes );
962 i_block_size = vorbis_packet_blocksize( id->p_vi, &op );
964 if( i_block_size < 0 ) i_block_size = 0;
965 i_samples = ( id->i_last_block_size +
967 id->i_last_block_size = i_block_size;
969 p_out->i_size = op.bytes;
970 p_out->i_length = (mtime_t)1000000 *
972 (mtime_t)id->f_dst.i_sample_rate;
974 //msg_Err( p_stream, "i_dts: %lld", id->i_dts );
977 p_out->i_dts = id->i_dts;
978 p_out->i_pts = id->i_dts;
980 id->i_samples_delay -= i_samples;
983 id->i_dts += p_out->i_length;
984 sout_BufferChain( out, p_out );
994 int i_frame_size = id->ff_enc_c->frame_size * 2 *
995 id->ff_dec_c->channels;
996 int i_out_size, i, j;
997 sout_buffer_t *p_out;
998 int16_t *p_buffer = (int16_t *)(id->p_buffer + i_buffer_pos -
1001 if( id->i_buffer_pos < i_frame_size )
1006 if( id->ff_dec_c->channels != id->ff_enc_c->channels )
1008 /* dumb downmixing */
1009 for( i = 0; i < id->ff_enc_c->frame_size; i++ )
1011 for( j = 0 ; j < id->f_dst.i_channels; j++ )
1013 p_buffer[i*id->f_dst.i_channels+j] =
1014 p_buffer[i*id->f_src.i_channels+j];
1019 /* msg_Warn( p_stream, "avcodec_encode_audio: frame size%d",
1021 i_out_size = avcodec_encode_audio( id->ff_enc_c,
1022 id->p_buffer_out, id->i_buffer_out, p_buffer );
1024 if( i_out_size <= 0 )
1029 id->i_buffer_pos -= i_frame_size;
1031 p_out = sout_BufferNew( p_stream->p_sout, i_out_size );
1032 memcpy( p_out->p_buffer, id->p_buffer_out, i_out_size );
1033 p_out->i_size = i_out_size;
1034 p_out->i_length = (mtime_t)1000000 *
1035 (mtime_t)id->ff_enc_c->frame_size /
1036 (mtime_t)id->ff_enc_c->sample_rate;
1039 p_out->i_dts = id->i_dts;
1040 p_out->i_pts = id->i_dts;
1043 id->i_dts += p_out->i_length;
1045 /* msg_Warn( p_stream, "frame dts=%lld len %lld out=%d",
1046 p_out->i_dts, p_out->i_length, i_out_size ); */
1048 sout_BufferChain( out, p_out );
1051 /* Copy the remaining raw samples */
1052 if( id->i_buffer_pos != 0 )
1054 memmove( id->p_buffer,
1055 &id->p_buffer[i_buffer_pos - id->i_buffer_pos],
1068 static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
1069 sout_stream_id_t *id )
1071 sout_stream_sys_t *p_sys = p_stream->p_sys;
1075 if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
1076 id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
1077 id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
1078 id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
1079 id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
1080 id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
1081 id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
1082 id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
1083 id->f_src.i_fourcc == VLC_FOURCC( 'G', 'R', 'E', 'Y' ) )
1086 id->ff_dec_c = avcodec_alloc_context();
1087 id->ff_dec_c->width = id->f_src.i_width;
1088 id->ff_dec_c->height = id->f_src.i_height;
1089 id->ff_dec_c->pix_fmt = get_ff_chroma( id->f_src.i_fourcc );
1094 i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
1095 if( i_ff_codec == 0 )
1097 msg_Err( p_stream, "cannot find decoder" );
1098 return VLC_EGENERIC;
1101 id->ff_dec = avcodec_find_decoder( i_ff_codec );
1104 msg_Err( p_stream, "cannot find decoder" );
1105 return VLC_EGENERIC;
1108 id->ff_dec_c = avcodec_alloc_context();
1109 id->ff_dec_c->width = id->f_src.i_width;
1110 id->ff_dec_c->height = id->f_src.i_height;
1111 /* id->ff_dec_c->bit_rate = id->f_src.i_bitrate; */
1112 id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
1113 id->ff_dec_c->extradata = id->f_src.p_extra_data;
1114 id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
1115 id->ff_dec_c->error_resilience= -1;
1116 if( id->ff_dec->capabilities & CODEC_CAP_TRUNCATED )
1118 id->ff_dec_c->flags |= CODEC_FLAG_TRUNCATED;
1121 if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
1123 msg_Err( p_stream, "cannot open decoder" );
1124 return VLC_EGENERIC;
1127 if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
1132 avcodec_decode_video( id->ff_dec_c, &frame,
1134 id->ff_dec_c->extradata, id->ff_dec_c->extradata_size );
1140 i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
1141 if( i_ff_codec == 0 )
1143 msg_Err( p_stream, "cannot find encoder" );
1144 return VLC_EGENERIC;
1147 id->ff_enc = avcodec_find_encoder( i_ff_codec );
1150 msg_Err( p_stream, "cannot find encoder" );
1151 return VLC_EGENERIC;
1154 id->ff_enc_c = avcodec_alloc_context();
1155 id->ff_enc_c->width = id->f_dst.i_width;
1156 id->ff_enc_c->height = id->f_dst.i_height;
1157 id->ff_enc_c->bit_rate = id->f_dst.i_bitrate;
1158 #if LIBAVCODEC_BUILD >= 4662
1159 id->ff_enc_c->frame_rate = 25 ; /* FIXME as it break mpeg */
1160 id->ff_enc_c->frame_rate_base= 1;
1162 id->ff_enc_c->frame_rate = 25 * FRAME_RATE_BASE;
1164 id->ff_enc_c->gop_size = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
1166 if( p_sys->i_vtolerance >= 0 )
1168 id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
1170 id->ff_enc_c->qmin = p_sys->i_qmin;
1171 id->ff_enc_c->qmax = p_sys->i_qmax;
1174 id->ff_enc_c->flags |= CODEC_FLAG_HQ;
1177 if( i_ff_codec == CODEC_ID_RAWVIDEO )
1179 id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
1181 /* XXX open it only when we have the first frame */
1182 id->b_enc_inited = VLC_FALSE;
1183 id->i_buffer_in = 0;
1184 id->i_buffer_in_pos = 0;
1185 id->p_buffer_in = NULL;
1187 id->i_buffer = 3*1024*1024;
1188 id->i_buffer_pos = 0;
1189 id->p_buffer = malloc( id->i_buffer );
1191 id->i_buffer_out = 0;
1192 id->i_buffer_out_pos = 0;
1193 id->p_buffer_out = NULL;
1195 id->p_ff_pic = avcodec_alloc_frame();
1196 id->p_ff_pic_tmp0 = NULL;
1197 id->p_ff_pic_tmp1 = NULL;
1198 id->p_ff_pic_tmp2 = NULL;
1199 id->p_vresample = NULL;
1203 static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
1207 avcodec_close( id->ff_dec_c );
1209 if( id->b_enc_inited )
1211 avcodec_close( id->ff_enc_c );
1216 free( id->p_ff_pic );
1219 if( id->p_ff_pic_tmp0 )
1221 free( id->p_ff_pic_tmp0->data[0] );
1222 free( id->p_ff_pic_tmp0 );
1224 if( id->p_ff_pic_tmp1)
1226 free( id->p_ff_pic_tmp1->data[0] );
1227 free( id->p_ff_pic_tmp1 );
1229 if( id->p_ff_pic_tmp2)
1231 free( id->p_ff_pic_tmp2->data[0] );
1232 free( id->p_ff_pic_tmp2 );
1234 if( id->p_vresample )
1236 free( id->p_vresample );
1239 free( id->ff_dec_c );
1240 free( id->ff_enc_c );
1242 free( id->p_buffer );
1245 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_id_t *id,
1246 sout_buffer_t *in, sout_buffer_t **out )
1248 sout_stream_sys_t *p_sys = p_stream->p_sys;
1259 i_data = in->i_size;
1260 p_data = in->p_buffer;
1265 frame = id->p_ff_pic;
1268 i_used = avcodec_decode_video( id->ff_dec_c, frame,
1275 avpicture_fill( (AVPicture*)frame,
1277 id->ff_dec_c->pix_fmt,
1278 id->ff_dec_c->width, id->ff_dec_c->height );
1285 msg_Warn( p_stream, "error");
1286 return VLC_EGENERIC;
1296 if( !id->b_enc_inited )
1298 /* XXX hack because of copy packetizer and mpeg4video that can failed
1300 if( id->ff_enc_c->width <= 0 )
1302 id->ff_enc_c->width =
1303 id->f_dst.i_width = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
1305 if( id->ff_enc_c->height <= 0 )
1307 id->ff_enc_c->height =
1308 id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
1311 if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
1313 msg_Err( p_stream, "cannot open encoder" );
1314 return VLC_EGENERIC;
1317 if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
1319 msg_Err( p_stream, "cannot add this stream" );
1320 transcode_video_ffmpeg_close( p_stream, id );
1321 id->b_transcode = VLC_FALSE;
1322 return VLC_EGENERIC;
1324 id->b_enc_inited = VLC_TRUE;
1329 if( p_stream->p_sys->b_deinterlace )
1331 if( id->p_ff_pic_tmp0 == NULL )
1335 id->p_ff_pic_tmp0 = avcodec_alloc_frame();
1336 i_size = avpicture_get_size( id->ff_dec_c->pix_fmt,
1337 id->ff_dec_c->width, id->ff_dec_c->height );
1339 buf = malloc( i_size );
1341 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp0, buf,
1342 id->ff_enc_c->pix_fmt,
1343 id->ff_dec_c->width, id->ff_dec_c->height );
1346 avpicture_deinterlace( (AVPicture*)id->p_ff_pic_tmp0, (AVPicture*)frame,
1347 id->ff_dec_c->pix_fmt,
1348 id->ff_dec_c->width, id->ff_dec_c->height );
1350 frame = id->p_ff_pic_tmp0;
1353 /* convert pix format */
1354 if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
1356 if( id->p_ff_pic_tmp1 == NULL )
1360 id->p_ff_pic_tmp1 = avcodec_alloc_frame();
1361 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1362 id->ff_dec_c->width, id->ff_dec_c->height );
1364 buf = malloc( i_size );
1366 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp1, buf,
1367 id->ff_enc_c->pix_fmt,
1368 id->ff_dec_c->width, id->ff_dec_c->height );
1371 img_convert( (AVPicture*)id->p_ff_pic_tmp1, id->ff_enc_c->pix_fmt,
1372 (AVPicture*)frame, id->ff_dec_c->pix_fmt,
1373 id->ff_dec_c->width, id->ff_dec_c->height );
1375 frame = id->p_ff_pic_tmp1;
1378 /* convert size and crop */
1379 if( id->ff_dec_c->width != id->ff_enc_c->width ||
1380 id->ff_dec_c->height != id->ff_enc_c->height ||
1381 p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
1382 p_sys->i_crop_left > 0 || p_sys->i_crop_right )
1384 if( id->p_ff_pic_tmp2 == NULL )
1388 id->p_ff_pic_tmp2 = avcodec_alloc_frame();
1389 i_size = avpicture_get_size( id->ff_enc_c->pix_fmt,
1390 id->ff_enc_c->width, id->ff_enc_c->height );
1392 buf = malloc( i_size );
1394 avpicture_fill( (AVPicture*)id->p_ff_pic_tmp2, buf,
1395 id->ff_enc_c->pix_fmt,
1396 id->ff_enc_c->width, id->ff_enc_c->height );
1399 img_resample_full_init( id->ff_enc_c->width, id->ff_enc_c->height,
1400 id->ff_dec_c->width, id->ff_dec_c->height,
1401 p_stream->p_sys->i_crop_top,
1402 p_stream->p_sys->i_crop_bottom,
1403 p_stream->p_sys->i_crop_left,
1404 p_stream->p_sys->i_crop_right );
1407 img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2, (AVPicture*)frame );
1409 frame = id->p_ff_pic_tmp2;
1412 i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer, id->i_buffer, frame );
1415 sout_buffer_t *p_out;
1416 p_out = sout_BufferNew( p_stream->p_sout, i_out );
1418 memcpy( p_out->p_buffer, id->p_buffer, i_out );
1420 p_out->i_size = i_out;
1421 p_out->i_length = in->i_length;
1422 p_out->i_dts = in->i_dts;
1423 p_out->i_pts = in->i_dts; /* FIXME */
1425 sout_BufferChain( out, p_out );