diff options
author | van <[email protected]> | 2008-12-06 09:31:16 +0000 |
---|---|---|
committer | van <[email protected]> | 2008-12-06 09:31:16 +0000 |
commit | 62c5a73bb1983cc97c2c9ab8037a4ff3fc0d111e (patch) | |
tree | 5b9caa556d3c8f156504b4d06e8d38e49e470ac4 | |
parent | f33a68eb3196a0fb0cb9324400fdd94c0187769e (diff) |
If we don't get signed 16 bits samples from the audio decoder, convert to signed 16 bit. (Fix for the pcm_u8 audio generated by Canon cameras.)
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2014 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/decavcodec.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 7f68100fa..d443b4ac0 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -62,6 +62,8 @@ #include "hb.h" #include "libavcodec/avcodec.h" +//#include "libavcodec/audioconvert.h" +#include "../contrib/ffmpeg/libavcodec/audioconvert.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" @@ -1085,6 +1087,35 @@ static void decodeAudio( hb_work_private_t *pv, uint8_t *data, int size ) pos += len; if( out_size > 0 ) { + // We require signed 16-bit ints for the output format. If + // we got something different convert it. + if ( context->sample_fmt != SAMPLE_FMT_S16 ) + { + // Note: av_audio_convert seems to be a work-in-progress but + // looks like it will eventually handle general audio + // mixdowns which would allow us much more flexibility + // in handling multichannel audio in HB. If we were doing + // 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_format( 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 + out_size = ( out_size * 2 ) / isamp; + buffer = malloc( out_size ); + + // 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 }; + + av_audio_convert( ctx, obuf, ostride, ibuf, istride, out_size >> 1 ); + av_audio_convert_free( ctx ); + } hb_buffer_t *buf = hb_buffer_init( 2 * out_size ); // convert from bytes to total samples @@ -1103,6 +1134,12 @@ static void decodeAudio( hb_work_private_t *pv, uint8_t *data, int size ) fl32[i] = buffer[i]; } hb_list_add( pv->list, buf ); + + // if we allocated a buffer for sample format conversion, free it + if ( buffer != pv->buffer ) + { + free( buffer ); + } } } } |