【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <unistd.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <math.h>
#include <string.h>
#include <malloc.h>
#include <sys/time.h>
#include <signal.h>
#include "mxcfb.h"
#include "ipu.h"
#include "g2d.h"
#define G2D_CACHEABLE 1
#define TFAIL -1
#define TPASS 0
#define NUMBER_BUFFERS 3
char v4l_capture_dev[100] = "/dev/video0";
#ifdef BUILD_FOR_ANDROID
char fb_display_dev[100] = "/dev/graphics/fb1";
char fb_display_bg_dev[100] = "/dev/graphics/fb0";
#else
char fb_display_dev[100] = "/dev/fb1";
char fb_display_bg_dev[100] = "/dev/fb0";
#endif
int fd_capture_v4l = 0;
int fd_fb_display = 0;
int fd_ipu = 0;
unsigned char * g_fb_display = NULL;
int g_input = 1;
int g_display_num_buffers = 3;
int g_capture_num_buffers = NUMBER_BUFFERS;
int g_in_width = 1920;
int g_in_height = 720;
int g_in_fmt = V4L2_PIX_FMT_RGB565;
int g_display_width = 1920;
int g_display_height = 720;
int g_display_top = 0;
int g_display_left = 0;
int g_display_fmt = V4L2_PIX_FMT_RGB24;
int g_display_base_phy;
int g_display_size;
int g_display_fg = 1;
int g_display_id = 1;
struct fb_var_screeninfo g_screen_info;
int g_frame_count = 0x7FFFFFFF;
int g_frame_size;
bool g_g2d_render = 0;
int g_g2d_fmt;
int g_mem_type = V4L2_MEMORY_MMAP;
int g_in_mode = 0;
struct testbuffer
{
unsigned char *start;
size_t offset;
unsigned int length;
};
struct testbuffer display_buffers[3];
struct testbuffer capture_buffers[NUMBER_BUFFERS];
int start_capturing(void)
{
unsigned int i;
struct v4l2_buffer buf;
enum v4l2_buf_type type;
for (i = 0; i < g_capture_num_buffers; i++) {
memset(&buf, 0, sizeof (buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = g_mem_type;
buf.index = i;
if (g_mem_type == V4L2_MEMORY_USERPTR) {
buf.length = capture_buffers[i].length;
buf.m.userptr = (unsigned long)capture_buffers[i].offset;
}
if (ioctl(fd_capture_v4l, VIDIOC_QUERYBUF, &buf) < 0) {
printf("VIDIOC_QUERYBUF error\n");
return TFAIL;
}
if (g_mem_type == V4L2_MEMORY_MMAP) {
capture_buffers[i].length = buf.length;
capture_buffers[i].offset = (size_t) buf.m.offset;
capture_buffers[i].start = mmap(NULL, capture_buffers[i].length,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd_capture_v4l, capture_buffers[i].offset);
memset(capture_buffers[i].start, 0xFF, capture_buffers[i].length);
}
}
for (i = 0; i < g_capture_num_buffers; i++) {
memset(&buf, 0, sizeof (buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = g_mem_type;
buf.index = i;
if (g_mem_type == V4L2_MEMORY_USERPTR)
buf.m.offset = (unsigned int)capture_buffers[i].start;
else
buf.m.offset = capture_buffers[i].offset;
buf.length = capture_buffers[i].length;
if (ioctl(fd_capture_v4l, VIDIOC_QBUF, &buf) < 0) {
printf("VIDIOC_QBUF error\n");
return TFAIL;
}
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl (fd_capture_v4l, VIDIOC_STREAMON, &type) < 0) {
printf("VIDIOC_STREAMON error\n");
return TFAIL;
}
return TPASS;
}
int prepare_display_buffers(void)
{
int i;
g_fb_display = (unsigned short *)mmap(0, g_display_size * g_display_num_buffers,
PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb_display, 0);
if (g_fb_display == NULL) {
printf("v4l2 tvin test: display mmap failed\n");
return TFAIL;
}
for (i = 0; i < g_display_num_buffers; i++) {
display_buffers[i].length = g_display_size;
display_buffers[i].offset = g_display_base_phy + g_display_size * i;
display_buffers[i].start = g_fb_display + (g_display_size * i);
}
return TPASS;
}
int v4l_capture_setup(void)
{
struct v4l2_capability cap;
struct v4l2_cropcap cropcap;
struct v4l2_control ctl;
struct v4l2_crop crop;
struct v4l2_format fmt;
struct v4l2_requestbuffers req;
struct v4l2_dbg_chip_ident chip;
struct v4l2_streamparm parm;
v4l2_std_id id;
unsigned int min;
if (ioctl (fd_capture_v4l, VIDIOC_QUERYCAP, &cap) < 0) {
if (EINVAL == errno) {
fprintf (stderr, "%s is no V4L2 device\n",
v4l_capture_dev);
return TFAIL;
} else {
fprintf (stderr, "%s isn not V4L device,unknow error\n",
v4l_capture_dev);
return TFAIL;
}
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf (stderr, "%s is no video capture device\n",
v4l_capture_dev);
return TFAIL;
}
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
fprintf (stderr, "%s does not support streaming i/o\n",
v4l_capture_dev);
return TFAIL;
}
if (ioctl(fd_capture_v4l, VIDIOC_S_INPUT, &g_input) < 0) {
printf("VIDIOC_S_INPUT failed\n");
close(fd_capture_v4l);
return TFAIL;
}
memset(&cropcap, 0, sizeof(cropcap));
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl (fd_capture_v4l, VIDIOC_CROPCAP, &cropcap) < 0) {
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect; /* reset to default */
if (ioctl (fd_capture_v4l, VIDIOC_S_CROP, &crop) < 0) {
switch (errno) {
case EINVAL:
/* Cropping not supported. */
fprintf (stderr, "%s doesn't support crop\n",
v4l_capture_dev);
break;
default:
/* Errors ignored. */
break;
}
}
} else {
/* Errors ignored. */
}
parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
parm.parm.capture.timeperframe.numerator = 1;
parm.parm.capture.timeperframe.denominator = 0;
parm.parm.capture.capturemode = 0;
parm.parm.capture.extendedmode = g_in_mode;
if (ioctl(fd_capture_v4l, VIDIOC_S_PARM, &parm) < 0) {
printf("VIDIOC_S_PARM failed\n");
close(fd_capture_v4l);
return TFAIL;
}
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 0;
fmt.fmt.pix.height = 0;
fmt.fmt.pix.pixelformat = g_in_fmt;
//fmt.fmt.pix.field = V4L2_FIELD_ANY;//V4L2_FIELD_INTERLACED
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if (ioctl (fd_capture_v4l, VIDIOC_S_FMT, &fmt) < 0) {
fprintf(stderr, "%s iformat not supported \n",
v4l_capture_dev);
return TFAIL;
}
/* Note VIDIOC_S_FMT may change width and height. */
/* Buggy driver paranoia. */
min = fmt.fmt.pix.width * 2;
if (fmt.fmt.pix.bytesperline < min)
fmt.fmt.pix.bytesperline = min;
min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
if (fmt.fmt.pix.sizeimage < min)
fmt.fmt.pix.sizeimage = min;
if (ioctl(fd_capture_v4l, VIDIOC_G_FMT, &fmt) < 0) {
printf("VIDIOC_G_FMT failed\n");
close(fd_capture_v4l);
return TFAIL;
}
g_in_width = fmt.fmt.pix.width;
g_in_height = fmt.fmt.pix.height;
printf("g_in_width = %d, g_in_height = %d.\r\n", g_in_width, g_in_height);
memset(&req, 0, sizeof (req));
req.count = g_capture_num_buffers;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = g_mem_type;
if (ioctl (fd_capture_v4l, VIDIOC_REQBUFS, &req) < 0) {
if (EINVAL == errno) {
fprintf (stderr, "%s does not support "
"memory mapping\n", v4l_capture_dev);
return TFAIL;
} else {
fprintf (stderr, "%s does not support "
"memory mapping, unknow error\n", v4l_capture_dev);
return TFAIL;
}
}
if (req.count < 2) {
fprintf (stderr, "Insufficient buffer memory on %s\n",
v4l_capture_dev);
return TFAIL;
}
return TPASS;
}
int fb_display_setup(void)
{
int fd_fb_bg = 0;
struct mxcfb_gbl_alpha alpha;
char node[8];
int retval = TPASS;
struct fb_fix_screeninfo fb_fix;
struct mxcfb_pos pos;
if (ioctl(fd_fb_display, FBIOGET_VSCREENINFO, &g_screen_info) < 0) {
printf("fb_display_setup FBIOGET_VSCREENINFO failed\n");
return TFAIL;
}
if (ioctl(fd_fb_display, FBIOGET_FSCREENINFO, &fb_fix) < 0) {
printf("fb_display_setup FBIOGET_FSCREENINFO failed\n");
return TFAIL;
}
printf("fb_fix.id = %s.\r\n", fb_fix.id);
if ((strcmp(fb_fix.id, "DISP4 FG") == 0) || (strcmp(fb_fix.id, "DISP3 FG") == 0))
{
g_display_fg = 1;
pos.x = g_display_left;
pos.y = g_display_top;
if (ioctl(fd_fb_display, MXCFB_SET_OVERLAY_POS, &pos) < 0) {
printf("fb_display_setup MXCFB_SET_OVERLAY_POS failed\n");
return TFAIL;
}
if (!g_g2d_render) {
g_screen_info.xres = g_display_width;
g_screen_info.yres = g_display_height;
//g_screen_info.xres = 1920;
//g_screen_info.yres = 720;
g_screen_info.yres_virtual = g_screen_info.yres * g_display_num_buffers;
g_screen_info.xres_virtual = g_screen_info.xres ;
g_screen_info.nonstd = g_display_fmt;
if (ioctl(fd_fb_display, FBIOPUT_VSCREENINFO, &g_screen_info) < 0) {
printf("fb_display_setup FBIOPUET_VSCREENINFO failed\n");
return TFAIL;
}
ioctl(fd_fb_display, FBIOGET_FSCREENINFO, &fb_fix);
ioctl(fd_fb_display, FBIOGET_VSCREENINFO, &g_screen_info);
}
sprintf(node, "%d", g_display_id - 1); //for iMX6
#ifdef BUILD_FOR_ANDROID
strcpy(fb_display_bg_dev, "/dev/graphics/fb");
#else
strcpy(fb_display_bg_dev, "/dev/fb");
#endif
strcat(fb_display_bg_dev, node);
if ((fd_fb_bg = open(fb_display_bg_dev, O_RDWR )) < 0) {
printf("Unable to open bg frame buffer\n");
return TFAIL;
}
/* Overlay setting */
alpha.alpha = 0;
alpha.enable = 1;
if (ioctl(fd_fb_bg, MXCFB_SET_GBL_ALPHA, &alpha) < 0) {
printf("Set global alpha failed\n");
close(fd_fb_bg);
return TFAIL;
}
}
ioctl(fd_fb_display, FBIOBLANK, FB_BLANK_UNBLANK);
g_display_base_phy = fb_fix.smem_start;
printf("fb: smem_start = 0x%x, smem_len = 0x%x.\r\n", (unsigned int)fb_fix.smem_start, (unsigned int)fb_fix.smem_len);
g_display_size = g_screen_info.xres * g_screen_info.yres * g_screen_info.bits_per_pixel / 8;
printf("fb: frame buffer size = 0x%x bytes.\r\n", g_display_size);
printf("fb: g_screen_info.xres = %d, g_screen_info.yres = %d.\r\n", g_screen_info.xres, g_screen_info.yres);
printf("fb: g_display_left = %d.\r\n", g_display_left);
printf("fb: g_display_top = %d.\r\n", g_display_top);
printf("fb: g_display_width = %d.\r\n", g_display_width);
printf("fb: g_display_height = %d.\r\n", g_display_height);
return TPASS;
}
int mxc_v4l_tvin_test(void)
{
struct v4l2_buffer capture_buf;
int i, j;
enum v4l2_buf_type type;
struct ipu_task task;
int total_time;
struct timeval tv_start, tv_current;
int display_buf_count = 0;
if (prepare_display_buffers() < 0) {
printf("prepare_display_buffers failed\n");
return TFAIL;
}
if (start_capturing() < 0) {
printf("start_capturing failed\n");
return TFAIL;
}
if (!g_g2d_render) {
memset(&task, 0, sizeof(struct ipu_task));
task.output.width = g_display_width;
task.output.height = g_display_height;
task.output.crop.w = g_display_width;
task.output.crop.h = g_display_height;
task.output.format = g_display_fmt;
task.input.width = g_in_width;
task.input.height = g_in_height;
task.input.crop.w = g_in_width;
task.input.crop.h = g_in_height;
task.input.format = g_in_fmt;
task.input.paddr = capture_buffers[0].offset;
task.output.paddr = display_buffers[0].offset;
if (ioctl(fd_ipu, IPU_CHECK_TASK, &task) != IPU_CHECK_OK) {
printf("IPU_CHECK_TASK failed.\r\n");
return TFAIL;
}
}
gettimeofday(&tv_start, 0);
printf("start time = %d s, %d us\n", (unsigned int) tv_start.tv_sec,
(unsigned int) tv_start.tv_usec);
for (i = 0; i < g_frame_count; i++)
{
memset(&capture_buf, 0, sizeof(capture_buf));
capture_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
capture_buf.memory = g_mem_type;
if (ioctl(fd_capture_v4l, VIDIOC_DQBUF, &capture_buf) < 0) {
printf("VIDIOC_DQBUF failed.\n");
return TFAIL;
}
task.input.paddr = capture_buffers[capture_buf.index].offset;
task.output.paddr = display_buffers[display_buf_count].offset;
if ((task.input.paddr != 0) && (task.output.paddr != 0))
{
if (ioctl(fd_ipu, IPU_QUEUE_TASK, &task) < 0) {
printf("IPU_QUEUE_TASK failed\n");
return TFAIL;
}
}
if (ioctl(fd_capture_v4l, VIDIOC_QBUF, &capture_buf) < 0) {
printf("VIDIOC_QBUF failed\n");
return TFAIL;
}
if (!g_g2d_render)
{
// g_screen_info.xoffset = 0;
// g_screen_info.yoffset = display_buf_count * g_display_height;
// if (ioctl(fd_fb_display, FBIOPAN_DISPLAY, &g_screen_info) < 0) {
// printf("FBIOPAN_DISPLAY failed, count = %d\n", i);
// break;
// }
display_buf_count ++;
if (display_buf_count >= g_display_num_buffers)
display_buf_count = 0;
display_buffers[0].start = display_buffers[(display_buf_count+1)%3].start;
}
}
gettimeofday(&tv_current, 0);
total_time = (tv_current.tv_sec - tv_start.tv_sec) * 1000000L;
total_time += tv_current.tv_usec - tv_start.tv_usec;
printf("total time for %u frames = %u us = %lld fps\n", i, total_time, (i * 1000000ULL) / total_time);
return TPASS;
}
int process_cmdline(int argc, char **argv)
{
int i, val;
char node[8];
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-ow") == 0) {
g_display_width = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-oh") == 0) {
g_display_height = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-ot") == 0) {
g_display_top = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-ol") == 0) {
g_display_left = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-c") == 0) {
g_frame_count = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-g2d") == 0) {
g_g2d_render = 1;
g_mem_type = V4L2_MEMORY_USERPTR;
}
else if (strcmp(argv[i], "-im") == 0) {
g_in_mode = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-x") == 0) {
val = atoi(argv[++i]);
sprintf(node, "%d", val);
strcpy(v4l_capture_dev, "/dev/video");
strcat(v4l_capture_dev, node);
}
else if (strcmp(argv[i], "-d") == 0) {
val = atoi(argv[++i]);
g_display_id = val;
sprintf(node, "%d", val);
#ifdef BUILD_FOR_ANDROID
strcpy(fb_display_dev, "/dev/graphics/fb");
#else
strcpy(fb_display_dev, "/dev/fb");
#endif
strcat(fb_display_dev, node);
}
else if (strcmp(argv[i], "-if") == 0) {
i++;
g_in_fmt = v4l2_fourcc(argv[i][0], argv[i][1],argv[i][2],argv[i][3]);
if ((g_in_fmt != V4L2_PIX_FMT_NV12) &&
(g_in_fmt != V4L2_PIX_FMT_UYVY) &&
(g_in_fmt != V4L2_PIX_FMT_YUYV) &&
(g_in_fmt != V4L2_PIX_FMT_YUV420)) {
printf("Default capture format is used: UYVY\n");
g_in_fmt = V4L2_PIX_FMT_UYVY;
}
}
else if (strcmp(argv[i], "-of") == 0) {
i++;
g_display_fmt = v4l2_fourcc(argv[i][0], argv[i][1],argv[i][2],argv[i][3]);
if ((g_display_fmt != V4L2_PIX_FMT_RGB565) &&
(g_display_fmt != V4L2_PIX_FMT_RGB24) &&
(g_display_fmt != V4L2_PIX_FMT_RGB32) &&
(g_display_fmt != V4L2_PIX_FMT_BGR32) &&
(g_display_fmt != V4L2_PIX_FMT_UYVY) &&
(g_display_fmt != V4L2_PIX_FMT_YUYV)) {
printf("Default display format is used: UYVY\n");
g_display_fmt = V4L2_PIX_FMT_UYVY;
}
}
else if (strcmp(argv[i], "-help") == 0) {
printf("MXC Video4Linux TVin Test\n\n" \
"Syntax: mxc_v4l2_tvin.out\n" \
" -ow <capture display width>\n" \
" -oh <capture display height>\n" \
" -ot <display top>\n" \
" -ol <display left>\n" \
" -g2d <GPU g2d render> \n" \
" -c <capture counter> \n" \
" -x <capture device> 0 = /dev/video0; 1 = /dev/video1 ...>\n" \
" -d <output frame buffer> 0 = /dev/fb0; 1 = /dev/fb1 ...>\n" \
" -if <capture format, only YU12, YUYV, UYVY and NV12 are supported> \n" \
" -of <display format, only RGBP, RGB3, RGB4, BGR4, YUYV, and UYVY are supported> \n");
return TFAIL;
}
}
if ((g_display_width == 0) || (g_display_height == 0)) {
printf("Zero display width or height\n");
return TFAIL;
}
return TPASS;
}
void signal_handle(int signal)
{
printf("Signal : %d", signal);
exit(1);
}
int main(int argc, char **argv)
{
int i;
enum v4l2_buf_type type;
signal(SIGKILL, signal_handle);
if (process_cmdline(argc, argv) < 0) {
return TFAIL;
}
if ((fd_capture_v4l = open(v4l_capture_dev, O_RDWR, 0)) < 0) {
printf("Unable to open %s\n", v4l_capture_dev);
return TFAIL;
}
if (v4l_capture_setup() < 0) {
printf("Setup v4l capture failed.\n");
return TFAIL;
}
if (!g_g2d_render) {
if ((fd_ipu = open("/dev/mxc_ipu", O_RDWR, 0)) < 0) {
printf("open ipu dev fail\n");
close(fd_capture_v4l);
return TFAIL;
}
}
if ((fd_fb_display = open(fb_display_dev, O_RDWR, 0)) < 0) {
printf("Unable to open %s\n", fb_display_dev);
close(fd_ipu);
close(fd_capture_v4l);
return TFAIL;
}
if (fb_display_setup() < 0) {
printf("Setup fb display failed.\n");
close(fd_ipu);
close(fd_capture_v4l);
close(fd_fb_display);
return TFAIL;
}
mxc_v4l_tvin_test();
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(fd_capture_v4l, VIDIOC_STREAMOFF, &type);
if (g_display_fg)
ioctl(fd_fb_display, FBIOBLANK, FB_BLANK_NORMAL);
munmap(g_fb_display, g_display_size * g_display_num_buffers);
for (i = 0; i < g_capture_num_buffers; i++) {
munmap(capture_buffers[i].start, capture_buffers[i].length);
}
close(fd_ipu);
close(fd_capture_v4l);
close(fd_fb_display);
return 0;
}
//iph.h
#ifndef __ASM_ARCH_IPU_H__
#define __ASM_ARCH_IPU_H__
#include <linux/types.h>
#include <linux/videodev2.h>
#ifndef __KERNEL__
#ifndef __cplusplus
typedef unsigned char bool;
#endif
#define irqreturn_t int
#define dma_addr_t int
#define uint32_t unsigned int
#define uint16_t unsigned short
#define uint8_t unsigned char
#define u32 unsigned int
#define u8 unsigned char
#define __u32 u32
#endif
/*!
* Enumeration of IPU rotation modes
*/
typedef enum {
/* Note the enum values correspond to BAM value */
IPU_ROTATE_NONE = 0,
IPU_ROTATE_VERT_FLIP = 1,
IPU_ROTATE_HORIZ_FLIP = 2,
IPU_ROTATE_180 = 3,
IPU_ROTATE_90_RIGHT = 4,
IPU_ROTATE_90_RIGHT_VFLIP = 5,
IPU_ROTATE_90_RIGHT_HFLIP = 6,
IPU_ROTATE_90_LEFT = 7,
} ipu_rotate_mode_t;
/*!
* Enumeration of VDI MOTION select
*/
typedef enum {
MED_MOTION = 0,
LOW_MOTION = 1,
HIGH_MOTION = 2,
} ipu_motion_sel;
/*!
* Enumeration of DI ports for ADC.
*/
typedef enum {
DISP0,
DISP1,
DISP2,
DISP3
} display_port_t;
/* IPU Pixel format definitions */
/* Four-character-code (FOURCC) */
#define fourcc(a, b, c, d)\
(((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
/*!
* @name IPU Pixel Formats
*
* Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
* the same used by V4L2 API.
*/
/*! @{ */
/*! @name Generic or Raw Data Formats */
/*! @{ */
#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') /*!< IPU Generic Data */
#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') /*!< IPU Generic Data */
#define IPU_PIX_FMT_GENERIC_16 fourcc('I', 'P', 'U', '2') /*!< IPU Generic Data */
#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6') /*!< IPU Generic Data */
#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8') /*!< IPU Generic Data */
/*! @} */
/*! @name RGB Formats */
/*! @{ */
#define IPU_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
#define IPU_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
#define IPU_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
#define IPU_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
#define IPU_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
#define IPU_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
#define IPU_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
#define IPU_PIX_FMT_GBR24 fourcc('G', 'B', 'R', '3') /*!< 24 GBR-8-8-8 */
#define IPU_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
#define IPU_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
#define IPU_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
#define IPU_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
#define IPU_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
/*! @} */
/*! @name YUV Interleaved Formats */
/*! @{ */
#define IPU_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
#define IPU_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
#define IPU_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVYU 4:2:2 */
#define IPU_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 VYYU 4:2:2 */
#define IPU_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
#define IPU_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
#define IPU_PIX_FMT_VYU444 fourcc('V', '4', '4', '4') /*!< 24 VYU 4:4:4 */
/* two planes -- one Y, one Cb + Cr interleaved */
#define IPU_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
/* two planes -- 12 tiled Y/CbCr 4:2:0 */
#define IPU_PIX_FMT_TILED_NV12 fourcc('T', 'N', 'V', 'P')
#define IPU_PIX_FMT_TILED_NV12F fourcc('T', 'N', 'V', 'F')
/*! @} */
/*! @name YUV Planar Formats */
/*! @{ */
#define IPU_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
/* non-interleaved 4:4:4 */
#define IPU_PIX_FMT_YUV444P fourcc('4', '4', '4', 'P') /*!< 24 YUV 4:4:4 */
/*! @} */
#define IPU_PIX_FMT_TILED_NV12_MBALIGN (16)
#define TILED_NV12_FRAME_SIZE(w, h) \
(ALIGN((w) * (h), SZ_4K) + ALIGN((w) * (h) / 2, SZ_4K))
/* IPU device */
typedef enum {
RGB_CS,
YUV_CS,
NULL_CS
} cs_t;
struct ipu_pos {
u32 x;
u32 y;
};
struct ipu_crop {
struct ipu_pos pos;
u32 w;
u32 h;
};
struct ipu_deinterlace {
bool enable;
u8 motion; /*see ipu_motion_sel*/
#define IPU_DEINTERLACE_FIELD_TOP 0
#define IPU_DEINTERLACE_FIELD_BOTTOM 1
#define IPU_DEINTERLACE_FIELD_MASK \
(IPU_DEINTERLACE_FIELD_TOP | IPU_DEINTERLACE_FIELD_BOTTOM)
/* deinterlace frame rate double flags */
#define IPU_DEINTERLACE_RATE_EN 0x80
#define IPU_DEINTERLACE_RATE_FRAME1 0x40
#define IPU_DEINTERLACE_RATE_MASK \
(IPU_DEINTERLACE_RATE_EN | IPU_DEINTERLACE_RATE_FRAME1)
#define IPU_DEINTERLACE_MAX_FRAME 2
u8 field_fmt;
};
struct ipu_input {
u32 width;
u32 height;
u32 format;
struct ipu_crop crop;
dma_addr_t paddr;
struct ipu_deinterlace deinterlace;
dma_addr_t paddr_n; /*valid when deinterlace enable*/
};
struct ipu_alpha {
#define IPU_ALPHA_MODE_GLOBAL 0
#define IPU_ALPHA_MODE_LOCAL 1
u8 mode;
u8 gvalue; /* 0~255 */
dma_addr_t loc_alp_paddr;
};
struct ipu_colorkey {
bool enable;
u32 value; /* RGB 24bit */
};
struct ipu_overlay {
u32 width;
u32 height;
u32 format;
struct ipu_crop crop;
struct ipu_alpha alpha;
struct ipu_colorkey colorkey;
dma_addr_t paddr;
};
struct ipu_output {
u32 width;
u32 height;
u32 format;
u8 rotate;
struct ipu_crop crop;
dma_addr_t paddr;
};
struct ipu_task {
struct ipu_input input;
struct ipu_output output;
bool overlay_en;
struct ipu_overlay overlay;
#define IPU_TASK_PRIORITY_NORMAL 0
#define IPU_TASK_PRIORITY_HIGH 1
u8 priority;
#define IPU_TASK_ID_ANY 0
#define IPU_TASK_ID_VF 1
#define IPU_TASK_ID_PP 2
#define IPU_TASK_ID_MAX 3
u8 task_id;
int timeout;
};
enum {
IPU_CHECK_OK = 0,
IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN = 0x1,
IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN = 0x2,
IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN = 0x4,
IPU_CHECK_ERR_MIN,
IPU_CHECK_ERR_INPUT_CROP,
IPU_CHECK_ERR_OUTPUT_CROP,
IPU_CHECK_ERR_OVERLAY_CROP,
IPU_CHECK_ERR_INPUT_OVER_LIMIT,
IPU_CHECK_ERR_OV_OUT_NO_FIT,
IPU_CHECK_ERR_OVERLAY_WITH_VDI,
IPU_CHECK_ERR_PROC_NO_NEED,
IPU_CHECK_ERR_SPLIT_INPUTW_OVER,
IPU_CHECK_ERR_SPLIT_INPUTH_OVER,
IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER,
IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER,
IPU_CHECK_ERR_SPLIT_WITH_ROT,
IPU_CHECK_ERR_NOT_SUPPORT,
IPU_CHECK_ERR_NOT16ALIGN,
IPU_CHECK_ERR_W_DOWNSIZE_OVER,
IPU_CHECK_ERR_H_DOWNSIZE_OVER,
};
/* IOCTL commands */
#define IPU_CHECK_TASK _IOWR('I', 0x1, struct ipu_task)
#define IPU_QUEUE_TASK _IOW('I', 0x2, struct ipu_task)
#define IPU_ALLOC _IOWR('I', 0x3, int)
#define IPU_FREE _IOW('I', 0x4, int)
#endif
//mxcfb.h
#ifndef __ASM_ARCH_MXCFB_H__
#define __ASM_ARCH_MXCFB_H__
#include <linux/fb.h>
#define FB_SYNC_OE_LOW_ACT 0x80000000
#define FB_SYNC_CLK_LAT_FALL 0x40000000
#define FB_SYNC_DATA_INVERT 0x20000000
#define FB_SYNC_CLK_IDLE_EN 0x10000000
#define FB_SYNC_SHARP_MODE 0x08000000
#define FB_SYNC_SWAP_RGB 0x04000000
#define FB_ACCEL_TRIPLE_FLAG 0x00000000
#define FB_ACCEL_DOUBLE_FLAG 0x00000001
struct mxcfb_gbl_alpha {
int enable;
int alpha;
};
struct mxcfb_loc_alpha {
int enable;
int alpha_in_pixel;
unsigned long alpha_phy_addr0;
unsigned long alpha_phy_addr1;
};
struct mxcfb_color_key {
int enable;
__u32 color_key;
};
struct mxcfb_pos {
__u16 x;
__u16 y;
};
struct mxcfb_gamma {
int enable;
int constk[16];
int slopek[16];
};
struct mxcfb_rect {
__u32 top;
__u32 left;
__u32 width;
__u32 height;
};
#define GRAYSCALE_8BIT 0x1
#define GRAYSCALE_8BIT_INVERTED 0x2
#define GRAYSCALE_4BIT 0x3
#define GRAYSCALE_4BIT_INVERTED 0x4
#define AUTO_UPDATE_MODE_REGION_MODE 0
#define AUTO_UPDATE_MODE_AUTOMATIC_MODE 1
#define UPDATE_SCHEME_SNAPSHOT 0
#define UPDATE_SCHEME_QUEUE 1
#define UPDATE_SCHEME_QUEUE_AND_MERGE 2
#define UPDATE_MODE_PARTIAL 0x0
#define UPDATE_MODE_FULL 0x1
#define WAVEFORM_MODE_AUTO 257
#define TEMP_USE_AMBIENT 0x1000
#define EPDC_FLAG_ENABLE_INVERSION 0x01
#define EPDC_FLAG_FORCE_MONOCHROME 0x02
#define EPDC_FLAG_USE_CMAP 0x04
#define EPDC_FLAG_USE_ALT_BUFFER 0x100
#define EPDC_FLAG_TEST_COLLISION 0x200
#define EPDC_FLAG_GROUP_UPDATE 0x400
#define EPDC_FLAG_USE_DITHERING_Y1 0x2000
#define EPDC_FLAG_USE_DITHERING_Y4 0x4000
#define FB_POWERDOWN_DISABLE -1
struct mxcfb_alt_buffer_data {
__u32 phys_addr;
__u32 width; /* width of entire buffer */
__u32 height; /* height of entire buffer */
struct mxcfb_rect alt_update_region; /* region within buffer to update */
};
struct mxcfb_update_data {
struct mxcfb_rect update_region;
__u32 waveform_mode;
__u32 update_mode;
__u32 update_marker;
int temp;
unsigned int flags;
struct mxcfb_alt_buffer_data alt_buffer_data;
};
struct mxcfb_update_marker_data {
__u32 update_marker;
__u32 collision_test;
};
/*
* Structure used to define waveform modes for driver
* Needed for driver to perform auto-waveform selection
*/
struct mxcfb_waveform_modes {
int mode_init;
int mode_du;
int mode_gc4;
int mode_gc8;
int mode_gc16;
int mode_gc32;
};
/*
* Structure used to define a 5*3 matrix of parameters for
* setting IPU DP CSC module related to this framebuffer.
*/
struct mxcfb_csc_matrix {
int param[5][3];
};
#define MXCFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t)
#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha)
#define MXCFB_SET_CLR_KEY _IOW('F', 0x22, struct mxcfb_color_key)
#define MXCFB_SET_OVERLAY_POS _IOWR('F', 0x24, struct mxcfb_pos)
#define MXCFB_GET_FB_IPU_CHAN _IOR('F', 0x25, u_int32_t)
#define MXCFB_SET_LOC_ALPHA _IOWR('F', 0x26, struct mxcfb_loc_alpha)
#define MXCFB_SET_LOC_ALP_BUF _IOW('F', 0x27, unsigned long)
#define MXCFB_SET_GAMMA _IOW('F', 0x28, struct mxcfb_gamma)
#define MXCFB_GET_FB_IPU_DI _IOR('F', 0x29, u_int32_t)
#define MXCFB_GET_DIFMT _IOR('F', 0x2A, u_int32_t)
#define MXCFB_GET_FB_BLANK _IOR('F', 0x2B, u_int32_t)
#define MXCFB_SET_DIFMT _IOW('F', 0x2C, u_int32_t)
#define MXCFB_CSC_UPDATE _IOW('F', 0x2D, struct mxcfb_csc_matrix)
/* IOCTLs for E-ink panel updates */
#define MXCFB_SET_WAVEFORM_MODES _IOW('F', 0x2B, struct mxcfb_waveform_modes)
#define MXCFB_SET_TEMPERATURE _IOW('F', 0x2C, int32_t)
#define MXCFB_SET_AUTO_UPDATE_MODE _IOW('F', 0x2D, __u32)
#define MXCFB_SEND_UPDATE _IOW('F', 0x2E, struct mxcfb_update_data)
#define MXCFB_WAIT_FOR_UPDATE_COMPLETE _IOWR('F', 0x2F, struct mxcfb_update_marker_data)
#define MXCFB_SET_PWRDOWN_DELAY _IOW('F', 0x30, int32_t)
#define MXCFB_GET_PWRDOWN_DELAY _IOR('F', 0x31, int32_t)
#define MXCFB_SET_UPDATE_SCHEME _IOW('F', 0x32, __u32)
#define MXCFB_GET_WORK_BUFFER _IOWR('F', 0x34, unsigned long)
#define MXCFB_DISABLE_EPDC_ACCESS _IO('F', 0x35)
#define MXCFB_ENABLE_EPDC_ACCESS _IO('F', 0x36)
#endif
来源:oschina
链接:https://my.oschina.net/urlove/blog/3146342