From d83f47c4865ace22bd5d3f9c94a4f41ec9186f26 Mon Sep 17 00:00:00 2001 From: Gildas Bazin Date: Mon, 27 Oct 2003 17:50:54 +0000 Subject: [PATCH] * modules/codec/vorbis.c: fixed vorbis encoding. * modules/codec/ffmpeg/*: fixed ffmpeg encoding. * modules/stream_out/transcode.c: transcoding is working again. --- modules/codec/ffmpeg/encoder.c | 124 ++++++----- modules/codec/ffmpeg/ffmpeg.c | 30 ++- modules/codec/vorbis.c | 37 ++-- modules/stream_out/transcode.c | 390 +++++++++++++++------------------ 4 files changed, 287 insertions(+), 294 deletions(-) diff --git a/modules/codec/ffmpeg/encoder.c b/modules/codec/ffmpeg/encoder.c index 199cd04225..9cae62ff6f 100644 --- a/modules/codec/ffmpeg/encoder.c +++ b/modules/codec/ffmpeg/encoder.c @@ -2,7 +2,7 @@ * encoder.c: video and audio encoder using the ffmpeg library ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: encoder.c,v 1.1 2003/10/27 01:04:38 gbazin Exp $ + * $Id: encoder.c,v 1.2 2003/10/27 17:50:54 gbazin Exp $ * * Authors: Laurent Aimar * Gildas Bazin @@ -80,17 +80,21 @@ struct encoder_sys_t /* * Common properties */ - int i_last_block_size; - int i_samples_delay; - mtime_t i_pts; + char *p_buffer; + char *p_buffer_out; + /* + * Videoo properties + */ mtime_t i_last_ref_pts; mtime_t i_buggy_pts_detect; + /* + * Audio properties + */ int i_frame_size; - - char *p_buffer; - char *p_buffer_out; + int i_samples_delay; + mtime_t i_pts; }; /***************************************************************************** @@ -102,24 +106,31 @@ int E_(OpenVideoEncoder)( vlc_object_t *p_this ) encoder_sys_t *p_sys = p_enc->p_sys; AVCodecContext *p_context; AVCodec *p_codec; - int i_ff_codec; + int i_codec_id, i_cat; + char *psz_namecodec; - /* find encoder */ - i_ff_codec = E_(GetFfmpegCodec)( p_enc->i_fourcc, 0, 0, 0 ); - if( !i_ff_codec ) + if( !E_(GetFfmpegCodec)( p_enc->i_fourcc, &i_cat, &i_codec_id, + &psz_namecodec ) ) { return VLC_EGENERIC; } - p_codec = avcodec_find_encoder( i_ff_codec ); - if( !p_codec ) + if( i_cat != VIDEO_ES ) { + msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec ); return VLC_EGENERIC; } - /* libavcodec needs to be initialized */ + /* Initialization must be done before avcodec_find_decoder() */ E_(InitLibavcodec)(p_this); + p_codec = avcodec_find_encoder( i_codec_id ); + if( !p_codec ) + { + msg_Err( p_enc, "cannot find encoder %s", psz_namecodec ); + return VLC_EGENERIC; + } + /* Allocate the memory needed to store the decoder's structure */ if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL ) { @@ -169,7 +180,7 @@ int E_(OpenVideoEncoder)( vlc_object_t *p_this ) } #endif - if( i_ff_codec == CODEC_ID_RAWVIDEO ) + if( i_codec_id == CODEC_ID_RAWVIDEO ) { p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->i_fourcc ); } @@ -193,6 +204,8 @@ int E_(OpenVideoEncoder)( vlc_object_t *p_this ) p_sys->i_last_ref_pts = 0; p_sys->i_buggy_pts_detect = 0; + msg_Dbg( p_enc, "found encoder %s", psz_namecodec ); + return VLC_SUCCESS; } @@ -229,7 +242,8 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict ) p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts; /* FIXME, 3-2 pulldown is not handled correctly */ - p_block->i_length = 0;//in->i_length; + p_block->i_length = I64C(1000000) * p_enc->i_frame_rate_base / + p_enc->i_frame_rate; p_block->i_pts = p_sys->p_context->coded_frame->pts; if( !p_sys->p_context->delay || @@ -257,7 +271,8 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict ) { /* Buggy libavcodec which doesn't update coded_frame->pts * correctly */ - p_block->i_length = 0;//in->i_length; + p_block->i_length = I64C(1000000) * p_enc->i_frame_rate_base / + p_enc->i_frame_rate; p_block->i_dts = p_block->i_pts = p_pict->date; } @@ -287,28 +302,34 @@ void E_(CloseVideoEncoder)( vlc_object_t *p_this ) int E_(OpenAudioEncoder)( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; - encoder_sys_t *p_sys = p_enc->p_sys; - AVCodecContext *p_context; + encoder_sys_t *p_sys; + AVCodecContext *p_context; AVCodec *p_codec; - int i_ff_codec; + int i_codec_id, i_cat; + char *psz_namecodec; - i_ff_codec = E_(GetFfmpegCodec)( p_enc->i_fourcc, 0, 0, 0 ); - if( i_ff_codec == 0 ) + if( !E_(GetFfmpegCodec)( p_enc->i_fourcc, &i_cat, &i_codec_id, + &psz_namecodec ) ) { - msg_Err( p_enc, "cannot find encoder id" ); return VLC_EGENERIC; } - p_codec = avcodec_find_encoder( i_ff_codec ); - if( !p_codec ) + if( i_cat != AUDIO_ES ) { - msg_Err( p_enc, "cannot find encoder (avcodec)" ); + msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec ); return VLC_EGENERIC; } - /* libavcodec needs to be initialized */ + /* Initialization must be done before avcodec_find_decoder() */ E_(InitLibavcodec)(p_this); + p_codec = avcodec_find_encoder( i_codec_id ); + if( !p_codec ) + { + msg_Err( p_enc, "cannot find encoder %s", psz_namecodec ); + return VLC_EGENERIC; + } + /* Allocate the memory needed to store the decoder's structure */ if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL ) { @@ -333,18 +354,13 @@ int E_(OpenAudioEncoder)( vlc_object_t *p_this ) p_context->extradata = NULL; p_context->flags |= CODEC_FLAG_GLOBAL_HEADER; - p_sys->i_samples_delay = 0; - p_sys->i_last_block_size = 0; - p_sys->i_pts = 0; - - if( avcodec_open( p_context, p_sys->p_codec ) ) + if( avcodec_open( p_context, p_codec ) < 0 ) { -#if 0 if( p_context->channels > 2 ) { p_context->channels = 2; - id->f_dst.i_channels = 2; - if( avcodec_open( id->ff_enc_c, id->ff_enc ) ) + //id->f_dst.i_channels = 2; + if( avcodec_open( p_context, p_codec ) < 0 ) { msg_Err( p_enc, "cannot open encoder" ); return VLC_EGENERIC; @@ -356,26 +372,24 @@ int E_(OpenAudioEncoder)( vlc_object_t *p_this ) msg_Err( p_enc, "cannot open encoder" ); return VLC_EGENERIC; } -#endif } p_enc->i_extra_data = p_context->extradata_size; p_enc->p_extra_data = p_context->extradata; p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER; - p_sys->p_buffer = malloc( p_context->frame_size * 2 * - p_context->channels * 2 ); - + p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels; + p_sys->p_buffer = malloc( p_sys->i_frame_size ); p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE ); - p_sys->i_frame_size = p_sys->p_context->frame_size * 2 * - p_context->channels; + msg_Warn( p_enc, "avcodec_setup_audio: %d %d %d %d", + p_context->frame_size, p_context->bit_rate, p_context->channels, + p_context->sample_rate ); - /* Hack for mp3 transcoding support */ - if( p_enc->i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) ) - { - p_enc->i_fourcc = VLC_FOURCC( 'm','p','g','a' ); - } + p_sys->i_samples_delay = 0; + p_sys->i_pts = 0; + + msg_Dbg( p_enc, "found encoder %s", psz_namecodec ); return VLC_SUCCESS; } @@ -387,6 +401,7 @@ static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) { encoder_sys_t *p_sys = p_enc->p_sys; block_t *p_block, *p_chain = NULL; + char *p_buffer = p_aout_buf->p_buffer; int i_samples = p_aout_buf->i_nb_samples; int i_samples_delay = p_sys->i_samples_delay; @@ -412,7 +427,7 @@ static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) p_samples = (int16_t *)p_sys->p_buffer; memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size ); p_buffer -= i_delay_size; - i_samples += i_samples_delay; + i_samples += i_samples_delay; i_samples_delay = 0; } else @@ -423,14 +438,17 @@ static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) i_out = avcodec_encode_audio( p_sys->p_context, p_sys->p_buffer_out, 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE, p_samples ); - if( i_out <= 0 ) - { - break; - } + +#if 0 + msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out ); +#endif + if( i_out < 0 ) break; p_buffer += p_sys->i_frame_size; p_sys->i_samples_delay -= p_sys->p_context->frame_size; - i_samples = p_sys->p_context->frame_size; + i_samples -= p_sys->p_context->frame_size; + + if( i_out == 0 ) continue; p_block = block_New( p_enc, i_out ); memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out ); @@ -447,7 +465,7 @@ static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) } /* Backup the remaining raw samples */ - if( p_sys->i_samples_delay > 0 ) + if( i_samples ) { memcpy( p_sys->p_buffer, p_buffer + i_samples_delay, i_samples * 2 * p_sys->p_context->channels ); diff --git a/modules/codec/ffmpeg/ffmpeg.c b/modules/codec/ffmpeg/ffmpeg.c index 19a7a0ab56..81199574db 100644 --- a/modules/codec/ffmpeg/ffmpeg.c +++ b/modules/codec/ffmpeg/ffmpeg.c @@ -2,7 +2,7 @@ * ffmpeg.c: video decoder using ffmpeg library ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: ffmpeg.c,v 1.55 2003/10/27 01:04:38 gbazin Exp $ + * $Id: ffmpeg.c,v 1.56 2003/10/27 17:50:54 gbazin Exp $ * * Authors: Laurent Aimar * Gildas Bazin @@ -136,10 +136,21 @@ vlc_module_end(); static int OpenDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*) p_this; - int i_cat; + int i_cat, i_codec_id; + char *psz_namecodec; + + if( !E_(GetFfmpegCodec)( p_dec->p_fifo->i_fourcc, &i_cat, &i_codec_id, + &psz_namecodec ) ) + { + return VLC_EGENERIC; + } - if( !E_(GetFfmpegCodec)( p_dec->p_fifo->i_fourcc, &i_cat, NULL, NULL ) ) + /* Initialization must be done before avcodec_find_decoder() */ + E_(InitLibavcodec)(p_this); + + if( !avcodec_find_decoder( i_codec_id ) ) { + msg_Err( p_dec, "codec not found (%s)", psz_namecodec ); return VLC_EGENERIC; } @@ -160,8 +171,6 @@ static int InitDecoder( decoder_t *p_dec ) AVCodecContext *p_context; AVCodec *p_codec; - E_(InitLibavcodec)( VLC_OBJECT(p_dec->p_fifo) ); - /* *** determine codec type *** */ E_(GetFfmpegCodec)( p_dec->p_fifo->i_fourcc, &i_cat, &i_codec_id, &psz_namecodec ); @@ -620,6 +629,13 @@ int E_(GetFfmpegCodec)( vlc_fourcc_t i_fourcc, int *pi_cat, psz_name = "A52 Audio (aka AC3)"; break; + /* AAC audio */ + case VLC_FOURCC('m','p','4','a'): + i_cat = AUDIO_ES; + i_codec = CODEC_ID_AAC; + psz_name = "MPEG AAC Audio"; + break; + default: i_cat = UNKNOWN_ES; i_codec = CODEC_ID_NONE; @@ -632,10 +648,10 @@ int E_(GetFfmpegCodec)( vlc_fourcc_t i_fourcc, int *pi_cat, if( pi_cat ) *pi_cat = i_cat; if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec; if( ppsz_name ) *ppsz_name = psz_name; - return( VLC_TRUE ); + return VLC_TRUE; } - return( VLC_FALSE ); + return VLC_FALSE; } int E_(GetFfmpegChroma)( vlc_fourcc_t i_chroma ) diff --git a/modules/codec/vorbis.c b/modules/codec/vorbis.c index 34da93bf1f..417694817b 100644 --- a/modules/codec/vorbis.c +++ b/modules/codec/vorbis.c @@ -1,8 +1,8 @@ /***************************************************************************** - * vorbis.c: vorbis decoder module making use of libvorbis. + * vorbis.c: vorbis decoder/encoder/packetizer module making use of libvorbis. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: vorbis.c,v 1.20 2003/10/27 01:04:38 gbazin Exp $ + * $Id: vorbis.c,v 1.21 2003/10/27 17:50:54 gbazin Exp $ * * Authors: Gildas Bazin * @@ -630,6 +630,7 @@ struct encoder_sys_t int i_last_block_size; int i_samples_delay; + int i_channels; /* * Packetizer output properties @@ -649,7 +650,7 @@ struct encoder_sys_t static int OpenEncoder( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; - encoder_sys_t *p_sys = p_enc->p_sys; + encoder_sys_t *p_sys; if( p_enc->i_fourcc != VLC_FOURCC('v','o','r','b') ) { @@ -685,6 +686,7 @@ static int OpenEncoder( vlc_object_t *p_this ) vorbis_analysis_init( &p_sys->vd, &p_sys->vi ); vorbis_block_init( &p_sys->vd, &p_sys->vb ); + p_sys->i_channels = aout_FormatNbChannels( &p_enc->format.audio ); p_sys->i_last_block_size = 0; p_sys->i_samples_delay = 0; p_sys->i_headers = 0; @@ -701,7 +703,7 @@ static int OpenEncoder( vlc_object_t *p_this ) static block_t *Headers( encoder_t *p_enc ) { encoder_sys_t *p_sys = p_enc->p_sys; - block_t *p_block, **pp_block = NULL; + block_t *p_block, *p_chain = NULL; /* Create theora headers */ if( !p_sys->i_headers ) @@ -718,14 +720,12 @@ static block_t *Headers( encoder_t *p_enc ) p_block->i_dts = p_block->i_pts = p_block->i_length = 0; - block_ChainAppend( pp_block, p_block ); + block_ChainAppend( &p_chain, p_block ); } p_sys->i_headers = 3; - - return *pp_block; } - return NULL; + return p_chain; } /**************************************************************************** @@ -739,16 +739,15 @@ static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) ogg_packet oggpacket; block_t *p_block, *p_chain = NULL; float **buffer; - int i_samples; + int i, j; p_sys->i_pts = p_aout_buf->start_date - (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay / (mtime_t)p_enc->format.audio.i_rate; - i_samples = p_aout_buf->i_nb_samples; - p_sys->i_samples_delay += i_samples; + p_sys->i_samples_delay += p_aout_buf->i_nb_samples; - buffer = vorbis_analysis_buffer( &p_sys->vd, i_samples ); + buffer = vorbis_analysis_buffer( &p_sys->vd, p_aout_buf->i_nb_samples ); #if 0 if( id->ff_dec_c->channels != id->ff_enc_c->channels ) @@ -765,22 +764,24 @@ static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) } } } +#endif /* convert samples to float and uninterleave */ - for( i = 0; i < id->f_dst.i_channels; i++ ) + for( i = 0; i < p_sys->i_channels; i++ ) { - for( j = 0 ; j < i_samples ; j++ ) + for( j = 0 ; j < p_aout_buf->i_nb_samples ; j++ ) { - buffer[i][j]= ((float)( ((int16_t *)id->p_buffer) - [j*id->f_src.i_channels + i ] ))/ 32768.f; + buffer[i][j]= ((float)( ((int16_t *)p_aout_buf->p_buffer ) + [j * p_sys->i_channels + i ] )) / 32768.f; } } -#endif - vorbis_analysis_wrote( &p_sys->vd, i_samples ); + vorbis_analysis_wrote( &p_sys->vd, p_aout_buf->i_nb_samples ); while( vorbis_analysis_blockout( &p_sys->vd, &p_sys->vb ) == 1 ) { + int i_samples; + vorbis_analysis( &p_sys->vb, NULL ); vorbis_bitrate_addblock( &p_sys->vb ); diff --git a/modules/stream_out/transcode.c b/modules/stream_out/transcode.c index 9b24835a5b..3a868af1fa 100644 --- a/modules/stream_out/transcode.c +++ b/modules/stream_out/transcode.c @@ -2,7 +2,7 @@ * transcode.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: transcode.c,v 1.44 2003/10/27 01:04:38 gbazin Exp $ + * $Id: transcode.c,v 1.45 2003/10/27 17:50:54 gbazin Exp $ * * Authors: Laurent Aimar * Gildas Bazin @@ -334,10 +334,6 @@ struct sout_stream_id_t mtime_t i_dts; mtime_t i_length; - int i_buffer_in; - int i_buffer_in_pos; - uint8_t *p_buffer_in; - int i_buffer; int i_buffer_pos; uint8_t *p_buffer; @@ -652,10 +648,6 @@ static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream, } } - id->i_buffer_in = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE; - id->i_buffer_in_pos = 0; - id->p_buffer_in = malloc( id->i_buffer_in ); - id->i_buffer = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE; id->i_buffer_pos = 0; id->p_buffer = malloc( id->i_buffer ); @@ -680,7 +672,7 @@ static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream, if( !id->p_encoder->p_module ) { vlc_object_destroy( id->p_encoder ); - id->p_encoder = NULL; + id->p_encoder = NULL; } id->b_enc_inited = VLC_FALSE; @@ -688,6 +680,12 @@ static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream, id->f_dst.i_extra_data = id->p_encoder->i_extra_data; id->f_dst.p_extra_data = id->p_encoder->p_extra_data; + /* Hack for mp3 transcoding support */ + if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) ) + { + id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','a' ); + } + return VLC_SUCCESS; } @@ -703,7 +701,6 @@ static void transcode_audio_ffmpeg_close( sout_stream_t *p_stream, module_Unneed( id->p_encoder, id->p_encoder->p_module ); vlc_object_destroy( id->p_encoder ); - free( id->p_buffer_in ); free( id->p_buffer ); } @@ -712,205 +709,159 @@ static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_buffer_t *in, sout_buffer_t **out ) { - vlc_bool_t b_again = VLC_FALSE; aout_buffer_t aout_buf; block_t *p_block; + int i_buffer = in->i_size; + char *p_buffer = in->p_buffer; + id->i_dts = in->i_dts; *out = NULL; - /* gather data into p_buffer_in */ - id->i_dts = in->i_dts - - (mtime_t)1000000 * - (mtime_t)(id->i_buffer_pos / 2 / id->ff_dec_c->channels )/ - (mtime_t)id->ff_dec_c->sample_rate; - - if( id->i_buffer_in_pos + (int)in->i_size > id->i_buffer_in ) + while( i_buffer ) { - /* extend buffer_in */ - id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024; - id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in ); - } - memcpy( &id->p_buffer_in[id->i_buffer_in_pos], - in->p_buffer, in->i_size ); - id->i_buffer_in_pos += in->i_size; + id->i_buffer_pos = 0; - do - { /* decode as much data as possible */ if( id->ff_dec ) { - for( ;; ) - { - int i_buffer_size; - int i_used; + int i_used; - i_used = avcodec_decode_audio( id->ff_dec_c, - (int16_t*)&id->p_buffer, - &i_buffer_size, id->p_buffer_in, - id->i_buffer_in_pos ); + i_used = avcodec_decode_audio( id->ff_dec_c, + (int16_t*)id->p_buffer, &id->i_buffer_pos, + p_buffer, i_buffer ); -#if 0 - msg_Warn( p_stream, "avcodec_decode_audio: %d used on %d", - i_used, id->i_buffer_in_pos ); +#if 1 + msg_Warn( p_stream, "avcodec_decode_audio: %d used on %d", + i_used, i_buffer ); #endif - - id->i_buffer_pos += i_buffer_size; - - if( i_used < 0 ) - { - msg_Warn( p_stream, "error audio decoding"); - id->i_buffer_in_pos = 0; - break; - } - else if( i_used < id->i_buffer_in_pos ) - { - memmove( id->p_buffer_in, - &id->p_buffer_in[i_used], - id->i_buffer_in - i_used ); - id->i_buffer_in_pos -= i_used; - } - else - { - id->i_buffer_in_pos = 0; - break; - } - - if( id->i_buffer_pos >= AVCODEC_MAX_AUDIO_FRAME_SIZE ) - { - /* buffer full */ - b_again = VLC_TRUE; - break; - } + if( i_used < 0 ) + { + msg_Warn( p_stream, "error audio decoding"); + break; } + + i_buffer -= i_used; + p_buffer += i_used; } else { - int16_t *sout = (int16_t*)&id->p_buffer[id->i_buffer_pos]; - int i_used = 0; + int16_t *sout = (int16_t*)id->p_buffer; - if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) ) - { - int8_t *sin = (int8_t*)id->p_buffer_in; - int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) - / 2, id->i_buffer_in_pos ); - i_used = i_samples; - while( i_samples > 0 ) - { - *sout++ = ( *sin++ ) << 8; - i_samples--; - } - } - else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) ) + if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) || + id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) ) { - int8_t *sin = (int8_t*)id->p_buffer_in; - int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) - / 2, id->i_buffer_in_pos ); - i_used = i_samples; - while( i_samples > 0 ) - { - *sout++ = ( *sin++ - 128 ) << 8; - i_samples--; - } + int8_t *sin = (int8_t*)p_buffer; + int i_used = __MIN( id->i_buffer/2, i_buffer ); + int i_samples = i_used; + + if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) ) + while( i_samples > 0 ) + { + *sout++ = ( *sin++ ) << 8; + i_samples--; + } + else + while( i_samples > 0 ) + { + *sout++ = ( *sin++ - 128 ) << 8; + i_samples--; + } + + i_buffer -= i_used; + p_buffer += i_used; + id->i_buffer_pos = i_used * 2; } - else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) ) + else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) || + id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) ) { - int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) - / 2, id->i_buffer_in_pos / 2); -#ifdef WORDS_BIGENDIAN - uint8_t *sin = (uint8_t*)id->p_buffer_in; - i_used = i_samples * 2; - while( i_samples > 0 ) - { - uint8_t tmp[2]; - - tmp[1] = *sin++; - tmp[0] = *sin++; - *sout++ = *(int16_t*)tmp; - i_samples--; - } + int16_t *sin = (int16_t*)p_buffer; + int i_used = __MIN( id->i_buffer, i_buffer ); + int i_samples = i_used / 2; + int b_invert_indianness; + if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) ) +#ifdef WORDS_BIGENDIAN + b_invert_indianness = 1; #else - memcpy( sout, id->p_buffer_in, i_samples * 2 ); - sout += i_samples; - i_used = i_samples * 2; + b_invert_indianness = 0; #endif - } - else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) ) - { - int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) - / 2, id->i_buffer_in_pos / 2); + else #ifdef WORDS_BIGENDIAN - memcpy( sout, id->p_buffer_in, i_samples * 2 ); - sout += i_samples; - i_used = i_samples * 2; + b_invert_indianness = 0; #else - uint8_t *sin = (uint8_t*)id->p_buffer_in; - i_used = i_samples * 2; - while( i_samples > 0 ) - { - uint8_t tmp[2]; + b_invert_indianness = 1; +#endif - tmp[1] = *sin++; - tmp[0] = *sin++; - *sout++ = *(int16_t*)tmp; - i_samples--; + if( b_invert_indianness ) + { + while( i_samples > 0 ) + { + uint8_t tmp[2]; + + tmp[1] = *sin++; + tmp[0] = *sin++; + *sout++ = *(int16_t*)tmp; + i_samples--; + } + } + else + { + memcpy( sout, sin, i_used ); + sout += i_samples; } -#endif - } - id->i_buffer_pos = (uint8_t*)sout - id->p_buffer; - if( i_used < id->i_buffer_in_pos ) - { - memmove( id->p_buffer_in, - &id->p_buffer_in[i_used], - id->i_buffer_in - i_used ); + i_buffer -= i_used; + p_buffer += i_used; + id->i_buffer_pos = i_used; } - id->i_buffer_in_pos -= i_used; } if( id->i_buffer_pos == 0 ) continue; /* Encode as much data as possible */ - if( id->b_enc_inited ) - { - while( id->p_encoder->pf_header && - (p_block = id->p_encoder->pf_header( id->p_encoder )) ) - { - sout_buffer_t *p_out; - p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer ); - memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer); - p_out->i_dts = in->i_dts; - p_out->i_pts = in->i_dts; - sout_BufferChain( out, p_out ); - } + if( !id->b_enc_inited && id->p_encoder->pf_header ) + { + p_block = id->p_encoder->pf_header( id->p_encoder ); + while( p_block ) + { + sout_buffer_t *p_out; + block_t *p_prev_block = p_block; + + p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer ); + memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer); + p_out->i_dts = p_out->i_pts = in->i_dts; + p_out->i_length = 0; + sout_BufferChain( out, p_out ); + + p_block = p_block->p_next; + block_Release( p_prev_block ); + } id->b_enc_inited = VLC_TRUE; - } + } aout_buf.p_buffer = id->p_buffer; aout_buf.i_nb_bytes = id->i_buffer_pos; - aout_buf.i_nb_samples = id->i_buffer_pos / 2 / id->ff_dec_c->channels; + aout_buf.i_nb_samples = id->i_buffer_pos / 2 / id->f_src.i_channels; aout_buf.start_date = id->i_dts; aout_buf.end_date = id->i_dts; - p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf ); - while( p_block ) - { - sout_buffer_t *p_out; - block_t *p_prev_block = p_block; - - p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer ); - memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer); - p_out->i_dts = p_block->i_dts; - p_out->i_pts = p_block->i_pts; - p_out->i_length = p_block->i_length; - sout_BufferChain( out, p_out ); - - p_block = p_block->p_next; - block_Release( p_prev_block ); - } - id->i_buffer_pos = 0; - - } while( b_again ); + p_block = id->p_encoder->pf_encode_audio( id->p_encoder, &aout_buf ); + while( p_block ) + { + sout_buffer_t *p_out; + block_t *p_prev_block = p_block; + + p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer ); + memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer); + p_out->i_dts = p_block->i_dts; + p_out->i_pts = p_block->i_pts; + p_out->i_length = p_block->i_length; + sout_BufferChain( out, p_out ); + + p_block = p_block->p_next; + block_Release( p_prev_block ); + } + } return VLC_SUCCESS; } @@ -1013,12 +964,12 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream, if( id->p_encoder->format.video.i_width <= 0 ) { id->p_encoder->format.video.i_width = id->f_dst.i_width = - id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right; + id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right; } if( id->p_encoder->format.video.i_height <= 0 ) { id->p_encoder->format.video.i_height = id->f_dst.i_height = - id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom; + id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom; } id->p_ff_pic = avcodec_alloc_frame(); @@ -1064,7 +1015,7 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream, } static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, - sout_stream_id_t *id ) + sout_stream_id_t *id ) { /* Close decoder */ if( id->ff_dec ) @@ -1189,21 +1140,28 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, id->p_encoder->i_extra_data = 0; id->p_encoder->p_extra_data = NULL; - id->p_encoder->p_module = - module_Need( id->p_encoder, "video encoder", NULL ); - if( !id->p_encoder->p_module ) - { - vlc_object_destroy( id->p_encoder ); - msg_Err( p_stream, "cannot find encoder" ); - return VLC_EGENERIC; - } + id->p_encoder->p_module = + module_Need( id->p_encoder, "video encoder", NULL ); + if( !id->p_encoder->p_module ) + { + vlc_object_destroy( id->p_encoder ); + msg_Err( p_stream, "cannot find encoder" ); + return VLC_EGENERIC; + } id->f_dst.i_extra_data = id->p_encoder->i_extra_data; id->f_dst.p_extra_data = id->p_encoder->p_extra_data; + /* Hack for mp2v/mp1v transcoding support */ + if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' ) || + id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','2','v' ) ) + { + id->f_dst.i_fourcc = VLC_FOURCC( 'm','p','g','v' ); + } + if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, - &id->f_dst ) ) ) + &id->f_dst ) ) ) { msg_Err( p_stream, "cannot add this stream" ); transcode_video_ffmpeg_close( p_stream, id ); @@ -1212,7 +1170,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, } while( id->p_encoder->pf_header && - (p_block = id->p_encoder->pf_header( id->p_encoder )) ) + (p_block = id->p_encoder->pf_header( id->p_encoder )) ) { sout_buffer_t *p_out; p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer ); @@ -1331,41 +1289,41 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, id->ff_dec_c->frame_rate_base / (2 * id->ff_dec_c->frame_rate); } - /* Encoding */ - block_t *p_block; - picture_t pic; - int i_plane; - - vout_InitPicture( VLC_OBJECT(p_stream), &pic, - id->p_encoder->format.video.i_chroma, - id->f_dst.i_width, id->f_dst.i_height, - id->f_dst.i_width * VOUT_ASPECT_FACTOR / - id->f_dst.i_height ); - - for( i_plane = 0; i_plane < pic.i_planes; i_plane++ ) - { - pic.p[i_plane].p_pixels = frame->data[i_plane]; - pic.p[i_plane].i_pitch = frame->linesize[i_plane]; - } - - pic.date = frame->pts; - - p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic ); - while( p_block ) - { - sout_buffer_t *p_out; - block_t *p_prev_block = p_block; - - p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer ); - memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer); - p_out->i_dts = p_block->i_dts; - p_out->i_pts = p_block->i_pts; - p_out->i_length = p_block->i_length; - sout_BufferChain( out, p_out ); - - p_block = p_block->p_next; - block_Release( p_prev_block ); - } + /* Encoding */ + block_t *p_block; + picture_t pic; + int i_plane; + + vout_InitPicture( VLC_OBJECT(p_stream), &pic, + id->p_encoder->format.video.i_chroma, + id->f_dst.i_width, id->f_dst.i_height, + id->f_dst.i_width * VOUT_ASPECT_FACTOR / + id->f_dst.i_height ); + + for( i_plane = 0; i_plane < pic.i_planes; i_plane++ ) + { + pic.p[i_plane].p_pixels = frame->data[i_plane]; + pic.p[i_plane].i_pitch = frame->linesize[i_plane]; + } + + pic.date = frame->pts; + + p_block = id->p_encoder->pf_encode_video( id->p_encoder, &pic ); + while( p_block ) + { + sout_buffer_t *p_out; + block_t *p_prev_block = p_block; + + p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer ); + memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer); + p_out->i_dts = p_block->i_dts; + p_out->i_pts = p_block->i_pts; + p_out->i_length = p_block->i_length; + sout_BufferChain( out, p_out ); + + p_block = p_block->p_next; + block_Release( p_prev_block ); + } if( i_data <= 0 ) { -- 2.39.5