yuv_comparator_impl.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // SPDX-License-Identifier: LGPL-2.1 OR BSD-3-Clause
  2. //--=========================================================================--
  3. // This file is a part of VPU Reference API project
  4. //-----------------------------------------------------------------------------
  5. //
  6. // This confidential and proprietary software may be used only
  7. // as authorized by a licensing agreement from Chips&Media Inc.
  8. // In the event of publication, the following notice is applicable:
  9. //
  10. // (C) COPYRIGHT CHIPS&MEDIA INC.
  11. // ALL RIGHTS RESERVED
  12. //
  13. // The entire notice above must be reproduced on all authorized
  14. // copies.
  15. //
  16. //--=========================================================================--
  17. #include "config.h"
  18. #include "main_helper.h"
  19. #include "../misc/skip.h"
  20. #if defined(PLATFORM_LINUX) || defined(PLATFORM_QNX)
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #endif
  24. #ifdef PLATFORM_NON_OS
  25. #ifdef LIB_C_STUB
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #endif
  29. #endif
  30. typedef struct {
  31. osal_file_t fp;
  32. Uint32 width;
  33. Uint32 height;
  34. Uint32 frameSize;
  35. BOOL cbcrInterleave;
  36. FrameBufferFormat format;
  37. char *path;
  38. Uint32 isVp9;
  39. } Context;
  40. #ifndef MAX
  41. #define MAX(a, b) (((a) > (b)) ? (a) : (b))
  42. #endif
  43. static Uint32 Calculate(
  44. Context* ctx
  45. )
  46. {
  47. Uint32 lumaSize = 0;
  48. Uint32 chromaSize = 0;
  49. Uint32 frameSize = 0;
  50. Uint32 frames = 0;
  51. Uint32 width = ctx->width;
  52. Uint32 height = ctx->height;
  53. Uint64 endPos = 0;
  54. BOOL cbcrInterleave = ctx->cbcrInterleave;
  55. FrameBufferFormat format = ctx->format;
  56. #if defined(PLATFORM_LINUX) || defined(PLATFORM_QNX)
  57. struct stat file_info;
  58. #endif
  59. #ifdef PLATFORM_NON_OS
  60. #ifdef LIB_C_STUB
  61. struct stat file_info;
  62. #endif
  63. #endif
  64. lumaSize = width * height;
  65. switch (format) {
  66. case FORMAT_400:
  67. chromaSize = 0;
  68. break;
  69. case FORMAT_YUYV:
  70. case FORMAT_YVYU:
  71. case FORMAT_UYVY:
  72. case FORMAT_VYUY:
  73. chromaSize = lumaSize;
  74. break;
  75. case FORMAT_420:
  76. chromaSize = lumaSize / 2;
  77. break;
  78. case FORMAT_422:
  79. case FORMAT_224:
  80. chromaSize = lumaSize;
  81. break;
  82. case FORMAT_444:
  83. chromaSize = lumaSize * 2;
  84. break;
  85. case FORMAT_420_P10_16BIT_LSB:
  86. case FORMAT_420_P10_16BIT_MSB:
  87. lumaSize *= 2;
  88. chromaSize = lumaSize/2;
  89. break;
  90. case FORMAT_420_P10_32BIT_LSB:
  91. case FORMAT_420_P10_32BIT_MSB:
  92. #ifdef DUMP_YUV_WHOLE_DATA
  93. if (cbcrInterleave) {
  94. lumaSize = ((VPU_ALIGN16(width)+11)/12*16) * height;
  95. chromaSize = VPU_ALIGN16(((VPU_ALIGN16(width/2))*2+11)/12*16) * height / 2;
  96. }
  97. else {
  98. lumaSize = ((VPU_ALIGN16(width)+11)/12*16) * height;
  99. chromaSize = VPU_ALIGN16(((VPU_ALIGN16(width/2))+11)/12*16) * height / 2 *2;
  100. }
  101. #else
  102. if (cbcrInterleave) {
  103. lumaSize = ((width+2)/3*4) * height;
  104. chromaSize = ((width+2)/3*4) * height / 2;
  105. }
  106. else {
  107. lumaSize = (width+2)/3*4 * height;
  108. chromaSize = (width/2+2)/3*4 * height / 2 *2;
  109. }
  110. #endif
  111. break;
  112. case FORMAT_422_P10_16BIT_MSB:
  113. case FORMAT_422_P10_16BIT_LSB:
  114. lumaSize *= 2;
  115. chromaSize = lumaSize;
  116. break;
  117. case FORMAT_422_P10_32BIT_LSB:
  118. case FORMAT_422_P10_32BIT_MSB:
  119. {
  120. Uint32 twice = cbcrInterleave ? 2 : 1;
  121. if (ctx->isVp9 == TRUE) {
  122. lumaSize = VPU_ALIGN32(((width+11)/12)*16);
  123. chromaSize = (((width/2)+11)*twice/12)*16;
  124. }
  125. else {
  126. width = VPU_ALIGN32(width);
  127. lumaSize = ((VPU_ALIGN16(width)+11)/12)*16;
  128. chromaSize = ((VPU_ALIGN16(width/2)+11)*twice/12)*16;
  129. if ((chromaSize*2) > lumaSize) {
  130. lumaSize = chromaSize * 2;
  131. }
  132. }
  133. if (cbcrInterleave == TRUE) {
  134. lumaSize = MAX(lumaSize, chromaSize);
  135. }
  136. }
  137. break;
  138. default:
  139. VLOG(ERR, "%s:%d Invalid format: %d\n", __FILE__, __LINE__, format);
  140. }
  141. frameSize = lumaSize + chromaSize;
  142. #ifdef PLATFORM_WIN32
  143. #if (_MSC_VER == 1200)
  144. osal_fseek(ctx->fp, 0, SEEK_END);
  145. endPos = ftell(ctx->fp);
  146. osal_fseek(ctx->fp, 0, SEEK_SET);
  147. #else
  148. _fseeki64((FILE*)ctx->fp, 0LL, SEEK_END);
  149. endPos = _ftelli64((FILE*)ctx->fp);
  150. _fseeki64((FILE*)ctx->fp, 0LL, SEEK_SET);
  151. #endif
  152. #else
  153. stat( ctx->path, &file_info);
  154. endPos = file_info.st_size;
  155. #endif
  156. frames = (Uint32)(endPos / frameSize);
  157. if (endPos % frameSize) {
  158. VLOG(ERR, "%s:%d Mismatch - file_size: %llu frameSize: %d\n",
  159. __FUNCTION__, __LINE__, endPos, frameSize);
  160. }
  161. ctx->frameSize = frameSize;
  162. return frames;
  163. }
  164. BOOL YUVComparator_Create(
  165. ComparatorImpl* impl,
  166. char* path
  167. )
  168. {
  169. Context* ctx;
  170. osal_file_t* fp;
  171. if ((fp=osal_fopen(path, "rb")) == NULL) {
  172. VLOG(ERR, "%s:%d failed to open yuv file: %s\n", __FUNCTION__, __LINE__, path);
  173. return FALSE;
  174. }
  175. if ((ctx=(Context*)osal_malloc(sizeof(Context))) == NULL) {
  176. osal_fclose(fp);
  177. return FALSE;
  178. }
  179. ctx->fp = fp;
  180. ctx->path = path;
  181. impl->context = ctx;
  182. impl->eof = FALSE;
  183. return TRUE;
  184. }
  185. BOOL YUVComparator_Destroy(
  186. ComparatorImpl* impl
  187. )
  188. {
  189. Context* ctx = (Context*)impl->context;
  190. osal_fclose(ctx->fp);
  191. osal_free(ctx);
  192. return TRUE;
  193. }
  194. BOOL YUVComparator_Compare(
  195. ComparatorImpl* impl,
  196. void* data,
  197. Uint32 size
  198. )
  199. {
  200. Uint8* pYuv = NULL;
  201. Context* ctx = (Context*)impl->context;
  202. BOOL match = FALSE;
  203. if ( data == (void *)COMPARATOR_SKIP ) {
  204. int fpos;
  205. fpos = osal_ftell(ctx->fp);
  206. osal_fseek(ctx->fp, fpos+size, SEEK_SET);
  207. if (IsEndOfFile(ctx->fp) == TRUE)
  208. impl->eof = TRUE;
  209. return TRUE;
  210. }
  211. pYuv = (Uint8*)osal_malloc(size);
  212. osal_fread(pYuv, 1, size, ctx->fp);
  213. if (IsEndOfFile(ctx->fp) == TRUE)
  214. impl->eof = TRUE;
  215. match = (osal_memcmp(data, (void*)pYuv, size) == 0 ? TRUE : FALSE);
  216. if (match == FALSE) {
  217. osal_file_t* fpGolden;
  218. osal_file_t* fpOutput;
  219. char tmp[200];
  220. VLOG(ERR, "MISMATCH WITH GOLDEN YUV at %d frame\n", impl->curIndex);
  221. sprintf(tmp, "./golden.yuv");
  222. if ((fpGolden=osal_fopen(tmp, "wb")) == NULL) {
  223. VLOG(ERR, "Faild to create golden.yuv\n");
  224. osal_free(pYuv);
  225. return FALSE;
  226. }
  227. VLOG(ERR, "Saving... Golden YUV at %s\n", tmp);
  228. sprintf(tmp, "./decoded.yuv");
  229. osal_fwrite(pYuv, 1, size, fpGolden);
  230. osal_fclose(fpGolden);
  231. if ((fpOutput=osal_fopen(tmp, "wb")) == NULL) {
  232. VLOG(ERR, "Faild to create golden.yuv\n");
  233. osal_free(pYuv);
  234. return FALSE;
  235. }
  236. VLOG(ERR, "Saving... decoded YUV at %s\n", tmp);
  237. osal_fwrite(data, 1, size, fpOutput);
  238. osal_fclose(fpOutput);
  239. }
  240. osal_free(pYuv);
  241. return match;
  242. }
  243. BOOL YUVComparator_Configure(
  244. ComparatorImpl* impl,
  245. ComparatorConfType type,
  246. void* val
  247. )
  248. {
  249. PictureInfo* yuv = NULL;
  250. Context* ctx = (Context*)impl->context;
  251. BOOL ret = TRUE;
  252. switch (type) {
  253. case COMPARATOR_CONF_SET_PICINFO:
  254. yuv = (PictureInfo*)val;
  255. ctx->width = yuv->width;
  256. ctx->height = yuv->height;
  257. ctx->format = yuv->format;
  258. ctx->cbcrInterleave = yuv->cbcrInterleave;
  259. //can not calculate a sequence changed YUV
  260. impl->numOfFrames = Calculate(ctx);
  261. break;
  262. default:
  263. ret = FALSE;
  264. break;
  265. }
  266. return ret;
  267. }
  268. BOOL YUVComparator_Rewind(
  269. ComparatorImpl* impl
  270. )
  271. {
  272. Context* ctx = (Context*)impl->context;
  273. Int32 ret;
  274. if ((ret=osal_fseek(ctx->fp, 0, SEEK_SET)) != 0) {
  275. VLOG(ERR, "%s:%d failed to osal_fseek(ret:%d)\n", __FUNCTION__, __LINE__, ret);
  276. return FALSE;
  277. }
  278. return TRUE;
  279. }
  280. ComparatorImpl yuvComparatorImpl = {
  281. NULL,
  282. NULL,
  283. 0,
  284. 0,
  285. YUVComparator_Create,
  286. YUVComparator_Destroy,
  287. YUVComparator_Compare,
  288. YUVComparator_Configure,
  289. YUVComparator_Rewind,
  290. FALSE,
  291. };