diff options
Diffstat (limited to 'Src/aacdec-mft/MP4AACDecoder.cpp')
-rw-r--r-- | Src/aacdec-mft/MP4AACDecoder.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/Src/aacdec-mft/MP4AACDecoder.cpp b/Src/aacdec-mft/MP4AACDecoder.cpp new file mode 100644 index 00000000..b431c067 --- /dev/null +++ b/Src/aacdec-mft/MP4AACDecoder.cpp @@ -0,0 +1,171 @@ +#include "MP4AACDecoder.h" +#include <Mferror.h> +#include <Mfapi.h> +#include "../external_dependencies/libmp4v2/mp4.h" +#include "util.h" +#include "../nsutil/pcm.h" + +MP4AACDecoder::MP4AACDecoder() +{ + isFloat = false; + gain=1.0f; + channels = 0; +} + +MP4AACDecoder::~MP4AACDecoder() +{ +} + +int MP4AACDecoder::OpenMP4(MP4FileHandle mp4_file, MP4TrackId mp4_track, size_t output_bits, size_t maxChannels, bool useFloat) +{ + HRESULT hr; + unsigned char *buffer; + uint32_t buffer_size; + + if (useFloat) { + this->bitsPerSample = 32; + } else if (output_bits) { + this->bitsPerSample = (unsigned int)output_bits; + } else { + this->bitsPerSample = 16; + } + + this->isFloat = useFloat; + + if (MP4GetTrackESConfiguration(mp4_file, mp4_track, (uint8_t **)&buffer, &buffer_size) && buffer) { + hr = decoder.Open(buffer, buffer_size); + if (SUCCEEDED(hr)) { + uint32_t local_sample_rate, local_channels; + hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels); + if (SUCCEEDED(hr)) { + this->channels = local_channels; + return MP4_SUCCESS; + } + } + } + return MP4_FAILURE; +} + +void MP4AACDecoder::Close() +{ +} + +void MP4AACDecoder::Flush() +{ + decoder.Flush(); +} + +int MP4AACDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *_bitsPerSample) +{ + bool dummy; + return GetOutputPropertiesEx(sampleRate, channels, _bitsPerSample, &dummy); +} + +int MP4AACDecoder::GetOutputPropertiesEx(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *useFloat) +{ + HRESULT hr; + UINT32 local_sample_rate, local_channels; + + hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels); + if (FAILED(hr)) { + return MP4_FAILURE; + } + + *sampleRate = local_sample_rate; + *channels = local_channels; + *bitsPerSample = this->bitsPerSample; + *useFloat = this->isFloat; + + return MP4_SUCCESS; +} + +int MP4AACDecoder::DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes) +{ + HRESULT hr; + + hr = decoder.Feed(inputBuffer, inputBufferBytes); + if (FAILED(hr)) { + return MP4_FAILURE; + } + + hr = decoder.Decode(outputBuffer, outputBufferBytes, this->bitsPerSample, this->isFloat, this->gain); + if (FAILED(hr)) { + return MP4_FAILURE; + } + + return MP4_SUCCESS; +} + +int MP4AACDecoder::OutputFrameSize(size_t *frameSize) +{ + if (channels == 0) { + return MP4_FAILURE; + } + + size_t local_frame_size; + if (FAILED(decoder.OutputBlockSizeSamples(&local_frame_size))) { + return MP4_FAILURE; + } + *frameSize = local_frame_size / channels; + + return MP4_SUCCESS; +} + +int MP4AACDecoder::CanHandleCodec(const char *codecName) +{ + return !strcmp(codecName, "mp4a"); +} + +int MP4AACDecoder::CanHandleType(uint8_t type) +{ + switch (type) + { + case MP4_TYPE_MPEG4_AUDIO: + return 1; + case MP4_TYPE_MPEG2_AAC_LC_AUDIO: + return 1; + default: + return 0; + } +} + +int MP4AACDecoder::CanHandleMPEG4Type(uint8_t type) +{ + switch (type) + { + case MP4_MPEG4_TYPE_AAC_LC_AUDIO: + case MP4_MPEG4_TYPE_AAC_HE_AUDIO: + case MP4_MPEG4_TYPE_PARAMETRIC_STEREO: + return 1; + default: + return 0; + } +} + +void MP4AACDecoder::EndOfStream() +{ + decoder.Feed(0, 0); +} + +#ifdef CBCLASS +#undef CBCLASS +#endif + +#define CBCLASS MP4AACDecoder +START_DISPATCH; +CB(MPEG4_AUDIO_OPENMP4, OpenMP4) +#if 0 +CB(MPEG4_AUDIO_BITRATE, GetCurrentBitrate) +#endif + +CB(MPEG4_AUDIO_FRAMESIZE, OutputFrameSize) +CB(MPEG4_AUDIO_OUTPUTINFO, GetOutputProperties) +CB(MPEG4_AUDIO_OUTPUTINFO_EX, GetOutputPropertiesEx) +CB(MPEG4_AUDIO_DECODE, DecodeSample) +VCB(MPEG4_AUDIO_FLUSH, Flush) +VCB(MPEG4_AUDIO_CLOSE, Close) +CB(MPEG4_AUDIO_HANDLES_CODEC, CanHandleCodec) +CB(MPEG4_AUDIO_HANDLES_TYPE, CanHandleType) +CB(MPEG4_AUDIO_HANDLES_MPEG4_TYPE, CanHandleMPEG4Type) +CB(MPEG4_AUDIO_SET_GAIN, SetGain) +END_DISPATCH;
\ No newline at end of file |