main_helper.c 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041
  1. //--=========================================================================--
  2. // This file is a part of VPU Reference API project
  3. //-----------------------------------------------------------------------------
  4. //
  5. // This confidential and proprietary software may be used only
  6. // as authorized by a licensing agreement from Chips&Media Inc.
  7. // In the event of publication, the following notice is applicable:
  8. //
  9. // (C) COPYRIGHT 2006 - 2014 CHIPS&MEDIA INC.
  10. // ALL RIGHTS RESERVED
  11. //
  12. // The entire notice above must be reproduced on all authorized
  13. // copies.
  14. //
  15. //--=========================================================================--
  16. #include <stdio.h>
  17. #include <stdarg.h>
  18. #include <string.h>
  19. #include <time.h>
  20. #include <errno.h>
  21. #include "vpuapifunc.h"
  22. #include "coda9/coda9_regdefine.h"
  23. #include "wave/common/common_vpuconfig.h"
  24. #include "wave/common/common_regdefine.h"
  25. #include "wave/wave4/wave4_regdefine.h"
  26. #include "wave/wave5/wave5_regdefine.h"
  27. #include "wave/coda7q/coda7q_regdefine.h"
  28. #include "vpuerror.h"
  29. #include "main_helper.h"
  30. #ifdef PLATFORM_LINUX
  31. #include <getopt.h>
  32. #endif
  33. #define BIT_DUMMY_READ_GEN 0x06000000
  34. #define BIT_READ_LATENCY 0x06000004
  35. #define W4_SET_READ_DELAY 0x01000000
  36. #define W4_SET_WRITE_DELAY 0x01000004
  37. #define MAX_CODE_BUF_SIZE (512*1024)
  38. #ifdef PLATFORM_WIN32
  39. #pragma warning(disable : 4996) //!<< disable waring C4996: The POSIX name for this item is deprecated.
  40. #endif
  41. char* EncPicTypeStringH264[] = {
  42. "IDR/I",
  43. "P",
  44. };
  45. char* EncPicTypeStringMPEG4[] = {
  46. "I",
  47. "P",
  48. };
  49. char* productNameList[] = {
  50. "CODA980",
  51. "CODA960",
  52. "CODA7503",
  53. "WAVE320",
  54. "WAVE410",
  55. "WAVE4102",
  56. "WAVE420",
  57. "WAVE412",
  58. "WAVE7Q",
  59. "WAVE420L",
  60. "WAVE510",
  61. "WAVE512",
  62. "WAVE515",
  63. "WAVE520",
  64. "Unknown",
  65. "Unknown",
  66. };
  67. #if defined(PLATFORM_LINUX) || defined(PLATFORM_QNX)
  68. #include <sys/stat.h>
  69. #include <unistd.h>
  70. #endif
  71. Int32 LoadFirmware(
  72. Int32 productId,
  73. Uint8** retFirmware,
  74. Uint32* retSizeInWord,
  75. const char* path
  76. )
  77. {
  78. Int32 nread;
  79. Uint32 totalRead, allocSize, readSize = 1024*1024;
  80. Uint8* firmware = NULL;
  81. osal_file_t fp;
  82. if ((fp=osal_fopen(path, "rb")) == NULL)
  83. {
  84. VLOG(ERR, "Failed to open %s\n", path);
  85. return -1;
  86. }
  87. totalRead = 0;
  88. if (PRODUCT_ID_W_SERIES(productId))
  89. {
  90. firmware = (Uint8*)osal_malloc(readSize);
  91. allocSize = readSize;
  92. nread = 0;
  93. while (TRUE)
  94. {
  95. if (allocSize < (totalRead+readSize))
  96. {
  97. allocSize += 2*nread;
  98. firmware = (Uint8*)realloc(firmware, allocSize);
  99. }
  100. nread = osal_fread((void*)&firmware[totalRead], 1, readSize, fp);
  101. totalRead += nread;
  102. if (nread < (Int32)readSize) break;
  103. }
  104. *retSizeInWord = (totalRead+1)/2;
  105. }
  106. else
  107. {
  108. Uint16* pusBitCode;
  109. pusBitCode = (Uint16 *)osal_malloc(MAX_CODE_BUF_SIZE);
  110. firmware = (Uint8*)pusBitCode;
  111. if (pusBitCode)
  112. {
  113. int code;
  114. while (!osal_feof(fp) || totalRead < (MAX_CODE_BUF_SIZE/2)) {
  115. code = -1;
  116. if (fscanf(fp, "%x", &code) <= 0) {
  117. /* matching failure or EOF */
  118. break;
  119. }
  120. pusBitCode[totalRead++] = (Uint16)code;
  121. }
  122. }
  123. *retSizeInWord = totalRead;
  124. }
  125. osal_fclose(fp);
  126. *retFirmware = firmware;
  127. return 0;
  128. }
  129. void PrintVpuVersionInfo(
  130. Uint32 core_idx
  131. )
  132. {
  133. Uint32 version;
  134. Uint32 revision;
  135. Uint32 productId;
  136. VPU_GetVersionInfo(core_idx, &version, &revision, &productId);
  137. VLOG(INFO, "VPU coreNum : [%d]\n", core_idx);
  138. VLOG(INFO, "Firmware : CustomerCode: %04x | version : %d.%d.%d rev.%d\n",
  139. (Uint32)(version>>16), (Uint32)((version>>(12))&0x0f), (Uint32)((version>>(8))&0x0f), (Uint32)((version)&0xff), revision);
  140. VLOG(INFO, "Hardware : %04x\n", productId);
  141. VLOG(INFO, "API : %d.%d.%d\n\n", API_VERSION_MAJOR, API_VERSION_MINOR, API_VERSION_PATCH);
  142. }
  143. BOOL OpenDisplayBufferFile(char *outputPath, VpuRect rcDisplay, TiledMapType mapType, FILE *fp[])
  144. {
  145. char strFile[MAX_FILE_PATH];
  146. int width;
  147. int height;
  148. width = rcDisplay.right - rcDisplay.left;
  149. height = rcDisplay.bottom - rcDisplay.top;
  150. if (mapType == LINEAR_FRAME_MAP) {
  151. if ((fp[0]=osal_fopen(outputPath, "wb")) == NULL) {
  152. VLOG(ERR, "%s:%d failed to open %s\n", __FUNCTION__, __LINE__, outputPath);
  153. goto ERR_OPEN_DISP_BUFFER_FILE;
  154. }
  155. }
  156. else {
  157. width = VPU_ALIGN16(width);
  158. height = VPU_ALIGN16(height);
  159. sprintf(strFile, "%s_%dx%d_fbc_data_y.bin", outputPath, width, height);
  160. if ((fp[0]=osal_fopen(strFile, "wb")) == NULL) {
  161. VLOG(ERR, "%s:%d failed to open %s\n", __FUNCTION__, __LINE__, strFile);
  162. goto ERR_OPEN_DISP_BUFFER_FILE;
  163. }
  164. sprintf(strFile, "%s_%dx%d_fbc_data_c.bin", outputPath, width, height);
  165. if ((fp[1]=osal_fopen(strFile, "wb")) == NULL) {
  166. VLOG(ERR, "%s:%d failed to open %s\n", __FUNCTION__, __LINE__, strFile);
  167. goto ERR_OPEN_DISP_BUFFER_FILE;
  168. }
  169. sprintf(strFile, "%s_%dx%d_fbc_table_y.bin", outputPath, width, height);
  170. if ((fp[2]=osal_fopen(strFile, "wb")) == NULL) {
  171. VLOG(ERR, "%s:%d failed to open %s\n", __FUNCTION__, __LINE__, strFile);
  172. goto ERR_OPEN_DISP_BUFFER_FILE;
  173. }
  174. sprintf(strFile, "%s_%dx%d_fbc_table_c.bin", outputPath, width, height);
  175. if ((fp[3]=osal_fopen(strFile, "wb")) == NULL) {
  176. VLOG(ERR, "%s:%d failed to open %s\n", __FUNCTION__, __LINE__, strFile);
  177. goto ERR_OPEN_DISP_BUFFER_FILE;
  178. }
  179. }
  180. return TRUE;
  181. ERR_OPEN_DISP_BUFFER_FILE:
  182. CloseDisplayBufferFile(fp);
  183. return FALSE;
  184. }
  185. void CloseDisplayBufferFile(FILE *fp[])
  186. {
  187. int i;
  188. for (i=0; i < OUTPUT_FP_NUMBER; i++) {
  189. if (fp[i] != NULL) {
  190. osal_fclose(fp[i]);
  191. fp[i] = NULL;
  192. }
  193. }
  194. }
  195. void SaveDisplayBufferToFile(DecHandle handle, FrameBuffer dispFrame, VpuRect rcDisplay, FILE *fp[])
  196. {
  197. Uint32 width;
  198. Uint32 height;
  199. Uint32 bpp;
  200. DecGetFramebufInfo fbInfo;
  201. if (dispFrame.myIndex < 0)
  202. return;
  203. if (dispFrame.mapType != COMPRESSED_FRAME_MAP) {
  204. //VLOG(INFO, "---> DUMP LINEAR(WTL) FRAMEBUFFER #%d\n", dispFrame.myIndex);
  205. size_t sizeYuv;
  206. Uint8* pYuv;
  207. pYuv = GetYUVFromFrameBuffer(handle, &dispFrame, rcDisplay, &width, &height, &bpp, &sizeYuv);
  208. osal_fwrite(pYuv, 1, sizeYuv, fp[0]);
  209. osal_free(pYuv);
  210. }
  211. else {
  212. int lumaTblSize;
  213. int chromaTblSize;
  214. int lSize;
  215. int cSize;
  216. Uint32 addr;
  217. Uint32 fbc_endian;
  218. unsigned char *buf;
  219. int coreIdx = VPU_HANDLE_CORE_INDEX(handle);
  220. //VLOG(INFO, "---> DUMP COMPRESSED FRAMEBUFFER #%d\n", dispFrame.myIndex);
  221. VPU_DecGiveCommand(handle, DEC_GET_FRAMEBUF_INFO, (void*)&fbInfo);
  222. width = rcDisplay.right - rcDisplay.left;
  223. height = rcDisplay.bottom - rcDisplay.top;
  224. width = VPU_ALIGN16(width);
  225. height = VPU_ALIGN16(height);
  226. switch (dispFrame.format) {
  227. case FORMAT_420_P10_16BIT_LSB:
  228. case FORMAT_420_P10_16BIT_MSB:
  229. bpp = 2;
  230. break;
  231. case FORMAT_420_P10_32BIT_LSB:
  232. case FORMAT_420_P10_32BIT_MSB:
  233. bpp = 1;
  234. break;
  235. default:
  236. bpp = 1;
  237. break;
  238. }
  239. fbc_endian = vdi_convert_endian(coreIdx, dispFrame.endian);
  240. lSize = width * height * bpp;
  241. cSize = width * height * bpp / 2;
  242. /* Dump Y compressed data */
  243. buf = osal_malloc(lSize);
  244. if (buf)
  245. {
  246. vdi_read_memory(coreIdx, dispFrame.bufY, buf, lSize, fbc_endian);
  247. osal_fwrite((void *)buf, sizeof(Uint8), lSize, fp[0]);
  248. osal_fflush(fp[0]);
  249. osal_free(buf);
  250. }
  251. /* Dump C compressed data */
  252. buf = osal_malloc(cSize);
  253. if (buf)
  254. {
  255. vdi_read_memory(coreIdx, dispFrame.bufCb, buf, cSize, fbc_endian);
  256. osal_fwrite((void *)buf, sizeof(Uint8), cSize, fp[1]);
  257. osal_fflush(fp[1]);
  258. osal_free(buf);
  259. }
  260. /* Dump Y Offset table */
  261. VPU_GetFBCOffsetTableSize(STD_HEVC, (int)width, (int)height, (int*)&lumaTblSize, (int*)&chromaTblSize);
  262. addr = fbInfo.vbFbcYTbl[dispFrame.myIndex].phys_addr;
  263. buf = osal_malloc(lumaTblSize);
  264. if (buf)
  265. {
  266. vdi_read_memory(coreIdx, addr, buf, lumaTblSize, fbc_endian);
  267. osal_fwrite((void *)buf, sizeof(Uint8), lumaTblSize, fp[2]);
  268. osal_fflush(fp[2]);
  269. osal_free(buf);
  270. }
  271. /* Dump C Offset table */
  272. addr = fbInfo.vbFbcCTbl[dispFrame.myIndex].phys_addr;
  273. buf = osal_malloc(chromaTblSize);
  274. if (buf)
  275. {
  276. vdi_read_memory(coreIdx, addr, buf, chromaTblSize, fbc_endian);
  277. osal_fwrite((void *)buf, sizeof(Uint8), chromaTblSize, fp[3]);
  278. osal_fflush(fp[3]);
  279. osal_free(buf);
  280. }
  281. }
  282. }
  283. void FreePreviousFramebuffer(
  284. Uint32 coreIdx,
  285. DecGetFramebufInfo* fb
  286. )
  287. {
  288. int i;
  289. if (fb->vbFrame.size > 0) {
  290. vdi_free_dma_memory(coreIdx, &fb->vbFrame);
  291. osal_memset((void*)&fb->vbFrame, 0x00, sizeof(vpu_buffer_t));
  292. }
  293. if (fb->vbWTL.size > 0) {
  294. vdi_free_dma_memory(coreIdx, &fb->vbWTL);
  295. osal_memset((void*)&fb->vbWTL, 0x00, sizeof(vpu_buffer_t));
  296. }
  297. for ( i=0 ; i<MAX_REG_FRAME; i++) {
  298. if (fb->vbFbcYTbl[i].size > 0) {
  299. vdi_free_dma_memory(coreIdx, &fb->vbFbcYTbl[i]);
  300. osal_memset((void*)&fb->vbFbcYTbl, 0x00, sizeof(vpu_buffer_t));
  301. }
  302. if (fb->vbFbcCTbl[i].size > 0) {
  303. vdi_free_dma_memory(coreIdx, &fb->vbFbcCTbl[i]);
  304. osal_memset((void*)&fb->vbFbcCTbl, 0x00, sizeof(vpu_buffer_t));
  305. }
  306. }
  307. }
  308. void PrintDecSeqWarningMessages(
  309. Uint32 productId,
  310. DecInitialInfo* seqInfo
  311. )
  312. {
  313. if (PRODUCT_ID_W_SERIES(productId))
  314. {
  315. if (seqInfo->seqInitErrReason&0x00000001) VLOG(WARN, "sps_max_sub_layer_minus1 shall be 0 to 6\n");
  316. if (seqInfo->seqInitErrReason&0x00000002) VLOG(WARN, "general_reserved_zero_44bits shall be 0.\n");
  317. if (seqInfo->seqInitErrReason&0x00000004) VLOG(WARN, "reserved_zero_2bits shall be 0\n");
  318. if (seqInfo->seqInitErrReason&0x00000008) VLOG(WARN, "sub_layer_reserved_zero_44bits shall be 0");
  319. if (seqInfo->seqInitErrReason&0x00000010) VLOG(WARN, "general_level_idc shall have one of level of Table A.1\n");
  320. if (seqInfo->seqInitErrReason&0x00000020) VLOG(WARN, "sps_max_dec_pic_buffering[i] <= MaxDpbSize\n");
  321. if (seqInfo->seqInitErrReason&0x00000040) VLOG(WARN, "trailing bits shall be 1000... pattern, 7.3.2.1\n");
  322. if (seqInfo->seqInitErrReason&0x00100000) VLOG(WARN, "Not supported or undefined profile: %d\n", seqInfo->profile);
  323. if (seqInfo->seqInitErrReason&0x00200000) VLOG(WARN, "Spec over level(%d)\n", seqInfo->level);
  324. }
  325. }
  326. void DisplayDecodedInformationForHevc(
  327. DecHandle handle,
  328. Uint32 frameNo,
  329. DecOutputInfo* decodedInfo
  330. )
  331. {
  332. Int32 logLevel;
  333. if (decodedInfo == NULL) {
  334. if (handle->productId == PRODUCT_ID_510 || handle->productId == PRODUCT_ID_512) {
  335. VLOG(TRACE, "I NO T POC NAL DECO DISP PRESCAN DISPFLAG RD_PTR WR_PTR FRM_START FRM_END WxH SEQ TEMP CYCLE (Seek, Parse, Dec)\n");
  336. }
  337. else {
  338. VLOG(TRACE, "I NO T POC NAL DECO DISP PRESCAN DISPFLAG RD_PTR WR_PTR FRM_START FRM_END WxH SEQ TEMP CYCLE \n");
  339. }
  340. VLOG(TRACE, "------------------------------------------------------------------------------------------------------------\n");
  341. }
  342. else {
  343. logLevel = (decodedInfo->decodingSuccess&0x01) == 0 ? ERR : TRACE;
  344. if (handle->productId == PRODUCT_ID_4102) {
  345. logLevel = (decodedInfo->indexFramePrescan == -2) ? TRACE : logLevel;
  346. }
  347. // Print informations
  348. if (handle->productId == PRODUCT_ID_510 || handle->productId == PRODUCT_ID_512) {
  349. VLOG(logLevel, "%02d %5d %d %4d(%4d) %3d %2d(%2d) %2d(%2d) %7d %08x %08x %08x %08x %08x %4dx%-4d %4d %4d %d(%d,%d,%d)\n",
  350. handle->instIndex, frameNo, decodedInfo->picType,
  351. decodedInfo->h265Info.decodedPOC, decodedInfo->h265Info.displayPOC, decodedInfo->nalType,
  352. decodedInfo->indexFrameDecoded, decodedInfo->indexFrameDecodedForTiled,
  353. decodedInfo->indexFrameDisplay, decodedInfo->indexFrameDisplayForTiled,
  354. decodedInfo->indexFramePrescan,
  355. decodedInfo->frameDisplayFlag,decodedInfo->rdPtr, decodedInfo->wrPtr,
  356. decodedInfo->bytePosFrameStart, decodedInfo->bytePosFrameEnd,
  357. decodedInfo->dispPicWidth, decodedInfo->dispPicHeight, decodedInfo->sequenceNo,
  358. decodedInfo->h265Info.temporalId, decodedInfo->frameCycle, decodedInfo->seekCycle, decodedInfo->parseCycle, decodedInfo->decodeCycle);
  359. }
  360. else {
  361. VLOG(logLevel, "%02d %5d %d %4d(%4d) %3d %2d(%2d) %2d(%2d) %7d %08x %08x %08x %08x %08x %4dx%-4d %4d %4d %d\n",
  362. handle->instIndex, frameNo, decodedInfo->picType,
  363. decodedInfo->h265Info.decodedPOC, decodedInfo->h265Info.displayPOC, decodedInfo->nalType,
  364. decodedInfo->indexFrameDecoded, decodedInfo->indexFrameDecodedForTiled,
  365. decodedInfo->indexFrameDisplay, decodedInfo->indexFrameDisplayForTiled,
  366. decodedInfo->indexFramePrescan,
  367. decodedInfo->frameDisplayFlag,decodedInfo->rdPtr, decodedInfo->wrPtr,
  368. decodedInfo->bytePosFrameStart, decodedInfo->bytePosFrameEnd,
  369. decodedInfo->dispPicWidth, decodedInfo->dispPicHeight, decodedInfo->sequenceNo,
  370. decodedInfo->h265Info.temporalId, decodedInfo->frameCycle);
  371. }
  372. if (logLevel == ERR) {
  373. VLOG(ERR, "\t>>ERROR REASON: 0x%08x(0x%08x)\n", decodedInfo->errorReason, decodedInfo->errorReasonExt);
  374. }
  375. if (decodedInfo->numOfErrMBs) {
  376. VLOG(WARN, "\t>> ErrorBlock: %d\n", decodedInfo->numOfErrMBs);
  377. }
  378. }
  379. }
  380. void DisplayDecodedInformationForVP9(DecHandle handle, Uint32 frameNo, DecOutputInfo* decodedInfo)
  381. {
  382. Int32 logLevel;
  383. if (decodedInfo == NULL) {
  384. // Print header
  385. VLOG(TRACE, "I NO T DECO DISP PRESCAN DISPFLAG RD_PTR WR_PTR FRM_START FRM_END WxH SEQ CYCLE\n");
  386. VLOG(TRACE, "--------------------------------------------------------------------------------------------\n");
  387. }
  388. else {
  389. logLevel = (decodedInfo->decodingSuccess&0x01) == 0 ? ERR : TRACE;
  390. // Print informations
  391. VLOG(logLevel, "%02d %5d %d %2d(%2d) %2d(%2d) %7d %08x %08x %08x %08x %08x %4dx%-4d %4d %d\n",
  392. handle->instIndex, frameNo, decodedInfo->picType,
  393. decodedInfo->indexFrameDecoded, decodedInfo->indexFrameDecodedForTiled,
  394. decodedInfo->indexFrameDisplay, decodedInfo->indexFrameDisplayForTiled,
  395. decodedInfo->indexFramePrescan,
  396. decodedInfo->frameDisplayFlag,decodedInfo->rdPtr, decodedInfo->wrPtr,
  397. decodedInfo->bytePosFrameStart, decodedInfo->bytePosFrameEnd,
  398. decodedInfo->dispPicWidth, decodedInfo->dispPicHeight,
  399. decodedInfo->sequenceNo, decodedInfo->frameCycle
  400. );
  401. if (logLevel == ERR) {
  402. VLOG(ERR, "\t>>ERROR REASON: 0x%08x(0x%08x)\n", decodedInfo->errorReason, decodedInfo->errorReasonExt);
  403. }
  404. if (decodedInfo->numOfErrMBs) {
  405. VLOG(WARN, "\t>> ErrorBlock: %d\n", decodedInfo->numOfErrMBs);
  406. }
  407. }
  408. }
  409. void DisplayDecodedInformationCommon(DecHandle handle, CodStd codec, Uint32 frameNo, DecOutputInfo* decodedInfo)
  410. {
  411. Int32 logLevel;
  412. if (decodedInfo == NULL) {
  413. // Print header
  414. VLOG(TRACE, "I NO T TID DEC_POC DECO DISP DISPFLAG RD_PTR WR_PTR FRM_START FRM_END WxH\n");
  415. VLOG(TRACE, "---------------------------------------------------------------------------------------\n");
  416. }
  417. else {
  418. VpuRect rc = decodedInfo->rcDisplay;
  419. Uint32 width = rc.right - rc.left;
  420. Uint32 height = rc.bottom - rc.top;
  421. char strTemporalId[16];
  422. char strPoc[16];
  423. logLevel = (decodedInfo->decodingSuccess&0x01) == 0 ? ERR : TRACE;
  424. // Print informations
  425. VLOG(logLevel, "%02d %5d %d %s %s %2d(%2d) %2d(%2d) %08x %08x %08x %08x %08x %dx%d\n",
  426. handle->instIndex, frameNo, decodedInfo->picType, strTemporalId, strPoc,
  427. decodedInfo->indexFrameDecoded, decodedInfo->indexFrameDecodedForTiled,
  428. decodedInfo->indexFrameDisplay, decodedInfo->indexFrameDisplayForTiled,
  429. decodedInfo->frameDisplayFlag,decodedInfo->rdPtr, decodedInfo->wrPtr,
  430. decodedInfo->bytePosFrameStart, decodedInfo->bytePosFrameEnd,
  431. width, height);
  432. if (logLevel == ERR) {
  433. VLOG(ERR, "\t>>ERROR REASON: 0x%08x(0x%08x)\n", decodedInfo->errorReason, decodedInfo->errorReasonExt);
  434. }
  435. if (decodedInfo->numOfErrMBs) {
  436. VLOG(WARN, "\t>> ErrorBlock: %d\n", decodedInfo->numOfErrMBs);
  437. }
  438. }
  439. }
  440. /**
  441. * \brief Print out decoded information such like RD_PTR, WR_PTR, PIC_TYPE, ..
  442. * \param decodedInfo If this parameter is not NULL then print out decoded informations
  443. * otherwise print out header.
  444. */
  445. void DisplayDecodedInformation(DecHandle handle, CodStd codec, Uint32 frameNo, DecOutputInfo* decodedInfo)
  446. {
  447. switch (codec)
  448. {
  449. case STD_HEVC:
  450. DisplayDecodedInformationForHevc(handle, frameNo, decodedInfo);
  451. break;
  452. case STD_VP9:
  453. DisplayDecodedInformationForVP9(handle, frameNo, decodedInfo);
  454. break;
  455. default:
  456. DisplayDecodedInformationCommon(handle, codec, frameNo, decodedInfo);
  457. break;
  458. }
  459. return;
  460. }
  461. static void Wave4DisplayEncodedInformation(
  462. EncHandle handle,
  463. CodStd codec,
  464. Uint32 frameNo,
  465. EncOutputInfo* encodedInfo,
  466. Int32 srcEndFlag,
  467. Int32 srcFrameIdx
  468. )
  469. {
  470. if (encodedInfo == NULL) {
  471. VLOG(INFO, "------------------------------------------------------------------------------\n");
  472. VLOG(INFO, "I NO T RECON RD_PTR WR_PTR BYTES SRCIDX USEDSRCIDX Cycle \n");
  473. VLOG(INFO, "------------------------------------------------------------------------------\n");
  474. } else {
  475. VLOG(INFO, "%02d %5d %5d %5d %08x %08x %8x %2d %2d %8d\n",
  476. handle->instIndex, encodedInfo->encPicCnt, encodedInfo->picType, encodedInfo->reconFrameIndex, encodedInfo->rdPtr, encodedInfo->wrPtr,
  477. encodedInfo->bitstreamSize, (srcEndFlag == 1 ? -1 : srcFrameIdx), encodedInfo->encSrcIdx, encodedInfo->frameCycle);
  478. }
  479. }
  480. static void Wave5DisplayEncodedInformation(
  481. EncHandle handle,
  482. CodStd codec,
  483. Uint32 frameNo,
  484. EncOutputInfo* encodedInfo,
  485. Int32 srcEndFlag,
  486. Int32 srcFrameIdx
  487. )
  488. {
  489. if (encodedInfo == NULL) {
  490. VLOG(INFO, "--------------------------------------------------------------------------------------------------------------\n");
  491. VLOG(INFO, " | Cycle\n");
  492. VLOG(INFO, "I NO T RECON RD_PTR WR_PTR BYTES SRCIDX USEDSRCIDX | FRAME PREPARING PROCESSING ENCODING\n");
  493. VLOG(INFO, "--------------------------------------------------------------------------------------------------------------\n");
  494. } else {
  495. VLOG(INFO, "%02d %5d %5d %5d %08x %08x %8x %2d %2d %8d %8d %8d %8d\n",
  496. handle->instIndex, encodedInfo->encPicCnt, encodedInfo->picType, encodedInfo->reconFrameIndex, encodedInfo->rdPtr, encodedInfo->wrPtr,
  497. encodedInfo->bitstreamSize, (srcEndFlag == 1 ? -1 : srcFrameIdx), encodedInfo->encSrcIdx,
  498. encodedInfo->frameCycle, encodedInfo->encPrepareCycle, encodedInfo->encProcessingCycle, encodedInfo->encEncodingCycle);
  499. }
  500. }
  501. static void Coda9DisplayEncodedInformation(
  502. DecHandle handle,
  503. CodStd codec,
  504. Uint32 frameNo,
  505. EncOutputInfo* encodedInfo
  506. )
  507. {
  508. if (encodedInfo == NULL) {
  509. // Print header
  510. VLOG(INFO, "I NO T RECON RD_PTR WR_PTR \n");
  511. VLOG(INFO, "-------------------------------------\n");
  512. }
  513. else {
  514. char** picTypeArray = (codec==STD_AVC ? EncPicTypeStringH264 : EncPicTypeStringMPEG4);
  515. char* strPicType;
  516. if (encodedInfo->picType > 2) strPicType = "?";
  517. else strPicType = picTypeArray[encodedInfo->picType];
  518. // Print informations
  519. VLOG(INFO, "%02d %5d %5s %5d %08x %08x\n",
  520. handle->instIndex, frameNo, strPicType,
  521. encodedInfo->reconFrameIndex, encodedInfo->rdPtr, encodedInfo->wrPtr);
  522. }
  523. }
  524. /*lint -esym(438, ap) */
  525. void
  526. DisplayEncodedInformation(
  527. EncHandle handle,
  528. CodStd codec,
  529. Uint32 frameNo,
  530. EncOutputInfo* encodedInfo,
  531. ...
  532. )
  533. {
  534. int srcEndFlag;
  535. int srcFrameIdx;
  536. va_list ap;
  537. switch (codec) {
  538. case STD_HEVC:
  539. va_start(ap, encodedInfo);
  540. srcEndFlag = va_arg(ap, Uint32);
  541. srcFrameIdx = va_arg(ap, Uint32);
  542. va_end(ap);
  543. if(handle->productId == PRODUCT_ID_520 )
  544. Wave5DisplayEncodedInformation(handle, codec, frameNo, encodedInfo, srcEndFlag , srcFrameIdx);
  545. else
  546. Wave4DisplayEncodedInformation(handle, codec, frameNo, encodedInfo, srcEndFlag , srcFrameIdx);
  547. break;
  548. default:
  549. Coda9DisplayEncodedInformation(handle, codec, frameNo, encodedInfo);
  550. break;
  551. }
  552. return;
  553. }
  554. /*lint +esym(438, ap) */
  555. void ChangePathStyle(
  556. char *str
  557. )
  558. {
  559. }
  560. void ReleaseVideoMemory(
  561. Uint32 coreIndex,
  562. vpu_buffer_t* memoryArr,
  563. Uint32 count
  564. )
  565. {
  566. Uint32 index;
  567. for (index=0; index<count; index++) {
  568. if (memoryArr[index].size)
  569. vdi_free_dma_memory(coreIndex, &memoryArr[index]);
  570. }
  571. }
  572. BOOL AllocateDecFrameBuffer(
  573. DecHandle decHandle,
  574. TestDecConfig* config,
  575. Uint32 tiledFbCount,
  576. Uint32 linearFbCount,
  577. FrameBuffer* retFbArray,
  578. vpu_buffer_t* retFbAddrs,
  579. Uint32* retStride
  580. )
  581. {
  582. Uint32 framebufSize;
  583. Uint32 totalFbCount;
  584. Uint32 coreIndex;
  585. Uint32 index;
  586. FrameBufferFormat format = config->wtlFormat;
  587. DecInitialInfo seqInfo;
  588. FrameBufferAllocInfo fbAllocInfo;
  589. RetCode ret;
  590. vpu_buffer_t* pvb;
  591. size_t framebufStride;
  592. size_t framebufHeight;
  593. Uint32 productId;
  594. DRAMConfig* pDramCfg = NULL;
  595. DRAMConfig dramCfg = {0};
  596. coreIndex = VPU_HANDLE_CORE_INDEX(decHandle);
  597. productId = VPU_HANDLE_PRODUCT_ID(decHandle);
  598. VPU_DecGiveCommand(decHandle, DEC_GET_SEQ_INFO, (void*)&seqInfo);
  599. if (productId == PRODUCT_ID_960) {
  600. pDramCfg = &dramCfg;
  601. ret = VPU_DecGiveCommand(decHandle, GET_DRAM_CONFIG, pDramCfg);
  602. }
  603. totalFbCount = tiledFbCount + linearFbCount;
  604. if (productId == PRODUCT_ID_4102 || productId == PRODUCT_ID_420 || productId == PRODUCT_ID_412 || productId == PRODUCT_ID_420L ||
  605. productId == PRODUCT_ID_510 || productId == PRODUCT_ID_512 || productId == PRODUCT_ID_515) {
  606. format = (seqInfo.lumaBitdepth > 8 || seqInfo.chromaBitdepth > 8) ? FORMAT_420_P10_16BIT_LSB : FORMAT_420;
  607. }
  608. else if (productId == PRODUCT_ID_7Q) {
  609. if (decHandle->codecMode == HEVC_DEC)
  610. format = (seqInfo.lumaBitdepth > 8 || seqInfo.chromaBitdepth > 8) ? FORMAT_420_P10_16BIT_LSB : FORMAT_420;
  611. else
  612. format = FORMAT_420;
  613. }
  614. if (decHandle->codecMode == C7_VP9_DEC) {
  615. framebufStride = CalcStride(VPU_ALIGN64(seqInfo.picWidth), seqInfo.picHeight, format, config->cbcrInterleave, config->mapType, TRUE);
  616. framebufHeight = VPU_ALIGN64(seqInfo.picHeight);
  617. framebufSize = VPU_GetFrameBufSize(decHandle->coreIdx, framebufStride, framebufHeight,
  618. config->mapType, format, config->cbcrInterleave, NULL);
  619. *retStride = framebufStride;
  620. }
  621. else if (productId == PRODUCT_ID_7Q && decHandle->codecMode != C7_HEVC_DEC) {
  622. framebufStride = CalcStride(seqInfo.picWidth, seqInfo.picHeight, format, config->cbcrInterleave, config->mapType, FALSE);
  623. framebufHeight = seqInfo.interlace ? VPU_ALIGN32(seqInfo.picHeight) : VPU_ALIGN16(seqInfo.picHeight);
  624. framebufSize = VPU_GetFrameBufSize(decHandle->coreIdx, framebufStride, framebufHeight,
  625. config->mapType, format, config->cbcrInterleave, NULL);
  626. *retStride = framebufStride;
  627. }
  628. else if (decHandle->codecMode == C7_AVS2_DEC) {
  629. framebufStride = CalcStride(seqInfo.picWidth, seqInfo.picHeight, format, config->cbcrInterleave, config->mapType, FALSE);
  630. framebufHeight = VPU_ALIGN8(seqInfo.picHeight);
  631. framebufSize = VPU_GetFrameBufSize(decHandle->coreIdx, framebufStride, framebufHeight,
  632. config->mapType, format, config->cbcrInterleave, pDramCfg);
  633. *retStride = framebufStride;
  634. }
  635. else {
  636. *retStride = VPU_ALIGN32(seqInfo.picWidth);
  637. framebufStride = CalcStride(seqInfo.picWidth, seqInfo.picHeight, format, config->cbcrInterleave, config->mapType, FALSE);
  638. framebufHeight = seqInfo.picHeight;
  639. framebufSize = VPU_GetFrameBufSize(decHandle->coreIdx, framebufStride, seqInfo.picHeight,
  640. config->mapType, format, config->cbcrInterleave, pDramCfg);
  641. }
  642. osal_memset((void*)&fbAllocInfo, 0x00, sizeof(fbAllocInfo));
  643. osal_memset((void*)retFbArray, 0x00, sizeof(FrameBuffer)*totalFbCount);
  644. fbAllocInfo.format = format;
  645. fbAllocInfo.cbcrInterleave = config->cbcrInterleave;
  646. fbAllocInfo.mapType = config->mapType;
  647. fbAllocInfo.stride = framebufStride;
  648. fbAllocInfo.height = framebufHeight;
  649. fbAllocInfo.size = framebufSize;
  650. fbAllocInfo.lumaBitDepth = seqInfo.lumaBitdepth;
  651. fbAllocInfo.chromaBitDepth = seqInfo.chromaBitdepth;
  652. fbAllocInfo.num = tiledFbCount;
  653. fbAllocInfo.endian = config->frameEndian;
  654. fbAllocInfo.type = FB_TYPE_CODEC;
  655. osal_memset((void*)retFbAddrs, 0x00, sizeof(vpu_buffer_t)*totalFbCount);
  656. for (index=0; index<tiledFbCount; index++) {
  657. pvb = &retFbAddrs[index];
  658. pvb->size = framebufSize;
  659. if (vdi_allocate_dma_memory(coreIndex, pvb) < 0) {
  660. VLOG(ERR, "%s:%d fail to allocate frame buffer\n", __FUNCTION__, __LINE__);
  661. ReleaseVideoMemory(coreIndex, retFbAddrs, totalFbCount);
  662. return FALSE;
  663. }
  664. retFbArray[index].bufY = pvb->phys_addr;
  665. retFbArray[index].bufCb = (PhysicalAddress)-1;
  666. retFbArray[index].bufCr = (PhysicalAddress)-1;
  667. retFbArray[index].updateFbInfo = TRUE;
  668. retFbArray[index].size = framebufSize;
  669. }
  670. if (tiledFbCount != 0) {
  671. if ((ret=VPU_DecAllocateFrameBuffer(decHandle, fbAllocInfo, retFbArray)) != RETCODE_SUCCESS) {
  672. VLOG(ERR, "%s:%d failed to VPU_DecAllocateFrameBuffer(), ret(%d)\n",
  673. __FUNCTION__, __LINE__, ret);
  674. ReleaseVideoMemory(coreIndex, retFbAddrs, totalFbCount);
  675. return FALSE;
  676. }
  677. }
  678. if (config->enableWTL == TRUE || linearFbCount != 0) {
  679. size_t linearStride;
  680. size_t picWidth;
  681. size_t picHeight;
  682. size_t fbHeight;
  683. Uint32 mapType = LINEAR_FRAME_MAP;
  684. FrameBufferFormat outFormat = config->wtlFormat;
  685. picWidth = seqInfo.picWidth;
  686. picHeight = seqInfo.picHeight;
  687. fbHeight = picHeight;
  688. if (decHandle->codecMode == C7_VP9_DEC) {
  689. fbHeight = VPU_ALIGN64(picHeight);
  690. }
  691. else if (decHandle->codecMode == C7_AVS2_DEC) {
  692. fbHeight = VPU_ALIGN8(picHeight);
  693. }
  694. else if (productId == PRODUCT_ID_7Q && decHandle->codecMode != C7_HEVC_DEC)
  695. {
  696. fbHeight = seqInfo.interlace ? VPU_ALIGN32(picHeight) : VPU_ALIGN16(picHeight);
  697. }
  698. else if (productId == PRODUCT_ID_960 || productId == PRODUCT_ID_980)
  699. {
  700. fbHeight = VPU_ALIGN32(picHeight);
  701. }
  702. if (decHandle->codecMode == C7_VP9_DEC) {
  703. linearStride = CalcStride(VPU_ALIGN64(picWidth), picHeight, outFormat, config->cbcrInterleave, (TiledMapType)mapType, TRUE);
  704. }
  705. else {
  706. linearStride = CalcStride(picWidth, picHeight, outFormat, config->cbcrInterleave, (TiledMapType)mapType, FALSE);
  707. }
  708. framebufSize = VPU_GetFrameBufSize(coreIndex, linearStride, fbHeight, (TiledMapType)mapType, outFormat, config->cbcrInterleave, pDramCfg);
  709. for (index=tiledFbCount; index<totalFbCount; index++) {
  710. pvb = &retFbAddrs[index];
  711. pvb->size = framebufSize;
  712. if (vdi_allocate_dma_memory(coreIndex, pvb) < 0) {
  713. VLOG(ERR, "%s:%d fail to allocate frame buffer\n", __FUNCTION__, __LINE__);
  714. ReleaseVideoMemory(coreIndex, retFbAddrs, totalFbCount);
  715. return FALSE;
  716. }
  717. retFbArray[index].bufY = pvb->phys_addr;
  718. retFbArray[index].bufCb = -1;
  719. retFbArray[index].bufCr = -1;
  720. retFbArray[index].updateFbInfo = TRUE;
  721. retFbArray[index].size = framebufSize;
  722. }
  723. fbAllocInfo.nv21 = config->nv21;
  724. fbAllocInfo.format = outFormat;
  725. fbAllocInfo.num = linearFbCount;
  726. fbAllocInfo.mapType = (TiledMapType)mapType;
  727. fbAllocInfo.stride = linearStride;
  728. fbAllocInfo.height = fbHeight;
  729. ret = VPU_DecAllocateFrameBuffer(decHandle, fbAllocInfo, &retFbArray[tiledFbCount]);
  730. if (ret != RETCODE_SUCCESS) {
  731. VLOG(ERR, "%s:%d failed to VPU_DecAllocateFrameBuffer() ret:%d\n",
  732. __FUNCTION__, __LINE__, ret);
  733. ReleaseVideoMemory(coreIndex, retFbAddrs, totalFbCount);
  734. return FALSE;
  735. }
  736. }
  737. return TRUE;
  738. }
  739. #if defined(_WIN32) || defined(__MSDOS__)
  740. #define DOS_FILESYSTEM
  741. #define IS_DIR_SEPARATOR(__c) ((__c == '/') || (__c == '\\'))
  742. #else
  743. /* UNIX style */
  744. #define IS_DIR_SEPARATOR(__c) (__c == '/')
  745. #endif
  746. char* GetDirname(
  747. const char* path
  748. )
  749. {
  750. int length;
  751. int i;
  752. char* upper_dir;
  753. if (path == NULL) return NULL;
  754. length = strlen(path);
  755. for (i=length-1; i>=0; i--) {
  756. if (IS_DIR_SEPARATOR(path[i])) break;
  757. }
  758. if (i<0) {
  759. upper_dir = strdup(".");
  760. } else {
  761. upper_dir = strdup(path);
  762. upper_dir[i] = 0;
  763. }
  764. return upper_dir;
  765. }
  766. char* GetBasename(
  767. const char* pathname
  768. )
  769. {
  770. const char* base = NULL;
  771. const char* p = pathname;
  772. if (p == NULL) {
  773. return NULL;
  774. }
  775. #if defined(DOS_FILESYSTEM)
  776. if (isalpha((int)p[0]) && p[1] == ':') {
  777. p += 2;
  778. }
  779. #endif
  780. for (base=p; *p; p++) {
  781. if (IS_DIR_SEPARATOR(*p)) {
  782. base = p+1;
  783. }
  784. }
  785. return (char*)base;
  786. }
  787. char* GetFileExtension(
  788. const char* filename
  789. )
  790. {
  791. Uint32 len;
  792. Uint32 i;
  793. len = strlen(filename);
  794. for (i=len-1; i>=0; i--) {
  795. if (filename[i] == '.') {
  796. return (char*)&filename[i+1];
  797. }
  798. }
  799. return NULL;
  800. }
  801. void byte_swap(unsigned char* data, int len)
  802. {
  803. Uint8 temp;
  804. Int32 i;
  805. for (i=0; i<len; i+=2) {
  806. temp = data[i];
  807. data[i] = data[i+1];
  808. data[i+1] = temp;
  809. }
  810. }
  811. BOOL IsEndOfFile(FILE* fp)
  812. {
  813. BOOL result = FALSE;
  814. Int32 index = 0;
  815. char cTemp;
  816. // Check current fp pos
  817. if (osal_feof(fp) != 0) {
  818. result = TRUE;
  819. }
  820. // Check next fp pos
  821. // Ignore newline character
  822. do {
  823. cTemp = fgetc(fp);
  824. index++;
  825. if (osal_feof(fp) != 0) {
  826. result = TRUE;
  827. break;
  828. }
  829. } while (cTemp == '\n' || cTemp == '\r');
  830. // Revert fp pos
  831. index *= (-1);
  832. osal_fseek(fp, index, SEEK_CUR);
  833. return result;
  834. }
  835. BOOL CalcYuvSize(
  836. Int32 format,
  837. Int32 picWidth,
  838. Int32 picHeight,
  839. Int32 cbcrInterleave,
  840. size_t *lumaSize,
  841. size_t *chromaSize,
  842. size_t *frameSize,
  843. Int32 *bitDepth,
  844. Int32 *packedFormat,
  845. Int32 *yuv3p4b)
  846. {
  847. Int32 temp_picWidth;
  848. Int32 chromaWidth;
  849. if ( bitDepth != 0)
  850. *bitDepth = 0;
  851. if ( packedFormat != 0)
  852. *packedFormat = 0;
  853. if ( yuv3p4b != 0)
  854. *yuv3p4b = 0;
  855. switch (format)
  856. {
  857. case FORMAT_420:
  858. if (lumaSize) *lumaSize = picWidth * picHeight;
  859. if (chromaSize) *chromaSize = picWidth * picHeight / 2;
  860. if (frameSize) *frameSize = picWidth * picHeight * 3 /2;
  861. break;
  862. case FORMAT_YUYV:
  863. case FORMAT_YVYU:
  864. case FORMAT_UYVY:
  865. case FORMAT_VYUY:
  866. if ( packedFormat != 0)
  867. *packedFormat = 1;
  868. if (lumaSize) *lumaSize = picWidth * picHeight;
  869. if (chromaSize) *chromaSize = picWidth * picHeight;
  870. if (frameSize) *frameSize = *lumaSize + *chromaSize;
  871. break;
  872. case FORMAT_224:
  873. if (lumaSize) *lumaSize = picWidth * picHeight;
  874. if (chromaSize) *chromaSize = picWidth * picHeight;
  875. if (frameSize) *frameSize = picWidth * picHeight * 4 / 2;
  876. break;
  877. case FORMAT_422:
  878. if (lumaSize) *lumaSize = picWidth * picHeight;
  879. if (chromaSize) *chromaSize = picWidth * picHeight;
  880. if (frameSize) *frameSize = picWidth * picHeight * 4 / 2;
  881. break;
  882. case FORMAT_444:
  883. if (lumaSize) *lumaSize = picWidth * picHeight;
  884. if (chromaSize) *chromaSize = picWidth * picHeight * 2;
  885. if (frameSize) *frameSize = picWidth * picHeight * 3;
  886. break;
  887. case FORMAT_400:
  888. if (lumaSize) *lumaSize = picWidth * picHeight;
  889. if (chromaSize) *chromaSize = 0;
  890. if (frameSize) *frameSize = picWidth * picHeight;
  891. break;
  892. case FORMAT_422_P10_16BIT_MSB:
  893. case FORMAT_422_P10_16BIT_LSB:
  894. if ( bitDepth != NULL) {
  895. *bitDepth = 10;
  896. }
  897. if (lumaSize) *lumaSize = picWidth * picHeight * 2;
  898. if (chromaSize) *chromaSize = *lumaSize;
  899. if (frameSize) *frameSize = *lumaSize + *chromaSize;
  900. break;
  901. case FORMAT_420_P10_16BIT_MSB:
  902. case FORMAT_420_P10_16BIT_LSB:
  903. if ( bitDepth != 0)
  904. *bitDepth = 10;
  905. if (lumaSize) *lumaSize = picWidth * picHeight * 2;
  906. if (chromaSize) *chromaSize = picWidth * picHeight;
  907. if (frameSize) *frameSize = *lumaSize + *chromaSize;
  908. break;
  909. case FORMAT_YUYV_P10_16BIT_MSB: // 4:2:2 10bit packed
  910. case FORMAT_YUYV_P10_16BIT_LSB:
  911. case FORMAT_YVYU_P10_16BIT_MSB:
  912. case FORMAT_YVYU_P10_16BIT_LSB:
  913. case FORMAT_UYVY_P10_16BIT_MSB:
  914. case FORMAT_UYVY_P10_16BIT_LSB:
  915. case FORMAT_VYUY_P10_16BIT_MSB:
  916. case FORMAT_VYUY_P10_16BIT_LSB:
  917. if ( bitDepth != 0)
  918. *bitDepth = 10;
  919. if ( packedFormat != 0)
  920. *packedFormat = 1;
  921. if (lumaSize) *lumaSize = picWidth * picHeight * 2;
  922. if (chromaSize) *chromaSize = picWidth * picHeight * 2;
  923. if (frameSize) *frameSize = *lumaSize + *chromaSize;
  924. break;
  925. case FORMAT_420_P10_32BIT_MSB:
  926. case FORMAT_420_P10_32BIT_LSB:
  927. if ( bitDepth != 0)
  928. *bitDepth = 10;
  929. if ( yuv3p4b != 0)
  930. *yuv3p4b = 1;
  931. temp_picWidth = VPU_ALIGN32(picWidth);
  932. chromaWidth = ((VPU_ALIGN16(temp_picWidth/2*(1<<cbcrInterleave))+2)/3*4);
  933. if ( cbcrInterleave == 1)
  934. {
  935. if (lumaSize) *lumaSize = (temp_picWidth+2)/3*4 * picHeight;
  936. if (chromaSize) *chromaSize = chromaWidth * picHeight/2;
  937. } else {
  938. if (lumaSize) *lumaSize = (temp_picWidth+2)/3*4 * picHeight;
  939. if (chromaSize) *chromaSize = chromaWidth * picHeight/2*2;
  940. }
  941. if (frameSize) *frameSize = *lumaSize + *chromaSize;
  942. break;
  943. case FORMAT_YUYV_P10_32BIT_MSB:
  944. case FORMAT_YUYV_P10_32BIT_LSB:
  945. case FORMAT_YVYU_P10_32BIT_MSB:
  946. case FORMAT_YVYU_P10_32BIT_LSB:
  947. case FORMAT_UYVY_P10_32BIT_MSB:
  948. case FORMAT_UYVY_P10_32BIT_LSB:
  949. case FORMAT_VYUY_P10_32BIT_MSB:
  950. case FORMAT_VYUY_P10_32BIT_LSB:
  951. if ( bitDepth != 0)
  952. *bitDepth = 10;
  953. if ( packedFormat != 0)
  954. *packedFormat = 1;
  955. if ( yuv3p4b != 0)
  956. *yuv3p4b = 1;
  957. if (frameSize) *frameSize = ((picWidth*2)+2)/3*4 * picHeight;
  958. if (lumaSize) *lumaSize = *frameSize/2;
  959. if (chromaSize) *chromaSize = *frameSize/2;
  960. break;
  961. default:
  962. if (frameSize) *frameSize = picWidth * picHeight * 3 / 2;
  963. VLOG(ERR, "%s:%d Not supported format(%d)\n", __FILE__, __LINE__, format);
  964. return FALSE;
  965. }
  966. return TRUE;
  967. }
  968. int GetPackedFormat (
  969. int srcBitDepth,
  970. int packedType,
  971. int p10bits,
  972. int msb)
  973. {
  974. int format = FORMAT_YUYV;
  975. // default pixel format = P10_16BIT_LSB (p10bits = 16, msb = 0)
  976. if (srcBitDepth == 8) {
  977. switch(packedType) {
  978. case PACKED_YUYV:
  979. format = FORMAT_YUYV;
  980. break;
  981. case PACKED_YVYU:
  982. format = FORMAT_YVYU;
  983. break;
  984. case PACKED_UYVY:
  985. format = FORMAT_UYVY;
  986. break;
  987. case PACKED_VYUY:
  988. format = FORMAT_VYUY;
  989. break;
  990. default:
  991. format = -1;
  992. }
  993. }
  994. else if (srcBitDepth == 10) {
  995. switch(packedType) {
  996. case PACKED_YUYV:
  997. if (p10bits == 16) {
  998. format = (msb == 0) ? FORMAT_YUYV_P10_16BIT_LSB : FORMAT_YUYV_P10_16BIT_MSB;
  999. }
  1000. else if (p10bits == 32) {
  1001. format = (msb == 0) ? FORMAT_YUYV_P10_32BIT_LSB : FORMAT_YUYV_P10_32BIT_MSB;
  1002. }
  1003. else {
  1004. format = -1;
  1005. }
  1006. break;
  1007. case PACKED_YVYU:
  1008. if (p10bits == 16) {
  1009. format = (msb == 0) ? FORMAT_YVYU_P10_16BIT_LSB : FORMAT_YVYU_P10_16BIT_MSB;
  1010. }
  1011. else if (p10bits == 32) {
  1012. format = (msb == 0) ? FORMAT_YVYU_P10_32BIT_LSB : FORMAT_YVYU_P10_32BIT_MSB;
  1013. }
  1014. else {
  1015. format = -1;
  1016. }
  1017. break;
  1018. case PACKED_UYVY:
  1019. if (p10bits == 16) {
  1020. format = (msb == 0) ? FORMAT_UYVY_P10_16BIT_LSB : FORMAT_UYVY_P10_16BIT_MSB;
  1021. }
  1022. else if (p10bits == 32) {
  1023. format = (msb == 0) ? FORMAT_UYVY_P10_32BIT_LSB : FORMAT_UYVY_P10_32BIT_MSB;
  1024. }
  1025. else {
  1026. format = -1;
  1027. }
  1028. break;
  1029. case PACKED_VYUY:
  1030. if (p10bits == 16) {
  1031. format = (msb == 0) ? FORMAT_VYUY_P10_16BIT_LSB : FORMAT_VYUY_P10_16BIT_MSB;
  1032. }
  1033. else if (p10bits == 32) {
  1034. format = (msb == 0) ? FORMAT_VYUY_P10_32BIT_LSB : FORMAT_VYUY_P10_32BIT_MSB;
  1035. }
  1036. else {
  1037. format = -1;
  1038. }
  1039. break;
  1040. default:
  1041. format = -1;
  1042. }
  1043. }
  1044. else {
  1045. format = -1;
  1046. }
  1047. return format;
  1048. }
  1049. void GenRegionToMap(
  1050. VpuRect *region, /**< The size of the ROI region for H.265 (start X/Y in CTU, end X/Y int CTU) */
  1051. int *roiLevel,
  1052. int num,
  1053. Uint32 mapWidth,
  1054. Uint32 mapHeight,
  1055. Uint8 *roiCtuMap)
  1056. {
  1057. Int32 roi_id, blk_addr;
  1058. Uint32 roi_map_size = mapWidth * mapHeight;
  1059. //init roi map
  1060. for (blk_addr=0; blk_addr<(Int32)roi_map_size; blk_addr++)
  1061. roiCtuMap[blk_addr] = 0;
  1062. //set roi map. roi_entry[i] has higher priority than roi_entry[i+1]
  1063. for (roi_id=(Int32)num-1; roi_id>=0; roi_id--)
  1064. {
  1065. Uint32 x, y;
  1066. VpuRect *roi = region + roi_id;
  1067. for (y=roi->top; y<=roi->bottom; y++)
  1068. {
  1069. for (x=roi->left; x<=roi->right; x++)
  1070. {
  1071. roiCtuMap[y*mapWidth + x] = *(roiLevel + roi_id);
  1072. }
  1073. }
  1074. }
  1075. }
  1076. void GenRegionToQpMap(
  1077. VpuRect *region, /**< The size of the ROI region for H.265 (start X/Y in CTU, end X/Y int CTU) */
  1078. int *roiLevel,
  1079. int num,
  1080. int initQp,
  1081. Uint32 mapWidth,
  1082. Uint32 mapHeight,
  1083. Uint8 *roiCtuMap)
  1084. {
  1085. Int32 roi_id, blk_addr;
  1086. Uint32 roi_map_size = mapWidth * mapHeight;
  1087. //init roi map
  1088. for (blk_addr=0; blk_addr<(Int32)roi_map_size; blk_addr++)
  1089. roiCtuMap[blk_addr] = initQp;
  1090. //set roi map. roi_entry[i] has higher priority than roi_entry[i+1]
  1091. for (roi_id=(Int32)num-1; roi_id>=0; roi_id--)
  1092. {
  1093. Uint32 x, y;
  1094. VpuRect *roi = region + roi_id;
  1095. for (y=roi->top; y<=roi->bottom; y++)
  1096. {
  1097. for (x=roi->left; x<=roi->right; x++)
  1098. {
  1099. roiCtuMap[y*mapWidth + x] = *(roiLevel + roi_id);
  1100. }
  1101. }
  1102. }
  1103. }
  1104. Int32 writeVuiRbsp(int coreIdx, TestEncConfig *encConfig, EncOpenParam *encOP, vpu_buffer_t *vbVuiRbsp)
  1105. {
  1106. if (encOP->encodeVuiRbsp == TRUE) {
  1107. vbVuiRbsp->size = VUI_HRD_RBSP_BUF_SIZE;
  1108. if (vdi_allocate_dma_memory(coreIdx, vbVuiRbsp) < 0) {
  1109. VLOG(ERR, "fail to allocate VUI rbsp buffer\n" );
  1110. return FALSE;
  1111. }
  1112. encOP->vuiRbspDataAddr = vbVuiRbsp->phys_addr;
  1113. if (encConfig->vui_rbsp_file_name) {
  1114. Uint8 *pVuiRbspBuf;
  1115. Int32 rbspSizeInByte = (encOP->vuiRbspDataSize+7)>>3;
  1116. ChangePathStyle(encConfig->vui_rbsp_file_name);
  1117. if ((encConfig->vui_rbsp_fp = osal_fopen(encConfig->vui_rbsp_file_name, "r")) == NULL) {
  1118. VLOG(ERR, "fail to open Prefix SEI NAL Data file, %s\n", encConfig->vui_rbsp_file_name);
  1119. return FALSE;
  1120. }
  1121. if (rbspSizeInByte > (Uint32)VUI_HRD_RBSP_BUF_SIZE)
  1122. VLOG(ERR, "VUI Rbsp size is bigger than buffer size\n");
  1123. pVuiRbspBuf = (Uint8*)osal_malloc(VUI_HRD_RBSP_BUF_SIZE);
  1124. osal_memset(pVuiRbspBuf, 0, VUI_HRD_RBSP_BUF_SIZE);
  1125. osal_fread(pVuiRbspBuf, 1, rbspSizeInByte, encConfig->vui_rbsp_fp);
  1126. vdi_write_memory(coreIdx, encOP->vuiRbspDataAddr, pVuiRbspBuf, rbspSizeInByte, encOP->streamEndian);
  1127. osal_free(pVuiRbspBuf);
  1128. }
  1129. }
  1130. return TRUE;
  1131. }
  1132. Int32 writeHrdRbsp(int coreIdx, TestEncConfig *encConfig, EncOpenParam *encOP, vpu_buffer_t *vbHrdRbsp)
  1133. {
  1134. if (encOP->encodeHrdRbspInVPS || encOP->encodeHrdRbspInVUI)
  1135. {
  1136. vbHrdRbsp->size = VUI_HRD_RBSP_BUF_SIZE;
  1137. if (vdi_allocate_dma_memory(coreIdx, vbHrdRbsp) < 0) {
  1138. VLOG(ERR, "fail to allocate HRD rbsp buffer\n" );
  1139. return FALSE;
  1140. }
  1141. encOP->hrdRbspDataAddr = vbHrdRbsp->phys_addr;
  1142. if (encConfig->hrd_rbsp_file_name) {
  1143. Uint8 *pHrdRbspBuf;
  1144. Int32 rbspSizeInByte = (encOP->hrdRbspDataSize+7)>>3;
  1145. ChangePathStyle(encConfig->hrd_rbsp_file_name);
  1146. if ((encConfig->hrd_rbsp_fp = osal_fopen(encConfig->hrd_rbsp_file_name, "r")) == NULL) {
  1147. VLOG(ERR, "fail to open Prefix SEI NAL Data file, %s\n", encConfig->hrd_rbsp_file_name);
  1148. return FALSE;
  1149. }
  1150. if (rbspSizeInByte > (Uint32)VUI_HRD_RBSP_BUF_SIZE)
  1151. VLOG(ERR, "HRD Rbsp size is bigger than buffer size\n");
  1152. pHrdRbspBuf = (Uint8*)osal_malloc(VUI_HRD_RBSP_BUF_SIZE);
  1153. osal_memset(pHrdRbspBuf, 0, VUI_HRD_RBSP_BUF_SIZE);
  1154. osal_fread(pHrdRbspBuf, 1, rbspSizeInByte, encConfig->hrd_rbsp_fp);
  1155. vdi_write_memory(coreIdx, encOP->hrdRbspDataAddr, pHrdRbspBuf, rbspSizeInByte, encOP->streamEndian);
  1156. osal_free(pHrdRbspBuf);
  1157. }
  1158. }
  1159. return TRUE;
  1160. }
  1161. #ifdef TEST_ENCODE_CUSTOM_HEADER
  1162. Int32 writeCustomHeader(int coreIdx, EncOpenParam *encOP, vpu_buffer_t *vbCustomHeader, hrd_t *hrd)
  1163. {
  1164. Uint32 rbspBitSize;
  1165. Uint8 *pRbspBuf;
  1166. Uint32 rbspByteSize;
  1167. vui_t vui;
  1168. encOP->encodeVuiRbsp = 1;
  1169. vbCustomHeader->size = VUI_HRD_RBSP_BUF_SIZE;
  1170. if (vdi_allocate_dma_memory(coreIdx, vbCustomHeader) < 0) {
  1171. VLOG(ERR, "fail to allocate VUI rbsp buffer\n" );
  1172. return FALSE;
  1173. }
  1174. encOP->vuiRbspDataAddr = vbCustomHeader->phys_addr;
  1175. pRbspBuf = (Uint8 *)osal_malloc(VUI_HRD_RBSP_BUF_SIZE);
  1176. if (pRbspBuf) {
  1177. osal_memset(pRbspBuf, 0, VUI_HRD_RBSP_BUF_SIZE);
  1178. vui.vui_parameters_presesent_flag = 1;
  1179. vui.vui_timing_info_present_flag = 1;
  1180. vui.vui_num_units_in_tick = 1000;
  1181. vui.vui_time_scale = (encOP->frameRateInfo)*1000.0;
  1182. vui.vui_hrd_parameters_present_flag = 1;
  1183. vui.def_disp_win_left_offset = 1;
  1184. vui.def_disp_win_right_offset = 1;
  1185. vui.def_disp_win_top_offset = 1;
  1186. vui.def_disp_win_bottom_offset = 1;
  1187. // HRD param : refer xInitHrdParameters in HM
  1188. {
  1189. int useSubCpbParams =0;
  1190. int bitRate = encOP->bitRate;
  1191. int isRandomAccess;
  1192. int cpbSize = bitRate; // Adjusting value to be equal to TargetBitrate
  1193. int bitRateScale;
  1194. int cpbSizeScale;
  1195. int i, j, numSubLayersM1;
  1196. Uint32 bitrateValue, cpbSizeValue;
  1197. Uint32 duCpbSizeValue;
  1198. Uint32 duBitRateValue = 0;
  1199. if (bitRate >0) {
  1200. hrd->nal_hrd_parameters_present_flag = 1;
  1201. hrd->vcl_hrd_parameters_present_flag = 1;
  1202. }
  1203. else {
  1204. hrd->nal_hrd_parameters_present_flag = 0;
  1205. hrd->vcl_hrd_parameters_present_flag = 0;
  1206. }
  1207. if (encOP->EncStdParam.hevcParam.independSliceMode != 0)
  1208. useSubCpbParams = 1;
  1209. if (encOP->EncStdParam.hevcParam.intraPeriod > 0)
  1210. isRandomAccess = 1;
  1211. else
  1212. isRandomAccess = 0;
  1213. hrd->sub_pic_hrd_params_present_flag = useSubCpbParams;
  1214. if (useSubCpbParams) {
  1215. hrd->tick_divisor_minus2 = 100-2;
  1216. hrd->du_cpb_removal_delay_increment_length_minus1 = 7; // 8-bit precision ( plus 1 for last DU in AU )
  1217. hrd->sub_pic_cpb_params_in_pic_timing_sei_flag = 1;
  1218. hrd->dpb_output_delay_du_length_minus1 = 5+7; // With sub-clock tick factor of 100, at least 7 bits to have the same value as AU dpb delay
  1219. }
  1220. else
  1221. hrd->sub_pic_cpb_params_in_pic_timing_sei_flag = 0;
  1222. // calculate scale value of bitrate and initial delay
  1223. bitRateScale = calcScale(bitRate);
  1224. if ( bitRateScale <= 6 )
  1225. hrd->bit_rate_scale = 0;
  1226. else
  1227. hrd->bit_rate_scale = bitRateScale -6;
  1228. cpbSizeScale = calcScale(cpbSize);
  1229. if ( cpbSizeScale <= 4 )
  1230. hrd->cpb_size_scale = 0;
  1231. else
  1232. hrd->cpb_size_scale = cpbSizeScale -4;
  1233. hrd->cpb_size_du_scale = 6; // in units of 2^( 4 + 6 ) = 1,024 bit
  1234. hrd->initial_cpb_removal_delay_length_minus1 = 15; // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit
  1235. if (isRandomAccess > 0) {
  1236. hrd->au_cpb_removal_delay_length_minus1 = 5;
  1237. hrd->dpb_output_delay_length_minus1 = 5;
  1238. }
  1239. else {
  1240. hrd->au_cpb_removal_delay_length_minus1 = 9;
  1241. hrd->dpb_output_delay_length_minus1 = 9;
  1242. }
  1243. numSubLayersM1 = 0;
  1244. if (encOP->EncStdParam.hevcParam.gopPresetIdx == 0) { // custom GOP
  1245. for(i=0; i<encOP->EncStdParam.hevcParam.gopParam.customGopSize; i++) {
  1246. if (numSubLayersM1 < encOP->EncStdParam.hevcParam.gopParam.picParam[i].temporalId)
  1247. numSubLayersM1 = encOP->EncStdParam.hevcParam.gopParam.picParam[i].temporalId;
  1248. }
  1249. }
  1250. hrd->vps_max_sub_layers_minus1 = numSubLayersM1;
  1251. // sub_layer_hrd_parameters
  1252. // BitRate[ i ] = ( bit_rate_value_minus1[ i ] + 1 ) * 2^( 6 + bit_rate_scale )
  1253. bitrateValue = bitRate / (1 << (6 + hrd->bit_rate_scale) ); // bitRate is in bits, so it needs to be scaled down
  1254. // CpbSize[ i ] = ( cpb_size_value_minus1[ i ] + 1 ) * 2^( 4 + cpb_size_scale )
  1255. cpbSizeValue = cpbSize / (1 << (4 + hrd->cpb_size_scale) ); // using bitRate results in 1 second CPB size
  1256. // DU CPB size could be smaller (i.e. bitrateValue / number of DUs), but we don't know
  1257. // in how many DUs the slice segment settings will result
  1258. duCpbSizeValue = bitrateValue;
  1259. duBitRateValue = cpbSizeValue;
  1260. for(i=0; i<hrd->vps_max_sub_layers_minus1; i++) {
  1261. hrd->fixed_pic_rate_general_flag[i] = 1;
  1262. hrd->fixed_pic_rate_within_cvs_flag[i] = 1; // fixed_pic_rate_general_flag[ i ] is equal to 1, the value of fixed_pic_rate_within_cvs_flag[ i ] is inferred to be equal to 1
  1263. hrd->elemental_duration_in_tc_minus1[i] = 0;
  1264. hrd->low_delay_hrd_flag[i] = 0;
  1265. hrd->cpb_cnt_minus1[i] = 0;
  1266. if (hrd->nal_hrd_parameters_present_flag) {
  1267. for (j=0; hrd->cpb_cnt_minus1[i]; j++) {
  1268. hrd->bit_rate_value_minus1[j][i] = bitrateValue-1;
  1269. hrd->cpb_size_value_minus1[j][i] = cpbSize -1;
  1270. hrd->cpb_size_du_value_minus1[j][i] = duCpbSizeValue -1;
  1271. hrd->bit_rate_du_value_minus1[j][i] = duBitRateValue -1;
  1272. hrd->cbr_flag[j][i] = 0;
  1273. }
  1274. }
  1275. if (hrd->vcl_hrd_parameters_present_flag) {
  1276. for (j=0; hrd->cpb_cnt_minus1[i]; j++) {
  1277. hrd->bit_rate_value_minus1[j][i] = bitrateValue-1;
  1278. hrd->cpb_size_value_minus1[j][i] = cpbSize -1;
  1279. hrd->cpb_size_du_value_minus1[j][i] = duCpbSizeValue -1;
  1280. hrd->bit_rate_du_value_minus1[j][i] = duBitRateValue -1;
  1281. hrd->cbr_flag[j][i] = 0;
  1282. }
  1283. }
  1284. }
  1285. }
  1286. EncodeVUI(hrd, &vui, pRbspBuf, VUI_HRD_RBSP_BUF_SIZE, &rbspByteSize, &rbspBitSize, encOP->frameRateInfo);
  1287. encOP->vuiRbspDataSize = rbspBitSize;
  1288. vdi_write_memory(coreIdx, encOP->vuiRbspDataAddr, pRbspBuf, rbspByteSize, encOP->streamEndian);
  1289. osal_free(pRbspBuf);
  1290. }
  1291. return TRUE;
  1292. }
  1293. Int32 allocateSeiNalDataBuf(int coreIdx, vpu_buffer_t *vbSeiNal, int srcFbNum)
  1294. {
  1295. Int32 i;
  1296. for (i = 0; i < srcFbNum; i++) { // the number of roi buffer should be the same as source buffer num.
  1297. vbSeiNal[i].size = SEI_NAL_DATA_BUF_SIZE;
  1298. if (vdi_allocate_dma_memory(coreIdx, &vbSeiNal[i]) < 0) {
  1299. VLOG(ERR, "fail to allocate SeiNalData buffer\n");
  1300. return FALSE;
  1301. }
  1302. }
  1303. return TRUE;
  1304. }
  1305. Int32 writeSeiNalData(EncHandle handle, int streamEndian, PhysicalAddress prefixSeiNalAddr, hrd_t *hrd)
  1306. {
  1307. sei_buffering_period_t buffering_period_sei;
  1308. Uint8 *pSeiBuf;
  1309. sei_active_parameter_t active_parameter_sei;
  1310. Int32 seiByteSize = 0;
  1311. HevcSEIDataEnc seiDataEnc;
  1312. sei_pic_timing_t pic_timing_sei;
  1313. pSeiBuf = (Uint8 *)osal_malloc(SEI_NAL_DATA_BUF_SIZE);
  1314. if (pSeiBuf)
  1315. {
  1316. osal_memset(pSeiBuf, 0x00, SEI_NAL_DATA_BUF_SIZE);
  1317. osal_memset(&seiDataEnc, 0x00, sizeof(seiDataEnc));
  1318. seiDataEnc.prefixSeiNalEnable = 1;
  1319. seiDataEnc.prefixSeiDataEncOrder = 0;
  1320. seiDataEnc.prefixSeiNalAddr = prefixSeiNalAddr;
  1321. active_parameter_sei.active_video_parameter_set_id = 0; // vps_video_parameter_set_id of the VPS. wave420 is 0
  1322. active_parameter_sei.self_contained_cvs_flag = 0;
  1323. active_parameter_sei.no_parameter_set_update_flag = 0;
  1324. active_parameter_sei.num_sps_ids_minus1 = 0;
  1325. active_parameter_sei.active_seq_parameter_set_id[0] = 0;// sps_seq_parameter_set_id of the SPS. wave420 is 0
  1326. // put sei_pic_timing
  1327. pic_timing_sei.pic_struct = 0;
  1328. pic_timing_sei.source_scan_type = 1;
  1329. pic_timing_sei.duplicate_flag = 0;
  1330. buffering_period_sei.nal_initial_cpb_removal_delay[0] = 2229;
  1331. buffering_period_sei.nal_initial_cpb_removal_offset[0] = 0;
  1332. seiByteSize = EncodePrefixSEI(&active_parameter_sei, &pic_timing_sei, &buffering_period_sei, hrd, pSeiBuf, SEI_NAL_DATA_BUF_SIZE);
  1333. seiDataEnc.prefixSeiDataSize = seiByteSize;
  1334. vdi_write_memory(handle->coreIdx, seiDataEnc.prefixSeiNalAddr, pSeiBuf, seiDataEnc.prefixSeiDataSize, streamEndian);
  1335. free(pSeiBuf);
  1336. }
  1337. VPU_EncGiveCommand(handle, ENC_SET_SEI_NAL_DATA, &seiDataEnc);
  1338. return TRUE;
  1339. }
  1340. #endif
  1341. int setRoiMap(int coreIdx, TestEncConfig *encConfig, EncOpenParam encOP, PhysicalAddress addrRoiMap,
  1342. Uint8 *roiMapBuf, int srcFrameWidth, int srcFrameHeight, EncParam *encParam, int maxCtuNum)
  1343. {
  1344. int i;
  1345. if (encConfig->roi_enable && encParam->srcEndFlag != 1) {
  1346. int roiNum=0;
  1347. // sample code to convert ROI coordinate to ROI map.
  1348. osal_memset(&encConfig->region[0], 0, sizeof(VpuRect)*MAX_ROI_NUMBER);
  1349. osal_memset(&encConfig->roiLevel[0], 0, sizeof(int)*MAX_ROI_NUMBER);
  1350. if (encConfig->roi_file_name) {
  1351. char lineStr[256] = {0, };
  1352. int val;
  1353. fgets(lineStr, 256, encConfig->roi_file);
  1354. sscanf(lineStr, "%x\n", &val);
  1355. if (val != 0xFFFF)
  1356. VLOG(ERR, "can't find the picture delimiter \n");
  1357. fgets(lineStr, 256, encConfig->roi_file);
  1358. sscanf(lineStr, "%d\n", &val); // picture index
  1359. fgets(lineStr, 256, encConfig->roi_file);
  1360. sscanf(lineStr, "%d\n", &roiNum); // number of roi regions
  1361. for (i = 0; i < roiNum; i++) {
  1362. fgets(lineStr, 256, encConfig->roi_file);
  1363. if (parseRoiCtuModeParam(lineStr, &encConfig->region[i], &encConfig->roiLevel[i], srcFrameWidth, srcFrameHeight) == 0 ) {
  1364. VLOG(ERR, "CFG file error : %s value is not available. \n", encConfig->roi_file_name);
  1365. }
  1366. }
  1367. }
  1368. encParam->ctuOptParam.addrRoiCtuMap = addrRoiMap;
  1369. encParam->ctuOptParam.mapEndian = VDI_LITTLE_ENDIAN;
  1370. encParam->ctuOptParam.mapStride = ((encOP.picWidth+63)&~63)>>6;
  1371. encParam->ctuOptParam.roiEnable = (roiNum != 0) ? encConfig->roi_enable : 0;
  1372. encParam->ctuOptParam.roiDeltaQp = encConfig->roi_delta_qp;
  1373. if (encParam->ctuOptParam.roiEnable) {
  1374. GenRegionToMap(&encConfig->region[0], &encConfig->roiLevel[0], roiNum, encParam->ctuOptParam.mapStride , ((encOP.picHeight+63)&~63)>>6, &roiMapBuf[0]);
  1375. vdi_write_memory(coreIdx, encParam->ctuOptParam.addrRoiCtuMap, roiMapBuf, maxCtuNum, encParam->ctuOptParam.mapEndian);
  1376. }
  1377. }
  1378. return TRUE;
  1379. }
  1380. int checkParamRestriction(Uint32 productId, TestEncConfig *encConfig)
  1381. {
  1382. if ( (encConfig->compare_type & (1<<MODE_SAVE_ENCODED)) && encConfig->bitstreamFileName[0] == 0) {
  1383. encConfig->compare_type &= ~(1<<MODE_SAVE_ENCODED);
  1384. VLOG(ERR,"You want to Save bitstream data. Set the path\n");
  1385. }
  1386. if ( (encConfig->compare_type & (1<<MODE_COMP_ENCODED)) && encConfig->ref_stream_path[0] == 0) {
  1387. encConfig->compare_type &= ~(1<<MODE_COMP_ENCODED);
  1388. VLOG(ERR,"You want to Compare bitstream data. Set the path\n");
  1389. }
  1390. /* CHECK PARAMETERS */
  1391. if (productId == PRODUCT_ID_420L) {
  1392. if (encConfig->rotAngle != 0) {
  1393. VLOG(ERR, "WAVE420L Not support rotation option\n");
  1394. return FALSE;
  1395. }
  1396. if (encConfig->mirDir != 0) {
  1397. VLOG(ERR, "WAVE420L Not support mirror option\n");
  1398. return FALSE;
  1399. }
  1400. if (encConfig->srcFormat3p4b == TRUE) {
  1401. VLOG(ERR, "WAVE420L Not support 3 pixel 4byte format option\n");
  1402. return FALSE;
  1403. }
  1404. if (encConfig->ringBufferEnable == TRUE) {
  1405. encConfig->ringBufferEnable = FALSE;
  1406. VLOG(ERR, "WAVE420L doesn't support ring-buffer.\n");
  1407. }
  1408. }
  1409. return TRUE;
  1410. }
  1411. int openRoiMapFile(TestEncConfig *encConfig)
  1412. {
  1413. if (encConfig->roi_enable) {
  1414. if (encConfig->roi_file_name) {
  1415. ChangePathStyle(encConfig->roi_file_name);
  1416. if ((encConfig->roi_file = osal_fopen(encConfig->roi_file_name, "r")) == NULL) {
  1417. VLOG(ERR, "fail to open ROI file, %s\n", encConfig->roi_file_name);
  1418. return FALSE;
  1419. }
  1420. }
  1421. }
  1422. return TRUE;
  1423. }
  1424. int allocateRoiMapBuf(int coreIdx, TestEncConfig encConfig, vpu_buffer_t *vbRoi, int srcFbNum, int ctuNum)
  1425. {
  1426. int i;
  1427. if (encConfig.roi_enable) {
  1428. //number of roi buffer should be the same as source buffer num.
  1429. for (i = 0; i < srcFbNum ; i++) {
  1430. vbRoi[i].size = ctuNum;
  1431. if (vdi_allocate_dma_memory(coreIdx, &vbRoi[i]) < 0) {
  1432. VLOG(ERR, "fail to allocate ROI buffer\n" );
  1433. return FALSE;
  1434. }
  1435. }
  1436. }
  1437. return TRUE;
  1438. }
  1439. int setCtuQpMap(int coreIdx, TestEncConfig *encConfig, EncOpenParam encOP, PhysicalAddress addrCtuQpMap,
  1440. Uint8 *ctuQpMapBuf, int srcFrameWidth, int srcFrameHeight, EncParam *encParam, int maxCtuNum)
  1441. {
  1442. int i;
  1443. if (encConfig->ctu_qp_enable && encParam->srcEndFlag != 1) {
  1444. int ctuQpNum=0;
  1445. // sample code to convert CTU coordinate to CTU MODE map.
  1446. osal_memset(&encConfig->region[0], 0, sizeof(VpuRect)*MAX_ROI_NUMBER);
  1447. osal_memset(&encConfig->ctuQp[0], 0, sizeof(int)*MAX_ROI_NUMBER);
  1448. if (encConfig->ctuqp_file_name) {
  1449. char lineStr[256] = {0, };
  1450. int val;
  1451. fgets(lineStr, 256, encConfig->ctuqp_file);
  1452. sscanf(lineStr, "%x\n", &val);
  1453. if (val != 0xFFFF)
  1454. VLOG(ERR, "can't find the picture delimiter \n");
  1455. fgets(lineStr, 256, encConfig->ctuqp_file);
  1456. sscanf(lineStr, "%d\n", &val); // picture index
  1457. fgets(lineStr, 256, encConfig->ctuqp_file);
  1458. sscanf(lineStr, "%d\n", &ctuQpNum); // number of roi regions
  1459. for (i = 0; i < ctuQpNum; i++) {
  1460. fgets(lineStr, 256, encConfig->ctuqp_file);
  1461. if (parseRoiCtuModeParam(lineStr, &encConfig->region[i], &encConfig->ctuQp[i], srcFrameWidth, srcFrameHeight) == 0 ) {
  1462. VLOG(ERR, "CFG file error : %s value is not available. \n", encConfig->ctuqp_file_name);
  1463. }
  1464. }
  1465. }
  1466. encParam->ctuOptParam.addrCtuQpMap = addrCtuQpMap;
  1467. encParam->ctuOptParam.mapEndian = VDI_LITTLE_ENDIAN;
  1468. encParam->ctuOptParam.mapStride = ((encOP.picWidth+63)&~63)>>6;
  1469. encParam->ctuOptParam.ctuQpEnable = encConfig->ctu_qp_enable;
  1470. if (encParam->ctuOptParam.ctuQpEnable) {
  1471. GenRegionToQpMap(&encConfig->region[0], &encConfig->ctuQp[0], ctuQpNum, encOP.EncStdParam.hevcParam.intraQP, encParam->ctuOptParam.mapStride , ((encOP.picHeight+63)&~63)>>6, &ctuQpMapBuf[0]);
  1472. vdi_write_memory(coreIdx, encParam->ctuOptParam.addrCtuQpMap, ctuQpMapBuf, maxCtuNum, encParam->ctuOptParam.mapEndian);
  1473. }
  1474. }
  1475. return TRUE;
  1476. }
  1477. int openCtuQpMapFile(TestEncConfig *encConfig)
  1478. {
  1479. if (encConfig->ctu_qp_enable) {
  1480. if (encConfig->ctuqp_file_name[0]) {
  1481. ChangePathStyle(encConfig->ctuqp_file_name);
  1482. if ((encConfig->ctuqp_file = osal_fopen(encConfig->ctuqp_file_name, "r")) == NULL) {
  1483. VLOG(ERR, "fail to open CTU QP file, %s\n", encConfig->ctuqp_file_name);
  1484. return FALSE;
  1485. }
  1486. }
  1487. }
  1488. return TRUE;
  1489. }
  1490. int allocateCtuQpMapBuf(int coreIdx, TestEncConfig encConfig, vpu_buffer_t *vbCtuQp, int srcFbNum, int ctuNum) {
  1491. int i;
  1492. if (encConfig.ctu_qp_enable) {
  1493. // the number of CTU mode buffer should be the same as source buffer num.
  1494. for (i = 0; i < srcFbNum; i++) {
  1495. vbCtuQp[i].size = ctuNum;
  1496. if (vdi_allocate_dma_memory(coreIdx, &vbCtuQp[i]) < 0) {
  1497. VLOG(ERR, "fail to allocate CTU QP buffer\n" );
  1498. return FALSE;
  1499. }
  1500. }
  1501. }
  1502. return TRUE;
  1503. }
  1504. // Define tokens for parsing scaling list file
  1505. const char* MatrixType[SCALING_LIST_SIZE_NUM][SL_NUM_MATRIX] =
  1506. {
  1507. {"INTRA4X4_LUMA", "INTRA4X4_CHROMAU", "INTRA4X4_CHROMAV", "INTER4X4_LUMA", "INTER4X4_CHROMAU", "INTER4X4_CHROMAV"},
  1508. {"INTRA8X8_LUMA", "INTRA8X8_CHROMAU", "INTRA8X8_CHROMAV", "INTER8X8_LUMA", "INTER8X8_CHROMAU", "INTER8X8_CHROMAV"},
  1509. {"INTRA16X16_LUMA", "INTRA16X16_CHROMAU", "INTRA16X16_CHROMAV", "INTER16X16_LUMA", "INTER16X16_CHROMAU", "INTER16X16_CHROMAV"},
  1510. {"INTRA32X32_LUMA", "INTRA32X32_CHROMAU_FROM16x16_CHROMAU", "INTRA32X32_CHROMAV_FROM16x16_CHROMAV","INTER32X32_LUMA", "INTER32X32_CHROMAU_FROM16x16_CHROMAU", "INTER32X32_CHROMAV_FROM16x16_CHROMAV"}
  1511. };
  1512. const char* MatrixType_DC[SCALING_LIST_SIZE_NUM - 2][SL_NUM_MATRIX] =
  1513. {
  1514. {"INTRA16X16_LUMA_DC", "INTRA16X16_CHROMAU_DC", "INTRA16X16_CHROMAV_DC", "INTER16X16_LUMA_DC", "INTER16X16_CHROMAU_DC", "INTER16X16_CHROMAV_DC"},
  1515. {"INTRA32X32_LUMA_DC", "INTRA32X32_CHROMAU_DC_FROM16x16_CHROMAU", "INTRA32X32_CHROMAV_DC_FROM16x16_CHROMAV", "INTER32X32_LUMA_DC","INTER32X32_CHROMAU_DC_FROM16x16_CHROMAU","INTER32X32_CHROMAV_DC_FROM16x16_CHROMAV"},
  1516. };
  1517. static Uint8* get_sl_addr(UserScalingList* sl, Uint32 size_id, Uint32 mat_id)
  1518. {
  1519. Uint8* addr = NULL;
  1520. switch(size_id)
  1521. {
  1522. case SCALING_LIST_4x4:
  1523. addr = sl->s4[mat_id];
  1524. break;
  1525. case SCALING_LIST_8x8:
  1526. addr = sl->s8[mat_id];
  1527. break;
  1528. case SCALING_LIST_16x16:
  1529. addr = sl->s16[mat_id];
  1530. break;
  1531. case SCALING_LIST_32x32:
  1532. addr = sl->s32[mat_id];
  1533. break;
  1534. }
  1535. return addr;
  1536. }
  1537. int parse_user_scaling_list(UserScalingList* sl, FILE* fp_sl)
  1538. {
  1539. #define LINE_SIZE (1024)
  1540. const Uint32 scaling_list_size[SCALING_LIST_SIZE_NUM] = {16, 64, 64, 64};
  1541. char line[LINE_SIZE];
  1542. Uint32 i;
  1543. Uint32 size_id, mat_id, data, num_coef = 0;
  1544. Uint8* src = NULL;
  1545. Uint8* ref = NULL;
  1546. char* ret;
  1547. const char* type_str;
  1548. for(size_id = 0; size_id < SCALING_LIST_SIZE_NUM; size_id++) // for 4, 8, 16, 32
  1549. {
  1550. num_coef = scaling_list_size[size_id];
  1551. for(mat_id = 0; mat_id < SL_NUM_MATRIX; mat_id++) // for intra_y, intra_cb, intra_cr, inter_y, inter_cb, inter_cr
  1552. {
  1553. src = get_sl_addr(sl, size_id, mat_id);
  1554. if(size_id == SCALING_LIST_32x32 && (mat_id % 3)) // derive scaling list of chroma32x32 from that of chrom16x16
  1555. {
  1556. ref = get_sl_addr(sl, size_id - 1, mat_id);
  1557. for(i = 0; i < num_coef; i++)
  1558. src[i] = ref[i];
  1559. }
  1560. else
  1561. {
  1562. fseek(fp_sl,0,0);
  1563. type_str = MatrixType[size_id][mat_id];
  1564. do
  1565. {
  1566. ret = fgets(line, LINE_SIZE, fp_sl);
  1567. if((ret == NULL) || (strstr(line, type_str) == NULL && feof(fp_sl)))
  1568. {
  1569. printf("Error: can't read a scaling list matrix(%s)\n", type_str);
  1570. return 0;
  1571. }
  1572. } while (strstr(line, type_str) == NULL);
  1573. // get all coeff
  1574. for(i = 0; i < num_coef; i++)
  1575. {
  1576. if(fscanf(fp_sl, "%d,", &data) != 1)
  1577. {
  1578. printf("Error: can't read a scaling list matrix(%s)\n", type_str);
  1579. return 0;
  1580. }
  1581. src[i] = data;
  1582. }
  1583. // get DC coeff for 16, 32
  1584. if(size_id > SCALING_LIST_8x8)
  1585. {
  1586. fseek(fp_sl,0,0);
  1587. type_str = MatrixType_DC[size_id - 2][mat_id];
  1588. do
  1589. {
  1590. ret = fgets(line, LINE_SIZE, fp_sl);
  1591. if((ret == NULL) || (strstr(line, type_str) == NULL && feof(fp_sl)))
  1592. {
  1593. printf("Error: can't read a scaling list matrix(%s)\n", type_str);
  1594. return 0;
  1595. }
  1596. } while (strstr(line, type_str) == NULL);
  1597. if(fscanf(fp_sl, "%d,", &data) != 1)
  1598. {
  1599. printf("Error: can't read a scaling list matrix(%s)\n", type_str);
  1600. return 0;
  1601. }
  1602. // overwrite DC value
  1603. src[0] = data;
  1604. }
  1605. }
  1606. } // for matrix id
  1607. } // for size id
  1608. return 1;
  1609. }
  1610. int parse_custom_lambda(Uint32 buf[NUM_CUSTOM_LAMBDA], FILE* fp)
  1611. {
  1612. int i, j = 0;
  1613. char lineStr[256] = {0, };
  1614. for(i = 0; i < 52; i++)
  1615. {
  1616. if( NULL == fgets(lineStr, 256, fp) )
  1617. {
  1618. printf("Error: can't read custom_lambda\n");
  1619. return 0;
  1620. }
  1621. else
  1622. {
  1623. sscanf(lineStr, "%d\n", &buf[j++]);
  1624. }
  1625. }
  1626. for(i = 0; i < 52; i++)
  1627. {
  1628. if( NULL == fgets(lineStr, 256, fp) )
  1629. {
  1630. printf("Error: can't read custom_lambda\n");
  1631. return 0;
  1632. }
  1633. else
  1634. sscanf(lineStr, "%d\n", &buf[j++]);
  1635. }
  1636. return 1;
  1637. }
  1638. #ifdef PLATFORM_LINUX
  1639. struct option* ConvertOptions(
  1640. struct OptionExt* cnmOpt,
  1641. Uint32 nItems
  1642. )
  1643. {
  1644. struct option* opt;
  1645. Uint32 i;
  1646. opt = (struct option*)osal_malloc(sizeof(struct option) * nItems);
  1647. if (opt == NULL) {
  1648. return NULL;
  1649. }
  1650. for (i=0; i<nItems; i++) {
  1651. osal_memcpy((void*)&opt[i], (void*)&cnmOpt[i], sizeof(struct option));
  1652. }
  1653. return opt;
  1654. }
  1655. int mkdir_recursive(
  1656. char *path,
  1657. mode_t omode
  1658. )
  1659. {
  1660. struct stat sb;
  1661. mode_t numask, oumask;
  1662. int first, last, retval;
  1663. char *p;
  1664. p = path;
  1665. oumask = 0;
  1666. retval = 0;
  1667. if (p[0] == '/') /* Skip leading '/'. */
  1668. ++p;
  1669. for (first = 1, last = 0; !last ; ++p) {
  1670. if (p[0] == '\0')
  1671. last = 1;
  1672. else if (p[0] != '/')
  1673. continue;
  1674. *p = '\0';
  1675. if (p[1] == '\0')
  1676. last = 1;
  1677. if (first) {
  1678. /*
  1679. * POSIX 1003.2:
  1680. * For each dir operand that does not name an existing
  1681. * directory, effects equivalent to those cased by the
  1682. * following command shall occcur:
  1683. *
  1684. * mkdir -p -m $(umask -S),u+wx $(dirname dir) &&
  1685. * mkdir [-m mode] dir
  1686. *
  1687. * We change the user's umask and then restore it,
  1688. * instead of doing chmod's.
  1689. */
  1690. oumask = umask(0);
  1691. numask = oumask & ~(S_IWUSR | S_IXUSR);
  1692. (void)umask(numask);
  1693. first = 0;
  1694. }
  1695. if (last)
  1696. (void)umask(oumask);
  1697. if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
  1698. if (errno == EEXIST || errno == EISDIR) {
  1699. if (stat(path, &sb) < 0) {
  1700. VLOG(INFO, "%s", path);
  1701. retval = 1;
  1702. break;
  1703. } else if (!S_ISDIR(sb.st_mode)) {
  1704. if (last)
  1705. errno = EEXIST;
  1706. else
  1707. errno = ENOTDIR;
  1708. VLOG(INFO, "%s", path);
  1709. retval = 1;
  1710. break;
  1711. }
  1712. } else {
  1713. VLOG(INFO, "%s", path);
  1714. retval = 1;
  1715. break;
  1716. }
  1717. } else if (1)
  1718. {
  1719. VLOG(INFO, "%s", path);
  1720. chmod(path, omode);
  1721. }
  1722. if (!last)
  1723. *p = '/';
  1724. }
  1725. if (!first && !last)
  1726. (void)umask(oumask);
  1727. return (retval);
  1728. }
  1729. #endif
  1730. BOOL TestMachineSetup(
  1731. TestMachine* machine
  1732. )
  1733. {
  1734. BOOL success = TRUE;
  1735. osal_init_keyboard();
  1736. InitializeDebugEnv(0, machine->testEnvOptions);
  1737. return success;
  1738. }
  1739. void TestMachineCleanUp(
  1740. TestMachine* machine
  1741. )
  1742. {
  1743. Uint32 i;
  1744. Listener* o;
  1745. for (i=0; i<machine->numObservers; i++) {
  1746. o = &machine->observers[i];
  1747. o->destruct(o);
  1748. }
  1749. ReleaseDebugEnv();
  1750. osal_close_keyboard();
  1751. }
  1752. void TestMachineAddListener(
  1753. TestMachine* machine,
  1754. Listener observer,
  1755. void* handle
  1756. )
  1757. {
  1758. Uint32 i = machine->numObservers;
  1759. if (i == MAX_OBSERVERS) {
  1760. return;
  1761. }
  1762. observer.construct(&observer, handle);
  1763. osal_memcpy(&machine->observers[i], (void*)&observer, sizeof(Listener));
  1764. machine->numObservers++;
  1765. }
  1766. BOOL TestMachineSetData(
  1767. TestMachine* machine,
  1768. void* data
  1769. )
  1770. {
  1771. Listener* o = NULL;
  1772. Uint32 i;
  1773. BOOL success = TRUE;
  1774. for (i=0; i<machine->numObservers; i++) {
  1775. o = &machine->observers[i];
  1776. if (o->update(o, data) == FALSE) {
  1777. success = FALSE;
  1778. }
  1779. }
  1780. return success;
  1781. }
  1782. int file_exist(
  1783. char* path
  1784. )
  1785. {
  1786. #ifdef _MSC_VER
  1787. DWORD attributes;
  1788. char temp[4096];
  1789. LPCTSTR lp_path = (LPCTSTR)temp;
  1790. if (path == NULL) {
  1791. return False;
  1792. }
  1793. strcpy(temp, path);
  1794. replace_character(temp, '/', '\\');
  1795. attributes = GetFileAttributes(lp_path);
  1796. return (attributes != (DWORD)-1);
  1797. #else
  1798. return !access(path, F_OK);
  1799. #endif
  1800. }
  1801. BOOL MkDir(
  1802. char* path
  1803. )
  1804. {
  1805. #ifdef _MSC_VER
  1806. char cmd[4096];
  1807. #endif
  1808. if (file_exist(path))
  1809. return TRUE;
  1810. #ifdef _MSC_VER
  1811. sprintf(cmd, "mkdir %s", path);
  1812. replace_character(cmd, '/', '\\');
  1813. if (system(cmd)) {
  1814. return FALSE;
  1815. }
  1816. return True;
  1817. #else
  1818. return mkdir_recursive(path, S_IRWXU | S_IRWXG | S_IRWXO);
  1819. #endif
  1820. }