X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fvorbis.c;h=c7e2b82eec3237b4db3c85a3da22b48f5d2b4200;hb=298f3d05b5dc4a0aa464dc9df1ff5f30b9021d3a;hp=cfaebf331d54e1292d370bea7f27541869318450;hpb=b3e29297c8c5525e1da4ba3efedee686c3c6d785;p=vlc diff --git a/modules/codec/vorbis.c b/modules/codec/vorbis.c index cfaebf331d..c7e2b82eec 100644 --- a/modules/codec/vorbis.c +++ b/modules/codec/vorbis.c @@ -1,7 +1,7 @@ /***************************************************************************** * vorbis.c: vorbis decoder/encoder/packetizer module using of libvorbis. ***************************************************************************** - * Copyright (C) 2001-2003 the VideoLAN team + * Copyright (C) 2001-2012 the VideoLAN team * Copyright (C) 2007 Société des arts technologiques * Copyright (C) 2007 Savoir-faire Linux * @@ -42,15 +42,20 @@ #include #ifdef MODULE_NAME_IS_tremor -#include +# include +# define INTERLEAVE_TYPE int32_t #else -#include +# include +# define INTERLEAVE_TYPE float -# ifndef OV_ECTL_RATEMANAGE_AVG +# ifdef ENABLE_SOUT +# define HAVE_VORBIS_ENCODER +# include +# ifndef OV_ECTL_RATEMANAGE_AVG # define OV_ECTL_RATEMANAGE_AVG 0x0 +# endif # endif - #endif /***************************************************************************** @@ -99,17 +104,29 @@ static const int pi_channels_maps[9] = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER - | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT - | AOUT_CHAN_MIDDLERIGHT, + | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT + | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT - | AOUT_CHAN_LFE + | AOUT_CHAN_LFE, }; /* -** channel order as defined in http://www.ogghelp.com/ogg/glossary.cfm#Audio_Channels +** channel order as defined in http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */ +/* recommended vorbis channel order for 8 channels */ +static const uint32_t pi_8channels_in[] = +{ AOUT_CHAN_LEFT, AOUT_CHAN_CENTER, AOUT_CHAN_RIGHT, + AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, + AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,AOUT_CHAN_LFE,0 }; + +/* recommended vorbis channel order for 7 channels */ +static const uint32_t pi_7channels_in[] = +{ AOUT_CHAN_LEFT, AOUT_CHAN_CENTER, AOUT_CHAN_RIGHT, + AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, + AOUT_CHAN_REARCENTER,AOUT_CHAN_LFE,0 }; + /* recommended vorbis channel order for 6 channels */ static const uint32_t pi_6channels_in[] = { AOUT_CHAN_LEFT, AOUT_CHAN_CENTER, AOUT_CHAN_RIGHT, @@ -117,7 +134,7 @@ static const uint32_t pi_6channels_in[] = /* recommended vorbis channel order for 4 channels */ static const uint32_t pi_4channels_in[] = -{ AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER, AOUT_CHAN_LFE, 0 }; +{ AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 }; /* recommended vorbis channel order for 3 channels */ static const uint32_t pi_3channels_in[] = @@ -129,7 +146,7 @@ static const uint32_t pi_3channels_in[] = static int OpenDecoder ( vlc_object_t * ); static int OpenPacketizer( vlc_object_t * ); static void CloseDecoder ( vlc_object_t * ); -static void *DecodeBlock ( decoder_t *, block_t ** ); +static block_t *DecodeBlock ( decoder_t *, block_t ** ); static int ProcessHeaders( decoder_t * ); static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** ); @@ -141,13 +158,7 @@ static void ParseVorbisComments( decoder_t * ); static void ConfigureChannelOrder(int *, int, uint32_t, bool ); -#ifdef MODULE_NAME_IS_tremor -static void Interleave ( int32_t *, const int32_t **, int, int, int * ); -#else -static void Interleave ( float *, const float **, int, int, int * ); -#endif - -#ifndef MODULE_NAME_IS_tremor +#ifdef HAVE_VORBIS_ENCODER static int OpenEncoder ( vlc_object_t * ); static void CloseEncoder ( vlc_object_t * ); static block_t *Encode ( encoder_t *, aout_buffer_t * ); @@ -187,27 +198,27 @@ vlc_module_begin () set_capability( "packetizer", 100 ) set_callbacks( OpenPacketizer, CloseDecoder ) -#ifndef MODULE_NAME_IS_tremor +#ifdef HAVE_VORBIS_ENCODER # define ENC_CFG_PREFIX "sout-vorbis-" add_submodule () set_description( N_("Vorbis audio encoder") ) - set_capability( "encoder", 100 ) + set_capability( "encoder", 130 ) set_callbacks( OpenEncoder, CloseEncoder ) - add_integer( ENC_CFG_PREFIX "quality", 0, NULL, ENC_QUALITY_TEXT, + add_integer( ENC_CFG_PREFIX "quality", 0, ENC_QUALITY_TEXT, ENC_QUALITY_LONGTEXT, false ) change_integer_range( 0, 10 ) - add_integer( ENC_CFG_PREFIX "max-bitrate", 0, NULL, ENC_MAXBR_TEXT, + add_integer( ENC_CFG_PREFIX "max-bitrate", 0, ENC_MAXBR_TEXT, ENC_MAXBR_LONGTEXT, false ) - add_integer( ENC_CFG_PREFIX "min-bitrate", 0, NULL, ENC_MINBR_TEXT, + add_integer( ENC_CFG_PREFIX "min-bitrate", 0, ENC_MINBR_TEXT, ENC_MINBR_LONGTEXT, false ) - add_bool( ENC_CFG_PREFIX "cbr", false, NULL, ENC_CBR_TEXT, + add_bool( ENC_CFG_PREFIX "cbr", false, ENC_CBR_TEXT, ENC_CBR_LONGTEXT, false ) #endif vlc_module_end () -#ifndef MODULE_NAME_IS_tremor +#ifdef HAVE_VORBIS_ENCODER static const char *const ppsz_enc_options[] = { "quality", "max-bitrate", "min-bitrate", "cbr", NULL }; @@ -222,12 +233,11 @@ static int OpenDecoder( vlc_object_t *p_this ) decoder_sys_t *p_sys; if( p_dec->fmt_in.i_codec != VLC_CODEC_VORBIS ) - { return VLC_EGENERIC; - } /* Allocate the memory needed to store the decoder's structure */ - if( ( p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) ) ) == NULL ) + p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) ); + if( unlikely( !p_sys ) ) return VLC_ENOMEM; /* Misc init */ @@ -249,10 +259,8 @@ static int OpenDecoder( vlc_object_t *p_this ) #endif /* Set callbacks */ - p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **)) - DecodeBlock; - p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **)) - DecodeBlock; + p_dec->pf_decode_audio = DecodeBlock; + p_dec->pf_packetize = DecodeBlock; return VLC_SUCCESS; } @@ -277,7 +285,7 @@ static int OpenPacketizer( vlc_object_t *p_this ) **************************************************************************** * This function must be fed with ogg packets. ****************************************************************************/ -static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) +static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; ogg_packet oggpacket; @@ -459,6 +467,21 @@ static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket, } } +/***************************************************************************** + * Interleave: helper function to interleave channels + *****************************************************************************/ +static void Interleave( INTERLEAVE_TYPE *p_out, const INTERLEAVE_TYPE **pp_in, + int i_nb_channels, int i_samples, int *pi_chan_table) +{ + for( int j = 0; j < i_samples; j++ ) + for( int i = 0; i < i_nb_channels; i++ ) + p_out[j * i_nb_channels + pi_chan_table[i]] = pp_in[i][j] +#ifdef MODULE_NAME_IS_tremor + * (FIXED32_ONE >> 24) +#endif + ; +} + /***************************************************************************** * DecodePacket: decodes a Vorbis packet. *****************************************************************************/ @@ -467,18 +490,10 @@ static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket ) decoder_sys_t *p_sys = p_dec->p_sys; int i_samples; -#ifdef MODULE_NAME_IS_tremor - int32_t **pp_pcm; -#else - float **pp_pcm; -#endif + INTERLEAVE_TYPE **pp_pcm; if( p_oggpacket->bytes && -#ifdef MODULE_NAME_IS_tremor - vorbis_synthesis( &p_sys->vb, p_oggpacket, 1 ) == 0 ) -#else vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 ) -#endif vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb ); /* **pp_pcm is a multichannel float vector. In stereo, for @@ -497,13 +512,8 @@ static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket ) if( p_aout_buffer == NULL ) return NULL; /* Interleave the samples */ -#ifdef MODULE_NAME_IS_tremor - Interleave( (int32_t *)p_aout_buffer->p_buffer, - (const int32_t **)pp_pcm, p_sys->vi.channels, i_samples, p_sys->pi_chan_table); -#else - Interleave( (float *)p_aout_buffer->p_buffer, - (const float **)pp_pcm, p_sys->vi.channels, i_samples, p_sys->pi_chan_table); -#endif + Interleave( (INTERLEAVE_TYPE*)p_aout_buffer->p_buffer, + (const INTERLEAVE_TYPE**)pp_pcm, p_sys->vi.channels, i_samples, p_sys->pi_chan_table); /* Tell libvorbis how many samples we actually consumed */ vorbis_synthesis_read( &p_sys->vd, i_samples ); @@ -562,10 +572,9 @@ static void ParseVorbisComments( decoder_t *p_dec ) *psz_value = '\0'; psz_value++; - if( !p_dec->p_description ) - p_dec->p_description = vlc_meta_New(); - if( p_dec->p_description ) - vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value ); + /* Don't add empty values */ + if( *psz_value == '\0' ) + break; if( !strcasecmp( psz_name, "REPLAYGAIN_TRACK_GAIN" ) || !strcasecmp( psz_name, "RG_RADIO" ) ) @@ -598,6 +607,16 @@ static void ParseVorbisComments( decoder_t *p_dec ) r->pb_peak[AUDIO_REPLAY_GAIN_ALBUM] = true; r->pf_peak[AUDIO_REPLAY_GAIN_ALBUM] = atof( psz_value ); } + else if( !strcasecmp( psz_name, "METADATA_BLOCK_PICTURE" ) ) + { /* Do nothing, for now */ } + else + { + if( !p_dec->p_description ) + p_dec->p_description = vlc_meta_New(); + if( p_dec->p_description ) + vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value ); + } + } free( psz_comment ); i++; @@ -605,13 +624,19 @@ static void ParseVorbisComments( decoder_t *p_dec ) } /***************************************************************************** - * Interleave: helper function to interleave channels + * *****************************************************************************/ static void ConfigureChannelOrder(int *pi_chan_table, int i_channels, uint32_t i_channel_mask, bool b_decode) { const uint32_t *pi_channels_in; switch( i_channels ) { + case 8: + pi_channels_in = pi_8channels_in; + break; + case 7: + pi_channels_in = pi_7channels_in; + break; case 6: case 5: pi_channels_in = pi_6channels_in; @@ -635,41 +660,16 @@ static void ConfigureChannelOrder(int *pi_chan_table, int i_channels, uint32_t i if( b_decode ) aout_CheckChannelReorder( pi_channels_in, NULL, - i_channel_mask & AOUT_CHAN_PHYSMASK, + i_channel_mask, i_channels, pi_chan_table ); else aout_CheckChannelReorder( NULL, pi_channels_in, - i_channel_mask & AOUT_CHAN_PHYSMASK, + i_channel_mask, i_channels, pi_chan_table ); } -/***************************************************************************** - * Interleave: helper function to interleave channels - *****************************************************************************/ -#ifdef MODULE_NAME_IS_tremor -static void Interleave( int32_t *p_out, const int32_t **pp_in, - int i_nb_channels, int i_samples, int *pi_chan_table) -{ - int i, j; - - for ( j = 0; j < i_samples; j++ ) - for ( i = 0; i < i_nb_channels; i++ ) - p_out[j * i_nb_channels + pi_chan_table[i]] = pp_in[i][j] * (FIXED32_ONE >> 24); -} -#else -static void Interleave( float *p_out, const float **pp_in, - int i_nb_channels, int i_samples, int *pi_chan_table ) -{ - int i, j; - - for ( j = 0; j < i_samples; j++ ) - for ( i = 0; i < i_nb_channels; i++ ) - p_out[j * i_nb_channels + pi_chan_table[i]] = pp_in[i][j]; -} -#endif - /***************************************************************************** * CloseDecoder: vorbis decoder destruction *****************************************************************************/ @@ -690,8 +690,7 @@ static void CloseDecoder( vlc_object_t *p_this ) free( p_sys ); } -#ifndef MODULE_NAME_IS_tremor - +#ifdef HAVE_VORBIS_ENCODER /***************************************************************************** * encoder_sys_t : vorbis encoder descriptor *****************************************************************************/ @@ -710,7 +709,7 @@ struct encoder_sys_t int i_last_block_size; int i_samples_delay; - int i_channels; + unsigned int i_channels; /* ** Channel reordering @@ -726,9 +725,8 @@ static int OpenEncoder( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; - int i_quality, i_min_bitrate, i_max_bitrate, i; + int i_quality, i_min_bitrate, i_max_bitrate; ogg_packet header[3]; - uint8_t *p_extra; if( p_enc->fmt_out.i_codec != VLC_CODEC_VORBIS && !p_enc->b_force ) @@ -742,7 +740,7 @@ static int OpenEncoder( vlc_object_t *p_this ) p_enc->p_sys = p_sys; p_enc->pf_encode_audio = Encode; - p_enc->fmt_in.i_codec = VLC_CODEC_FL32; + p_enc->fmt_in.i_codec = VLC_CODEC_FL32; p_enc->fmt_out.i_codec = VLC_CODEC_VORBIS; config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg ); @@ -849,8 +847,6 @@ 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; - unsigned int j; mtime_t i_pts = p_aout_buf->i_pts - (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay / @@ -861,9 +857,9 @@ static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) buffer = vorbis_analysis_buffer( &p_sys->vd, p_aout_buf->i_nb_samples ); /* convert samples to float and uninterleave */ - for( i = 0; i < p_sys->i_channels; i++ ) + for( unsigned int i = 0; i < p_sys->i_channels; i++ ) { - for( j = 0 ; j < p_aout_buf->i_nb_samples ; j++ ) + for( unsigned int j = 0 ; j < p_aout_buf->i_nb_samples ; j++ ) { buffer[i][j]= ((float *)p_aout_buf->p_buffer) [j * p_sys->i_channels + p_sys->pi_chan_table[i]]; @@ -923,4 +919,4 @@ static void CloseEncoder( vlc_object_t *p_this ) free( p_sys ); } -#endif /* HAVE_VORBIS_VORBISENC_H && !MODULE_NAME_IS_tremor */ +#endif /* HAVE_VORBIS_ENCODER */