main_multi_instance_test.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. // SPDX-License-Identifier: LGPL-2.1 OR BSD-3-Clause
  2. /*
  3. * Copyright (c) 2019, Chips&Media
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <stdio.h>
  27. #include <stdint.h>
  28. #include <string.h>
  29. #include <time.h>
  30. #include <getopt.h>
  31. #include "main_helper.h"
  32. #include "cnm_app.h"
  33. #include "decoder_listener.h"
  34. #include "encoder_listener.h"
  35. enum waitStatus {
  36. WAIT_AFTER_INIT = 0,
  37. WAIT_AFTER_DEC_OPEN = 1,
  38. WAIT_AFTER_SEQ_INIT = 2,
  39. WAIT_AFTER_REG_BUF = 3,
  40. WAIT_BEFORE_DEC_START = 4,
  41. WAIT_BEFORE_DEC_CLOSE = 5,
  42. WAIT_AFTER_ENC_OPEN = 6,
  43. WAIT_AFTER_INIT_SEQ = 7,
  44. WAIT_AFTER_REG_FRAME = 8,
  45. WAIT_BEFORE_ENC_START = 9,
  46. WAIT_BEFORE_ENC_CLOSE = 10,
  47. WAIT_NOT_DEFINED = 11,
  48. WAIT_STATUS_MAX
  49. };
  50. enum get_result_status{
  51. GET_RESULT_INIT,
  52. GET_RESULT_BEFORE_WAIT_INT, //before calling wait interrupt.
  53. GET_RESULT_AFTER_WAIT_INT //got interrupt.
  54. };
  55. static Uint32 sizeInWord;
  56. static Uint16* pusBitCode;
  57. typedef struct {
  58. char inputFilePath[256];
  59. char localFile[256];
  60. char outputFilePath[256];
  61. char refFilePath[256];
  62. CodStd stdMode;
  63. BOOL afbce;
  64. BOOL afbcd;
  65. BOOL scaler;
  66. size_t sclw;
  67. size_t sclh;
  68. Int32 bsmode;
  69. BOOL enableWTL;
  70. BOOL enableMVC;
  71. int compareType;
  72. TestDecConfig decConfig;
  73. TestEncConfig encConfig;
  74. BOOL isEncoder;
  75. } InstTestConfig;
  76. typedef struct {
  77. Uint32 totProcNum; /* the number of process */
  78. Uint32 curProcNum;
  79. Uint32 numMulti;
  80. Uint32 cores;
  81. BOOL performance; /* for performance measurement */
  82. Uint32 pfClock; /* for performance measurement */
  83. Uint32 fps; /* for performance measurement */
  84. Uint32 numFrames;
  85. InstTestConfig instConfig[MAX_NUM_INSTANCE];
  86. } TestMultiConfig;
  87. static void WaitForNextStep(Int32 instIdx, Int32 curStepName)
  88. {
  89. }
  90. static void Help(const char *programName)
  91. {
  92. VLOG(INFO, "------------------------------------------------------------------------------\n");
  93. VLOG(INFO, "%s(API v%d.%d.%d)\n", GetBasename(programName), API_VERSION_MAJOR, API_VERSION_MINOR, API_VERSION_PATCH);
  94. VLOG(INFO, "\tAll rights reserved by Chips&Media(C)\n");
  95. VLOG(INFO, "\tSample program controlling the Chips&Media VPU\n");
  96. VLOG(INFO, "------------------------------------------------------------------------------\n");
  97. VLOG(INFO, "%s [option] --input <stream list file, aka cmd file>\n", GetBasename(programName));
  98. VLOG(INFO, "-h help\n");
  99. VLOG(INFO, "-c enable comparison mode\n");
  100. VLOG(INFO, " 1 : compare with golden stream that specified --ref_file_path option\n");
  101. VLOG(INFO, "-e 0 : decoder, 1: encoder\n");
  102. VLOG(INFO, "-n number of frames\n");
  103. VLOG(INFO, "--codec The index of codec\n");
  104. VLOG(INFO, " AVC = 0, VC1 = 1, MPEG2 = 2, MPEG4 = 3, H263 = 4\n");
  105. VLOG(INFO, " DIV3 = 5, RV = 6, AVS = 7, THO = 9, VP3 = 10, VP8 = 11, HEVC = 12, VP9 = 13\n");
  106. VLOG(INFO, " AVC_ENC = 14, MP4_ENC = 17, H263_ENC = 18, HEVC_ENC = 26\n");
  107. VLOG(INFO, "--input bitstream(decoder) or cfg(encoder) path\n");
  108. VLOG(INFO, "--output yuv(decoder) or bitstream(encoder) path\n");
  109. VLOG(INFO, "--ref_file_path Golden md5 or stream path\n");
  110. VLOG(INFO, "--pf 0: disable peformance report(default), 1: enable performance report\n");
  111. VLOG(INFO, "--pf-clock peformance clock in Hz(It must be BCLK for WAVE5 series).\n");
  112. VLOG(INFO, "--scaler enable scaler option. default 0\n");
  113. VLOG(INFO, "--sclw set scale width value.\n");
  114. VLOG(INFO, "--sclh set scale height value.\n");
  115. VLOG(INFO, "--bsmode set bitstream mode.\n");
  116. VLOG(INFO, "--enable-wtl enable wtl option. default 0\n");
  117. }
  118. static void SetEncMultiParam(TestMultiConfig* multiConfig, Uint32 idx, Int32 productId)
  119. {
  120. InstTestConfig *instConfig = &multiConfig->instConfig[idx];
  121. TestEncConfig *encCfg = &instConfig->encConfig;
  122. encCfg->stdMode = multiConfig->instConfig[idx].stdMode;
  123. encCfg->frame_endian = 0;
  124. encCfg->stream_endian = 0;
  125. encCfg->yuv_mode = YUV_MODE_YUV_LOADER;
  126. encCfg->mapType = LINEAR_FRAME_MAP;
  127. if (TRUE == PRODUCT_ID_W_SERIES(productId)) {
  128. encCfg->mapType = COMPRESSED_FRAME_MAP;
  129. }
  130. strcpy(encCfg->cfgFileName, multiConfig->instConfig[idx].inputFilePath);
  131. strcpy(encCfg->bitstreamFileName, multiConfig->instConfig[idx].outputFilePath);
  132. if (TRUE == PRODUCT_ID_W_SERIES(productId)) {
  133. if (multiConfig->instConfig[idx].compareType == MD5_COMPARE) {
  134. encCfg->compareType |= (1 << MODE_COMP_RECON);
  135. strcpy(encCfg->ref_recon_md5_path, multiConfig->instConfig[idx].refFilePath);
  136. }
  137. else if (multiConfig->instConfig[idx].compareType == STREAM_COMPARE) {
  138. encCfg->compareType |= (1 << MODE_COMP_ENCODED);
  139. strcpy(encCfg->ref_stream_path, multiConfig->instConfig[idx].refFilePath);
  140. }
  141. }
  142. else { // coda9 encoder case
  143. char imageRootDir[256]="./yuv";
  144. encCfg->compareType = (TRUE == (BOOL)multiConfig->instConfig[idx].compareType) ? STREAM_COMPARE : NO_COMPARE;
  145. strcpy(encCfg->ref_stream_path, multiConfig->instConfig[idx].refFilePath);
  146. strcpy(encCfg->yuvSourceBaseDir, imageRootDir);
  147. multiConfig->instConfig[idx].encConfig.lineBufIntEn = TRUE;
  148. }
  149. multiConfig->instConfig[idx].encConfig.performance = multiConfig->performance;
  150. multiConfig->instConfig[idx].encConfig.pfClock = multiConfig->pfClock;
  151. multiConfig->instConfig[idx].encConfig.fps = multiConfig->fps;
  152. multiConfig->instConfig[idx].encConfig.outNum = multiConfig->numFrames;
  153. encCfg->srcFormat = FORMAT_420_P10_16BIT_LSB;
  154. multiConfig->instConfig[idx].encConfig.productId = productId;
  155. }
  156. static void SetDecMultiParam(TestMultiConfig* multiConfig, Uint32 idx, Int32 productId)
  157. {
  158. multiConfig->instConfig[idx].decConfig.bitFormat = multiConfig->instConfig[idx].stdMode;
  159. multiConfig->instConfig[idx].decConfig.bitstreamMode = multiConfig->instConfig[idx].bsmode;
  160. multiConfig->instConfig[idx].decConfig.feedingMode = (multiConfig->instConfig[idx].bsmode == BS_MODE_INTERRUPT) ? FEEDING_METHOD_FIXED_SIZE : FEEDING_METHOD_FRAME_SIZE;
  161. multiConfig->instConfig[idx].decConfig.streamEndian = VPU_STREAM_ENDIAN;
  162. multiConfig->instConfig[idx].decConfig.frameEndian = VPU_FRAME_ENDIAN;
  163. multiConfig->instConfig[idx].decConfig.cbcrInterleave = FALSE;
  164. multiConfig->instConfig[idx].decConfig.nv21 = FALSE;
  165. multiConfig->instConfig[idx].decConfig.enableWTL = multiConfig->instConfig[idx].enableWTL;
  166. multiConfig->instConfig[idx].decConfig.coda9.enableMvc = multiConfig->instConfig[idx].enableMVC;
  167. multiConfig->instConfig[idx].decConfig.wtlMode = FF_FRAME;
  168. multiConfig->instConfig[idx].decConfig.wtlFormat = FORMAT_420;
  169. if (TRUE == PRODUCT_ID_W_SERIES(productId)) {
  170. multiConfig->instConfig[idx].decConfig.mapType = COMPRESSED_FRAME_MAP;
  171. multiConfig->instConfig[idx].decConfig.wave.bwOptimization = TRUE;
  172. }
  173. else
  174. {
  175. multiConfig->instConfig[idx].decConfig.mapType = LINEAR_FRAME_MAP;
  176. }
  177. multiConfig->instConfig[idx].decConfig.bsSize = (5*1024*1024);
  178. multiConfig->instConfig[idx].decConfig.productId = productId;
  179. if (multiConfig->instConfig[idx].scaler == TRUE) {
  180. multiConfig->instConfig[idx].decConfig.scaleDownWidth = multiConfig->instConfig[idx].sclw;
  181. multiConfig->instConfig[idx].decConfig.scaleDownHeight = multiConfig->instConfig[idx].sclh;
  182. }
  183. strcpy(multiConfig->instConfig[idx].decConfig.inputPath, multiConfig->instConfig[idx].inputFilePath);
  184. if (multiConfig->instConfig[idx].localFile[0]) {
  185. strcpy(multiConfig->instConfig[idx].decConfig.inputPath, multiConfig->instConfig[idx].localFile);
  186. }
  187. strcpy(multiConfig->instConfig[idx].decConfig.outputPath, multiConfig->instConfig[idx].outputFilePath);
  188. if (multiConfig->instConfig[idx].compareType == MD5_COMPARE) {
  189. multiConfig->instConfig[idx].decConfig.compareType = MD5_COMPARE;
  190. strcpy(multiConfig->instConfig[idx].decConfig.md5Path, multiConfig->instConfig[idx].refFilePath);
  191. }
  192. else if (multiConfig->instConfig[idx].compareType == YUV_COMPARE) {
  193. multiConfig->instConfig[idx].decConfig.compareType = YUV_COMPARE;
  194. strcpy(multiConfig->instConfig[idx].decConfig.refYuvPath, multiConfig->instConfig[idx].refFilePath);
  195. }
  196. else {
  197. multiConfig->instConfig[idx].decConfig.compareType = NO_COMPARE;
  198. }
  199. multiConfig->instConfig[idx].decConfig.performance = multiConfig->performance;
  200. multiConfig->instConfig[idx].decConfig.pfClock = multiConfig->pfClock;
  201. multiConfig->instConfig[idx].decConfig.fps = multiConfig->fps;
  202. multiConfig->instConfig[idx].decConfig.forceOutNum = multiConfig->numFrames;
  203. }
  204. static void MultiDecoderListener(Component com, Uint64 event, void* data, void* context)
  205. {
  206. DecHandle decHandle = NULL;
  207. ComponentGetParameter(NULL, com, GET_PARAM_DEC_HANDLE, &decHandle);
  208. if (decHandle == NULL && event != COMPONENT_EVENT_DEC_DECODED_ALL) {
  209. // Terminated state
  210. return;
  211. }
  212. switch (event) {
  213. case COMPONENT_EVENT_DEC_OPEN:
  214. WaitForNextStep(decHandle->instIndex, WAIT_AFTER_DEC_OPEN);
  215. break;
  216. case COMPONENT_EVENT_DEC_COMPLETE_SEQ:
  217. WaitForNextStep(decHandle->instIndex, WAIT_AFTER_SEQ_INIT);
  218. HandleDecCompleteSeqEvent(com, (CNMComListenerDecCompleteSeq*)data, (DecListenerContext*)context);
  219. break;
  220. case COMPONENT_EVENT_DEC_REGISTER_FB:
  221. WaitForNextStep(decHandle->instIndex, WAIT_AFTER_REG_BUF);
  222. HandleDecRegisterFbEvent(com, (CNMComListenerDecRegisterFb*)data, (DecListenerContext*)context);
  223. break;
  224. case COMPONENT_EVENT_DEC_READY_ONE_FRAME:
  225. WaitForNextStep(decHandle->instIndex, WAIT_BEFORE_DEC_START);
  226. break;
  227. case COMPONENT_EVENT_DEC_GET_OUTPUT_INFO:
  228. HandleDecGetOutputEvent(com, (CNMComListenerDecDone*)data, (DecListenerContext*)context);
  229. break;
  230. case COMPONENT_EVENT_DEC_DECODED_ALL:
  231. // It isn't possible to get handle when a component is terminated state.
  232. decHandle = (DecHandle)data;
  233. if (decHandle) WaitForNextStep(decHandle->instIndex, WAIT_BEFORE_DEC_CLOSE);
  234. break;
  235. default:
  236. break;
  237. }
  238. }
  239. static BOOL CreateDecoderTask(CNMTask task, CNMComponentConfig* config, DecListenerContext* lsnCtx)
  240. {
  241. BOOL success = FALSE;
  242. RetCode ret = RETCODE_SUCCESS;
  243. if (RETCODE_SUCCESS != (ret=SetUpDecoderOpenParam(&(config->decOpenParam), &(config->testDecConfig)))) {
  244. VLOG(ERR, "%s:%d SetUpDecoderOpenParam failed Error code is 0x%x \n", __FUNCTION__, __LINE__, ret);
  245. return FALSE;
  246. }
  247. Component feeder = ComponentCreate("feeder", config);
  248. Component renderer = ComponentCreate("renderer", config);
  249. Component decoder = ComponentCreate("wave_decoder", config);
  250. CNMTaskAdd(task, feeder);
  251. CNMTaskAdd(task, decoder);
  252. CNMTaskAdd(task, renderer);
  253. if ((success=SetupDecListenerContext(lsnCtx, config, renderer)) == TRUE) {
  254. ComponentRegisterListener(decoder, COMPONENT_EVENT_DEC_ALL, MultiDecoderListener, (void*)lsnCtx);
  255. }
  256. return success;
  257. }
  258. static void MultiEncoderListener(Component com, Uint64 event, void* data, void* context)
  259. {
  260. EncHandle encHandle = NULL;
  261. CNMComListenerEncStartOneFrame* lsnStartEnc = NULL;
  262. ProductId productId;
  263. UNREFERENCED_PARAMETER(lsnStartEnc);
  264. ComponentGetParameter(NULL, com, GET_PARAM_ENC_HANDLE, &encHandle);
  265. if (encHandle == NULL && event != COMPONENT_EVENT_ENC_ENCODED_ALL) {
  266. // Terminated state
  267. return;
  268. }
  269. switch (event) {
  270. case COMPONENT_EVENT_ENC_OPEN:
  271. WaitForNextStep(encHandle->instIndex, WAIT_AFTER_ENC_OPEN);
  272. break;
  273. case COMPONENT_EVENT_ENC_COMPLETE_SEQ:
  274. WaitForNextStep(encHandle->instIndex, WAIT_AFTER_INIT_SEQ);
  275. HandleEncCompleteSeqEvent(com, (CNMComListenerEncCompleteSeq*)data, (EncListenerContext*)context);
  276. break;
  277. case COMPONENT_EVENT_ENC_REGISTER_FB:
  278. WaitForNextStep(encHandle->instIndex, WAIT_AFTER_REG_FRAME);
  279. break;
  280. case COMPONENT_EVENT_ENC_READY_ONE_FRAME:
  281. WaitForNextStep(encHandle->instIndex, WAIT_BEFORE_ENC_START);
  282. break;
  283. case COMPONENT_EVENT_ENC_START_ONE_FRAME:
  284. break;
  285. case COMPONENT_EVENT_ENC_GET_OUTPUT_INFO:
  286. encHandle = ((CNMComListenerEncDone*)data)->handle;
  287. productId = VPU_GetProductId(VPU_HANDLE_CORE_INDEX(encHandle));
  288. if (TRUE == PRODUCT_ID_W_SERIES(productId)) {
  289. HandleEncGetOutputEvent(com, (CNMComListenerEncDone*)data, (EncListenerContext*)context);
  290. }
  291. else {
  292. Coda9HandleEncGetOutputEvent(com, (CNMComListenerEncDone*)data, (EncListenerContext*)context);
  293. }
  294. break;
  295. case COMPONENT_EVENT_CODA9_ENC_MAKE_HEADER:
  296. Coda9HandleEncMakeHeaderEvent(com, (CNMComListenerEncMakeHeader*)data, (EncListenerContext*)context);
  297. break;
  298. case COMPONENT_EVENT_ENC_ENCODED_ALL:
  299. // It isn't possible to get handle when a component is terminated state.
  300. encHandle = (EncHandle)data;
  301. if (encHandle)
  302. WaitForNextStep(encHandle->instIndex, WAIT_BEFORE_ENC_CLOSE);
  303. break;
  304. case COMPONENT_EVENT_ENC_FULL_INTERRUPT:
  305. HandleEncFullEvent(com, (CNMComListenerEncFull*)data, (EncListenerContext*)context);
  306. break;
  307. case COMPONENT_EVENT_ENC_CLOSE:
  308. HandleEncGetEncCloseEvent(com, (CNMComListenerEncClose*)data, (EncListenerContext*)context);
  309. break;
  310. default:
  311. break;
  312. }
  313. }
  314. static BOOL CreateEncoderTask(CNMTask task, CNMComponentConfig* config, EncListenerContext* lsnCtx)
  315. {
  316. Component feeder;
  317. Component encoder;
  318. Component reader;
  319. BOOL success = FALSE;
  320. #ifdef SUPPORT_LOOK_AHEAD_RC
  321. CNMComponentConfig config_pass1;
  322. Component yuvFeeder_pass1;
  323. Component encoder_pass1;
  324. Component reader_pass1;
  325. EncListenerContext lsnCtxPass1;
  326. #endif
  327. if (SetupEncoderOpenParam(&config->encOpenParam, &config->testEncConfig, NULL) == FALSE) {
  328. return FALSE;
  329. }
  330. #ifdef SUPPORT_LOOK_AHEAD_RC
  331. if (config->encOpenParam.EncStdParam.waveParam.larcEnable == TRUE) {
  332. osal_memcpy(&config_pass1, config, sizeof(*config));
  333. replaceAll(config_pass1.testEncConfig.cfgFileName, config->testEncConfig.cfgFileName, "pass2", "pass1");
  334. config_pass1.testEncConfig.larcPass = LOOK_AHEAD_RC_PASS1;
  335. SetupEncoderOpenParam(&config_pass1.encOpenParam, &config_pass1.testEncConfig, NULL);
  336. config_pass1.testEncConfig.compareType = 0; //we don't use the look-ahead-rc pass 1 data
  337. config_pass1.testEncConfig.bitstreamFileName[0]=0;
  338. config->testEncConfig.larcPass = LOOK_AHEAD_RC_PASS2;
  339. }
  340. if (config->encOpenParam.EncStdParam.waveParam.larcEnable == TRUE) {
  341. yuvFeeder_pass1 = ComponentCreate("yuvfeeder", &config_pass1);
  342. encoder_pass1 = ComponentCreate("wave_encoder", &config_pass1);
  343. reader_pass1 = ComponentCreate("reader", &config_pass1);
  344. CNMTaskAdd(task, yuvFeeder_pass1);
  345. CNMTaskAdd(task, encoder_pass1);
  346. CNMTaskAdd(task, reader_pass1);
  347. }
  348. #endif
  349. feeder = ComponentCreate("yuvfeeder", config);
  350. encoder = ComponentCreate("wave_encoder", config);
  351. reader = ComponentCreate("reader", config);
  352. CNMTaskAdd(task, feeder);
  353. CNMTaskAdd(task, encoder);
  354. CNMTaskAdd(task, reader);
  355. if ((success=SetupEncListenerContext(lsnCtx, config)) == TRUE) {
  356. ComponentRegisterListener(encoder, COMPONENT_EVENT_ENC_ALL, MultiEncoderListener, (void*)lsnCtx);
  357. #ifdef SUPPORT_LOOK_AHEAD_RC
  358. if (config->encOpenParam.EncStdParam.waveParam.larcEnable == TRUE) {
  359. if ((SetupEncListenerContext(&lsnCtxPass1, &config_pass1)) == TRUE) {
  360. ComponentRegisterListener(encoder_pass1, COMPONENT_EVENT_ENC_ALL, EncoderListener, (void*)&lsnCtxPass1);
  361. }
  362. }
  363. #endif
  364. }
  365. return success;
  366. }
  367. static BOOL MultiInstanceTest(TestMultiConfig* multiConfig, Uint16* fw, Uint32 size)
  368. {
  369. Uint32 i;
  370. CNMComponentConfig config;
  371. CNMTask task;
  372. DecListenerContext* decListenerCtx = (DecListenerContext*)osal_malloc(sizeof(DecListenerContext) * MAX_NUM_INSTANCE);
  373. EncListenerContext* encListenerCtx = (EncListenerContext*)osal_malloc(sizeof(EncListenerContext) * MAX_NUM_INSTANCE);
  374. BOOL ret = FALSE;
  375. BOOL success = TRUE;
  376. BOOL match = TRUE;
  377. CNMAppInit();
  378. for (i=0; i < multiConfig->numMulti; i++) {
  379. task = CNMTaskCreate();
  380. memset((void*)&config, 0x00, sizeof(CNMComponentConfig));
  381. config.bitcode = (Uint8*)fw;
  382. config.sizeOfBitcode = size;
  383. if (multiConfig->instConfig[i].isEncoder == TRUE) {
  384. memcpy((void*)&config.testEncConfig, &multiConfig->instConfig[i].encConfig, sizeof(TestEncConfig));
  385. success = CreateEncoderTask(task, &config, &encListenerCtx[i]);
  386. }
  387. else
  388. {
  389. memcpy((void*)&config.testDecConfig, &multiConfig->instConfig[i].decConfig, sizeof(TestDecConfig));
  390. success = CreateDecoderTask(task, &config, &decListenerCtx[i]);
  391. }
  392. CNMAppAdd(task);
  393. if (success == FALSE) {
  394. CNMAppStop();
  395. return FALSE;
  396. }
  397. }
  398. ret = CNMAppRun();
  399. for (i=0; i<multiConfig->numMulti; i++) {
  400. if (multiConfig->instConfig[i].isEncoder == TRUE) {
  401. match &= (encListenerCtx[i].match == TRUE && encListenerCtx[i].matchOtherInfo == TRUE);
  402. ClearEncListenerContext(&encListenerCtx[i]);
  403. }
  404. else
  405. {
  406. match &= decListenerCtx[i].match;
  407. ClearDecListenerContext(&decListenerCtx[i]);
  408. }
  409. }
  410. if (ret == TRUE) ret = match;
  411. osal_free(decListenerCtx);
  412. osal_free(encListenerCtx);
  413. return ret;
  414. }
  415. int main(int argc, char **argv)
  416. {
  417. Int32 coreIndex = 0;
  418. Uint32 productId = 0;
  419. TestMultiConfig multiConfig;
  420. int opt, index, i;
  421. char* tempArg;
  422. char* optString = "fc:e:hn:";
  423. struct option options[] = {
  424. {"instance-num", 1, NULL, 0},
  425. {"codec", 1, NULL, 0},
  426. {"input", 1, NULL, 0},
  427. {"output", 1, NULL, 0},
  428. {"ref_file_path", 1, NULL, 0},
  429. {"scaler", 1, NULL, 0},
  430. {"sclw", 1, NULL, 0},
  431. {"sclh", 1, NULL, 0},
  432. {"bsmode", 1, NULL, 0},
  433. {"enable-wtl", 1, NULL, 0},
  434. {"pf", 1, NULL, 0},
  435. {"pf-clock", 1, NULL, 0},
  436. {"fps", 1, NULL, 0},
  437. {"cores", 1, NULL, 0},
  438. {"ring", 1, NULL, 0},
  439. {NULL, 0, NULL, 0},
  440. };
  441. const char* name;
  442. char* firmwarePath = NULL;
  443. Uint32 ret = 0;
  444. osal_memset(&multiConfig, 0x00, sizeof(multiConfig));
  445. #if 1
  446. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  447. SetDefaultDecTestConfig(&multiConfig.instConfig[i].decConfig);
  448. }
  449. #endif
  450. while ((opt=getopt_long(argc, argv, optString, options, &index)) != -1) {
  451. switch (opt) {
  452. case 'c':
  453. tempArg = strtok(optarg, ",");
  454. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  455. multiConfig.instConfig[i].compareType = atoi(tempArg);
  456. tempArg = strtok(NULL, ",");
  457. if (tempArg == NULL)
  458. break;
  459. }
  460. break;
  461. case 'e':
  462. tempArg = strtok(optarg, ",");
  463. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  464. multiConfig.instConfig[i].isEncoder = atoi(tempArg);
  465. tempArg = strtok(NULL, ",");
  466. if (tempArg == NULL)
  467. break;
  468. }
  469. break;
  470. case 'h':
  471. Help(argv[0]);
  472. return 0;
  473. case 'n':
  474. multiConfig.numFrames = atoi(optarg);
  475. break;
  476. case 0:
  477. name = options[index].name;
  478. if (strcmp("instance-num", name) == 0) {
  479. multiConfig.numMulti = atoi(optarg);
  480. }
  481. else if (strcmp("codec", name) == 0) {
  482. tempArg = strtok(optarg, ",");
  483. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  484. multiConfig.instConfig[i].stdMode = (CodStd)atoi(tempArg);
  485. tempArg = strtok(NULL, ",");
  486. if (tempArg == NULL)
  487. break;
  488. }
  489. }
  490. else if (strcmp("input", name) == 0) {
  491. tempArg = strtok(optarg, ",");
  492. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  493. osal_memcpy(multiConfig.instConfig[i].inputFilePath, tempArg, strlen(tempArg));
  494. multiConfig.instConfig[i].inputFilePath[strlen(tempArg)] = 0;
  495. VLOG(INFO, "inputFilePath[%d]=%s\n",i,multiConfig.instConfig[i].inputFilePath);
  496. ChangePathStyle(multiConfig.instConfig[i].inputFilePath);
  497. tempArg = strtok(NULL, ",");
  498. if (tempArg == NULL)
  499. break;
  500. }
  501. }
  502. else if (strcmp("output", name) == 0) {
  503. tempArg = strtok(optarg, ",");
  504. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  505. osal_memcpy(multiConfig.instConfig[i].outputFilePath, tempArg, strlen(tempArg));
  506. multiConfig.instConfig[i].outputFilePath[strlen(tempArg)] = 0;
  507. ChangePathStyle(multiConfig.instConfig[i].outputFilePath);
  508. tempArg = strtok(NULL, ",");
  509. if (tempArg == NULL)
  510. break;
  511. }
  512. }
  513. else if (strcmp("ref_file_path", name) == 0) {
  514. tempArg = strtok(optarg, ",");
  515. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  516. osal_memcpy(multiConfig.instConfig[i].refFilePath, tempArg, strlen(tempArg));
  517. ChangePathStyle(multiConfig.instConfig[i].refFilePath);
  518. tempArg = strtok(NULL, ",");
  519. if (tempArg == NULL)
  520. break;
  521. }
  522. }
  523. else if (strcmp("scaler", name) == 0) {
  524. tempArg = strtok(optarg, ",");
  525. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  526. multiConfig.instConfig[i].scaler = atoi(tempArg);
  527. tempArg = strtok(NULL, ",");
  528. if (tempArg == NULL)
  529. break;
  530. }
  531. }
  532. else if (strcmp("sclw", name) == 0) {
  533. tempArg = strtok(optarg, ",");
  534. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  535. multiConfig.instConfig[i].sclw = atoi(tempArg);
  536. tempArg = strtok(NULL, ",");
  537. if (tempArg == NULL)
  538. break;
  539. }
  540. }
  541. else if (strcmp("sclh", name) == 0) {
  542. tempArg = strtok(optarg, ",");
  543. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  544. multiConfig.instConfig[i].sclh = atoi(tempArg);
  545. tempArg = strtok(NULL, ",");
  546. if (tempArg == NULL)
  547. break;
  548. }
  549. }
  550. else if (strcmp("bsmode", name) == 0) {
  551. tempArg = strtok(optarg, ",");
  552. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  553. multiConfig.instConfig[i].bsmode = atoi(tempArg);
  554. tempArg = strtok(NULL, ",");
  555. if (tempArg == NULL)
  556. break;
  557. }
  558. }
  559. else if (strcmp("enable-wtl", name) == 0) {
  560. tempArg = strtok(optarg, ",");
  561. for(i = 0; i < MAX_NUM_INSTANCE; i++) {
  562. multiConfig.instConfig[i].enableWTL = atoi(tempArg);
  563. tempArg = strtok(NULL, ",");
  564. if (tempArg == NULL)
  565. break;
  566. }
  567. }
  568. else if (!strcmp(options[index].name, "pf")) {
  569. multiConfig.performance = (BOOL)atoi(optarg);
  570. }
  571. else if (!strcmp(options[index].name, "pf-clock")) {
  572. multiConfig.pfClock = (Uint32)atoi(optarg);
  573. }
  574. else if (!strcmp(options[index].name, "fps")) {
  575. multiConfig.fps = (Uint32)atoi(optarg);
  576. }
  577. else {
  578. VLOG(ERR, "unknown --%s\n", name);
  579. Help(argv[0]);
  580. return 1;
  581. }
  582. break;
  583. case '?':
  584. return 1;
  585. }
  586. }
  587. InitLog();
  588. productId = VPU_GetProductId(coreIndex);
  589. switch (productId) {
  590. case PRODUCT_ID_960: firmwarePath = CORE_0_BIT_CODE_FILE_PATH; break;
  591. case PRODUCT_ID_980: firmwarePath = CORE_1_BIT_CODE_FILE_PATH; break;
  592. case PRODUCT_ID_511: firmwarePath = CORE_6_BIT_CODE_FILE_PATH; break;
  593. case PRODUCT_ID_517: firmwarePath = CORE_7_BIT_CODE_FILE_PATH; break;
  594. case PRODUCT_ID_521: firmwarePath = CORE_6_BIT_CODE_FILE_PATH; break;
  595. default:
  596. VLOG(ERR, "<%s:%d> Unknown productId(%d)\n", __FUNCTION__, __LINE__, productId);
  597. return 1;
  598. }
  599. if (LoadFirmware(productId, (Uint8**)&pusBitCode, &sizeInWord, firmwarePath) < 0) {
  600. VLOG(ERR, "%s:%d Failed to load firmware: %s\n", __FUNCTION__, __LINE__, firmwarePath);
  601. return 1;
  602. }
  603. for (i = 0; i < MAX_NUM_INSTANCE; i++) {
  604. if (multiConfig.instConfig[i].isEncoder == FALSE)
  605. SetDecMultiParam(&multiConfig, i, productId);
  606. else
  607. SetEncMultiParam(&multiConfig, i, productId);
  608. }
  609. if (TRUE == multiConfig.performance) {
  610. LoadBalancerInit();
  611. }
  612. do {
  613. if (MultiInstanceTest(&multiConfig, pusBitCode, sizeInWord) == FALSE) {
  614. VLOG(ERR, "Failed to MultiInstanceTest()\n");
  615. ret = 1;
  616. break;
  617. }
  618. } while(FALSE);
  619. osal_free(pusBitCode);
  620. if (TRUE == multiConfig.performance) {
  621. LoadBalancerRelease();
  622. }
  623. return ret;
  624. }