求助imx6ull怎么使用pxp模块用作yuv转rgb

用户04252025-10-20 12:42:07105

这是我的代码,但是pxp只给我转换了一帧的数据,软件转格式cpu开销太高了,有没有大佬啊。
static int v4l2_print_on_lcd()
{

struct pollfd fds[1];
int pxp_fd = open("/dev/pxp_device", O_RDWR);
if (pxp_fd < 0) {
    perror("open error");
}

struct pxp_chan_handle pxp_handle = {0};   // 保存所申请像素管道信息的结构体
if (ioctl(pxp_fd, PXP_IOC_GET_CHAN, &pxp_handle) < 0) 
{
    /* 错误处理 */
    perror("Failed to get PXP channel");
    close(pxp_fd);

}

// struct pxp_mem_desc {
// unsigned int handle;
// unsigned int size;
// dma_addr_t phys_addr;
// unsigned int virt_uaddr; /* virtual user space address */
// unsigned int mtype;
//};
struct pxp_mem_desc pxp_buffer = {0};
pxp_buffer.size = FRAME_WIDTH * FRAME_HEIGHT * 2; //rgb565 每个像素2字节
pxp_buffer.mtype = MEMORY_TYPE_UNCACHED;

/* 申请pxp所需要的物理地址并映射到用户空间 */
if (ioctl(pxp_fd, PXP_IOC_GET_PHYMEM, &pxp_buffer)) {
	perror("ioctl PXP_IOC_GET_PHYMEM error");
	close(pxp_fd);
}

pxp_buffer.virt_uaddr = (unsigned int)mmap(NULL,
						pxp_buffer.size,
						PROT_READ | PROT_WRITE, MAP_SHARED, 
						pxp_fd, 
						pxp_buffer.phys_addr
					);
if ((void*)pxp_buffer.virt_uaddr == MAP_FAILED) {
	perror("pxp_buffer.virt_uaddr mmap error");
	close(pxp_fd);
}
printf("申请的地址%p\n", pxp_buffer.virt_uaddr);
struct pxp_mem_flush flush = { .handle = pxp_buffer.handle, .type = CACHE_CLEAN };
/* 配置pxp */

	/* 输入配置 */
struct pxp_config_data pxp_config = {0};
pxp_config.s0_param.paddr = pxp_buffer.phys_addr;
pxp_config.s0_param.width = FRAME_WIDTH;
pxp_config.s0_param.height = FRAME_HEIGHT;
pxp_config.s0_param.pixel_fmt = PXP_PIX_FMT_YUYV;
pxp_config.s0_param.stride = FRAME_WIDTH * 2;

pxp_config.proc_data.srect.top = 0;
pxp_config.proc_data.srect.left = 0;
pxp_config.proc_data.srect.width = FRAME_WIDTH;
pxp_config.proc_data.srect.height = FRAME_HEIGHT;

	/* 输出配置 */
pxp_config.out_param.paddr = lcd_paddr;
pxp_config.out_param.width = FRAME_WIDTH;
pxp_config.out_param.height = FRAME_HEIGHT;
pxp_config.out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
pxp_config.out_param.stride = FRAME_WIDTH * 2;
pxp_config.proc_data.drect.left = 0;
pxp_config.proc_data.drect.top = 0;
pxp_config.proc_data.drect.width = FRAME_WIDTH;
pxp_config.proc_data.drect.height = FRAME_HEIGHT;

pxp_config.layer_nr = 1;
pxp_config.proc_data.yuv = 1;

if (ioctl(pxp_fd, PXP_IOC_CONFIG_CHAN, &pxp_config) < 0) {
	perror("ioctl PXP_IOC_CONFIG_CHAN error");
	close(pxp_fd);
	return -1;
}

fds[0].fd = fd;
fds[0].events = POLLIN;
short out[FRAME_WIDTH * FRAME_HEIGHT ];
while (1) {




	struct v4l2_buffer buf = {0};
	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	buf.memory = V4L2_MEMORY_MMAP;

	int ret = poll(fds,1, 1000);

	if (ret < 0) {
		perror("poll error");
		return;
	} else if (ret == 0) {
		printf("等待帧数据超时\n");
		continue;
	} else {
		if (fds->revents & POLLIN) {
			int ret = ioctl(fd, VIDIOC_DQBUF, &buf);
			if (ret < 0) {
				perror("ioctl VIDIOC_DQBUF");
			}
			printf("dma:first few bytes---before memcpy: %02x %02x %02x %02x\n", ((unsigned char*)pxp_buffer.virt_uaddr)[0], ((unsigned char*)pxp_buffer.virt_uaddr)[1], ((unsigned char*)pxp_buffer.virt_uaddr)[2], ((unsigned char*)pxp_buffer.virt_uaddr)[3]);
			memcpy((void*)pxp_buffer.virt_uaddr, buf_infos[buf.index].start, FRAME_WIDTH * FRAME_HEIGHT * 2);
			if (ioctl(pxp_fd, PXP_IOC_FLUSH_PHYMEM, &flush) < 0) {
				perror("PXP_IOC_FLUSH_PHYMEM clean");
			}
			 printf("dma:first few bytes---after memcpy: %02x %02x %02x %02x\n", ((unsigned char*)pxp_buffer.virt_uaddr)[0], ((unsigned char*)pxp_buffer.virt_uaddr)[1], ((unsigned char*)pxp_buffer.virt_uaddr)[2], ((unsigned char*)pxp_buffer.virt_uaddr)[3]);
			
			

// YUV422ToRGB565(buf_infos[buf.index].start, out, FRAME_WIDTH, FRAME_HEIGHT );
// memcpy(screen_base, out, buf_infos[buf.index].length);
if (ioctl(pxp_fd, PXP_IOC_START_CHAN, &pxp_handle) != 0) {
perror("ioctl PXP_IOC_START_CHAN error");
close(pxp_fd);
return -1;

			}

			if (ioctl(pxp_fd, PXP_IOC_WAIT4CMPLT, &pxp_handle) != 0) {
				
				perror("ioctl PXP_IOC_START_CHAN error");
				close(pxp_fd);
				return -1;
				
			}
			msync(screen_base, FRAME_WIDTH * FRAME_HEIGHT *2, MS_SYNC);
			printf("lcd:first few bytes: %02x %02x %02x %02x\n",
			screen_base[0],
			screen_base[1],
			screen_base[2],
			screen_base[3]);
			if ((ret = ioctl(fd, VIDIOC_QBUF, &buf)) < 0) {
				perror("ioctl VIDIOC_QBUF error");

			}

		
		}//if
	}//else
	//msync(screen_base, FRAME_WIDTH *FRAME_HEIGHT *2, MS_SYNC);
	usleep(20000);
	

}//while
return 0;

}//v4l2_print_on_lcd

浏览 (105)
点赞
收藏
评论
暂无数据