X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Ftwolame.c;h=79c64b7ebe6da2ca18805dc4ef43f434596cbbb4;hb=a9ac943471c67fb3416f21246e389decda12cc38;hp=6a3f33e890ce6a1f48cb8a10212d124fa0818ce7;hpb=89b6530d8abd99b96b9f33af022022241fe97ee2;p=vlc diff --git a/modules/codec/twolame.c b/modules/codec/twolame.c index 6a3f33e890..79c64b7ebe 100644 --- a/modules/codec/twolame.c +++ b/modules/codec/twolame.c @@ -1,25 +1,26 @@ /***************************************************************************** * twolame.c: libtwolame encoder (MPEG-1/2 layer II) module - * (using libtwolame from http://users.tpg.com.au/adslblvi/) + * (using libtwolame from http://www.twolame.org/) ***************************************************************************** - * Copyright (C) 2004-2005 the VideoLAN team + * Copyright (C) 2004-2005 VLC authors and VideoLAN * $Id$ * * Authors: Christophe Massiot + * Gildas Bazin * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -32,8 +33,6 @@ #include #include #include -#include -#include #include @@ -45,7 +44,7 @@ ****************************************************************************/ static int OpenEncoder ( vlc_object_t * ); static void CloseEncoder ( vlc_object_t * ); -static block_t *Encode ( encoder_t *, aout_buffer_t * ); +static block_t *Encode ( encoder_t *, block_t * ); /***************************************************************************** * Module descriptor @@ -74,19 +73,19 @@ static const char *const ppsz_stereo_descriptions[] = vlc_module_begin () set_shortname( "Twolame") set_description( N_("Libtwolame audio encoder") ) - set_capability( "encoder", 50 ) + set_capability( "encoder", 120 ) set_callbacks( OpenEncoder, CloseEncoder ) set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_ACODEC ) - add_float( ENC_CFG_PREFIX "quality", 0.0, NULL, ENC_QUALITY_TEXT, + add_float( ENC_CFG_PREFIX "quality", 0.0, ENC_QUALITY_TEXT, ENC_QUALITY_LONGTEXT, false ) - add_integer( ENC_CFG_PREFIX "mode", 0, NULL, ENC_MODE_TEXT, + add_integer( ENC_CFG_PREFIX "mode", 0, ENC_MODE_TEXT, ENC_MODE_LONGTEXT, false ) - change_integer_list( pi_stereo_values, ppsz_stereo_descriptions, NULL ); - add_bool( ENC_CFG_PREFIX "vbr", 0, NULL, ENC_VBR_TEXT, + change_integer_list( pi_stereo_values, ppsz_stereo_descriptions ); + add_bool( ENC_CFG_PREFIX "vbr", false, ENC_VBR_TEXT, ENC_VBR_LONGTEXT, false ) - add_integer( ENC_CFG_PREFIX "psy", 3, NULL, ENC_PSY_TEXT, + add_integer( ENC_CFG_PREFIX "psy", 3, ENC_PSY_TEXT, ENC_PSY_LONGTEXT, false ) vlc_module_end () @@ -129,12 +128,11 @@ static int OpenEncoder( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; - vlc_value_t val; int i_frequency; - if( p_enc->fmt_out.i_codec != VLC_CODEC_MPGA && - p_enc->fmt_out.i_codec != VLC_FOURCC('m','p','2','a') && - p_enc->fmt_out.i_codec != VLC_FOURCC('m','p','2',' ') && + if( p_enc->fmt_out.i_codec != VLC_CODEC_MP2 && + p_enc->fmt_out.i_codec != VLC_CODEC_MPGA && + p_enc->fmt_out.i_codec != VLC_FOURCC( 'm', 'p', '2', 'a' ) && !p_enc->b_force ) { return VLC_EGENERIC; @@ -163,7 +161,6 @@ static int OpenEncoder( vlc_object_t *p_this ) return VLC_ENOMEM; p_enc->p_sys = p_sys; - p_enc->pf_encode_audio = Encode; p_enc->fmt_in.i_codec = VLC_CODEC_S16N; p_enc->fmt_out.i_cat = AUDIO_ES; @@ -177,16 +174,13 @@ static int OpenEncoder( vlc_object_t *p_this ) twolame_set_in_samplerate( p_sys->p_twolame, p_enc->fmt_out.audio.i_rate ); twolame_set_out_samplerate( p_sys->p_twolame, p_enc->fmt_out.audio.i_rate ); - var_Get( p_enc, ENC_CFG_PREFIX "vbr", &val ); - if ( val.b_bool ) + if( var_GetBool( p_enc, ENC_CFG_PREFIX "vbr" ) ) { - float i_quality; - var_Get( p_enc, ENC_CFG_PREFIX "quality", &val ); - i_quality = val.i_int; - if ( i_quality > 50.0 ) i_quality = 50.0; - if ( i_quality < 0.0 ) i_quality = 0.0; + float f_quality = var_GetFloat( p_enc, ENC_CFG_PREFIX "quality" ); + if ( f_quality > 50.f ) f_quality = 50.f; + if ( f_quality < 0.f ) f_quality = 0.f; twolame_set_VBR( p_sys->p_twolame, 1 ); - twolame_set_VBR_q( p_sys->p_twolame, i_quality ); + twolame_set_VBR_q( p_sys->p_twolame, f_quality ); } else { @@ -219,8 +213,7 @@ static int OpenEncoder( vlc_object_t *p_this ) else { twolame_set_num_channels( p_sys->p_twolame, 2 ); - var_Get( p_enc, ENC_CFG_PREFIX "mode", &val ); - switch ( val.i_int ) + switch( var_GetInteger( p_enc, ENC_CFG_PREFIX "mode" ) ) { case 1: twolame_set_mode( p_sys->p_twolame, TWOLAME_DUAL_CHANNEL ); @@ -235,8 +228,8 @@ static int OpenEncoder( vlc_object_t *p_this ) } } - var_Get( p_enc, ENC_CFG_PREFIX "psy", &val ); - twolame_set_psymodel( p_sys->p_twolame, val.i_int ); + twolame_set_psymodel( p_sys->p_twolame, + var_GetInteger( p_enc, ENC_CFG_PREFIX "psy" ) ); if ( twolame_init_params( p_sys->p_twolame ) ) { @@ -244,6 +237,8 @@ static int OpenEncoder( vlc_object_t *p_this ) return -VLC_EGENERIC; } + p_enc->pf_encode_audio = Encode; + p_sys->i_nb_samples = 0; return VLC_SUCCESS; @@ -256,22 +251,56 @@ static int OpenEncoder( vlc_object_t *p_this ) ****************************************************************************/ static void Bufferize( encoder_t *p_enc, int16_t *p_in, int i_nb_samples ) { - int16_t *p_buffer = p_enc->p_sys->p_buffer - + (p_enc->p_sys->i_nb_samples - * p_enc->fmt_in.audio.i_channels); + encoder_sys_t *p_sys = p_enc->p_sys; + const unsigned i_offset = p_sys->i_nb_samples * p_enc->fmt_in.audio.i_channels; + const unsigned i_len = ARRAY_SIZE(p_sys->p_buffer); + + if( i_offset >= i_len ) + { + msg_Err( p_enc, "buffer full" ); + return; + } - memcpy( p_buffer, p_in, i_nb_samples * p_enc->fmt_in.audio.i_channels - * sizeof(int16_t) ); + unsigned i_copy = i_nb_samples * p_enc->fmt_in.audio.i_channels; + if( i_copy + i_offset > i_len) + { + msg_Err( p_enc, "dropping samples" ); + i_copy = i_len - i_offset; + } + + memcpy( p_sys->p_buffer + i_offset, p_in, i_copy * sizeof(int16_t) ); } -static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) +static block_t *Encode( encoder_t *p_enc, block_t *p_aout_buf ) { encoder_sys_t *p_sys = p_enc->p_sys; + block_t *p_chain = NULL; + + if( unlikely( !p_aout_buf ) ) { + int i_used = 0; + block_t *p_block; + + i_used = twolame_encode_flush( p_sys->p_twolame, + p_sys->p_out_buffer, MAX_CODED_FRAME_SIZE ); + if( i_used <= 0 ) + return NULL; + + p_block = block_Alloc( i_used ); + if( !p_block ) + return NULL; + memcpy( p_block->p_buffer, p_sys->p_out_buffer, i_used ); + p_block->i_length = CLOCK_FREQ * + (mtime_t)MPEG_FRAME_SIZE / (mtime_t)p_enc->fmt_out.audio.i_rate; + p_block->i_dts = p_block->i_pts = p_sys->i_pts; + p_sys->i_pts += p_block->i_length; + + return p_block; + } + int16_t *p_buffer = (int16_t *)p_aout_buf->p_buffer; int i_nb_samples = p_aout_buf->i_nb_samples; - block_t *p_chain = NULL; - p_sys->i_pts = p_aout_buf->start_date - + p_sys->i_pts = p_aout_buf->i_pts - (mtime_t)1000000 * (mtime_t)p_sys->i_nb_samples / (mtime_t)p_enc->fmt_out.audio.i_rate; @@ -287,10 +316,23 @@ static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) i_used = twolame_encode_buffer_interleaved( p_sys->p_twolame, p_sys->p_buffer, MPEG_FRAME_SIZE, p_sys->p_out_buffer, MAX_CODED_FRAME_SIZE ); + /* On error, buffer samples and return what was already encoded */ + if( i_used < 0 ) + { + msg_Err( p_enc, "encoder error: %d", i_used ); + break; + } + p_sys->i_nb_samples = 0; - p_block = block_New( p_enc, i_used ); - vlc_memcpy( p_block->p_buffer, p_sys->p_out_buffer, i_used ); - p_block->i_length = (mtime_t)1000000 * + p_block = block_Alloc( i_used ); + if( !p_block ) + { + if( p_chain ) + block_ChainRelease( p_chain ); + return NULL; + } + memcpy( p_block->p_buffer, p_sys->p_out_buffer, i_used ); + p_block->i_length = CLOCK_FREQ * (mtime_t)MPEG_FRAME_SIZE / (mtime_t)p_enc->fmt_out.audio.i_rate; p_block->i_dts = p_block->i_pts = p_sys->i_pts; p_sys->i_pts += p_block->i_length;