test_rga_color.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Unit test: RGA NV12->RGBX color conversion
  3. * Tests the specific conversion that display.c needs.
  4. */
  5. #define _GNU_SOURCE
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <errno.h>
  12. #include <sys/ioctl.h>
  13. #include <sys/mman.h>
  14. #include <linux/dma-heap.h>
  15. #include <rga/im2d.h>
  16. #include <rga/rga.h>
  17. static int dma_heap_alloc(const char *heap_name, size_t size, int *fd) {
  18. char path[64];
  19. snprintf(path, sizeof(path), "/dev/dma_heap/%s", heap_name);
  20. int heap_fd = open(path, O_RDWR | O_CLOEXEC);
  21. if (heap_fd < 0) return -1;
  22. struct dma_heap_allocation_data data = { .len = size, .fd_flags = O_RDWR | O_CLOEXEC };
  23. int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &data);
  24. close(heap_fd);
  25. if (ret < 0) return -1;
  26. *fd = data.fd;
  27. return 0;
  28. }
  29. static rga_buffer_t import_rga_buf(int fd, int w, int h, int stride_w, int stride_h, int format) {
  30. im_handle_param_t param;
  31. memset(&param, 0, sizeof(param));
  32. param.width = w;
  33. param.height = h;
  34. param.format = format;
  35. rga_buffer_handle_t handle = importbuffer_fd(fd, &param);
  36. if (handle == 0) {
  37. fprintf(stderr, " importbuffer_fd failed for fd=%d w=%d h=%d fmt=%d\n", fd, w, h, format);
  38. rga_buffer_t empty; memset(&empty, 0, sizeof(empty));
  39. return empty;
  40. }
  41. return wrapbuffer_handle_t(handle, w, h, stride_w, stride_h, format);
  42. }
  43. static void test_nv12_to_rgbx(const char *heap, int w, int h, int rgbx_rga_fmt,
  44. int rgbx_pixel_stride, int rgbx_byte_stride) {
  45. printf("=== NV12->RGBX test: heap=%s %dx%d, rgbx_fmt=%d, pixel_stride=%d, byte_stride=%d ===\n",
  46. heap, w, h, rgbx_rga_fmt, rgbx_pixel_stride, rgbx_byte_stride);
  47. size_t nv12_sz = (size_t)w * h * 3 / 2;
  48. size_t rgbx_sz = (size_t)rgbx_byte_stride * h;
  49. int nv12_fd = -1, rgbx_fd = -1;
  50. if (dma_heap_alloc(heap, nv12_sz, &nv12_fd) < 0) {
  51. printf(" FAIL: nv12 alloc\n\n"); return;
  52. }
  53. if (dma_heap_alloc(heap, rgbx_sz, &rgbx_fd) < 0) {
  54. printf(" FAIL: rgbx alloc\n"); close(nv12_fd); return;
  55. }
  56. void *nv12_map = mmap(NULL, nv12_sz, PROT_READ | PROT_WRITE, MAP_SHARED, nv12_fd, 0);
  57. void *rgbx_map = mmap(NULL, rgbx_sz, PROT_READ | PROT_WRITE, MAP_SHARED, rgbx_fd, 0);
  58. if (nv12_map == MAP_FAILED || rgbx_map == MAP_FAILED) {
  59. printf(" FAIL: mmap\n"); close(nv12_fd); close(rgbx_fd); return;
  60. }
  61. /* Fill NV12 with white (Y=0xFF, UV=0x80) */
  62. memset(nv12_map, 0xFF, w * h);
  63. memset((uint8_t*)nv12_map + w * h, 0x80, w * h / 2);
  64. memset(rgbx_map, 0x00, rgbx_sz);
  65. /* Test 1: wrapbuffer_fd_t */
  66. printf(" Test 1: wrapbuffer_fd_t (NV12) + wrapbuffer_fd_t (RGBX)...\n");
  67. {
  68. rga_buffer_t src = wrapbuffer_fd_t(0, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
  69. rga_buffer_t dst = wrapbuffer_fd_t(0, w, h, rgbx_byte_stride, h, rgbx_rga_fmt);
  70. printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
  71. }
  72. /* Test 2: import NV12, wrapbuffer_fd_t RGBX */
  73. printf(" Test 2: import NV12 + wrapbuffer_fd_t RGBX (byte_stride=%d)...\n", rgbx_byte_stride);
  74. {
  75. rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
  76. rga_buffer_t dst = wrapbuffer_fd_t(0, w, h, rgbx_byte_stride, h, rgbx_rga_fmt);
  77. printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
  78. if (src.handle && dst.handle) {
  79. im_rect src_rect = {0, 0, w, h};
  80. im_rect dst_rect = {0, 0, w, h};
  81. rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
  82. im_rect prect; memset(&prect, 0, sizeof(prect));
  83. int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
  84. printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
  85. if (ret == IM_STATUS_SUCCESS) {
  86. uint8_t *p = (uint8_t*)rgbx_map;
  87. printf(" dst[0..3] = %02x %02x %02x %02x (expect ~FF FF FF 00 for white)\n",
  88. p[0], p[1], p[2], p[3]);
  89. }
  90. }
  91. }
  92. /* Test 3: import both, pixel stride for RGBX */
  93. printf(" Test 3: import both, RGBX pixel_stride=%d...\n", rgbx_pixel_stride);
  94. {
  95. rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
  96. rga_buffer_t dst = import_rga_buf(rgbx_fd, w, h, rgbx_pixel_stride, h, rgbx_rga_fmt);
  97. printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
  98. if (src.handle && dst.handle) {
  99. im_rect src_rect = {0, 0, w, h};
  100. im_rect dst_rect = {0, 0, w, h};
  101. rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
  102. im_rect prect; memset(&prect, 0, sizeof(prect));
  103. int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
  104. printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
  105. if (ret == IM_STATUS_SUCCESS) {
  106. uint8_t *p = (uint8_t*)rgbx_map;
  107. printf(" dst[0..3] = %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
  108. }
  109. }
  110. }
  111. /* Test 4: import both, byte stride for RGBX */
  112. printf(" Test 4: import both, RGBX byte_stride=%d...\n", rgbx_byte_stride);
  113. {
  114. rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
  115. rga_buffer_t dst = import_rga_buf(rgbx_fd, w, h, rgbx_byte_stride, h, rgbx_rga_fmt);
  116. printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
  117. if (src.handle && dst.handle) {
  118. im_rect src_rect = {0, 0, w, h};
  119. im_rect dst_rect = {0, 0, w, h};
  120. rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
  121. im_rect prect; memset(&prect, 0, sizeof(prect));
  122. int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
  123. printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
  124. if (ret == IM_STATUS_SUCCESS) {
  125. uint8_t *p = (uint8_t*)rgbx_map;
  126. printf(" dst[0..3] = %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
  127. }
  128. }
  129. }
  130. /* Test 5: use rkformat_t - try RGB888 */
  131. printf(" Test 5: NV12->RK_FORMAT_RGB_888...\n");
  132. {
  133. size_t rgb888_sz = (size_t)w * 3 * h;
  134. int rgb888_fd = -1;
  135. if (dma_heap_alloc(heap, rgb888_sz, &rgb888_fd) == 0) {
  136. void *rgb888_map = mmap(NULL, rgb888_sz, PROT_READ | PROT_WRITE, MAP_SHARED, rgb888_fd, 0);
  137. if (rgb888_map != MAP_FAILED) {
  138. memset(rgb888_map, 0, rgb888_sz);
  139. rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
  140. rga_buffer_t dst = import_rga_buf(rgb888_fd, w, h, w * 3, h, RK_FORMAT_RGB_888);
  141. printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
  142. if (src.handle && dst.handle) {
  143. im_rect src_rect = {0, 0, w, h};
  144. im_rect dst_rect = {0, 0, w, h};
  145. rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
  146. im_rect prect; memset(&prect, 0, sizeof(prect));
  147. int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
  148. printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
  149. }
  150. munmap(rgb888_map, rgb888_sz);
  151. }
  152. close(rgb888_fd);
  153. }
  154. }
  155. munmap(nv12_map, nv12_sz);
  156. munmap(rgbx_map, rgbx_sz);
  157. close(nv12_fd);
  158. close(rgbx_fd);
  159. printf("\n");
  160. }
  161. int main(void) {
  162. printf("=== RGA NV12->RGBX Color Conversion Test ===\n\n");
  163. /* Small test first */
  164. test_nv12_to_rgbx("system-uncached", 320, 240, RK_FORMAT_RGBX_8888, 320, 320*4);
  165. test_nv12_to_rgbx("system-uncached", 320, 240, RK_FORMAT_BGRA_8888, 320, 320*4);
  166. test_nv12_to_rgbx("system-uncached", 320, 240, RK_FORMAT_ARGB_8888, 320, 320*4);
  167. /* Full-size */
  168. test_nv12_to_rgbx("system-uncached", 1920, 1080, RK_FORMAT_RGBX_8888, 1920, 1920*4);
  169. test_nv12_to_rgbx("system-uncached", 1920, 1080, RK_FORMAT_BGRA_8888, 1920, 1920*4);
  170. test_nv12_to_rgbx("system-uncached", 1920, 1080, RK_FORMAT_ARGB_8888, 1920, 1920*4);
  171. printf("=== Done ===\n");
  172. return 0;
  173. }