📄 video_output.c
字号:
/* * video_output.c *//* Standard Linux headers */#include <stdio.h> // always include stdio.h#include <stdlib.h> // always include stdlib.h#include <string.h> // defines memset and memcpy methods#include <fcntl.h> // defines open, read, write methods#include <unistd.h> // defines close and sleep methods#include <sys/mman.h> // defines mmap method#include <sys/ioctl.h> // defines ioctl method#include <linux/fb.h> // defines framebuffer driver methods/* Application header files */#include "video_output.h" // video driver definitions#include "debug.h" // DBG and ERR macros/* Bits per pixel for video window */#define SCREEN_BPP 16/****************************************************************************** * video_output_setup ******************************************************************************//* input parameters: *//* int *fdByRef -- File descriptor passed by reference. It is used *//* to return the file descriptor of the device *//* opened by this function. *//* char *device -- Device node for FBDEV driver *//* char **displayBuffersArray -- an array of output buffer pointers. *//* The array must be allocated (i.e not just a *//* pointer with no memory assocaited with it) *//* The array is filled in as a return value with *//* pointers to the buffers mmap'ed by the driver *//* int numDisplayBufs -- number of buffers for the driver to mmap *//* int *displayWidthByRef -- used as both an input and output value: *//* on input: requested display frame width *//* on output: granted display frame width *//* int *displayHeightByRef -- identical to displayWidthByRef, *//* but for height *//* uint32_t zoomFactor -- zoom factor for display. Accepts: *//* ZOOM_1X, ZOOM_2X, ZOOM4X as defined in *//* video_display.h *//* *//* *//* return value: *//* int -- file descriptor of the newly opened display device, or *//* VCAP_FAILURE if failure (VCAP_FAILURE must be negative) *//* *//******************************************************************************/int video_output_setup(int *fdByRef, char *device, char **displayBuffersArray, int numDisplayBuffers, int *displayWidthByRef, int *displayHeightByRef, uint32_t zoomFactor){ int displayFd; // file descriptor for opened device struct fb_var_screeninfo varInfo; // variable display screen information int frameSize, lineWidth; // line and frame sizes in bytes struct Zoom_Params zoom; // specifies zoom of 1x, 2x or 4x int i; // for loop index /* define a macro to handle the repetitive cleanup required upon failure */ #define failure_procedure() close(displayFd); \ *fdByRef = -1; \ for(i=0; i<numDisplayBuffers; i++){ \ displayBuffersArray[i] = NULL; \ } \ *displayWidthByRef = 0; \ *displayHeightByRef = 0; \ return VOUT_FAILURE DBG("Initializing display device: %s\n", device); /* Open the display device */ displayFd = open(device, O_RDWR); if (displayFd == -1) { ERR("Failed to open fb device %s\n", device); failure_procedure(); } DBG("\tDisplay device opened with file descriptor: %d\n", displayFd); /* Query driver for current state of variable screen info */ if (ioctl(displayFd, FBIOGET_VSCREENINFO, &varInfo) == -1) { ERR("Failed FBIOGET_VSCREENINFO on %s\n", device); failure_procedure(); } /* Configure display resolution */ /* Driver currently only supports xres_virtual = 720, which sets */ /* xres = 720 in this implementation */ if( *displayWidthByRef != 720){ ERR("Display driver only currently supports width of 720\n"); failure_procedure(); } /* Setting xres_virtual = xres assures that a 1-d buffer will */ /* properly display. (Otherwise would require zero filling */ /* of unused xres_virtual for each line.) */ /* Multiple frames are mapped along y-axis as yres_virtual */ varInfo.xres = *displayWidthByRef; varInfo.xres_virtual = *displayWidthByRef; varInfo.yres = *displayHeightByRef; varInfo.yres_virtual = (*displayHeightByRef) * numDisplayBuffers; /* screen bits per pixel *must* be 16 -- DM6446/3 hardware req. */ varInfo.bits_per_pixel = SCREEN_BPP; /* Request video display format */ if (ioctl(displayFd, FBIOPUT_VSCREENINFO, &varInfo) == -1) { ERR("Failed FBIOPUT_VSCREENINFO on file descriptor %d\n", displayFd); failure_procedure(); } /* Get allocated video display format */ if (ioctl(displayFd, FBIOGET_VSCREENINFO, &varInfo) == -1) { ERR("Failed FBIOFET_VSCREENINFO on file descriptor %d\n", displayFd); failure_procedure(); } /* Calculate frame size and line width based on granted resolution */ frameSize = varInfo.xres * varInfo.yres * SCREEN_BPP/8; lineWidth = varInfo.xres * SCREEN_BPP/8; /* Map the video buffers to user space */ /* xres_virtual = xres guarantees they can all be mapped as one */ /* continuous buffer */ displayBuffersArray[0] = (char *) mmap (NULL, frameSize * numDisplayBuffers, PROT_READ | PROT_WRITE, MAP_SHARED, displayFd, 0); if (displayBuffersArray[0] == MAP_FAILED) { ERR("Failed mmap on file descriptor %d\n", displayFd); return VOUT_FAILURE; } /* Set the displayBuffersArray array with offsets from the one */ /* continuous memory segment. */ DBG("\tMapped display buffer 0, size %d to location %p\n", frameSize, displayBuffersArray[0]); for(i = 1; i< numDisplayBuffers; i++){ displayBuffersArray[i] = displayBuffersArray[i-1] + frameSize; DBG("\tMapped display buffer %d, size %d to location %p\n", i, frameSize, displayBuffersArray[i]); } /* Set the display zoom factor */ zoom.WindowID = VID1_INDEX; zoom.Zoom_H = zoomFactor; zoom.Zoom_V = zoomFactor; if (ioctl(displayFd, FBIO_SETZOOM, &zoom)) { ERR("Failed set zoom parameters on file descriptor %d\n", displayFd); failure_procedure(); } DBG("\tDisplay set to %dx%d resolution\n",varInfo.xres, varInfo.yres); switch( zoomFactor ) { case ZOOM_1X : DBG("\tZoom factor set to 1x\n"); break; case ZOOM_2X : DBG("\tZoom factor set to 2x\n"); break; case ZOOM_4X : DBG("\tZoom factor set to 4x\n"); break; default : DBG("\tUnrecognized zoom factor\n"); } /* Set return-by-reference values and return VOUT_SUCCESS */ /* (note: displayBuffersArray has already been filled) */ /* Allocated is not guaranteed to be the same as requested value. */ /* return actual allocated value via provided pointers */ *displayWidthByRef = varInfo.xres; *displayHeightByRef = varInfo.yres; /* return file descriptor for newly opened device via supplied pointer */ *fdByRef = displayFd; /* return the file descriptor of the newly opened device. */ return VOUT_SUCCESS;}/****************************************************************************** * flip_display_buffers ******************************************************************************//* input parameters: *//* int displayFd -- file descriptor for the driver as returned by *//* video_output_setup *//* int displayIdx -- index of the output buffer to be displayed *//* *//* *//* return value: *//* int -- VOUT_SUCCESS or VOUT_FAILURE as defined in *//* video_display.h *//* *//******************************************************************************/int flip_display_buffers(int displayFd, int displayIdx){ struct fb_var_screeninfo vInfo; // variable info for display screen /* Get current state of the display screen variable information */ if (ioctl(displayFd, FBIOGET_VSCREENINFO, &vInfo) == -1) { ERR("Failed FBIOGET_VSCREENINFO\n"); return VOUT_FAILURE; } /* modify y offset to select a display screen */ vInfo.yoffset = vInfo.yres * displayIdx; /* Swap the working buffer for the displayed buffer */ if (ioctl(displayFd, FBIOPAN_DISPLAY, &vInfo) == -1) { ERR("Failed FBIOPAN_DISPLAY\n"); return VOUT_FAILURE; } /* Halt thread until FBIOPAN_DISPLAY is latched at VSYNC */ if (ioctl(displayFd, FBIO_WAITFORVSYNC, &vInfo) == -1) { ERR("Failed FBIO_WAITFORVSYNC\n"); return VOUT_FAILURE; } return VOUT_SUCCESS;}/****************************************************************************** * video_output_cleanup ******************************************************************************//* input parameters: *//* int displayFd -- file descriptor for the driver as returned by *//* video_output_setup *//* char *displayBuffersArray -- pointer to the array of driver buffer *//* pointers that was filled by video_output_setup *//* int numDisplayBuffers -- number of buffers in displayBuffersArray *//* *//* *//* return value: *//* int -- VOUT_SUCCESS or VOUT_FAILURE as defined in *//* video_display.h *//* *//******************************************************************************/void video_output_cleanup(int displayFd, char **displayBuffersArray, int numDisplayBuffers){ struct fb_var_screeninfo varInfo; // variable display screen info int frameSize; // display frame size in bytes /* Get display frame resolution from the variable info */ if (ioctl(displayFd, FBIOGET_VSCREENINFO, &varInfo) == -1) { ERR("Failed FBIOFET_VSCREENINFO for file descriptor %d\n", displayFd); } /* Calculate frame size so we know how much to un-map */ frameSize = varInfo.xres * varInfo.yres * SCREEN_BPP/8; /* Un-memory-map display buffers from this process */ munmap(displayBuffersArray[0], frameSize * numDisplayBuffers); DBG("unmapped contiguous display buffer block of\n"); DBG("\tsize %d at location %p\n", (frameSize * numDisplayBuffers), displayBuffersArray[0]); /* Close display device */ close(displayFd); DBG("Closed video display device (file descriptor %d)\n", displayFd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -