📄 video_osd.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_osd.h" // video driver definitions#include "debug.h" // DBG and ERR macros/* Bits per pixel for video window */#define SCREEN_BPP 16/* Global variables to hold attribute and osd window attributes */struct fb_var_screeninfo attrInfo;struct fb_var_screeninfo osdInfo;/****************************************************************************** * video_osd_setup ******************************************************************************//* input parameters: *//* int *osdFdByRef -- used to return the file desc of OSD device *//* int *attrFdByRef -- used to return the file desc of attribute dev *//* char *osdDevice -- string containing name of OSD device *//* char *attrDevice -- string containing name of attribute device *//* unsigned char trans -- 8-bit binary pattern to use as a fill for the *//* attribute window. 0x00 = transparent OSD *//* 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 are *//* alpha blends. 0x77 shows OSD only (no video) *//* 0x99-0xFF are same, but OSD blinks. *//* unsigned short **osdDisplayByRef -- used to return a pointer to the *//* mmap'ed osd buffer *//* unsigned short **attrDisplayByRef -- used to return a pointer to the *//* mmap'ed attribute buffer *//* *//******************************************************************************/int video_osd_setup(int *osdFdByRef, int *attrFdByRef, char *osdDevice, char *attrDevice, unsigned char trans, unsigned short **osdDisplayByRef, unsigned short **attrDisplayByRef){ int size; *osdFdByRef = open(osdDevice, O_RDWR); if (*osdFdByRef == -1) { ERR("Failed to open OSD device %s\n", osdDevice); return VOSD_FAILURE; } *attrFdByRef = open(attrDevice, O_RDWR); if (*attrFdByRef == -1) { ERR("Failed to open attribute window device %s\n", attrDevice); close(*osdFdByRef); return VOSD_FAILURE; } DBG("OSD device %s opened with file descriptor %d\n", osdDevice, *osdFdByRef); DBG("Attribute device %s opened with file descriptor %d\n", attrDevice, *attrFdByRef); if (ioctl(*osdFdByRef, FBIOGET_VSCREENINFO, &osdInfo) == -1) { ERR("Error reading variable info for file descriptor %d\n", *osdFdByRef); close(*attrFdByRef); close(*osdFdByRef); return VOSD_FAILURE; } /* Sixteen bits per pixel */ size = osdInfo.xres_virtual * osdInfo.yres * 2; *osdDisplayByRef = (unsigned short *) mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *osdFdByRef, 0); if (*osdDisplayByRef == MAP_FAILED) { ERR("Failed mmap on file descripor %d\n", *osdFdByRef); close(*attrFdByRef); close(*osdFdByRef); return VOSD_FAILURE; } DBG("Mapped osd window to location %p, size %d (%#x)\n", *osdDisplayByRef, size, size); /* Fill the window with the new attribute value */ memset(*osdDisplayByRef, 0, size); DBG("\tFilled OSD window with pattern: 0x0\n"); if (ioctl(*attrFdByRef, FBIOGET_VSCREENINFO, &attrInfo) == -1) { ERR("Error reading variable info for file descriptor %d\n", *attrFdByRef); close(*attrFdByRef); close(*osdFdByRef); return VOSD_FAILURE; } /* One nibble per pixel */ size = attrInfo.xres_virtual * attrInfo.yres / 2; *attrDisplayByRef = (unsigned short *) mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *attrFdByRef, 0); if (*attrDisplayByRef == MAP_FAILED) { ERR("Failed mmap on file descripor %d\n", *attrFdByRef); close(*attrFdByRef); close(*osdFdByRef); return VOSD_FAILURE; } DBG("Mapped attribute window to location %p, size %d (%#x)\n", *attrDisplayByRef, size, size); /* Fill the window with the new attribute value */ memset(*attrDisplayByRef, trans, size); DBG("\tFilled attribute window with pattern: %#x\n", trans); return VOSD_SUCCESS;}/****************************************************************************** * video_osd_place ******************************************************************************//* input parameters: *//* unsigned short *osdDisplay -- mmap'ed location of osd window *//* unsigned short *attrDisplay -- mmap'ed location of attribute window *//* unsigned short *picture -- bitmapped picture array *//* int x_offset -- x offset to place picture in osd *//* int y_offset -- y offset to place picture in osd *//* int x_picsize -- x dimension of picture *//* int y_picsize -- y dimension of picture *//* *//* NOTE: this function does not check offsets and picture size against *//* dimensions of osd and attr window. If your math is wrong, you will *//* get a segmentation fault (or worse) *//* *//******************************************************************************/int video_osd_place(unsigned short *osdDisplay, unsigned short *attrDisplay, unsigned short *picture, unsigned char trans, int x_offset, int y_offset, int x_picsize, int y_picsize){ int i; unsigned short *displayOrigin; unsigned short *attrOrigin; displayOrigin = osdDisplay + (y_offset * osdInfo.xres_virtual) + x_offset; attrOrigin = attrDisplay + (y_offset * (attrInfo.xres_virtual >> 2)) + (x_offset >> 2); for(i=0; i<y_picsize; i++){ memcpy(displayOrigin + (i*osdInfo.xres_virtual), picture + (i*x_picsize), (x_picsize << 1)); memset(attrOrigin + (i*(attrInfo.xres_virtual >> 2)), trans, (x_picsize >> 1) ); } return VOSD_SUCCESS;}/****************************************************************************** * video_osd_scroll ******************************************************************************//* input parameters: *//* unsigned short *osdDisplay -- mmap'ed location of osd window *//* unsigned short *attrDisplay -- mmap'ed location of attribute window *//* unsigned short *picture -- bitmapped picture array *//* int x_offset -- x offset to place picture in osd *//* int y_offset -- y offset to place picture in osd *//* int x_picsize -- x dimension of picture *//* int y_picsize -- y dimension of picture *//* int x_scroll -- x scrolling offset *//* int y_scroll -- y scrolling offset *//* *//* NOTE: this function does not check offsets and picture size against *//* dimensions of osd and attr window. If your math is wrong, you will *//* get a segmentation fault (or worse) *//* *//* NOTE #2: This function does not set the attribute window's transparency *//* use video_osd_place once as an initialization before using scroll *//* *//******************************************************************************/int video_osd_scroll(unsigned short *osdDisplay, unsigned short *attrDisplay, unsigned short *picture, int x_offset, int y_offset, int x_picsize, int y_picsize, int x_scroll, int y_scroll){ int i; unsigned short *displayOrigin; unsigned short *attrOrigin; displayOrigin = osdDisplay + (y_offset * osdInfo.xres_virtual) + x_offset; attrOrigin = attrDisplay + (y_offset * (attrInfo.xres_virtual >> 2)) + (x_offset >> 2); for(i=0; i<(y_picsize - y_scroll); i++){ memcpy(displayOrigin + (i*osdInfo.xres_virtual), picture + ((i+y_scroll)*x_picsize) + x_scroll, ((x_picsize-x_scroll) << 1)); memcpy(displayOrigin + (i*osdInfo.xres_virtual) + (x_picsize-x_scroll), picture + ((i+y_scroll)*x_picsize), ((x_scroll) << 1)); } for(i=(y_picsize - y_scroll); i<y_picsize; i++){ memcpy(displayOrigin + (i*osdInfo.xres_virtual), picture+ ((i-y_picsize+y_scroll)*x_picsize) + x_scroll, ((x_picsize-x_scroll) << 1)); memcpy(displayOrigin +(i*osdInfo.xres_virtual) + (x_picsize -x_scroll), picture + ((i-y_picsize+y_scroll)*x_picsize), (x_scroll << 1)); } return VOSD_SUCCESS;}/****************************************************************************** * video_osd_circframe ******************************************************************************//* input parameters: *//* unsigned short *osdDisplay -- mmap'ed location of osd window *//* unsigned short *attrDisplay -- mmap'ed location of attribute window *//* unsigned short fillval -- color fill for the frame in 5-6-5 RGB *//* unsigned char trans -- transparency value for the frame *//* 0x00 = transparent frame (so you won't see it) *//* 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 are *//* alpha blends. 0x77 shows solid frame *//* 0x99-0xFF are same, but OSD blinks. *//* *//******************************************************************************/int video_osd_circframe(unsigned short *osdDisplay, unsigned short *attrDisplay, unsigned short fillval, unsigned char trans){ int i, j; float x, y, x_scale, y_scale; char *attrChar = (char *) attrDisplay; x_scale = (float) (osdInfo.xres_virtual >> 1); y_scale = (float) (osdInfo.yres >> 1); for(j=0;j<osdInfo.yres;j++){ for(i=0;i<osdInfo.xres_virtual;i+=2){ x = (float) i - x_scale; y = (float) j - y_scale; if(((x*x / (x_scale*x_scale)) + (y*y/(y_scale*y_scale))) > 0.9){ attrChar[(j*attrInfo.xres_virtual + i) >> 1] = trans; osdDisplay[j*osdInfo.xres_virtual + i] = fillval; osdDisplay[j*osdInfo.xres_virtual + i + 1] = fillval; } } } return VOSD_SUCCESS;}/****************************************************************************** * video_osd_cleanup ******************************************************************************//* input parameters: *//* int osdFd -- file descriptor of open attr window *//* int attrFd -- file descriptor of open osd window *//* unsigned short *osdDisplay -- mmap'ed location of osd window *//* unsigned short *attrDisplay -- mmap'ed location of attribute window *//* *//******************************************************************************/int video_osd_cleanup(int osdFd, int attrFd, unsigned short *osdDisplay, unsigned short *attrDisplay){ struct fb_var_screeninfo vInfo; int size; DBG("Entering osd window cleanup\n"); if (ioctl(osdFd, FBIOGET_VSCREENINFO, &vInfo) == -1) { ERR("Error reading variable information for file descriptor %d\n", osdFd); close(attrFd); close(osdFd); return VOSD_FAILURE; } /* Sixteen bits per pixel */ size = vInfo.xres_virtual * vInfo.yres * 2; munmap(osdDisplay, size); close(osdFd); DBG("\tClosed osd window (file descriptor: %d)\n", osdFd); DBG("\tUnmapped osd window memory (%p)\n", osdDisplay); DBG("Entering attribute window cleanup\n"); if (ioctl(attrFd, FBIOGET_VSCREENINFO, &vInfo) == -1) { ERR("Error reading variable information for file descriptor %d\n", attrFd); close(attrFd); close(osdFd); return VOSD_FAILURE; } /* One nibble per pixel */ size = vInfo.xres_virtual * vInfo.yres / 2; munmap(attrDisplay, size); close(attrFd); DBG("\tClosed attribute window (file descriptor: %d)\n", attrFd); DBG("\tUnmapped attribute window memory (%p)\n", attrDisplay); return VOSD_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -