diff options
author | jstebbins <[email protected]> | 2011-04-08 16:49:24 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2011-04-08 16:49:24 +0000 |
commit | f20621c2d30ad805dfefcab335506f660a133ffe (patch) | |
tree | 5d1a3e9e844b94584790b7f002c3fdec39081326 /libhb | |
parent | de122b044e99b0ad1abff0ba51e1a4d9e7d8b020 (diff) |
Change internal audio representation range
...from float [-32768...32767] to float [-1.0...1.0]
Using the range [-1.0..1.0] requires fewer translations of the range for our
various encoders and decoders. This also gets rid of a hacky
translation from float to int to float in decavcodec audio decoding.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3908 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/deca52.c | 2 | ||||
-rw-r--r-- | libhb/decavcodec.c | 52 | ||||
-rw-r--r-- | libhb/decdca.c | 4 | ||||
-rw-r--r-- | libhb/declpcm.c | 14 | ||||
-rw-r--r-- | libhb/encac3.c | 17 | ||||
-rw-r--r-- | libhb/encfaac.c | 6 | ||||
-rw-r--r-- | libhb/enclame.c | 2 | ||||
-rw-r--r-- | libhb/encvorbis.c | 3 | ||||
-rw-r--r-- | libhb/hb.c | 23 | ||||
-rw-r--r-- | libhb/hbffmpeg.h | 1 | ||||
-rw-r--r-- | libhb/platform/macosx/encca_aac.c | 8 | ||||
-rw-r--r-- | libhb/stream.c | 1 | ||||
-rw-r--r-- | libhb/sync.c | 4 |
13 files changed, 70 insertions, 67 deletions
diff --git a/libhb/deca52.c b/libhb/deca52.c index 0958a9139..3148bc672 100644 --- a/libhb/deca52.c +++ b/libhb/deca52.c @@ -106,7 +106,7 @@ static int deca52Init( hb_work_object_t * w, hb_job_t * job ) /* will only be actually used if we're not doing AC3 passthru */ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); - pv->level = 32768.0; + pv->level = 1.0; pv->dynamic_range_compression = audio->config.out.dynamic_range_compression; return 0; diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 5fe5f8e81..b35d57119 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -111,7 +111,6 @@ struct hb_work_private_s void* buffer; struct SwsContext *sws_context; // if we have to rescale or convert color space hb_downmix_t *downmix; - hb_sample_t *downmix_buffer; int cadence[12]; hb_chan_map_t *out_map; }; @@ -205,6 +204,7 @@ static int decavcodecInit( hb_work_object_t * w, hb_job_t * job ) pv->parser = av_parser_init( codec_id ); pv->context = avcodec_alloc_context(); + hb_ff_set_sample_fmt( pv->context, codec ); hb_avcodec_open( pv->context, codec ); if ( w->audio != NULL ) @@ -305,11 +305,6 @@ static void closePrivData( hb_work_private_t ** ppv ) { hb_downmix_close( &(pv->downmix) ); } - if ( pv->downmix_buffer ) - { - free( pv->downmix_buffer ); - pv->downmix_buffer = NULL; - } free( pv ); } *ppv = NULL; @@ -528,6 +523,7 @@ static int decavcodecBSInfo( hb_work_object_t *w, const hb_buffer_t *buf, AVCodecParserContext *parser = av_parser_init( codec->id ); AVCodecContext *context = avcodec_alloc_context(); + hb_ff_set_sample_fmt( context, codec ); hb_avcodec_open( context, codec ); uint8_t *buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE ); int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; @@ -1160,6 +1156,7 @@ static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in, // There's a mis-feature in ffmpeg that causes the context to be // incorrectly initialized the 1st time avcodec_open is called. // If you close it and open a 2nd time, it finishes the job. + hb_ff_set_sample_fmt( pv->context, codec ); hb_avcodec_open( pv->context, codec ); hb_avcodec_close( pv->context ); hb_avcodec_open( pv->context, codec ); @@ -1280,6 +1277,7 @@ static void init_ffmpeg_context( hb_work_object_t *w ) if ( ! pv->context->codec ) { AVCodec *codec = avcodec_find_decoder( pv->context->codec_id ); + hb_ff_set_sample_fmt( pv->context, codec ); hb_avcodec_open( pv->context, codec ); } // set up our best guess at the frame duration. @@ -1491,7 +1489,7 @@ static int decavcodecviInfo( hb_work_object_t *w, hb_work_info_t *info ) static hb_buffer_t * downmixAudio( hb_audio_t *audio, hb_work_private_t *pv, - int16_t *buffer, + hb_sample_t *buffer, int channels, int nsamples ) { @@ -1499,20 +1497,12 @@ static hb_buffer_t * downmixAudio( if ( pv->downmix ) { - pv->downmix_buffer = realloc(pv->downmix_buffer, nsamples * sizeof(hb_sample_t)); - - int i; - for( i = 0; i < nsamples; ++i ) - { - pv->downmix_buffer[i] = buffer[i]; - } - int n_ch_samples = nsamples / channels; int out_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); buf = hb_buffer_init( n_ch_samples * out_channels * sizeof(float) ); hb_sample_t *samples = (hb_sample_t *)buf->data; - hb_downmix(pv->downmix, samples, pv->downmix_buffer, n_ch_samples); + hb_downmix(pv->downmix, samples, buffer, n_ch_samples); } else { @@ -1540,7 +1530,7 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat while ( pos < size ) { - int16_t *buffer = pv->buffer; + float *buffer = pv->buffer; if ( buffer == NULL ) { pv->buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE ); @@ -1556,7 +1546,7 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; int nsamples; - int len = avcodec_decode_audio3( context, buffer, &out_size, &avp ); + int len = avcodec_decode_audio3( context, (int16_t*)buffer, &out_size, &avp ); if ( len < 0 ) { return; @@ -1574,7 +1564,7 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat { // We require signed 16-bit ints for the output format. If // we got something different convert it. - if ( context->sample_fmt != SAMPLE_FMT_S16 ) + if ( context->sample_fmt != AV_SAMPLE_FMT_FLT ) { // Note: av_audio_convert seems to be a work-in-progress but // looks like it will eventually handle general audio @@ -1583,27 +1573,31 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat // anything more complicated than a one-for-one format // conversion we'd probably want to cache the converter // context in the pv. - int isamp = av_get_bits_per_sample_fmt( context->sample_fmt ) / 8; - AVAudioConvert *ctx = av_audio_convert_alloc( SAMPLE_FMT_S16, 1, - context->sample_fmt, 1, - NULL, 0 ); - // get output buffer size (in 2-byte samples) then malloc a buffer + int isamp; + AVAudioConvert *ctx; + + isamp = av_get_bits_per_sample_fmt( context->sample_fmt ) / 8; + ctx = av_audio_convert_alloc( AV_SAMPLE_FMT_FLT, 1, + context->sample_fmt, 1, + NULL, 0 ); + + // get output buffer size then malloc a buffer nsamples = out_size / isamp; - buffer = av_malloc( nsamples * 2 ); + buffer = av_malloc( nsamples * sizeof(hb_sample_t) ); - // we're doing straight sample format conversion which behaves as if - // there were only one channel. + // we're doing straight sample format conversion which + // behaves as if there were only one channel. const void * const ibuf[6] = { pv->buffer }; void * const obuf[6] = { buffer }; const int istride[6] = { isamp }; - const int ostride[6] = { 2 }; + const int ostride[6] = { sizeof(hb_sample_t) }; av_audio_convert( ctx, obuf, ostride, ibuf, istride, nsamples ); av_audio_convert_free( ctx ); } else { - nsamples = out_size / 2; + nsamples = out_size / sizeof(hb_sample_t); } if ( pts == AV_NOPTS_VALUE ) diff --git a/libhb/decdca.c b/libhb/decdca.c index 9b85905fd..62f460915 100644 --- a/libhb/decdca.c +++ b/libhb/decdca.c @@ -84,7 +84,7 @@ static int decdcaInit( hb_work_object_t * w, hb_job_t * job ) /* will only be actually used if we're not doing AC3 passthru */ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); - pv->level = 32768.0; + pv->level = 1.0; return 0; } @@ -268,7 +268,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) { for ( k = 0; k < pv->out_discrete_channels; k++ ) { - samples_out[(pv->out_discrete_channels*j)+k] = samples_in[(256*k)+j] * 32767; + samples_out[(pv->out_discrete_channels*j)+k] = samples_in[(256*k)+j]; } } diff --git a/libhb/declpcm.c b/libhb/declpcm.c index f47fe87b9..fc120a333 100644 --- a/libhb/declpcm.c +++ b/libhb/declpcm.c @@ -198,7 +198,7 @@ static hb_buffer_t *Decode( hb_work_object_t *w ) case 16: // 2 byte, big endian, signed (the right shift sign extends) while ( --count >= 0 ) { - *odat++ = ( (int)( frm[0] << 24 ) >> 16 ) | frm[1]; + *odat++ = (float)(( (int)( frm[0] << 24 ) >> 16 ) | frm[1]) / 32768.0; frm += 2; } break; @@ -209,9 +209,9 @@ static hb_buffer_t *Decode( hb_work_object_t *w ) while ( --count >= 0 ) { *odat++ = (float)( ( (int)( frm[0] << 24 ) >> 12 ) | - ( frm[1] << 4 ) | ( frm[2] >> 4 ) ) / 16.; + ( frm[1] << 4 ) | ( frm[2] >> 4 ) ) / (16. * 32768.0); *odat++ = (float)( ( (int)( frm[2] << 28 ) >> 16 ) | - ( frm[3] << 8 ) | frm[4] ) / 16.; + ( frm[3] << 8 ) | frm[4] ) / (16. * 32768.0); frm += 5; } break; @@ -227,13 +227,13 @@ static hb_buffer_t *Decode( hb_work_object_t *w ) while ( --count >= 0 ) { *odat++ = (float)( ( (int)( frm[0] << 24 ) >> 8 ) | - ( frm[1] << 8 ) | frm[8] ) / 256.; + ( frm[1] << 8 ) | frm[8] ) / (256. * 32768.0); *odat++ = (float)( ( (int)( frm[2] << 24 ) >> 8 ) | - ( frm[3] << 8 ) | frm[9] ) / 256.; + ( frm[3] << 8 ) | frm[9] ) / (256. * 32768.0); *odat++ = (float)( ( (int)( frm[4] << 24 ) >> 8 ) | - ( frm[5] << 8 ) | frm[10] ) / 256.; + ( frm[5] << 8 ) | frm[10] ) / (256. * 32768.0); *odat++ = (float)( ( (int)( frm[6] << 24 ) >> 8 ) | - ( frm[7] << 8 ) | frm[11] ) / 256.; + ( frm[7] << 8 ) | frm[11] ) / (256. * 32768.0); frm += 12; } break; diff --git a/libhb/encac3.c b/libhb/encac3.c index 179086607..693e8b02e 100644 --- a/libhb/encac3.c +++ b/libhb/encac3.c @@ -18,7 +18,6 @@ struct hb_work_private_s unsigned long output_bytes; hb_list_t * list; uint8_t * buf; - float * samples; }; int encac3Init( hb_work_object_t *, hb_job_t * ); @@ -53,7 +52,6 @@ int encac3Init( hb_work_object_t * w, hb_job_t * job ) pv->output_bytes = AC3_MAX_CODED_FRAME_SIZE; pv->buf = malloc( pv->input_samples * sizeof( float ) ); - pv->samples = malloc( pv->input_samples * sizeof( float ) ); codec = avcodec_find_encoder( CODEC_ID_AC3 ); if( !codec ) @@ -127,12 +125,6 @@ void encac3Close( hb_work_object_t * w ) pv->buf = NULL; } - if ( pv->samples ) - { - free( pv->samples ); - pv->samples = NULL; - } - if ( pv->list ) hb_list_empty( &pv->list ); @@ -147,7 +139,6 @@ static hb_buffer_t * Encode( hb_work_object_t * w ) uint64_t pts, pos; hb_audio_t * audio = w->audio; hb_buffer_t * buf; - int ii; if( hb_list_bytes( pv->list ) < pv->input_samples * sizeof( float ) ) { @@ -188,15 +179,9 @@ static hb_buffer_t * Encode( hb_work_object_t * w ) (float*)pv->buf, AC3_SAMPLES_PER_FRAME); } - for (ii = 0; ii < pv->input_samples; ii++) - { - // ffmpeg float samples are -1.0 to 1.0 - pv->samples[ii] = ((float*)pv->buf)[ii] / 32768.0; - } - buf = hb_buffer_init( pv->output_bytes ); buf->size = avcodec_encode_audio( pv->context, buf->data, buf->alloc, - (short*)pv->samples ); + (short*)pv->buf ); buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate; buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME / audio->config.out.samplerate; diff --git a/libhb/encfaac.c b/libhb/encfaac.c index c4a57100f..b8ff8347c 100644 --- a/libhb/encfaac.c +++ b/libhb/encfaac.c @@ -207,6 +207,12 @@ static hb_buffer_t * Encode( hb_work_object_t * w ) uint64_t pts, pos; hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ), &pts, &pos ); + + int i; + float *fltBuf = (float*)pv->buf; + for ( i = 0; i < pv->input_samples; i++ ) + fltBuf[i] *= 32768.0; + int size = faacEncEncode( pv->faac, (int32_t *)pv->buf, pv->input_samples, pv->obuf, pv->output_bytes ); diff --git a/libhb/enclame.c b/libhb/enclame.c index 955aca626..ba05e1fc0 100644 --- a/libhb/enclame.c +++ b/libhb/enclame.c @@ -50,6 +50,7 @@ int enclameInit( hb_work_object_t * w, hb_job_t * job ) pv->lame = lame_init(); // use ABR + lame_set_scale( pv->lame, 32768.0 ); lame_set_VBR( pv->lame, vbr_abr ); lame_set_VBR_mean_bitrate_kbps( pv->lame, audio->config.out.bitrate ); lame_set_in_samplerate( pv->lame, audio->config.out.samplerate ); @@ -120,7 +121,6 @@ static hb_buffer_t * Encode( hb_work_object_t * w ) hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ), &pts, &pos); - memset(samples, 0, 2*1152*sizeof(float)); for( i = 0; i < 1152; i++ ) { for( j = 0; j < pv->out_discrete_channels; j++ ) diff --git a/libhb/encvorbis.c b/libhb/encvorbis.c index 609e45ffd..1c7e323ba 100644 --- a/libhb/encvorbis.c +++ b/libhb/encvorbis.c @@ -242,9 +242,10 @@ static hb_buffer_t * Encode( hb_work_object_t * w ) { for( j = 0; j < pv->out_discrete_channels; j++) { - buffer[j][i] = ((float *) pv->buf)[(pv->out_discrete_channels * i + pv->channel_map[j])] / 32768.f; + buffer[j][i] = ((float *) pv->buf)[(pv->out_discrete_channels * i + pv->channel_map[j])]; } } + vorbis_analysis_wrote( &pv->vd, OGGVORBIS_FRAME_SIZE ); /* Try to extract again */ diff --git a/libhb/hb.c b/libhb/hb.c index 92e743cc6..4c16156c5 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -241,6 +241,29 @@ int hb_ff_layout_xlat(int64_t ff_channel_layout, int channels) return hb_layout; } +// Set sample format to AV_SAMPLE_FMT_FLT if supported. +// If it is not supported, we will have to translate using +// av_audio_convert. +void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec) +{ + if ( codec && codec->sample_fmts ) + { + if ( codec->type != AVMEDIA_TYPE_AUDIO ) + return; // Not audio + + const enum AVSampleFormat *fmt; + + for ( fmt = codec->sample_fmts; *fmt != -1; fmt++ ) + { + if ( *fmt == AV_SAMPLE_FMT_FLT ) + { + context->sample_fmt = AV_SAMPLE_FMT_FLT; + break; + } + } + } +} + /** * Registers work objects, by adding the work object to a liked list. * @param w Handle to hb_work_object_t to register. diff --git a/libhb/hbffmpeg.h b/libhb/hbffmpeg.h index 205bd0f64..3c7d1ead6 100644 --- a/libhb/hbffmpeg.h +++ b/libhb/hbffmpeg.h @@ -15,3 +15,4 @@ struct SwsContext* hb_sws_get_context(int srcW, int srcH, enum PixelFormat srcFormat, int dstW, int dstH, enum PixelFormat dstFormat, int flags); +void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec); diff --git a/libhb/platform/macosx/encca_aac.c b/libhb/platform/macosx/encca_aac.c index 762559cae..21b458960 100644 --- a/libhb/platform/macosx/encca_aac.c +++ b/libhb/platform/macosx/encca_aac.c @@ -280,14 +280,6 @@ static OSStatus inInputDataProc( AudioConverterRef converter, UInt32 *npackets, *npackets = buffers->mBuffers[0].mDataByteSize / pv->isamplesiz; - /* transform data from [-32768,32767] to [-1.0,1.0] */ - float *fdata = buffers->mBuffers[0].mData; - int i; - - for( i = 0; i < *npackets * pv->nchannels; i++ ) { - fdata[i] = fdata[i] / 32768.f; - } - pv->ibytes -= buffers->mBuffers[0].mDataByteSize; return noErr; diff --git a/libhb/stream.c b/libhb/stream.c index ccc10f746..f48edbe4c 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -2837,6 +2837,7 @@ static void ffmpeg_add_codec( hb_stream_t *stream, int stream_index ) context->error_recognition = 1; context->error_concealment = FF_EC_GUESS_MVS|FF_EC_DEBLOCK; AVCodec *codec = avcodec_find_decoder( context->codec_id ); + hb_ff_set_sample_fmt( context, codec ); hb_avcodec_open( context, codec ); } diff --git a/libhb/sync.c b/libhb/sync.c index 19ee605f0..bceeb10b5 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -1172,9 +1172,9 @@ static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf, sample = (double)*(((float*)buf->data)+ii); sample *= sync->gain_factor; if (sample > 0) - sample = MIN(sample, 32767.0); + sample = MIN(sample, 1.0); else - sample = MAX(sample, -32768.0); + sample = MAX(sample, -1.0); *(((float*)buf->data)+ii) = sample; } } |