X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fflac.c;h=d7130dc3dec31f2f4f84e6cb52829082a0741573;hb=731c247b2348f81296c623684dff5fa6bb39105e;hp=b1b8e883466078998a41d4e4add5aa037f95ed85;hpb=24eee4b8f2941ab42a9f02bc2c0b80ad4255a2be;p=vlc diff --git a/modules/codec/flac.c b/modules/codec/flac.c index b1b8e88346..d7130dc3de 100644 --- a/modules/codec/flac.c +++ b/modules/codec/flac.c @@ -30,7 +30,8 @@ # include "config.h" #endif -#include +#include +#include #include #include @@ -84,7 +85,7 @@ struct decoder_sys_t } stream_info; #endif - vlc_bool_t b_stream_info; + bool b_stream_info; /* * Common properties @@ -106,7 +107,7 @@ enum { STATE_SEND_DATA }; -static int pi_channels_maps[7] = +static const int pi_channels_maps[7] = { 0, AOUT_CHAN_CENTER, @@ -160,6 +161,8 @@ static void DecoderErrorCallback( const FLAC__StreamDecoder *decoder, static void Interleave32( int32_t *p_out, const int32_t * const *pp_in, int i_nb_channels, int i_samples ); +static void Interleave24( int8_t *p_out, const int32_t * const *pp_in, + int i_nb_channels, int i_samples ); static void Interleave16( int16_t *p_out, const int32_t * const *pp_in, int i_nb_channels, int i_samples ); @@ -173,29 +176,29 @@ static uint8_t flac_crc8( const uint8_t *data, unsigned len ); /***************************************************************************** * Module descriptor *****************************************************************************/ -vlc_module_begin(); +vlc_module_begin () - set_category( CAT_INPUT ); - set_subcategory( SUBCAT_INPUT_ACODEC ); - add_shortcut( "flac" ); + set_category( CAT_INPUT ) + set_subcategory( SUBCAT_INPUT_ACODEC ) + add_shortcut( "flac" ) #ifdef USE_LIBFLAC - set_description( _("Flac audio decoder") ); - set_capability( "decoder", 100 ); - set_callbacks( OpenDecoder, CloseDecoder ); + set_description( N_("Flac audio decoder") ) + set_capability( "decoder", 100 ) + set_callbacks( OpenDecoder, CloseDecoder ) - add_submodule(); - set_description( _("Flac audio encoder") ); - set_capability( "encoder", 100 ); - set_callbacks( OpenEncoder, CloseEncoder ); + add_submodule () + set_description( N_("Flac audio encoder") ) + set_capability( "encoder", 100 ) + set_callbacks( OpenEncoder, CloseEncoder ) - add_submodule(); + add_submodule () #endif - set_description( _("Flac audio packetizer") ); - set_capability( "packetizer", 100 ); - set_callbacks( OpenPacketizer, CloseDecoder ); + set_description( N_("Flac audio packetizer") ) + set_capability( "packetizer", 100 ) + set_callbacks( OpenPacketizer, CloseDecoder ) -vlc_module_end(); +vlc_module_end () /***************************************************************************** * OpenDecoder: probe the decoder and return score @@ -213,15 +216,12 @@ static int OpenDecoder( vlc_object_t *p_this ) /* Allocate the memory needed to store the decoder's structure */ if( ( p_dec->p_sys = p_sys = (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) - { - msg_Err( p_dec, "out of memory" ); return VLC_ENOMEM; - } /* Misc init */ aout_DateSet( &p_sys->end_date, 0 ); p_sys->i_state = STATE_NOSYNC; - p_sys->b_stream_info = VLC_FALSE; + p_sys->b_stream_info = false; p_sys->p_block=NULL; p_sys->bytestream = block_BytestreamInit(); @@ -316,7 +316,7 @@ static void CloseDecoder( vlc_object_t *p_this ) FLAC__stream_decoder_delete( p_sys->p_flac ); #endif - if( p_sys->p_block ) free( p_sys->p_block ); + free( p_sys->p_block ); free( p_sys ); } @@ -388,7 +388,7 @@ static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block ) p_sys->i_state = STATE_NOSYNC; block_BytestreamFlush( &p_sys->bytestream ); } -// aout_DateSet( &p_sys->end_date, 0 ); + aout_DateSet( &p_sys->end_date, 0 ); block_Release( *pp_block ); return NULL; } @@ -410,6 +410,8 @@ static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block ) else if( !aout_DateGet( &p_sys->end_date ) ) { /* The first PTS is as good as anything else. */ + p_sys->i_rate = p_dec->fmt_out.audio.i_rate; + aout_DateInit( &p_sys->end_date, p_sys->i_rate ); aout_DateSet( &p_sys->end_date, (*pp_block)->i_pts ); } @@ -619,7 +621,7 @@ DecoderWriteCallback( const FLAC__StreamDecoder *decoder, decoder_sys_t *p_sys = p_dec->p_sys; p_sys->p_aout_buffer = - p_dec->pf_aout_buffer_new( p_dec, frame->header.blocksize ); + decoder_NewAudioBuffer( p_dec, frame->header.blocksize ); if( p_sys->p_aout_buffer == NULL ) return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; @@ -630,6 +632,10 @@ DecoderWriteCallback( const FLAC__StreamDecoder *decoder, Interleave16( (int16_t *)p_sys->p_aout_buffer->p_buffer, buffer, frame->header.channels, frame->header.blocksize ); break; + case 24: + Interleave24( (int8_t *)p_sys->p_aout_buffer->p_buffer, buffer, + frame->header.channels, frame->header.blocksize ); + break; default: Interleave32( (int32_t *)p_sys->p_aout_buffer->p_buffer, buffer, frame->header.channels, frame->header.blocksize ); @@ -664,6 +670,9 @@ static void DecoderMetadataCallback( const FLAC__StreamDecoder *decoder, case 16: p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE; break; + case 24: + p_dec->fmt_out.i_codec = AOUT_FMT_S24_NE; + break; default: msg_Dbg( p_dec, "strange bit/sample value: %d", metadata->data.stream_info.bits_per_sample ); @@ -687,7 +696,7 @@ static void DecoderMetadataCallback( const FLAC__StreamDecoder *decoder, p_dec->fmt_out.audio.i_channels, p_dec->fmt_out.audio.i_rate, p_dec->fmt_out.audio.i_bitspersample ); - p_sys->b_stream_info = VLC_TRUE; + p_sys->b_stream_info = true; p_sys->stream_info = metadata->data.stream_info; return; @@ -739,6 +748,28 @@ static void Interleave32( int32_t *p_out, const int32_t * const *pp_in, } } } + +static void Interleave24( int8_t *p_out, const int32_t * const *pp_in, + int i_nb_channels, int i_samples ) +{ + int i, j; + for ( j = 0; j < i_samples; j++ ) + { + for ( i = 0; i < i_nb_channels; i++ ) + { +#ifdef WORDS_BIGENDIAN + p_out[3*(j * i_nb_channels + i)+0] = (pp_in[i][j] >> 16) & 0xff; + p_out[3*(j * i_nb_channels + i)+1] = (pp_in[i][j] >> 8 ) & 0xff; + p_out[3*(j * i_nb_channels + i)+2] = (pp_in[i][j] >> 0 ) & 0xff; +#else + p_out[3*(j * i_nb_channels + i)+2] = (pp_in[i][j] >> 16) & 0xff; + p_out[3*(j * i_nb_channels + i)+1] = (pp_in[i][j] >> 8 ) & 0xff; + p_out[3*(j * i_nb_channels + i)+0] = (pp_in[i][j] >> 0 ) & 0xff; +#endif + } + } +} + static void Interleave16( int16_t *p_out, const int32_t * const *pp_in, int i_nb_channels, int i_samples ) { @@ -829,12 +860,13 @@ static int SyncInfo( decoder_t *p_dec, uint8_t *p_buf, { decoder_sys_t *p_sys = p_dec->p_sys; int i_header, i_temp, i_read; - int i_blocksize = 0, i_blocksize_hint = 0, i_sample_rate_hint = 0; + unsigned i_blocksize = 0; + int i_blocksize_hint = 0, i_sample_rate_hint = 0; uint64_t i_sample_number = 0; - vlc_bool_t b_variable_blocksize = ( p_sys->b_stream_info && + bool b_variable_blocksize = ( p_sys->b_stream_info && p_sys->stream_info.min_blocksize != p_sys->stream_info.max_blocksize ); - vlc_bool_t b_fixed_blocksize = ( p_sys->b_stream_info && + bool b_fixed_blocksize = ( p_sys->b_stream_info && p_sys->stream_info.min_blocksize == p_sys->stream_info.max_blocksize ); /* Check syncword */ @@ -1015,12 +1047,12 @@ static int SyncInfo( decoder_t *p_dec, uint8_t *p_buf, if( i_blocksize_hint && b_variable_blocksize ) { i_sample_number = read_utf8( &p_buf[i_header++], &i_read ); - if( i_sample_number == I64C(0xffffffffffffffff) ) return 0; + if( i_sample_number == INT64_C(0xffffffffffffffff) ) return 0; } else { i_sample_number = read_utf8( &p_buf[i_header++], &i_read ); - if( i_sample_number == I64C(0xffffffffffffffff) ) return 0; + if( i_sample_number == INT64_C(0xffffffffffffffff) ) return 0; if( p_sys->b_stream_info ) i_sample_number *= p_sys->stream_info.min_blocksize; @@ -1060,6 +1092,13 @@ static int SyncInfo( decoder_t *p_dec, uint8_t *p_buf, return 0; } + /* Sanity check using stream info header when possible */ + if( p_sys->b_stream_info ) + { + if( i_blocksize < p_sys->stream_info.min_blocksize || + i_blocksize > p_sys->stream_info.max_blocksize ) + return 0; + } return i_blocksize; } @@ -1105,14 +1144,14 @@ static uint64_t read_utf8( const uint8_t *p_buf, int *pi_read ) i = 6; } else { - return I64C(0xffffffffffffffff); + return INT64_C(0xffffffffffffffff); } for( j = 1; j <= i; j++ ) { if( !(p_buf[j] & 0x80) || (p_buf[j] & 0x40) ) /* 10xxxxxx */ { - return I64C(0xffffffffffffffff); + return INT64_C(0xffffffffffffffff); } i_result <<= 6; i_result |= (p_buf[j] & 0x3F); @@ -1123,7 +1162,7 @@ static uint64_t read_utf8( const uint8_t *p_buf, int *pi_read ) } /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */ -static uint8_t const flac_crc8_table[256] = { +static const uint8_t flac_crc8_table[256] = { 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, @@ -1229,10 +1268,7 @@ static int OpenEncoder( vlc_object_t *p_this ) /* Allocate the memory needed to store the decoder's structure */ if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL ) - { - msg_Err( p_enc, "out of memory" ); - return VLC_EGENERIC; - } + return VLC_ENOMEM; p_enc->p_sys = p_sys; p_enc->pf_encode_audio = Encode; p_enc->fmt_out.i_codec = VLC_FOURCC('f','l','a','c'); @@ -1337,7 +1373,7 @@ static void CloseEncoder( vlc_object_t *p_this ) FLAC__stream_encoder_delete( p_sys->p_flac ); - if( p_sys->p_buffer ) free( p_sys->p_buffer ); + free( p_sys->p_buffer ); free( p_sys ); }