blob: 59f72ed86b34c80368c4cf7326cfcd71f808fd2c [file] [log] [blame]
/**
* Copyright (C) 2020 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.
*/
// This PoC is written using aac_dec_fuzzer.cpp as reference.
#include "aacdecoder_lib.h"
#include <stdlib.h>
constexpr uint8_t kNumberOfLayers = 1;
constexpr uint8_t kMaxChannelCount = 8;
constexpr uint8_t kConfigBytes = 92;
constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
class Codec {
public:
Codec() = default;
~Codec() { deInitDecoder(); }
bool initDecoder();
void decodeFrames(UCHAR *data, UINT size);
void deInitDecoder();
private:
HANDLE_AACDECODER mAacDecoderHandle = nullptr;
AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
bool mConfigFlag = false;
};
bool Codec::initDecoder() {
mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
if (!mAacDecoderHandle) {
return false;
}
return true;
}
void Codec::deInitDecoder() {
aacDecoder_Close(mAacDecoderHandle);
mAacDecoderHandle = nullptr;
}
void Codec::decodeFrames(UCHAR *data, UINT size) {
while (size > 0) {
UINT inputSize = size;
UINT valid = size;
if (!mConfigFlag) {
inputSize = kConfigBytes;
aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &inputSize);
data += kConfigBytes;
size -= kConfigBytes;
mConfigFlag = true;
continue;
}
aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
INT_PCM outputBuf[kMaxOutBufferSize];
do {
mErrorCode = aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf,
sizeof(outputBuf), 0);
} while (mErrorCode == AAC_DEC_OK);
UINT offset = inputSize - valid;
data += offset;
size = valid;
}
}
int main(int argc, char *argv[]) {
if (argc != 2) {
return EXIT_FAILURE;
}
FILE *fp = fopen(argv[1], "rb");
if (!fp) {
return EXIT_FAILURE;
}
fseek(fp, 0, SEEK_END);
UINT size = ftell(fp);
fseek(fp, 0, SEEK_SET);
UCHAR *data = new UCHAR[size];
fread(data, sizeof(UCHAR), size, fp);
fclose(fp);
fp = nullptr;
Codec *codec = new Codec();
if (!codec) {
delete[] data;
return EXIT_FAILURE;
}
if (codec->initDecoder()) {
codec->decodeFrames((UCHAR *)(data), static_cast<UINT>(size));
}
delete codec;
delete[] data;
return EXIT_SUCCESS;
}