diff options
Diffstat (limited to 'Src/aacdec-mft/AVIAACDecoder.cpp')
-rw-r--r-- | Src/aacdec-mft/AVIAACDecoder.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/Src/aacdec-mft/AVIAACDecoder.cpp b/Src/aacdec-mft/AVIAACDecoder.cpp new file mode 100644 index 00000000..f2cf1591 --- /dev/null +++ b/Src/aacdec-mft/AVIAACDecoder.cpp @@ -0,0 +1,116 @@ +#include "AVIAACDecoder.h" +#include <math.h> +#include "../nsutil/pcm.h" + +int AVIDecoder::CreateAudioDecoder(const nsavi::AVIH *avi_header, + const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, + unsigned int preferred_bits, unsigned int max_channels, bool floating_point, + ifc_aviaudiodecoder **decoder) +{ + nsavi::audio_format *waveformat = (nsavi::audio_format *)stream_format; + + if (waveformat->format == nsavi::audio_format_aac) + { + AVIAACDecoder *aac_decoder = AVIAACDecoder::Create(waveformat, preferred_bits, max_channels, floating_point); + if (aac_decoder) + { + *decoder = aac_decoder; + return CREATEDECODER_SUCCESS; + } + return CREATEDECODER_SUCCESS; + } + + return CREATEDECODER_NOT_MINE; + +} + +#define CBCLASS AVIDecoder +START_DISPATCH; +CB(CREATE_AUDIO_DECODER, CreateAudioDecoder) +END_DISPATCH; +#undef CBCLASS + +AVIAACDecoder *AVIAACDecoder::Create(const nsavi::audio_format *waveformat, unsigned int preferred_bits, unsigned int max_channels, bool floating_point) +{ + if (!floating_point) + { + if (preferred_bits >= 24) + preferred_bits=24; + else + preferred_bits=16; + } + /*if (!max_channels) + max_channels = 8;*/ + + if (waveformat->extra_size_bytes) + { + AVIAACDecoder * decoder = new AVIAACDecoder(preferred_bits, floating_point); + if (decoder && SUCCEEDED(decoder->decoder.Open((const unsigned char *)(waveformat + 1), waveformat->extra_size_bytes))) { + return decoder; + } + delete decoder; + } + + return 0; +} + +AVIAACDecoder::AVIAACDecoder(unsigned int bps, bool floating_point) +: bps(bps), floating_point(floating_point) +{ +} + +int AVIAACDecoder::OutputFrameSize(size_t *frame_size) +{ + size_t local_frame_size; + if (FAILED(decoder.OutputBlockSizeSamples(&local_frame_size))) { + return AVI_FAILURE; + } + + *frame_size = local_frame_size; + return AVI_SUCCESS; +} + +int AVIAACDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat) +{ + uint32_t local_sample_rate, local_channels; + HRESULT hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels); + if (FAILED(hr)) { + return AVI_FAILURE; + } + + *sampleRate = local_sample_rate; + *channels = local_channels; + *bitsPerSample = bps; + *isFloat = floating_point; + return AVI_SUCCESS; +} + +int AVIAACDecoder::DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes) +{ + if (SUCCEEDED(decoder.Feed(*inputBuffer, *inputBufferBytes)) + && SUCCEEDED(decoder.Decode(outputBuffer, outputBufferBytes, bps, false, 1.0))) { + *inputBufferBytes = 0; + return AVI_SUCCESS; + } + return AVI_FAILURE; +} + +void AVIAACDecoder::Flush() +{ + decoder.Flush(); +} + +void AVIAACDecoder::Close() +{ + delete this; +} + +#define CBCLASS AVIAACDecoder +START_DISPATCH; +CB(OUTPUT_FRAME_SIZE, OutputFrameSize) +CB(GET_OUTPUT_PROPERTIES, GetOutputProperties) +CB(DECODE_CHUNK, DecodeChunk) +VCB(FLUSH, Flush) +VCB(CLOSE, Close) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file |