summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvan <[email protected]>2008-12-06 09:31:16 +0000
committervan <[email protected]>2008-12-06 09:31:16 +0000
commit62c5a73bb1983cc97c2c9ab8037a4ff3fc0d111e (patch)
tree5b9caa556d3c8f156504b4d06e8d38e49e470ac4
parentf33a68eb3196a0fb0cb9324400fdd94c0187769e (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.c37
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 );
+ }
}
}
}