xref: /OK3568_Linux_fs/external/rockit/mpi/example/mod/test_mpi_sys.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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