| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /*
- * Unit test: RGA NV12->RGBX color conversion
- * Tests the specific conversion that display.c needs.
- */
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/ioctl.h>
- #include <sys/mman.h>
- #include <linux/dma-heap.h>
- #include <rga/im2d.h>
- #include <rga/rga.h>
- static int dma_heap_alloc(const char *heap_name, size_t size, int *fd) {
- char path[64];
- snprintf(path, sizeof(path), "/dev/dma_heap/%s", heap_name);
- int heap_fd = open(path, O_RDWR | O_CLOEXEC);
- if (heap_fd < 0) return -1;
- struct dma_heap_allocation_data data = { .len = size, .fd_flags = O_RDWR | O_CLOEXEC };
- int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &data);
- close(heap_fd);
- if (ret < 0) return -1;
- *fd = data.fd;
- return 0;
- }
- static rga_buffer_t import_rga_buf(int fd, int w, int h, int stride_w, int stride_h, int format) {
- im_handle_param_t param;
- memset(¶m, 0, sizeof(param));
- param.width = w;
- param.height = h;
- param.format = format;
- rga_buffer_handle_t handle = importbuffer_fd(fd, ¶m);
- if (handle == 0) {
- fprintf(stderr, " importbuffer_fd failed for fd=%d w=%d h=%d fmt=%d\n", fd, w, h, format);
- rga_buffer_t empty; memset(&empty, 0, sizeof(empty));
- return empty;
- }
- return wrapbuffer_handle_t(handle, w, h, stride_w, stride_h, format);
- }
- static void test_nv12_to_rgbx(const char *heap, int w, int h, int rgbx_rga_fmt,
- int rgbx_pixel_stride, int rgbx_byte_stride) {
- printf("=== NV12->RGBX test: heap=%s %dx%d, rgbx_fmt=%d, pixel_stride=%d, byte_stride=%d ===\n",
- heap, w, h, rgbx_rga_fmt, rgbx_pixel_stride, rgbx_byte_stride);
- size_t nv12_sz = (size_t)w * h * 3 / 2;
- size_t rgbx_sz = (size_t)rgbx_byte_stride * h;
- int nv12_fd = -1, rgbx_fd = -1;
- if (dma_heap_alloc(heap, nv12_sz, &nv12_fd) < 0) {
- printf(" FAIL: nv12 alloc\n\n"); return;
- }
- if (dma_heap_alloc(heap, rgbx_sz, &rgbx_fd) < 0) {
- printf(" FAIL: rgbx alloc\n"); close(nv12_fd); return;
- }
- void *nv12_map = mmap(NULL, nv12_sz, PROT_READ | PROT_WRITE, MAP_SHARED, nv12_fd, 0);
- void *rgbx_map = mmap(NULL, rgbx_sz, PROT_READ | PROT_WRITE, MAP_SHARED, rgbx_fd, 0);
- if (nv12_map == MAP_FAILED || rgbx_map == MAP_FAILED) {
- printf(" FAIL: mmap\n"); close(nv12_fd); close(rgbx_fd); return;
- }
- /* Fill NV12 with white (Y=0xFF, UV=0x80) */
- memset(nv12_map, 0xFF, w * h);
- memset((uint8_t*)nv12_map + w * h, 0x80, w * h / 2);
- memset(rgbx_map, 0x00, rgbx_sz);
- /* Test 1: wrapbuffer_fd_t */
- printf(" Test 1: wrapbuffer_fd_t (NV12) + wrapbuffer_fd_t (RGBX)...\n");
- {
- rga_buffer_t src = wrapbuffer_fd_t(0, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
- rga_buffer_t dst = wrapbuffer_fd_t(0, w, h, rgbx_byte_stride, h, rgbx_rga_fmt);
- printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
- }
- /* Test 2: import NV12, wrapbuffer_fd_t RGBX */
- printf(" Test 2: import NV12 + wrapbuffer_fd_t RGBX (byte_stride=%d)...\n", rgbx_byte_stride);
- {
- rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
- rga_buffer_t dst = wrapbuffer_fd_t(0, w, h, rgbx_byte_stride, h, rgbx_rga_fmt);
- printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
- if (src.handle && dst.handle) {
- im_rect src_rect = {0, 0, w, h};
- im_rect dst_rect = {0, 0, w, h};
- rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
- im_rect prect; memset(&prect, 0, sizeof(prect));
- int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
- printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
- if (ret == IM_STATUS_SUCCESS) {
- uint8_t *p = (uint8_t*)rgbx_map;
- printf(" dst[0..3] = %02x %02x %02x %02x (expect ~FF FF FF 00 for white)\n",
- p[0], p[1], p[2], p[3]);
- }
- }
- }
- /* Test 3: import both, pixel stride for RGBX */
- printf(" Test 3: import both, RGBX pixel_stride=%d...\n", rgbx_pixel_stride);
- {
- rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
- rga_buffer_t dst = import_rga_buf(rgbx_fd, w, h, rgbx_pixel_stride, h, rgbx_rga_fmt);
- printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
- if (src.handle && dst.handle) {
- im_rect src_rect = {0, 0, w, h};
- im_rect dst_rect = {0, 0, w, h};
- rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
- im_rect prect; memset(&prect, 0, sizeof(prect));
- int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
- printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
- if (ret == IM_STATUS_SUCCESS) {
- uint8_t *p = (uint8_t*)rgbx_map;
- printf(" dst[0..3] = %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
- }
- }
- }
- /* Test 4: import both, byte stride for RGBX */
- printf(" Test 4: import both, RGBX byte_stride=%d...\n", rgbx_byte_stride);
- {
- rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
- rga_buffer_t dst = import_rga_buf(rgbx_fd, w, h, rgbx_byte_stride, h, rgbx_rga_fmt);
- printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
- if (src.handle && dst.handle) {
- im_rect src_rect = {0, 0, w, h};
- im_rect dst_rect = {0, 0, w, h};
- rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
- im_rect prect; memset(&prect, 0, sizeof(prect));
- int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
- printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
- if (ret == IM_STATUS_SUCCESS) {
- uint8_t *p = (uint8_t*)rgbx_map;
- printf(" dst[0..3] = %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
- }
- }
- }
- /* Test 5: use rkformat_t - try RGB888 */
- printf(" Test 5: NV12->RK_FORMAT_RGB_888...\n");
- {
- size_t rgb888_sz = (size_t)w * 3 * h;
- int rgb888_fd = -1;
- if (dma_heap_alloc(heap, rgb888_sz, &rgb888_fd) == 0) {
- void *rgb888_map = mmap(NULL, rgb888_sz, PROT_READ | PROT_WRITE, MAP_SHARED, rgb888_fd, 0);
- if (rgb888_map != MAP_FAILED) {
- memset(rgb888_map, 0, rgb888_sz);
- rga_buffer_t src = import_rga_buf(nv12_fd, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
- rga_buffer_t dst = import_rga_buf(rgb888_fd, w, h, w * 3, h, RK_FORMAT_RGB_888);
- printf(" src.handle=%u dst.handle=%u\n", src.handle, dst.handle);
- if (src.handle && dst.handle) {
- im_rect src_rect = {0, 0, w, h};
- im_rect dst_rect = {0, 0, w, h};
- rga_buffer_t pat; memset(&pat, 0, sizeof(pat));
- im_rect prect; memset(&prect, 0, sizeof(prect));
- int ret = improcess(src, dst, pat, src_rect, dst_rect, prect, IM_SYNC);
- printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
- }
- munmap(rgb888_map, rgb888_sz);
- }
- close(rgb888_fd);
- }
- }
- munmap(nv12_map, nv12_sz);
- munmap(rgbx_map, rgbx_sz);
- close(nv12_fd);
- close(rgbx_fd);
- printf("\n");
- }
- int main(void) {
- printf("=== RGA NV12->RGBX Color Conversion Test ===\n\n");
- /* Small test first */
- test_nv12_to_rgbx("system-uncached", 320, 240, RK_FORMAT_RGBX_8888, 320, 320*4);
- test_nv12_to_rgbx("system-uncached", 320, 240, RK_FORMAT_BGRA_8888, 320, 320*4);
- test_nv12_to_rgbx("system-uncached", 320, 240, RK_FORMAT_ARGB_8888, 320, 320*4);
- /* Full-size */
- test_nv12_to_rgbx("system-uncached", 1920, 1080, RK_FORMAT_RGBX_8888, 1920, 1920*4);
- test_nv12_to_rgbx("system-uncached", 1920, 1080, RK_FORMAT_BGRA_8888, 1920, 1920*4);
- test_nv12_to_rgbx("system-uncached", 1920, 1080, RK_FORMAT_ARGB_8888, 1920, 1920*4);
- printf("=== Done ===\n");
- return 0;
- }
|