summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-04-08 16:49:24 +0000
committerjstebbins <[email protected]>2011-04-08 16:49:24 +0000
commitf20621c2d30ad805dfefcab335506f660a133ffe (patch)
tree5d1a3e9e844b94584790b7f002c3fdec39081326 /libhb
parentde122b044e99b0ad1abff0ba51e1a4d9e7d8b020 (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.c2
-rw-r--r--libhb/decavcodec.c52
-rw-r--r--libhb/decdca.c4
-rw-r--r--libhb/declpcm.c14
-rw-r--r--libhb/encac3.c17
-rw-r--r--libhb/encfaac.c6
-rw-r--r--libhb/enclame.c2
-rw-r--r--libhb/encvorbis.c3
-rw-r--r--libhb/hb.c23
-rw-r--r--libhb/hbffmpeg.h1
-rw-r--r--libhb/platform/macosx/encca_aac.c8
-rw-r--r--libhb/stream.c1
-rw-r--r--libhb/sync.c4
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;
}
}