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 
24 #include "cmnMemory.h"
25 #include "voAMRWB.h"
26 
27 #include "AmrwbEncTestEnvironment.h"
28 
29 #define OUTPUT_FILE "/data/local/tmp/amrwbEncode.out"
30 #define VOAMRWB_RFC3267_HEADER_INFO "#!AMR-WB\n"
31 
32 constexpr int32_t kInputBufferSize = 640;
33 constexpr int32_t kOutputBufferSize = 1024;
34 
35 static AmrwbEncTestEnvironment *gEnv = nullptr;
36 
37 class AmrwbEncoderTest : public ::testing::TestWithParam<tuple<string, int32_t, VOAMRWBFRAMETYPE>> {
38   public:
AmrwbEncoderTest()39     AmrwbEncoderTest() : mEncoderHandle(nullptr) {
40         tuple<string, int32_t, VOAMRWBFRAMETYPE> params = GetParam();
41         mInputFile = gEnv->getRes() + get<0>(params);
42         mMode = get<1>(params);
43         mFrameType = get<2>(params);
44         mMemOperator.Alloc = cmnMemAlloc;
45         mMemOperator.Copy = cmnMemCopy;
46         mMemOperator.Free = cmnMemFree;
47         mMemOperator.Set = cmnMemSet;
48         mMemOperator.Check = cmnMemCheck;
49 
50         mUserData.memflag = VO_IMF_USERMEMOPERATOR;
51         mUserData.memData = (VO_PTR)(&mMemOperator);
52     }
53 
~AmrwbEncoderTest()54     ~AmrwbEncoderTest() {
55         if (mEncoderHandle) {
56             mEncoderHandle = nullptr;
57         }
58     }
59 
60     string mInputFile;
61     unsigned char mOutputBuf[kOutputBufferSize];
62     unsigned char mInputBuf[kInputBufferSize];
63     VOAMRWBFRAMETYPE mFrameType;
64     VO_AUDIO_CODECAPI mApiHandle;
65     VO_MEM_OPERATOR mMemOperator;
66     VO_CODEC_INIT_USERDATA mUserData;
67     VO_HANDLE mEncoderHandle;
68     int32_t mMode;
69 };
70 
TEST_P(AmrwbEncoderTest,CreateAmrwbEncoderTest)71 TEST_P(AmrwbEncoderTest, CreateAmrwbEncoderTest) {
72     int32_t status = voGetAMRWBEncAPI(&mApiHandle);
73     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to get api handle";
74 
75     status = mApiHandle.Init(&mEncoderHandle, VO_AUDIO_CodingAMRWB, &mUserData);
76     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to init AMRWB encoder";
77 
78     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &mFrameType);
79     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder frame type to " << mFrameType;
80 
81     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_MODE, &mMode);
82     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder mode to %d" << mMode;
83     ALOGV("AMR-WB encoder created successfully");
84 
85     status = mApiHandle.Uninit(mEncoderHandle);
86     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to delete AMRWB encoder";
87     ALOGV("AMR-WB encoder deleted successfully");
88 }
89 
TEST_P(AmrwbEncoderTest,AmrwbEncodeTest)90 TEST_P(AmrwbEncoderTest, AmrwbEncodeTest) {
91     VO_CODECBUFFER inData;
92     VO_CODECBUFFER outData;
93     VO_AUDIO_OUTPUTINFO outFormat;
94 
95     FILE *fpInput = fopen(mInputFile.c_str(), "rb");
96     ASSERT_NE(fpInput, nullptr) << "Error opening input file " << mInputFile;
97 
98     FILE *fpOutput = fopen(OUTPUT_FILE, "wb");
99     ASSERT_NE(fpOutput, nullptr) << "Error opening output file " << OUTPUT_FILE;
100 
101     uint32_t status = voGetAMRWBEncAPI(&mApiHandle);
102     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to get api handle";
103 
104     status = mApiHandle.Init(&mEncoderHandle, VO_AUDIO_CodingAMRWB, &mUserData);
105     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to init AMRWB encoder";
106 
107     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &mFrameType);
108     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder frame type to " << mFrameType;
109 
110     status = mApiHandle.SetParam(mEncoderHandle, VO_PID_AMRWB_MODE, &mMode);
111     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to set AMRWB encoder mode to " << mMode;
112 
113     if (mFrameType == VOAMRWB_RFC3267) {
114         /* write RFC3267 Header info to indicate single channel AMR file storage format */
115         int32_t size = strlen(VOAMRWB_RFC3267_HEADER_INFO);
116         memcpy(mOutputBuf, VOAMRWB_RFC3267_HEADER_INFO, size);
117         fwrite(mOutputBuf, 1, size, fpOutput);
118     }
119 
120     int32_t frameNum = 0;
121     while (1) {
122         int32_t buffLength =
123                 (int32_t)fread(mInputBuf, sizeof(signed char), kInputBufferSize, fpInput);
124 
125         if (buffLength == 0 || feof(fpInput)) break;
126         ASSERT_EQ(buffLength, kInputBufferSize) << "Error in reading input file";
127 
128         inData.Buffer = (unsigned char *)mInputBuf;
129         inData.Length = buffLength;
130         outData.Buffer = mOutputBuf;
131         status = mApiHandle.SetInputData(mEncoderHandle, &inData);
132         ASSERT_EQ(status, VO_ERR_NONE) << "Failed to setup Input data";
133 
134         do {
135             status = mApiHandle.GetOutputData(mEncoderHandle, &outData, &outFormat);
136             ASSERT_NE(status, VO_ERR_LICENSE_ERROR) << "Failed to encode the file";
137             if (status == 0) {
138                 frameNum++;
139                 fwrite(outData.Buffer, 1, outData.Length, fpOutput);
140                 fflush(fpOutput);
141             }
142         } while (status != VO_ERR_INPUT_BUFFER_SMALL);
143     }
144 
145     ALOGV("Number of frames processed: %d", frameNum);
146     status = mApiHandle.Uninit(mEncoderHandle);
147     ASSERT_EQ(status, VO_ERR_NONE) << "Failed to delete AMRWB encoder";
148 
149     if (fpInput) {
150         fclose(fpInput);
151     }
152     if (fpOutput) {
153         fclose(fpOutput);
154     }
155 }
156 
157 INSTANTIATE_TEST_SUITE_P(
158         AmrwbEncoderTestAll, AmrwbEncoderTest,
159         ::testing::Values(
160                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD66, VOAMRWB_DEFAULT),
161                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD885, VOAMRWB_DEFAULT),
162                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1265, VOAMRWB_DEFAULT),
163                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1425, VOAMRWB_DEFAULT),
164                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1585, VOAMRWB_DEFAULT),
165                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1825, VOAMRWB_DEFAULT),
166                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1985, VOAMRWB_DEFAULT),
167                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2305, VOAMRWB_DEFAULT),
168                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2385, VOAMRWB_DEFAULT),
169                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD66, VOAMRWB_ITU),
170                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD885, VOAMRWB_ITU),
171                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1265, VOAMRWB_ITU),
172                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1425, VOAMRWB_ITU),
173                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1585, VOAMRWB_ITU),
174                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1825, VOAMRWB_ITU),
175                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1985, VOAMRWB_ITU),
176                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2305, VOAMRWB_ITU),
177                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2385, VOAMRWB_ITU),
178                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD66, VOAMRWB_RFC3267),
179                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD885, VOAMRWB_RFC3267),
180                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1265, VOAMRWB_RFC3267),
181                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1425, VOAMRWB_RFC3267),
182                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1585, VOAMRWB_RFC3267),
183                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1825, VOAMRWB_RFC3267),
184                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD1985, VOAMRWB_RFC3267),
185                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2305, VOAMRWB_RFC3267),
186                 make_tuple("bbb_raw_1ch_16khz_s16le.raw", VOAMRWB_MD2385, VOAMRWB_RFC3267)));
187 
main(int argc,char ** argv)188 int main(int argc, char **argv) {
189     gEnv = new AmrwbEncTestEnvironment();
190     ::testing::AddGlobalTestEnvironment(gEnv);
191     ::testing::InitGoogleTest(&argc, argv);
192     int status = gEnv->initFromOptions(argc, argv);
193     if (status == 0) {
194         status = RUN_ALL_TESTS();
195         ALOGV("Test result = %d\n", status);
196     }
197     return status;
198 }
199