yuvLoaderfeeder.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. // SPDX-License-Identifier: LGPL-2.1 OR BSD-3-Clause
  2. //------------------------------------------------------------------------------
  3. // File: vpuio.c
  4. //
  5. // Copyright (c) 2006, Chips & Media. All rights reserved.
  6. //------------------------------------------------------------------------------
  7. #include <string.h>
  8. #include "main_helper.h"
  9. //#define SAVE_WHOLE_LOADED_YUV
  10. //#define DUMP_REFC_TYPE
  11. #ifdef SAVE_WHOLE_LOADED_YUV
  12. FILE *save_fp;
  13. int save_frame_cnt=0;
  14. int save_frame_max=10;
  15. #endif
  16. typedef struct {
  17. osal_file_t* fp;
  18. Uint8* pYuv;
  19. Uint32 cbcrInterleave;
  20. Uint32 nv21;
  21. Uint32 packedFormat;
  22. } Context;
  23. enum {
  24. OUTPUT_PLANAR = 0,
  25. OUTPUT_NV12 = 2,
  26. OUTPUT_NV21 = 3,
  27. OUTPUT_PACKED = 4,
  28. };
  29. typedef unsigned short pel; // the size of pel should be 16.
  30. typedef struct{
  31. pel* src_buf[3];
  32. Int32 rot_mode;
  33. Int32 src_stride;
  34. Int32 src_width;
  35. Int32 src_height;
  36. Int32 padded_y_stride;
  37. Int32 padded_c_stride;
  38. Int32 padded_y_height;
  39. Int32 padded_c_height;
  40. Int32 enc_stride;
  41. Int32 enc_width;
  42. Int32 enc_height;
  43. Int32 enc_c_stride;
  44. pel* p_out_buf[3];
  45. pel* out_buf;
  46. pel* pad_buf;
  47. }prp_t;
  48. void conv_image (unsigned short *outbuf, unsigned short *inbuf,
  49. int pic_width, int pic_height, int out_width, int out_height, int frm_format, int packedFormat)
  50. {
  51. int x, y;
  52. int iaddr, oaddr;
  53. int temp, tbase;
  54. if ( packedFormat == NOT_PACKED )
  55. {
  56. if (frm_format == OUTPUT_PLANAR) { // planar
  57. // Y
  58. iaddr = 0;
  59. oaddr = 0;
  60. for (y=0; y<out_height; y++) {
  61. for (x=0; x<out_width; x++) {
  62. if (y >= pic_height) {
  63. if (x >= pic_width)
  64. outbuf[oaddr] = temp;
  65. else {
  66. temp = inbuf[x + pic_width*(pic_height-1)];
  67. outbuf[oaddr] = temp;
  68. }
  69. } else {
  70. if (x >= pic_width)
  71. outbuf[oaddr] = temp;
  72. else {
  73. temp = inbuf[iaddr];
  74. outbuf[oaddr] = temp;
  75. iaddr++;
  76. }
  77. }
  78. oaddr++;
  79. }
  80. }
  81. // U
  82. tbase = pic_width*pic_height;
  83. iaddr = tbase;
  84. oaddr = out_width*out_height;
  85. for (y=0; y<out_height/2; y++) {
  86. for (x=0; x<out_width/2; x++) {
  87. if (y >= pic_height/2) {
  88. if (x >= pic_width/2)
  89. outbuf[oaddr] = temp;
  90. else {
  91. temp = inbuf[tbase + x + (pic_width/2)*(pic_height/2-1)];
  92. outbuf[oaddr] = temp;
  93. }
  94. } else {
  95. if (x >= pic_width/2)
  96. outbuf[oaddr] = temp;
  97. else {
  98. temp = inbuf[iaddr];
  99. outbuf[oaddr] = temp;
  100. iaddr++;
  101. }
  102. }
  103. oaddr++;
  104. }
  105. }
  106. // V
  107. tbase = pic_width*pic_height*5/4;
  108. iaddr = tbase;
  109. oaddr = out_width*out_height*5/4;
  110. for (y=0; y<out_height/2; y++) {
  111. for (x=0; x<out_width/2; x++) {
  112. if (y >= pic_height/2) {
  113. if (x >= pic_width/2)
  114. outbuf[oaddr] = temp;
  115. else {
  116. temp = inbuf[tbase + x + (pic_width/2)*(pic_height/2-1)];
  117. outbuf[oaddr] = temp;
  118. }
  119. } else {
  120. if (x >= pic_width/2)
  121. outbuf[oaddr] = temp;
  122. else {
  123. temp = inbuf[iaddr];
  124. outbuf[oaddr] = temp;
  125. iaddr++;
  126. }
  127. }
  128. oaddr++;
  129. }
  130. }
  131. } else if (frm_format == OUTPUT_NV12 || frm_format == OUTPUT_NV21) { // NV12, NV21
  132. // Y
  133. iaddr = 0;
  134. oaddr = 0;
  135. for (y=0; y<out_height; y++) {
  136. for (x=0; x<out_width; x++) {
  137. if (y >= pic_height) {
  138. if (x >= pic_width)
  139. outbuf[oaddr] = temp;
  140. else {
  141. temp = inbuf[x + pic_width*(pic_height-1)];
  142. outbuf[oaddr] = temp;
  143. }
  144. } else {
  145. if (x >= pic_width)
  146. outbuf[oaddr] = temp;
  147. else {
  148. temp = inbuf[iaddr];
  149. outbuf[oaddr] = temp;
  150. iaddr++;
  151. }
  152. }
  153. oaddr++;
  154. }
  155. }
  156. // U
  157. tbase = (frm_format == OUTPUT_NV12) ? pic_width*pic_height : pic_width*pic_height*5/4;
  158. iaddr = tbase;
  159. oaddr = out_width*out_height;
  160. for (y=0; y<out_height/2; y++) {
  161. for (x=0; x<out_width/2; x++) {
  162. if (y >= pic_height/2) {
  163. if (x >= pic_width/2)
  164. outbuf[oaddr] = temp;
  165. else {
  166. temp = inbuf[tbase + x + (pic_width/2)*(pic_height/2-1)];
  167. outbuf[oaddr] = temp;
  168. }
  169. } else {
  170. if (x >= pic_width/2)
  171. outbuf[oaddr] = temp;
  172. else {
  173. temp = inbuf[iaddr];
  174. outbuf[oaddr] = temp;
  175. iaddr++;
  176. }
  177. }
  178. oaddr+=2;
  179. }
  180. }
  181. // V
  182. tbase = (frm_format == OUTPUT_NV12) ? pic_width*pic_height*5/4 : pic_width*pic_height;
  183. iaddr = tbase;
  184. oaddr = out_width*out_height + 1;
  185. for (y=0; y<out_height/2; y++) {
  186. for (x=0; x<out_width/2; x++) {
  187. if (y >= pic_height/2) {
  188. if (x >= pic_width/2)
  189. outbuf[oaddr] = temp;
  190. else {
  191. temp = inbuf[tbase + x + (pic_width/2)*(pic_height/2-1)];
  192. outbuf[oaddr] = temp;
  193. }
  194. } else {
  195. if (x >= pic_width/2)
  196. outbuf[oaddr] = temp;
  197. else {
  198. temp = inbuf[iaddr];
  199. outbuf[oaddr] = temp;
  200. iaddr++;
  201. }
  202. }
  203. oaddr+=2;
  204. }
  205. }
  206. }
  207. else {
  208. printf("Error) Unknown frame format: %d\n", frm_format);
  209. }
  210. } else {/* packdformat */
  211. if ( packedFormat == PACKED_YUYV || packedFormat == PACKED_YVYU){
  212. oaddr = 0;
  213. } else {
  214. oaddr = 1;
  215. }
  216. // Y
  217. iaddr = 0;
  218. for (y=0; y<out_height; y++) {
  219. for (x=0; x<out_width; x++) {
  220. if (y >= pic_height) {
  221. if (x >= pic_width)
  222. outbuf[oaddr] = temp;
  223. else {
  224. temp = inbuf[x + pic_width*(pic_height-1)];
  225. outbuf[oaddr] = temp;
  226. }
  227. } else {
  228. if (x >= pic_width)
  229. outbuf[oaddr] = temp;
  230. else {
  231. temp = inbuf[iaddr];
  232. outbuf[oaddr] = temp;
  233. iaddr++;
  234. }
  235. }
  236. oaddr+=2;
  237. }
  238. }
  239. // U
  240. switch (packedFormat)
  241. {
  242. case PACKED_YUYV: oaddr = 1;break;
  243. case PACKED_YVYU: oaddr = 3;break;
  244. case PACKED_UYVY: oaddr = 0;break;
  245. case PACKED_VYUY: oaddr = 2;break;
  246. default:
  247. VLOG(ERR, "%s:%d Not supported format(%d)\n", __FILE__, __LINE__, packedFormat);
  248. break;
  249. }
  250. tbase = pic_width*pic_height;
  251. iaddr = tbase;
  252. for (y=0; y<out_height; y++) {
  253. for (x=0; x<out_width/2; x++) {
  254. if (y >= pic_height) {
  255. if (x >= pic_width/2)
  256. outbuf[oaddr] = temp;
  257. else {
  258. temp = inbuf[tbase + x + (pic_width/2)*(pic_height/2-1)];
  259. outbuf[oaddr] = temp;
  260. }
  261. } else {
  262. if (x >= pic_width/2)
  263. outbuf[oaddr] = temp;
  264. else {
  265. temp = inbuf[iaddr];
  266. outbuf[oaddr] = temp;
  267. iaddr++;
  268. }
  269. }
  270. oaddr+=4;
  271. }
  272. if (y%2 == 0)
  273. iaddr = iaddr - out_width/2;
  274. }
  275. // V
  276. switch (packedFormat)
  277. {
  278. case PACKED_YUYV: oaddr = 3;break;
  279. case PACKED_YVYU: oaddr = 1;break;
  280. case PACKED_UYVY: oaddr = 2;break;
  281. case PACKED_VYUY: oaddr = 0;break;
  282. default:
  283. VLOG(ERR, "%s:%d Not supported format(%d)\n", __FILE__, __LINE__, packedFormat);
  284. break;
  285. }
  286. tbase = pic_width*pic_height*5/4;
  287. iaddr = tbase;
  288. for (y=0; y<out_height; y++) {
  289. for (x=0; x<out_width/2; x++) {
  290. if (y >= pic_height) {
  291. if (x >= pic_width/2)
  292. outbuf[oaddr] = temp;
  293. else {
  294. temp = inbuf[tbase + x + (pic_width/2)*(pic_height/2-1)];
  295. outbuf[oaddr] = temp;
  296. }
  297. } else {
  298. if (x >= pic_width/2)
  299. outbuf[oaddr] = temp;
  300. else {
  301. temp = inbuf[iaddr];
  302. outbuf[oaddr] = temp;
  303. iaddr++;
  304. }
  305. }
  306. oaddr+=4;
  307. }
  308. if (y%2 == 0)
  309. iaddr = iaddr - out_width/2;
  310. }
  311. }
  312. }
  313. int write_image_to_file (FILE *fp, unsigned short *outbuf,
  314. int out_width, int out_height, int pxl_format, int frm_format, int packedFormat)
  315. {
  316. int i, x, y;
  317. unsigned short tmp16;
  318. unsigned int tmp32;
  319. int width, height;
  320. int size;
  321. unsigned char *temp = (unsigned char*)outbuf;
  322. size = (packedFormat) ? out_width*out_height*2 : out_width*out_height*3/2;
  323. //***** 8bit
  324. if (pxl_format == 0) {
  325. for (i=0; i<size; i++)
  326. fputc(temp[i]&0xff, fp);
  327. }
  328. //***** 16bit
  329. else if (pxl_format == 1) {
  330. for (i=0; i<size; i++) {
  331. //tmp16 = (outbuf[i]&0x3ff)<<6;
  332. tmp16 = outbuf[i];
  333. #ifdef DUMP_REFC_TYPE
  334. byte_swap((unsigned char *)&tmp16, 2);
  335. #endif
  336. fputc(tmp16&0xff, fp);
  337. fputc((tmp16>>8)&0xff, fp);
  338. }
  339. } else if (pxl_format == 5) {
  340. for (i=0; i<size; i++) {
  341. //tmp16 = outbuf[i]&0x3ff;
  342. tmp16 = outbuf[i];
  343. #ifdef DUMP_REFC_TYPE
  344. byte_swap((unsigned char *)&tmp16, 2);
  345. #endif
  346. fputc(tmp16&0xff, fp);
  347. fputc((tmp16>>8)&0xff, fp);
  348. }
  349. }
  350. //***** 32bit
  351. else {
  352. // Y
  353. width = (packedFormat) ? out_width*2 : out_width;
  354. height = out_height;
  355. for (y=0; y<height; y++) {
  356. for (x=0; x<width; x=x+3) {
  357. if (pxl_format == 2) {
  358. if (x+1 >= width)
  359. tmp32 = ((outbuf[x+0+width*y]&0x3ff)<<22);
  360. else if (x+2 >= width)
  361. tmp32 = ((outbuf[x+0+width*y]&0x3ff)<<22) |
  362. ((outbuf[x+1+width*y]&0x3ff)<<12);
  363. else
  364. tmp32 = ((outbuf[x+0+width*y]&0x3ff)<<22) |
  365. ((outbuf[x+1+width*y]&0x3ff)<<12) |
  366. ((outbuf[x+2+width*y]&0x3ff)<<2);
  367. } else if (pxl_format == 6) {
  368. if (x+1 >= width)
  369. tmp32 = (outbuf[x+0+width*y]&0x3ff);
  370. else if (x+2 >= width)
  371. tmp32 = (outbuf[x+0+width*y]&0x3ff) |
  372. ((outbuf[x+1+width*y]&0x3ff)<<10);
  373. else
  374. tmp32 = (outbuf[x+0+width*y]&0x3ff) |
  375. ((outbuf[x+1+width*y]&0x3ff)<<10) |
  376. ((outbuf[x+2+width*y]&0x3ff)<<20);
  377. }
  378. fputc((tmp32>>24)&0xff, fp);
  379. fputc((tmp32>>16)&0xff, fp);
  380. fputc((tmp32>>8)&0xff, fp);
  381. fputc(tmp32&0xff, fp);
  382. }
  383. }
  384. if (packedFormat) // packed
  385. return 1;
  386. width = (frm_format == 2 || frm_format == 3) ? out_width : out_width/2;
  387. height = out_height/2;
  388. // Cb
  389. for (y=0; y<height; y++) {
  390. for (x=0; x<width; x=x+3) {
  391. if (pxl_format == 2) {
  392. if (x+1 >= width)
  393. tmp32 = ((outbuf[out_width*out_height+x+0+width*y]&0x3ff)<<22);
  394. else if (x+2 >= width)
  395. tmp32 = ((outbuf[out_width*out_height+x+0+width*y]&0x3ff)<<22) |
  396. ((outbuf[out_width*out_height+x+1+width*y]&0x3ff)<<12);
  397. else
  398. tmp32 = ((outbuf[out_width*out_height+x+0+width*y]&0x3ff)<<22) |
  399. ((outbuf[out_width*out_height+x+1+width*y]&0x3ff)<<12) |
  400. ((outbuf[out_width*out_height+x+2+width*y]&0x3ff)<<2);
  401. } else if (pxl_format == 6) {
  402. if (x+1 >= width)
  403. tmp32 = (outbuf[out_width*out_height+x+0+width*y]&0x3ff);
  404. else if (x+2 >= width)
  405. tmp32 = (outbuf[out_width*out_height+x+0+width*y]&0x3ff) |
  406. ((outbuf[out_width*out_height+x+1+width*y]&0x3ff)<<10);
  407. else
  408. tmp32 = (outbuf[out_width*out_height+x+0+width*y]&0x3ff) |
  409. ((outbuf[out_width*out_height+x+1+width*y]&0x3ff)<<10) |
  410. ((outbuf[out_width*out_height+x+2+width*y]&0x3ff)<<20);
  411. }
  412. fputc((tmp32>>24)&0xff, fp);
  413. fputc((tmp32>>16)&0xff, fp);
  414. fputc((tmp32>>8)&0xff, fp);
  415. fputc(tmp32&0xff, fp);
  416. }
  417. }
  418. if (frm_format == 2 || frm_format == 3) // interleave
  419. return 1;
  420. width = out_width/2;
  421. height = out_height/2;
  422. // Cr
  423. for (y=0; y<height; y++) {
  424. for (x=0; x<width; x=x+3) {
  425. if (pxl_format == 2) {
  426. if (x+1 >= width)
  427. tmp32 = ((outbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff)<<22);
  428. else if (x+2 >= width)
  429. tmp32 = ((outbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff)<<22) |
  430. ((outbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<12);
  431. else
  432. tmp32 = ((outbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff)<<22) |
  433. ((outbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<12) |
  434. ((outbuf[out_width*out_height*5/4+x+2+width*y]&0x3ff)<<2);
  435. } else if (pxl_format == 6) {
  436. if (x+1 >= width)
  437. tmp32 = (outbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff);
  438. else if (x+2 >= width)
  439. tmp32 = (outbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff) |
  440. ((outbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<10);
  441. else
  442. tmp32 = (outbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff) |
  443. ((outbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<10) |
  444. ((outbuf[out_width*out_height*5/4+x+2+width*y]&0x3ff)<<20);
  445. }
  446. fputc((tmp32>>24)&0xff, fp);
  447. fputc((tmp32>>16)&0xff, fp);
  448. fputc((tmp32>>8)&0xff, fp);
  449. fputc(tmp32&0xff, fp);
  450. }
  451. }
  452. }
  453. return 1;
  454. }
  455. int write_image_to_mem (unsigned short *out_mem, unsigned short *inbuf,
  456. int out_width, int out_height, int pxl_format, int frm_format, int packedFormat)
  457. {
  458. int i, x, y;
  459. unsigned int tmp32;
  460. int width, height;
  461. int size;
  462. int oaddr=0;
  463. unsigned char *temp = (unsigned char *)out_mem;
  464. size = (packedFormat) ? out_width*out_height*2 : out_width*out_height*3/2;
  465. // 8BIT
  466. if (pxl_format == 0) {
  467. for (i=0; i<size; i++)
  468. temp[oaddr++] = inbuf[i]&0xff;
  469. }
  470. // 16BIT
  471. else if (pxl_format == 1 || pxl_format == 5) {
  472. for (i=0; i<size; i++) {
  473. out_mem[oaddr++] = inbuf[i];
  474. }
  475. }
  476. // 32BIT
  477. else {
  478. // Y
  479. width = (packedFormat) ? out_width*2 : out_width;
  480. height = out_height;
  481. for (y=0; y<height; y++) {
  482. for (x=0; x<width; x=x+3) {
  483. if (pxl_format == 2) {
  484. if (x+1 >= width)
  485. tmp32 = ((inbuf[x+0+width*y]&0x3ff)<<22);
  486. else if (x+2 >= width)
  487. tmp32 = ((inbuf[x+0+width*y]&0x3ff)<<22) |
  488. ((inbuf[x+1+width*y]&0x3ff)<<12);
  489. else
  490. tmp32 = ((inbuf[x+0+width*y]&0x3ff)<<22) |
  491. ((inbuf[x+1+width*y]&0x3ff)<<12) |
  492. ((inbuf[x+2+width*y]&0x3ff)<<2);
  493. } else if (pxl_format == 6) {
  494. if (x+1 >= width)
  495. tmp32 = (inbuf[x+0+width*y]&0x3ff);
  496. else if (x+2 >= width)
  497. tmp32 = (inbuf[x+0+width*y]&0x3ff) |
  498. ((inbuf[x+1+width*y]&0x3ff)<<10);
  499. else
  500. tmp32 = (inbuf[x+0+width*y]&0x3ff) |
  501. ((inbuf[x+1+width*y]&0x3ff)<<10) |
  502. ((inbuf[x+2+width*y]&0x3ff)<<20);
  503. }
  504. temp[oaddr++] = (tmp32>>24)&0xff;
  505. temp[oaddr++] = (tmp32>>16)&0xff;
  506. temp[oaddr++] = (tmp32>>8)&0xff;
  507. temp[oaddr++] = tmp32&0xff;
  508. }
  509. }
  510. if (packedFormat) // packed
  511. return 1;
  512. width = (frm_format == 2 || frm_format == 3) ? out_width : out_width/2;
  513. height = out_height/2;
  514. // Cb
  515. for (y=0; y<height; y++) {
  516. for (x=0; x<width; x=x+3) {
  517. if (pxl_format == 2) {
  518. if (x+1 >= width)
  519. tmp32 = ((inbuf[out_width*out_height+x+0+width*y]&0x3ff)<<22);
  520. else if (x+2 >= width)
  521. tmp32 = ((inbuf[out_width*out_height+x+0+width*y]&0x3ff)<<22) |
  522. ((inbuf[out_width*out_height+x+1+width*y]&0x3ff)<<12);
  523. else
  524. tmp32 = ((inbuf[out_width*out_height+x+0+width*y]&0x3ff)<<22) |
  525. ((inbuf[out_width*out_height+x+1+width*y]&0x3ff)<<12) |
  526. ((inbuf[out_width*out_height+x+2+width*y]&0x3ff)<<2);
  527. } else if (pxl_format == 6) {
  528. if (x+1 >= width)
  529. tmp32 = (inbuf[out_width*out_height+x+0+width*y]&0x3ff);
  530. else if (x+2 >= width)
  531. tmp32 = (inbuf[out_width*out_height+x+0+width*y]&0x3ff) |
  532. ((inbuf[out_width*out_height+x+1+width*y]&0x3ff)<<10);
  533. else
  534. tmp32 = (inbuf[out_width*out_height+x+0+width*y]&0x3ff) |
  535. ((inbuf[out_width*out_height+x+1+width*y]&0x3ff)<<10) |
  536. ((inbuf[out_width*out_height+x+2+width*y]&0x3ff)<<20);
  537. }
  538. temp[oaddr++] = (tmp32>>24)&0xff;
  539. temp[oaddr++] = (tmp32>>16)&0xff;
  540. temp[oaddr++] = (tmp32>>8)&0xff;
  541. temp[oaddr++] = tmp32&0xff;
  542. }
  543. }
  544. if (frm_format == 2 || frm_format == 3) // interleave
  545. return 1;
  546. width = out_width/2;
  547. height = out_height/2;
  548. // Cr
  549. for (y=0; y<height; y++) {
  550. for (x=0; x<width; x=x+3) {
  551. if (pxl_format == 2) {
  552. if (x+1 >= width)
  553. tmp32 = ((inbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff)<<22);
  554. else if (x+2 >= width)
  555. tmp32 = ((inbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff)<<22) |
  556. ((inbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<12);
  557. else
  558. tmp32 = ((inbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff)<<22) |
  559. ((inbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<12) |
  560. ((inbuf[out_width*out_height*5/4+x+2+width*y]&0x3ff)<<2);
  561. } else if (pxl_format == 6) {
  562. if (x+1 >= width)
  563. tmp32 = (inbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff);
  564. else if (x+2 >= width)
  565. tmp32 = (inbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff) |
  566. ((inbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<10);
  567. else
  568. tmp32 = (inbuf[out_width*out_height*5/4+x+0+width*y]&0x3ff) |
  569. ((inbuf[out_width*out_height*5/4+x+1+width*y]&0x3ff)<<10) |
  570. ((inbuf[out_width*out_height*5/4+x+2+width*y]&0x3ff)<<20);
  571. }
  572. temp[oaddr++] = (tmp32>>24)&0xff;
  573. temp[oaddr++] = (tmp32>>16)&0xff;
  574. temp[oaddr++] = (tmp32>>8)&0xff;
  575. temp[oaddr++] = tmp32&0xff;
  576. }
  577. }
  578. }
  579. return 1;
  580. }
  581. BOOL loaderYuvFeeder_Create(
  582. YuvFeederImpl* impl,
  583. const char* path,
  584. Uint32 packed,
  585. Uint32 fbStride,
  586. Uint32 fbHeight)
  587. {
  588. Context* ctx;
  589. osal_file_t* fp;
  590. Uint8* pYuv;
  591. if ((fp=osal_fopen(path, "rb")) == NULL) {
  592. VLOG(ERR, "%s:%d failed to open yuv file: %s\n", __FUNCTION__, __LINE__, path);
  593. return FALSE;
  594. }
  595. if ( packed == 1 )
  596. pYuv = osal_malloc(fbStride*fbHeight*3*2);//packed, unsigned short
  597. else
  598. pYuv = osal_malloc(fbStride*fbHeight*3);//unsigned short
  599. if ((ctx=(Context*)osal_malloc(sizeof(Context))) == NULL) {
  600. osal_free(pYuv);
  601. osal_fclose(fp);
  602. return FALSE;
  603. }
  604. osal_memset(ctx, 0, sizeof(Context));
  605. ctx->fp = fp;
  606. ctx->pYuv = pYuv;
  607. impl->context = ctx;
  608. return TRUE;
  609. }
  610. BOOL loaderYuvFeeder_Destory(
  611. YuvFeederImpl *impl
  612. )
  613. {
  614. Context* ctx = (Context*)impl->context;
  615. osal_fclose(ctx->fp);
  616. osal_free(ctx->pYuv);
  617. osal_free(ctx);
  618. return TRUE;
  619. }
  620. BOOL loaderYuvFeeder_Feed(
  621. YuvFeederImpl* impl,
  622. Int32 coreIdx,
  623. FrameBuffer* fb,
  624. size_t picWidth,
  625. size_t picHeight,
  626. void* arg
  627. )
  628. {
  629. size_t srcFrameSize, lumaSize, chromaSize;
  630. Int32 ystride;
  631. Int32 out_frm_format;
  632. Context* ctx = (Context*)impl->context;
  633. Uint8* pYuv_int8 = ctx->pYuv;
  634. osal_file_t yuvFp = ctx->fp;
  635. Uint16* pYuv_int16 = NULL, *pYuv2_int16 = NULL;
  636. Int32 outsize, out_width, out_height, pxl_format, yuv3p4b = 0;
  637. Int32 bitdepth = 0;
  638. Uint32 i;
  639. UNREFERENCED_PARAMETER(arg);
  640. if ( fb->cbcrInterleave == TRUE ) {
  641. if ( ctx->nv21)
  642. out_frm_format = OUTPUT_NV21 ;
  643. else
  644. out_frm_format = OUTPUT_NV12 ;
  645. }
  646. else {
  647. out_frm_format = OUTPUT_PLANAR;
  648. }
  649. switch (fb->format) {
  650. case FORMAT_420:
  651. case FORMAT_YUYV:
  652. case FORMAT_YVYU:
  653. case FORMAT_UYVY:
  654. case FORMAT_VYUY:
  655. pxl_format = 0;
  656. break;
  657. case FORMAT_420_P10_16BIT_LSB:
  658. case FORMAT_YUYV_P10_16BIT_LSB:
  659. case FORMAT_YVYU_P10_16BIT_LSB:
  660. case FORMAT_UYVY_P10_16BIT_LSB:
  661. case FORMAT_VYUY_P10_16BIT_LSB:
  662. bitdepth = 10;
  663. pxl_format = 5;
  664. break;
  665. case FORMAT_420_P10_16BIT_MSB:
  666. case FORMAT_YUYV_P10_16BIT_MSB:
  667. case FORMAT_YVYU_P10_16BIT_MSB:
  668. case FORMAT_UYVY_P10_16BIT_MSB:
  669. case FORMAT_VYUY_P10_16BIT_MSB:
  670. bitdepth = 10;
  671. pxl_format = 1;
  672. break;
  673. case FORMAT_420_P10_32BIT_LSB:
  674. case FORMAT_YUYV_P10_32BIT_LSB:
  675. case FORMAT_YVYU_P10_32BIT_LSB:
  676. case FORMAT_UYVY_P10_32BIT_LSB:
  677. case FORMAT_VYUY_P10_32BIT_LSB:
  678. bitdepth = 10;
  679. pxl_format = 6;
  680. yuv3p4b = 1;
  681. break;
  682. case FORMAT_420_P10_32BIT_MSB:
  683. case FORMAT_YUYV_P10_32BIT_MSB:
  684. case FORMAT_YVYU_P10_32BIT_MSB:
  685. case FORMAT_UYVY_P10_32BIT_MSB:
  686. case FORMAT_VYUY_P10_32BIT_MSB:
  687. bitdepth = 10;
  688. pxl_format = 2;
  689. yuv3p4b = 1;
  690. break;
  691. default:
  692. VLOG(ERR, "%s:%d Not supported format(%d)\n", __FILE__, __LINE__, fb->format);
  693. break;
  694. }
  695. {
  696. int input_format = fb->format;
  697. input_format = FORMAT_420;
  698. if ( yuv3p4b == 1 )//calculate input YUV(16BIT) size
  699. CalcYuvSize(FORMAT_420_P10_16BIT_LSB, picWidth, picHeight, fb->cbcrInterleave, &lumaSize, &chromaSize, &srcFrameSize, NULL, NULL, NULL);
  700. else if (bitdepth == 10)
  701. CalcYuvSize(FORMAT_420_P10_16BIT_LSB, picWidth, picHeight, fb->cbcrInterleave, &lumaSize, &chromaSize, &srcFrameSize, NULL, NULL, NULL);
  702. else
  703. CalcYuvSize(input_format, picWidth, picHeight, fb->cbcrInterleave, &lumaSize, &chromaSize, &srcFrameSize, NULL, NULL, NULL);
  704. }
  705. out_width = (yuv3p4b&&ctx->packedFormat==0) ? ((picWidth+31)/32)*32 : picWidth;
  706. out_height = (yuv3p4b) ? ((picHeight+7)/8)*8 : picHeight;
  707. outsize = (ctx->packedFormat) ? out_width*out_height*2 : out_width*out_height*3/2;
  708. outsize*=2;//align margin
  709. if ((pYuv_int16 = (Uint16*)osal_malloc(outsize * sizeof(Uint16))) == NULL) {
  710. printf("malloc error: outbuf\n");
  711. return 0;
  712. }
  713. if ((pYuv2_int16 = (Uint16*)osal_malloc(outsize * sizeof(Uint16))) == NULL) {
  714. printf("malloc error: outbuf\n");
  715. return 0;
  716. }
  717. if ( bitdepth == 0 ) {
  718. if( !osal_fread(pYuv_int8, 1, srcFrameSize, yuvFp) )
  719. {
  720. if( !osal_feof( yuvFp ) )
  721. VLOG(ERR, "YUV Data osal_fread failed file handle is 0x%x \n", yuvFp );
  722. if ( pYuv_int16 )
  723. osal_free(pYuv_int16);
  724. if ( pYuv2_int16 )
  725. osal_free(pYuv2_int16);
  726. return 0;
  727. }
  728. for (i=0; i<srcFrameSize; i++)
  729. pYuv_int16[i] = (unsigned short) pYuv_int8[i];
  730. }
  731. else {
  732. if( !osal_fread(pYuv_int16, 1, srcFrameSize, yuvFp) )
  733. {
  734. if( !osal_feof( yuvFp ) )
  735. VLOG(ERR, "YUV Data osal_fread failed file handle is 0x%x \n", yuvFp );
  736. if ( pYuv_int16 )
  737. osal_free(pYuv_int16);
  738. if ( pYuv2_int16 )
  739. osal_free(pYuv2_int16);
  740. return 0;
  741. }
  742. if ( yuv3p4b == 0 )
  743. {
  744. /**************************************************************
  745. * when 10bit source YUV == LITTLE ENDIAN, 16LSB, alway do byte-swapping
  746. **************************************************************/
  747. for (i=0; i<srcFrameSize/2; i++) {
  748. pYuv_int8[i*2] = (Uint8)(pYuv_int16[i]>>8)&0xff;
  749. pYuv_int8[i*2 + 1] = (Uint8)(pYuv_int16[i])&0xff;
  750. }
  751. #if 0
  752. /***************************************************************
  753. * when 10bit source YUV == BIG ENDIAN, 16LSB
  754. **************************************************************/
  755. osal_memcpy(pYuv_int8, pYuv_int16, srcFrameSize);
  756. #endif
  757. }
  758. else
  759. {
  760. /***************************************************************
  761. * when 10bit source YUV == LITTLE ENDIAN, 16LSB
  762. **************************************************************/
  763. osal_memcpy(pYuv_int8, pYuv_int16, srcFrameSize);
  764. #if 0
  765. /***************************************************************
  766. * when 10bit source YUV == BIG ENDIAN, 16LSB
  767. **************************************************************/
  768. for (i=0; i<srcFrameSize/2; i++) {
  769. pYuv_int8[i*2] = (Uint8)(pYuv_int16[i]>>8)&0xff;
  770. pYuv_int8[i*2 + 1] = (Uint8)(pYuv_int16[i])&0xff;
  771. }
  772. #endif
  773. }
  774. }
  775. if (yuv3p4b==1 && ctx->packedFormat) {
  776. ystride = picWidth;
  777. } else if (yuv3p4b == 1) {
  778. ystride = VPU_ALIGN32(picWidth);
  779. } else {
  780. ystride = VPU_ALIGN16(picWidth);
  781. }
  782. if ( out_frm_format != OUTPUT_PLANAR || ctx->packedFormat || yuv3p4b )
  783. {
  784. conv_image((unsigned short *)pYuv2_int16, ((bitdepth==0) ? ((unsigned short*)pYuv_int16) : ((unsigned short *)pYuv_int8)), picWidth, picHeight, out_width, out_height, out_frm_format, ctx->packedFormat);
  785. write_image_to_mem((unsigned short *)pYuv_int8, (unsigned short *)pYuv2_int16, ystride, out_height, pxl_format, out_frm_format, ctx->packedFormat);
  786. }
  787. #if 0
  788. {
  789. char fileName[MAX_FILE_PATH];
  790. #ifdef SAVE_WHOLE_LOADED_YUV
  791. #else
  792. FILE *save_fp;
  793. #endif
  794. char *frm_string;
  795. char *pixel_string;
  796. if ( ctx->packedFormat == 1)
  797. frm_string = "YUYV";
  798. else if ( ctx->packedFormat == 2)
  799. frm_string = "YVYU";
  800. else if ( ctx->packedFormat == 3)
  801. frm_string = "UYVY";
  802. else if ( ctx->packedFormat == 4)
  803. frm_string = "VYUY";
  804. else if ( out_frm_format == OUTPUT_NV12 ) {
  805. frm_string = "NV12";
  806. } else if ( out_frm_format == OUTPUT_NV21 ) {
  807. frm_string = "NV21";
  808. }
  809. else
  810. {
  811. frm_string = "I420";
  812. }
  813. if ( yuv3p4b )
  814. pixel_string = "3P4B";
  815. else if ( bitdepth == 10 )
  816. pixel_string = "1P2B";
  817. else
  818. pixel_string = "8b";
  819. sprintf(fileName, "loaded_%s_%dx%d_%s.yuv", pixel_string, picWidth, picHeight, frm_string);
  820. VLOG(INFO, "save %s\n", fileName);
  821. #ifdef SAVE_WHOLE_LOADED_YUV
  822. if ( save_frame_cnt == 0)
  823. save_fp = osal_fopen(fileName, "wb");
  824. #else
  825. save_fp = osal_fopen(fileName, "wb");
  826. #endif
  827. if ( yuv3p4b == 0 )
  828. write_image_to_file(save_fp, (unsigned short *)pYuv_int8, out_width, out_height, pxl_format, out_frm_format, ctx->packedFormat);
  829. else
  830. write_image_to_file(save_fp, (unsigned short *)pYuv2_int16, out_width, out_height, pxl_format, out_frm_format, ctx->packedFormat);
  831. osal_fflush(save_fp);
  832. #ifdef SAVE_WHOLE_LOADED_YUV
  833. if ( ++save_frame_cnt == save_frame_max )
  834. osal_fclose(save_fp);
  835. #else
  836. osal_fclose(save_fp);
  837. #endif
  838. }
  839. #endif
  840. if ( yuv3p4b && ctx->packedFormat) {
  841. out_width = ((picWidth*2)+2)/3*4;
  842. }
  843. else if(ctx->packedFormat) {
  844. out_width *= 2; // 8bit packed mode(YUYV) only. (need to add 10bit cases later)
  845. if (bitdepth != 0) // 10bit packed
  846. out_width *= 2;
  847. }
  848. LoadYuvImageBurstFormat(coreIdx, pYuv_int8, out_width, out_height, fb, TRUE);
  849. if ( pYuv_int16 )
  850. osal_free(pYuv_int16);
  851. if ( pYuv2_int16 )
  852. osal_free(pYuv2_int16);
  853. return TRUE;
  854. }
  855. BOOL loaderYuvFeeder_Configure(
  856. YuvFeederImpl* impl,
  857. Uint32 cmd,
  858. YuvInfo yuv
  859. )
  860. {
  861. Context* ctx = (Context*)impl->context;
  862. UNREFERENCED_PARAMETER(cmd);
  863. ctx->cbcrInterleave = yuv.cbcrInterleave;
  864. ctx->nv21 = yuv.nv21;
  865. ctx->packedFormat = yuv.packedFormat;
  866. return TRUE;
  867. }
  868. YuvFeederImpl loaderYuvFeederImpl = {
  869. NULL,
  870. loaderYuvFeeder_Create,
  871. loaderYuvFeeder_Feed,
  872. loaderYuvFeeder_Destory,
  873. loaderYuvFeeder_Configure,
  874. };