aboutsummaryrefslogtreecommitdiff
path: root/Src/aacdec-mft/MP4AACDecoder.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/aacdec-mft/MP4AACDecoder.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/aacdec-mft/MP4AACDecoder.cpp')
-rw-r--r--Src/aacdec-mft/MP4AACDecoder.cpp171
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