1 /******************************************************************************
2 *
3 * Copyright (C) 2020 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <string.h>
21 #include <utils/Log.h>
22 #include <algorithm>
23 #include "cmnMemory.h"
24 #include "voAMRWB.h"
25 #include "cnst.h"
26
27 typedef int(VO_API *VOGETAUDIOENCAPI)(VO_AUDIO_CODECAPI *pEncHandle);
28 const int32_t kInputBufferSize = L_FRAME16k * sizeof(int16_t) * 2;
29 const int32_t kOutputBufferSize = 2 * kInputBufferSize;
30 const int32_t kModes[] = {VOAMRWB_MD66 /* 6.60kbps */, VOAMRWB_MD885 /* 8.85kbps */,
31 VOAMRWB_MD1265 /* 12.65kbps */, VOAMRWB_MD1425 /* 14.25kbps */,
32 VOAMRWB_MD1585 /* 15.85kbps */, VOAMRWB_MD1825 /* 18.25kbps */,
33 VOAMRWB_MD1985 /* 19.85kbps */, VOAMRWB_MD2305 /* 23.05kbps */,
34 VOAMRWB_MD2385 /* 23.85kbps */, VOAMRWB_N_MODES /* Invalid Mode */};
35 const VOAMRWBFRAMETYPE kFrameTypes[] = {VOAMRWB_DEFAULT, VOAMRWB_ITU, VOAMRWB_RFC3267};
36
37 class Codec {
38 public:
39 Codec() = default;
~Codec()40 ~Codec() { deInitEncoder(); }
41 bool initEncoder(const uint8_t *data);
42 void deInitEncoder();
43 void encodeFrames(const uint8_t *data, size_t size);
44
45 private:
46 VO_AUDIO_CODECAPI *mApiHandle = nullptr;
47 VO_MEM_OPERATOR *mMemOperator = nullptr;
48 VO_HANDLE mEncoderHandle = nullptr;
49 };
50
initEncoder(const uint8_t * data)51 bool Codec::initEncoder(const uint8_t *data) {
52 uint8_t startByte = *data;
53 int32_t mode = kModes[(startByte >> 4) % 10];
54 VOAMRWBFRAMETYPE frameType = kFrameTypes[startByte % 3];
55 mMemOperator = new VO_MEM_OPERATOR;
56 if (!mMemOperator) {
57 return false;
58 }
59
60 mMemOperator->Alloc = cmnMemAlloc;
61 mMemOperator->Copy = cmnMemCopy;
62 mMemOperator->Free = cmnMemFree;
63 mMemOperator->Set = cmnMemSet;
64 mMemOperator->Check = cmnMemCheck;
65
66 VO_CODEC_INIT_USERDATA userData;
67 memset(&userData, 0, sizeof(userData));
68 userData.memflag = VO_IMF_USERMEMOPERATOR;
69 userData.memData = (VO_PTR)mMemOperator;
70
71 mApiHandle = new VO_AUDIO_CODECAPI;
72 if (!mApiHandle) {
73 return false;
74 }
75 if (VO_ERR_NONE != voGetAMRWBEncAPI(mApiHandle)) {
76 // Failed to get api handle
77 return false;
78 }
79 if (VO_ERR_NONE != mApiHandle->Init(&mEncoderHandle, VO_AUDIO_CodingAMRWB, &userData)) {
80 // Failed to init AMRWB encoder
81 return false;
82 }
83 if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &frameType)) {
84 // Failed to set AMRWB encoder frame type
85 return false;
86 }
87 if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AMRWB_MODE, &mode)) {
88 // Failed to set AMRWB encoder mode
89 return false;
90 }
91 return true;
92 }
93
deInitEncoder()94 void Codec::deInitEncoder() {
95 if (mEncoderHandle) {
96 mApiHandle->Uninit(mEncoderHandle);
97 mEncoderHandle = nullptr;
98 }
99 if (mApiHandle) {
100 delete mApiHandle;
101 mApiHandle = nullptr;
102 }
103 if (mMemOperator) {
104 delete mMemOperator;
105 mMemOperator = nullptr;
106 }
107 }
108
encodeFrames(const uint8_t * data,size_t size)109 void Codec::encodeFrames(const uint8_t *data, size_t size) {
110 do {
111 int32_t minSize = std::min((int32_t)size, kInputBufferSize);
112 uint8_t outputBuf[kOutputBufferSize] = {};
113 VO_CODECBUFFER inData;
114 VO_CODECBUFFER outData;
115 VO_AUDIO_OUTPUTINFO outFormat;
116 inData.Buffer = (unsigned char *)data;
117 inData.Length = minSize;
118 outData.Buffer = outputBuf;
119 mApiHandle->SetInputData(mEncoderHandle, &inData);
120 mApiHandle->GetOutputData(mEncoderHandle, &outData, &outFormat);
121 data += minSize;
122 size -= minSize;
123 } while (size > 0);
124 }
125
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)126 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
127 if (size < 1) {
128 return 0;
129 }
130 Codec *codec = new Codec();
131 if (!codec) {
132 return 0;
133 }
134 if (codec->initEncoder(data)) {
135 // Consume first byte
136 ++data;
137 --size;
138 codec->encodeFrames(data, size);
139 }
140 delete codec;
141 return 0;
142 }
143