| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "Mp3DecoderTest" |
| |
| #include <utils/Log.h> |
| |
| #include <audio_utils/sndfile.h> |
| #include <memory> |
| #include <stdio.h> |
| |
| #include "mp3reader.h" |
| #include "pvmp3decoder_api.h" |
| |
| #include "Mp3DecoderTestEnvironment.h" |
| |
| #define OUTPUT_FILE "/data/local/tmp/mp3Decode.out" |
| |
| constexpr int32_t kInputBufferSize = 1024 * 10; |
| constexpr int32_t kOutputBufferSize = 4608 * 2; |
| constexpr int32_t kMaxCount = 10; |
| constexpr int32_t kNumFrameReset = 150; |
| |
| static Mp3DecoderTestEnvironment *gEnv = nullptr; |
| |
| class Mp3DecoderTest : public ::testing::TestWithParam<string> { |
| public: |
| Mp3DecoderTest() : mConfig(nullptr) {} |
| |
| ~Mp3DecoderTest() { |
| if (mConfig) { |
| delete mConfig; |
| mConfig = nullptr; |
| } |
| } |
| |
| virtual void SetUp() override { |
| mConfig = new tPVMP3DecoderExternal{}; |
| ASSERT_NE(mConfig, nullptr) << "Failed to initialize config. No Memory available"; |
| mConfig->equalizerType = flat; |
| mConfig->crcEnabled = false; |
| } |
| |
| tPVMP3DecoderExternal *mConfig; |
| Mp3Reader mMp3Reader; |
| |
| ERROR_CODE DecodeFrames(void *decoderbuf, SNDFILE *outFileHandle, SF_INFO sfInfo, |
| int32_t frameCount = INT32_MAX); |
| SNDFILE *openOutputFile(SF_INFO *sfInfo); |
| }; |
| |
| ERROR_CODE Mp3DecoderTest::DecodeFrames(void *decoderBuf, SNDFILE *outFileHandle, SF_INFO sfInfo, |
| int32_t frameCount) { |
| uint8_t inputBuf[kInputBufferSize]; |
| int16_t outputBuf[kOutputBufferSize]; |
| uint32_t bytesRead; |
| ERROR_CODE decoderErr; |
| while (frameCount > 0) { |
| bool success = mMp3Reader.getFrame(inputBuf, &bytesRead); |
| if (!success) { |
| break; |
| } |
| mConfig->inputBufferCurrentLength = bytesRead; |
| mConfig->inputBufferMaxLength = 0; |
| mConfig->inputBufferUsedLength = 0; |
| mConfig->pInputBuffer = inputBuf; |
| mConfig->pOutputBuffer = outputBuf; |
| mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t); |
| decoderErr = pvmp3_framedecoder(mConfig, decoderBuf); |
| if (decoderErr != NO_DECODING_ERROR) break; |
| sf_writef_short(outFileHandle, outputBuf, mConfig->outputFrameSize / sfInfo.channels); |
| frameCount--; |
| } |
| return decoderErr; |
| } |
| |
| SNDFILE *Mp3DecoderTest::openOutputFile(SF_INFO *sfInfo) { |
| memset(sfInfo, 0, sizeof(SF_INFO)); |
| sfInfo->channels = mMp3Reader.getNumChannels(); |
| sfInfo->format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; |
| sfInfo->samplerate = mMp3Reader.getSampleRate(); |
| SNDFILE *outFileHandle = sf_open(OUTPUT_FILE, SFM_WRITE, sfInfo); |
| return outFileHandle; |
| } |
| |
| TEST_F(Mp3DecoderTest, MultiCreateMp3DecoderTest) { |
| size_t memRequirements = pvmp3_decoderMemRequirements(); |
| ASSERT_NE(memRequirements, 0) << "Failed to get the memory requirement size"; |
| unique_ptr<char[]> decoderBuf(new char[memRequirements]); |
| ASSERT_NE(decoderBuf, nullptr) |
| << "Failed to allocate decoder memory of size " << memRequirements; |
| for (int count = 0; count < kMaxCount; count++) { |
| pvmp3_InitDecoder(mConfig, (void*)decoderBuf.get()); |
| ALOGV("Decoder created successfully"); |
| } |
| } |
| |
| TEST_P(Mp3DecoderTest, DecodeTest) { |
| size_t memRequirements = pvmp3_decoderMemRequirements(); |
| ASSERT_NE(memRequirements, 0) << "Failed to get the memory requirement size"; |
| unique_ptr<char[]> decoderBuf(new char[memRequirements]); |
| ASSERT_NE(decoderBuf, nullptr) |
| << "Failed to allocate decoder memory of size " << memRequirements; |
| |
| pvmp3_InitDecoder(mConfig, (void*)decoderBuf.get()); |
| ALOGV("Decoder created successfully"); |
| string inputFile = gEnv->getRes() + GetParam(); |
| bool status = mMp3Reader.init(inputFile.c_str()); |
| ASSERT_TRUE(status) << "Unable to initialize the mp3Reader"; |
| |
| // Open the output file. |
| SF_INFO sfInfo; |
| SNDFILE *outFileHandle = openOutputFile(&sfInfo); |
| ASSERT_NE(outFileHandle, nullptr) << "Error opening output file for writing decoded output"; |
| |
| ERROR_CODE decoderErr = DecodeFrames((void*)decoderBuf.get(), outFileHandle, sfInfo); |
| ASSERT_EQ(decoderErr, NO_DECODING_ERROR) << "Failed to decode the frames"; |
| ASSERT_EQ(sfInfo.channels, mConfig->num_channels) << "Number of channels does not match"; |
| ASSERT_EQ(sfInfo.samplerate, mConfig->samplingRate) << "Sample rate does not match"; |
| |
| mMp3Reader.close(); |
| sf_close(outFileHandle); |
| } |
| |
| TEST_P(Mp3DecoderTest, ResetDecoderTest) { |
| size_t memRequirements = pvmp3_decoderMemRequirements(); |
| ASSERT_NE(memRequirements, 0) << "Failed to get the memory requirement size"; |
| unique_ptr<char[]> decoderBuf(new char[memRequirements]); |
| ASSERT_NE(decoderBuf, nullptr) |
| << "Failed to allocate decoder memory of size " << memRequirements; |
| |
| pvmp3_InitDecoder(mConfig, (void*)decoderBuf.get()); |
| ALOGV("Decoder created successfully."); |
| string inputFile = gEnv->getRes() + GetParam(); |
| bool status = mMp3Reader.init(inputFile.c_str()); |
| ASSERT_TRUE(status) << "Unable to initialize the mp3Reader"; |
| |
| // Open the output file. |
| SF_INFO sfInfo; |
| SNDFILE *outFileHandle = openOutputFile(&sfInfo); |
| ASSERT_NE(outFileHandle, nullptr) << "Error opening output file for writing decoded output"; |
| |
| ERROR_CODE decoderErr; |
| decoderErr = DecodeFrames((void*)decoderBuf.get(), outFileHandle, sfInfo, kNumFrameReset); |
| ASSERT_EQ(decoderErr, NO_DECODING_ERROR) << "Failed to decode the frames"; |
| ASSERT_EQ(sfInfo.channels, mConfig->num_channels) << "Number of channels does not match"; |
| ASSERT_EQ(sfInfo.samplerate, mConfig->samplingRate) << "Sample rate does not match"; |
| |
| pvmp3_resetDecoder((void*)decoderBuf.get()); |
| // Decode the same file. |
| decoderErr = DecodeFrames((void*)decoderBuf.get(), outFileHandle, sfInfo); |
| ASSERT_EQ(decoderErr, NO_DECODING_ERROR) << "Failed to decode the frames"; |
| ASSERT_EQ(sfInfo.channels, mConfig->num_channels) << "Number of channels does not match"; |
| ASSERT_EQ(sfInfo.samplerate, mConfig->samplingRate) << "Sample rate does not match"; |
| |
| mMp3Reader.close(); |
| sf_close(outFileHandle); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(Mp3DecoderTestAll, Mp3DecoderTest, |
| ::testing::Values(("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3"), |
| ("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3"), |
| ("bug_136053885.mp3"), |
| ("bbb_2ch_44kHz_lame_crc.mp3"), |
| ("bbb_mp3_stereo_192kbps_48000hz.mp3"))); |
| |
| int main(int argc, char **argv) { |
| gEnv = new Mp3DecoderTestEnvironment(); |
| ::testing::AddGlobalTestEnvironment(gEnv); |
| ::testing::InitGoogleTest(&argc, argv); |
| int status = gEnv->initFromOptions(argc, argv); |
| if (status == 0) { |
| status = RUN_ALL_TESTS(); |
| ALOGV("Test result = %d\n", status); |
| } |
| return status; |
| } |