xref: /aosp_15_r20/frameworks/av/media/module/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "AmrwbEncoderTest"
19 
20 #include <utils/Log.h>
21 
22 #include <stdio.h>
23 #include <fstream>
24 
25 #include "cmnMemory.h"
26 #include "voAMRWB.h"
27 
28 #include "AmrwbEncTestEnvironment.h"
29 
30 #define OUTPUT_FILE "/data/local/tmp/amrwbEncode.out"
31 #define VOAMRWB_RFC3267_HEADER_INFO "#!AMR-WB\n"
32 
33 constexpr int32_t kInputBufferSize = 640;
34 constexpr int32_t kOutputBufferSize = 1024;
35 
36 static AmrwbEncTestEnvironment *gEnv = nullptr;
37 
38 class AmrwbEncoderTest : public ::testing::TestWithParam<tuple<string, int32_t,
39                                                                VOAMRWBFRAMETYPE, string>> {
40   public:
AmrwbEncoderTest()41     AmrwbEncoderTest() : mEncoderHandle(nullptr) {
42         tuple<string, int32_t, VOAMRWBFRAMETYPE, string> params = GetParam();
43         mInputFile = gEnv->getRes() + get<0>(params);
44         mMode = get<1>(params);
45         mFrameType = get<2>(params);
46         refFilePath = gEnv->getRes() + get<3>(params);
47         mMemOperator.Alloc = cmnMemAlloc;
48         mMemOperator.Copy = cmnMemCopy;
49         mMemOperator.Free = cmnMemFree;
50         mMemOperator.Set = cmnMemSet;
51         mMemOperator.Check = cmnMemCheck;
52 
53         mUserData.memflag = VO_IMF_USERMEMOPERATOR;
54         mUserData.memData = (VO_PTR)(&mMemOperator);
55     }
56 
~AmrwbEncoderTest()57     ~AmrwbEncoderTest() {
58         if (mEncoderHandle) {
59             mEncoderHandle = nullptr;
60         }
61     }
62 
63     string mInputFile;
64     unsigned char mOutputBuf[kOutputBufferSize];
65     unsigned char mInputBuf[kInputBufferSize];
66     VOAMRWBFRAMETYPE mFrameType;
67     VO_AUDIO_CODECAPI mApiHandle;
68     VO_MEM_OPERATOR mMemOperator;
69     VO_CODEC_INIT_USERDATA mUserData;
70     VO_HANDLE mEncoderHandle;
71     int32_t mMode;
72     string refFilePath;
73 
74     bool compareBinaryFiles(const string& refFilePath, const string& outFilePath);
75 };
76 
compareBinaryFiles(const std::string & refFilePath,const std::string & outFilePath)77 bool AmrwbEncoderTest::compareBinaryFiles(const std::string &refFilePath,
78                                           const std::string &outFilePath) {
79     std::ifstream refFile(refFilePath, std::ios::binary | std::ios::ate);
80     std::ifstream outFile(outFilePath, std::ios::binary | std::ios::ate);
81     assert(refFile.is_open() && "Error opening reference file " + refFilePath);
82     assert(outFile.is_open() && "Error opening output file " + outFilePath);
83 
84     std::streamsize refFileSize = refFile.tellg();
85     std::streamsize outFileSize = outFile.tellg();
86     if (refFileSize != outFileSize) {
87         ALOGE("Error, File size mismatch: Reference file size = %td bytes,"
88                "but output file size = %td bytes", refFileSize, outFileSize);
89         return false;
90     }
91 
92     refFile.seekg(0, std::ios::beg);
93     outFile.seekg(0, std::ios::beg);
94     constexpr std::streamsize kBufferSize = 16 * 1024;
95     char refBuffer[kBufferSize];
96     char outBuffer[kBufferSize];
97 
98     while (refFile && outFile) {
99         refFile.read(refBuffer, kBufferSize);
100         outFile.read(outBuffer, kBufferSize);
101 
102         std::streamsize refBytesRead = refFile.gcount();
103         std::streamsize outBytesRead = outFile.gcount();
104 
105         if (refBytesRead != outBytesRead || memcmp(refBuffer, outBuffer, refBytesRead) != 0) {
106             ALOGE("Error, File content mismatch.");
107             return false;
108         }
109     }
110     return true;
111 }
112 
TEST_P(AmrwbEncoderTest,CreateAmrwbEncoderTest)113 TEST_P(AmrwbEncoderTest, CreateAmrwbEncoderTest) {
114     int32_t status = voGetAMRWBEncAPI(&mApiHandle);
115     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to get api handle";
116 
117     status = mApiHandle.Init(&mEncoderHandle, VO_AUDIO_CodingAMRWB, &mUserData);
118     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to init AMRWB encoder";
119 
120     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &mFrameType);
121     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder frame type to " << mFrameType;
122 
123     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_MODE, &mMode);
124     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder mode to %d" << mMode;
125     ALOGV("AMR-WB encoder created successfully");
126 
127     status = mApiHandle.Uninit(mEncoderHandle);
128     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to delete AMRWB encoder";
129     ALOGV("AMR-WB encoder deleted successfully");
130 }
131 
TEST_P(AmrwbEncoderTest,AmrwbEncodeTest)132 TEST_P(AmrwbEncoderTest, AmrwbEncodeTest) {
133     VO_CODECBUFFER inData;
134     VO_CODECBUFFER outData;
135     VO_AUDIO_OUTPUTINFO outFormat;
136 
137     FILE *fpInput = fopen(mInputFile.c_str(), "rb");
138     ASSERT_NE(fpInput, nullptr) << "Error opening input file " << mInputFile;
139 
140     FILE *fpOutput = fopen(OUTPUT_FILE, "wb");
141     ASSERT_NE(fpOutput, nullptr) << "Error opening output file " << OUTPUT_FILE;
142 
143     uint32_t status = voGetAMRWBEncAPI(&mApiHandle);
144     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to get api handle";
145 
146     status = mApiHandle.Init(&mEncoderHandle, VO_AUDIO_CodingAMRWB, &mUserData);
147     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to init AMRWB encoder";
148 
149     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &mFrameType);
150     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder frame type to " << mFrameType;
151 
152     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_MODE, &mMode);
153     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder mode to " << mMode;
154 
155     if (mFrameType == VOAMRWB_RFC3267) {
156         /* write RFC3267 Header info to indicate single channel AMR file storage format */
157         int32_t size = strlen(VOAMRWB_RFC3267_HEADER_INFO);
158         memcpy(mOutputBuf, VOAMRWB_RFC3267_HEADER_INFO, size);
159         fwrite(mOutputBuf, 1, size, fpOutput);
160     }
161 
162     int32_t frameNum = 0;
163     while (1) {
164         int32_t buffLength =
165                 (int32_t)fread(mInputBuf, sizeof(signed char), kInputBufferSize, fpInput);
166 
167         if (buffLength == 0 || feof(fpInput)) break;
168         ASSERT_EQ(buffLength, kInputBufferSize) << "Error in reading input file";
169 
170         inData.Buffer = (unsigned char *)mInputBuf;
171         inData.Length = buffLength;
172         outData.Buffer = mOutputBuf;
173         status = mApiHandle.SetInputData(mEncoderHandle, &inData);
174         ASSERT_EQ(status, VO_ERR_NONE) << "Failed to setup Input data";
175 
176         do {
177             status = mApiHandle.GetOutputData(mEncoderHandle, &outData, &outFormat);
178             ASSERT_NE(status, VO_ERR_LICENSE_ERROR) << "Failed to encode the file";
179             if (status == 0) {
180                 frameNum++;
181                 fwrite(outData.Buffer, 1, outData.Length, fpOutput);
182                 fflush(fpOutput);
183             }
184         } while (status != VO_ERR_INPUT_BUFFER_SMALL);
185     }
186 
187     ALOGV("Number of frames processed: %d", frameNum);
188     status = mApiHandle.Uninit(mEncoderHandle);
189     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to delete AMRWB encoder";
190 
191     if (fpInput) {
192         fclose(fpInput);
193     }
194     if (fpOutput) {
195         fclose(fpOutput);
196     }
197 
198     ASSERT_TRUE(compareBinaryFiles(refFilePath, OUTPUT_FILE))
199     << "Error, Binary file comparison failed: Output file "
200     << OUTPUT_FILE << " does not match the reference file " << refFilePath << ".";
201 }
202 
203 INSTANTIATE_TEST_SUITE_P(
204     AmrwbEncoderTestAll, AmrwbEncoderTest,
205     ::testing::Values(
206         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD66, VOAMRWB_DEFAULT,
207                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD66_VOAMRWB_DEFAULT_ref.amrwb"),
208         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD885, VOAMRWB_DEFAULT,
209                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD885_VOAMRWB_DEFAULT_ref.amrwb"),
210         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1265, VOAMRWB_DEFAULT,
211                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1265_VOAMRWB_DEFAULT_ref.amrwb"),
212         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1425, VOAMRWB_DEFAULT,
213                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1425_VOAMRWB_DEFAULT_ref.amrwb"),
214         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1585, VOAMRWB_DEFAULT,
215                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1585_VOAMRWB_DEFAULT_ref.amrwb"),
216         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1825, VOAMRWB_DEFAULT,
217                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1825_VOAMRWB_DEFAULT_ref.amrwb"),
218         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1985, VOAMRWB_DEFAULT,
219                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1985_VOAMRWB_DEFAULT_ref.amrwb"),
220         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2305, VOAMRWB_DEFAULT,
221                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD2305_VOAMRWB_DEFAULT_ref.amrwb"),
222         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2385, VOAMRWB_DEFAULT,
223                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD2385_VOAMRWB_DEFAULT_ref.amrwb"),
224         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD66, VOAMRWB_ITU,
225                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD66_VOAMRWB_ITU_ref.amrwb"),
226         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD885, VOAMRWB_ITU,
227                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD885_VOAMRWB_ITU_ref.amrwb"),
228         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1265, VOAMRWB_ITU,
229                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1265_VOAMRWB_ITU_ref.amrwb"),
230         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1425, VOAMRWB_ITU,
231                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1425_VOAMRWB_ITU_ref.amrwb"),
232         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1585, VOAMRWB_ITU,
233                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1585_VOAMRWB_ITU_ref.amrwb"),
234         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1825, VOAMRWB_ITU,
235                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1825_VOAMRWB_ITU_ref.amrwb"),
236         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1985, VOAMRWB_ITU,
237                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1985_VOAMRWB_ITU_ref.amrwb"),
238         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2305, VOAMRWB_ITU,
239                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD2305_VOAMRWB_ITU_ref.amrwb"),
240         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2385, VOAMRWB_ITU,
241                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD2385_VOAMRWB_ITU_ref.amrwb"),
242         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD66, VOAMRWB_RFC3267,
243                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD66_VOAMRWB_RFC3267_ref.amrwb"),
244         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD885, VOAMRWB_RFC3267,
245                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD885_VOAMRWB_RFC3267_ref.amrwb"),
246         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1265, VOAMRWB_RFC3267,
247                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1265_VOAMRWB_RFC3267_ref.amrwb"),
248         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1425, VOAMRWB_RFC3267,
249                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1425_VOAMRWB_RFC3267_ref.amrwb"),
250         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1585, VOAMRWB_RFC3267,
251                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1585_VOAMRWB_RFC3267_ref.amrwb"),
252         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1825, VOAMRWB_RFC3267,
253                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1825_VOAMRWB_RFC3267_ref.amrwb"),
254         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1985, VOAMRWB_RFC3267,
255                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD1985_VOAMRWB_RFC3267_ref.amrwb"),
256         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2305, VOAMRWB_RFC3267,
257                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD2305_VOAMRWB_RFC3267_ref.amrwb"),
258         make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2385, VOAMRWB_RFC3267,
259                     "bbb_raw_1ch_16khz_s16le_VOAMRWB_MD2385_VOAMRWB_RFC3267_ref.amrwb")));
260 
main(int argc,char ** argv)261 int main(int argc, char **argv) {
262     gEnv = new AmrwbEncTestEnvironment();
263     ::testing::AddGlobalTestEnvironment(gEnv);
264     ::testing::InitGoogleTest(&argc, argv);
265     int status = gEnv->initFromOptions(argc, argv);
266     if (status == 0) {
267         status = RUN_ALL_TESTS();
268         ALOGV("Test result = %d\n", status);
269     }
270     return status;
271 }
272