1 /* Copyright 2020 Rockchip Electronics Co. LTD
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #undef DBG_MOD_ID
17 #define DBG_MOD_ID RK_ID_SYS
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <cstring>
22 #include <cstdlib>
23
24 #include "rk_debug.h"
25 #include "rk_mpi_sys.h"
26 #include "rk_mpi_ao.h"
27 #include "rk_mpi_adec.h"
28
29 #include "test_comm_argparse.h"
30
31 typedef struct _rkTestSysCtx {
32 RK_S32 s32LoopCount;
33 RK_S32 s32DevId;
34 RK_S32 s32SrcChnId;
35 RK_S32 s32DstChnNum;
36
37 ADEC_CHN_ATTR_S *pstADecChnAttr;
38 } TEST_SYS_CTX_S;
39
test_ao_dev_init(TEST_SYS_CTX_S * pstCtx)40 RK_S32 test_ao_dev_init(TEST_SYS_CTX_S *pstCtx) {
41 AUDIO_DEV aoDevId = (AUDIO_DEV)pstCtx->s32DevId;
42 AIO_ATTR_S aoAttr;
43
44 memset(&aoAttr, 0, sizeof(AIO_ATTR_S));
45 aoAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
46 aoAttr.enSamplerate = AUDIO_SAMPLE_RATE_44100;
47 aoAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
48 aoAttr.u32FrmNum = 512;
49 aoAttr.u32PtNumPerFrm = 1024;
50 aoAttr.u32EXFlag = 0;
51 aoAttr.u32ChnCnt = 2;
52
53 RK_MPI_AO_SetPubAttr(aoDevId, &aoAttr);
54 RK_MPI_AO_Enable(aoDevId);
55
56 return RK_SUCCESS;
57 }
58
test_ao_dev_deinit(TEST_SYS_CTX_S * pstCtx)59 RK_S32 test_ao_dev_deinit(TEST_SYS_CTX_S *pstCtx) {
60 RK_S32 s32Ret = RK_SUCCESS;
61
62 s32Ret = RK_MPI_AO_Disable(pstCtx->s32DevId);
63 if (s32Ret != RK_SUCCESS) {
64 RK_LOGE("failed to disable ao dev, err: %d", s32Ret);
65 return RK_FAILURE;
66 }
67
68 return s32Ret;
69 }
70
test_adec_create_chn_attr()71 ADEC_CHN_ATTR_S* test_adec_create_chn_attr() {
72 ADEC_CHN_ATTR_S *pstChnAttr = reinterpret_cast<ADEC_CHN_ATTR_S *>
73 (malloc(sizeof(ADEC_CHN_ATTR_S)));
74 memset(pstChnAttr, 0, sizeof(ADEC_CHN_ATTR_S));
75 ADEC_ATTR_CODEC_S *pstCodecAttr = &pstChnAttr->stCodecAttr;
76
77 // attr of adec
78 pstCodecAttr->u32Channels = 2;
79 pstCodecAttr->u32SampleRate = 16000;
80 pstCodecAttr->u32ExtraDataSize = 0;
81 pstCodecAttr->pExtraData = RK_NULL;
82
83 // attr of chn
84 pstChnAttr->enType = RK_AUDIO_ID_ADPCM_G726;
85 pstChnAttr->enMode = ADEC_MODE_PACK;
86 pstChnAttr->u32BufCount = 4;
87 pstChnAttr->u32BufSize = 8192;
88
89 return pstChnAttr;
90 }
91
test_adec_destroy_chn_attr(ADEC_CHN_ATTR_S ** ppstChnAttr)92 void test_adec_destroy_chn_attr(ADEC_CHN_ATTR_S **ppstChnAttr) {
93 ADEC_CHN_ATTR_S *pstChnAttr = *ppstChnAttr;
94 if (pstChnAttr == RK_NULL) {
95 return;
96 }
97
98 ADEC_ATTR_CODEC_S *pstCodecAttr = &pstChnAttr->stCodecAttr;
99 if (pstCodecAttr->pExtraData != RK_NULL) {
100 free(pstCodecAttr->pExtraData);
101 pstCodecAttr->pExtraData = RK_NULL;
102 }
103 pstCodecAttr->u32ExtraDataSize = 0;
104
105 free(pstChnAttr);
106 *ppstChnAttr = RK_NULL;
107 }
108
test_adec_create_channel(TEST_SYS_CTX_S * pstCtx,RK_S32 s32ChnId)109 RK_S32 test_adec_create_channel(TEST_SYS_CTX_S *pstCtx, RK_S32 s32ChnId) {
110 RK_S32 s32Ret = RK_SUCCESS;
111 ADEC_CHN AdChn = (ADEC_CHN)s32ChnId;
112 ADEC_CHN_ATTR_S *pstChnAttr = test_adec_create_chn_attr();
113 s32Ret = RK_MPI_ADEC_CreateChn(AdChn, pstChnAttr);
114 if (s32Ret) {
115 RK_LOGE("failed to create adec chn %d, err %d", AdChn, s32Ret);
116 return RK_FAILURE;
117 }
118
119 return s32Ret;
120 }
121
test_adec_destroy_channel(TEST_SYS_CTX_S * pstCtx,RK_S32 s32ChnId)122 RK_S32 test_adec_destroy_channel(TEST_SYS_CTX_S *pstCtx, RK_S32 s32ChnId) {
123 RK_S32 s32Ret = RK_SUCCESS;
124 RK_S32 s32DevId = pstCtx->s32DevId;
125 ADEC_CHN AdChn = (ADEC_CHN)s32ChnId;
126
127 s32Ret = RK_MPI_ADEC_DestroyChn(AdChn);
128 if (s32Ret != RK_SUCCESS) {
129 RK_LOGE("failed to destroy adec channel(%d), err: %d", AdChn, s32Ret);
130 }
131
132 test_adec_destroy_chn_attr(&pstCtx->pstADecChnAttr);
133 return s32Ret;
134 }
135
test_ao_enable_channel(TEST_SYS_CTX_S * pstCtx,RK_S32 s32ChnId)136 RK_S32 test_ao_enable_channel(TEST_SYS_CTX_S *pstCtx, RK_S32 s32ChnId) {
137 RK_S32 s32Ret = RK_SUCCESS;
138 ADEC_CHN AdChn = (ADEC_CHN)s32ChnId;
139
140 s32Ret = RK_MPI_AO_EnableChn(pstCtx->s32DevId, AdChn);
141 if (s32Ret != 0) {
142 RK_LOGE("failed to enable ao chn %d, err %d", AdChn, s32Ret);
143 return RK_FAILURE;
144 }
145
146 return s32Ret;
147 }
148
test_ao_disable_channel(TEST_SYS_CTX_S * pstCtx,RK_S32 s32ChnId)149 RK_S32 test_ao_disable_channel(TEST_SYS_CTX_S *pstCtx, RK_S32 s32ChnId) {
150 RK_S32 s32Ret = RK_SUCCESS;
151 AO_CHN AoChn = (AO_CHN)s32ChnId;
152
153 s32Ret = RK_MPI_AO_DisableChn(pstCtx->s32DevId, AoChn);
154 if (s32Ret != RK_SUCCESS) {
155 RK_LOGE("failed to disable ao channel(%d), err: %d", AoChn, s32Ret);
156 return RK_FAILURE;
157 }
158
159 return RK_SUCCESS;
160 }
161
test_bind_adec_ao(TEST_SYS_CTX_S * pstCtx,RK_S32 s32SrcChnId,RK_S32 s32DstChnId)162 RK_S32 test_bind_adec_ao(TEST_SYS_CTX_S *pstCtx, RK_S32 s32SrcChnId, RK_S32 s32DstChnId) {
163 RK_S32 s32Ret = RK_SUCCESS;
164 RK_S32 s32DevId = pstCtx->s32DevId;
165 MPP_CHN_S stSrcChn, stDstChn;
166
167 stSrcChn.enModId = RK_ID_ADEC;
168 stSrcChn.s32DevId = s32DevId;
169 stSrcChn.s32ChnId = s32SrcChnId;
170
171 stDstChn.enModId = RK_ID_AO;
172 stDstChn.s32DevId = s32DevId;
173 stDstChn.s32ChnId = s32DstChnId;
174 s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDstChn);
175
176 return s32Ret;
177 }
178
test_unbind_adec_ao(TEST_SYS_CTX_S * pstCtx,RK_S32 s32SrcChnId,RK_S32 s32DstChnId)179 RK_S32 test_unbind_adec_ao(TEST_SYS_CTX_S *pstCtx, RK_S32 s32SrcChnId, RK_S32 s32DstChnId) {
180 RK_S32 s32Ret = RK_SUCCESS;
181 RK_S32 s32DevId = pstCtx->s32DevId;
182
183 MPP_CHN_S stSrcChn, stDstChn;
184 stSrcChn.enModId = RK_ID_ADEC;
185 stSrcChn.s32DevId = s32DevId;
186 stSrcChn.s32ChnId = s32SrcChnId;
187
188 stDstChn.enModId = RK_ID_AO;
189 stDstChn.s32DevId = s32DevId;
190 stDstChn.s32ChnId = s32DstChnId;
191 s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn);
192
193 return s32Ret;
194 }
195
test_mpi_sys_get_bind_by_src(TEST_SYS_CTX_S * pstCtx,RK_S32 s32ChnId)196 RK_S32 test_mpi_sys_get_bind_by_src(TEST_SYS_CTX_S *pstCtx, RK_S32 s32ChnId) {
197 RK_S32 s32Ret = RK_SUCCESS;
198 MPP_CHN_S stSrcChn;
199 MPP_BIND_DEST_S pstBindDest;
200
201 memset(&stSrcChn, 0, sizeof(MPP_CHN_S));
202 memset(&pstBindDest, 0, sizeof(MPP_BIND_DEST_S));
203 stSrcChn.enModId = RK_ID_ADEC;
204 stSrcChn.s32DevId = pstCtx->s32DevId;
205 stSrcChn.s32ChnId = s32ChnId;
206 s32Ret = RK_MPI_SYS_GetBindbySrc(&stSrcChn, &pstBindDest);
207 if (s32Ret == RK_SUCCESS) {
208 for (RK_S32 i=0; i < pstBindDest.u32Num; i++) {
209 MPP_CHN_S *pstDstChn = &pstBindDest.astMppChn[i];
210 RK_LOGD("get dst channel(modId=%d, devId=%d, chnId=%d)",
211 pstDstChn->enModId, pstDstChn->s32DevId, pstDstChn->s32ChnId);
212 }
213 } else {
214 RK_LOGE("failed to RK_MPI_SYS_GetBindbySrc");
215 }
216
217 return s32Ret;
218 }
219
test_mpi_sys_get_bind_by_dest(TEST_SYS_CTX_S * pstCtx,RK_S32 s32ChnId)220 RK_S32 test_mpi_sys_get_bind_by_dest(TEST_SYS_CTX_S *pstCtx, RK_S32 s32ChnId) {
221 RK_S32 s32Ret = RK_SUCCESS;
222 MPP_CHN_S stSrcChn;
223 MPP_CHN_S stDstChn;
224
225 memset(&stSrcChn, 0, sizeof(MPP_CHN_S));
226 memset(&stDstChn, 0, sizeof(MPP_CHN_S));
227 stDstChn.enModId = RK_ID_AO;
228 stDstChn.s32DevId = pstCtx->s32DevId;
229 stDstChn.s32ChnId = s32ChnId;
230 s32Ret = RK_MPI_SYS_GetBindbyDest(&stDstChn, &stSrcChn);
231 if (s32Ret == RK_SUCCESS) {
232 RK_LOGD("get src channel(modId=%d, devId=%d, chnId=%d)",
233 stSrcChn.enModId, stSrcChn.s32DevId, stSrcChn.s32ChnId);
234 } else {
235 RK_LOGE("failed to RK_MPI_SYS_GetBindbyDest");
236 }
237
238 return s32Ret;
239 }
240
unit_test_mpi_sys_bind(TEST_SYS_CTX_S * pstCtx)241 RK_S32 unit_test_mpi_sys_bind(TEST_SYS_CTX_S *pstCtx) {
242 RK_S32 s32Ret = RK_SUCCESS;
243 RK_S32 s32SrcChnId = pstCtx->s32SrcChnId;
244 RK_S32 s32DstNumChn = pstCtx->s32DstChnNum;
245
246 // init Ao device
247 s32Ret = test_ao_dev_init(pstCtx);
248
249 // create adec channel
250 s32Ret = test_adec_create_channel(pstCtx, s32SrcChnId);
251 if (s32Ret != RK_SUCCESS) {
252 goto __FAILED_ADEC;
253 }
254
255 // enable ao channel
256 for (RK_S32 s32DstChnId = 0; s32DstChnId < s32DstNumChn; s32DstChnId++) {
257 s32Ret = test_ao_enable_channel(pstCtx, s32DstChnId);
258 if (s32Ret != RK_SUCCESS) {
259 goto __FAILED_AO;
260 }
261 // bind adec->ao
262 s32Ret = test_bind_adec_ao(pstCtx, s32SrcChnId, s32DstChnId);
263 if (s32Ret == RK_SUCCESS) {
264 RK_LOGD("succeed to bind ADEC(%d) AO(%d)", s32SrcChnId, s32DstChnId);
265 }
266 }
267
268 // test RK_MPI_SYS_GetBindbyDest/GetBindbySrc
269 s32Ret = test_mpi_sys_get_bind_by_src(pstCtx, s32SrcChnId);
270 for (RK_S32 s32DstChnId = 0; s32DstChnId < s32DstNumChn; s32DstChnId++) {
271 s32Ret = test_mpi_sys_get_bind_by_dest(pstCtx, s32DstChnId);
272 }
273
274 __FAILED_AO:
275 for (RK_S32 s32DstChnId = 0; s32DstChnId < s32DstNumChn; s32DstChnId++) {
276 // unbind adec->ao
277 s32Ret = test_unbind_adec_ao(pstCtx, s32SrcChnId, s32DstChnId);
278 if (s32Ret == RK_SUCCESS) {
279 RK_LOGD("succeed to unbind ADEC(%d) AO(%d)", s32SrcChnId, s32DstChnId);
280 }
281 // disable ao channel
282 test_ao_disable_channel(pstCtx, s32DstChnId);
283 }
284
285 test_adec_destroy_channel(pstCtx, s32SrcChnId);
286
287 __FAILED_ADEC:
288 // deinit Ao device
289 s32Ret = test_ao_dev_deinit(pstCtx);
290
291 return s32Ret;
292 }
293
unit_test_mpi_sys(TEST_SYS_CTX_S * pstCtx)294 RK_S32 unit_test_mpi_sys(TEST_SYS_CTX_S *pstCtx) {
295 RK_S32 s32Ret = RK_SUCCESS;
296 RK_S32 loopCount = pstCtx->s32LoopCount;
297 do {
298 s32Ret = unit_test_mpi_sys_bind(pstCtx);
299 loopCount--;
300 RK_LOGI("looping times %d", pstCtx->s32LoopCount - loopCount);
301 } while (loopCount > 0);
302
303 return s32Ret;
304 }
305
306 static const char *const usages[] = {
307 "./rk_mpi_sys_test...",
308 NULL,
309 };
310
main(RK_S32 argc,const char ** argv)311 RK_S32 main(RK_S32 argc, const char **argv) {
312 RK_S32 s32Ret = RK_SUCCESS;
313 TEST_SYS_CTX_S stCtx;
314
315 memset(&stCtx, 0, sizeof(TEST_SYS_CTX_S));
316 stCtx.s32LoopCount = 1;
317 stCtx.s32DevId = 0;
318 stCtx.s32SrcChnId = 0;
319 stCtx.s32DstChnNum = 1;
320
321 struct argparse_option options[] = {
322 OPT_HELP(),
323 OPT_GROUP("basic options:"),
324 OPT_INTEGER('n', "loop_count", &(stCtx.s32LoopCount),
325 "loop running count. default(1)", NULL, 0, 0),
326 OPT_INTEGER('\0', "device_id", &(stCtx.s32DevId),
327 "MODULE device id. default(0)", NULL, 0, 0),
328 OPT_INTEGER('\0', "src_channel_id", &(stCtx.s32SrcChnId),
329 "source MODULE channel id. default(0)", NULL, 0, 0),
330 OPT_INTEGER('\0', "dst_channel_count", &(stCtx.s32DstChnNum),
331 "the count of dst MODULE channel. default(1)", NULL, 0, 0),
332 OPT_END(),
333 };
334
335 struct argparse argparse;
336 argparse_init(&argparse, options, usages, 0);
337 argparse_describe(&argparse, "\nselect a test case to run.",
338 "\nuse --help for details.");
339
340 argc = argparse_parse(&argparse, argc, argv);
341
342 s32Ret = RK_MPI_SYS_Init();
343 if (s32Ret != RK_SUCCESS) {
344 return s32Ret;
345 }
346
347 s32Ret = unit_test_mpi_sys(&stCtx);
348 if (s32Ret != RK_SUCCESS) {
349 goto __FAILED;
350 }
351
352 s32Ret = RK_MPI_SYS_Exit();
353 if (s32Ret != RK_SUCCESS) {
354 return s32Ret;
355 }
356 RK_LOGI("test running ok.");
357 return RK_SUCCESS;
358
359 __FAILED:
360 RK_MPI_SYS_Exit();
361 RK_LOGE("test running failed!");
362 return s32Ret;
363 }
364