?? em85xxosd.c
字號:
/*** $Id: em85xxosd.c,v 1.9 2005/05/18 11:00:21 weiym Exp $**** em85xxosd.c: NEWGAL driver for EM85xx OSD.** ** Copyright (C) 2003 Feynman Software.*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/file.h>#include <sys/stat.h>#include <fcntl.h>#include <signal.h>#include <sched.h>#include "common.h"#include "newgal.h"#include "sysvideo.h"#include "pixels_c.h"#include "realmagichwl_userland/caribbean_plainc.h"#include "realmagichwl_kernelland/realmagichwl.h"#include "realmagichwl_userland/realmagichwl_userland_api.h"#include "realmagichwl_kernelland/include/rm84cmn.h"#include "em85xxosd.h"#define EM85XXOSDVID_DRIVER_NAME "em85xxosd"/* Initialization/Query functions */static int EM85XXOSD_VideoInit(_THIS, GAL_PixelFormat *vformat);static GAL_Rect **EM85XXOSD_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags);static GAL_Surface *EM85XXOSD_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags);static int EM85XXOSD_SetColors(_THIS, int first, int count, GAL_Color *palette);static void EM85XXOSD_VideoQuit(_THIS);/* Hardware surface functions */static int EM85XXOSD_AllocHWSurface(_THIS, GAL_Surface *surface);static void EM85XXOSD_FreeHWSurface(_THIS, GAL_Surface *surface);static void EM85XXOSD_UpdateRects (_THIS, int numrects, GAL_Rect *rects);/* EM85XXOSD driver bootstrap functions */static int EM85XXOSD_Available(void){ return(1);}static char stack_updater [512];static int task_do_update (void* data){ _THIS; this = data; while (this->hidden->status == 2) { usleep (50000); // 50 ms if (this->hidden->dirty) { asm ("mcr p15, 0, r0, c7, c10, 0\n"); RUA_OSDFB_REFRESH (this->hidden->handle, 0); // manually refresh now this->hidden->dirty = FALSE; } } return 0;}static void EM85XXOSD_DeleteDevice(GAL_VideoDevice *device){ free(device->hidden); free(device);}static GAL_VideoDevice *EM85XXOSD_CreateDevice(int devindex){ GAL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ device = (GAL_VideoDevice *)malloc(sizeof(GAL_VideoDevice)); if ( device ) { memset(device, 0, (sizeof *device)); device->hidden = (struct GAL_PrivateVideoData *) malloc((sizeof *device->hidden)); } if ( (device == NULL) || (device->hidden == NULL) ) { GAL_OutOfMemory(); if ( device ) { free(device); } return(0); } memset(device->hidden, 0, (sizeof *device->hidden)); /* Set the function pointers */ device->VideoInit = EM85XXOSD_VideoInit; device->ListModes = EM85XXOSD_ListModes; device->SetVideoMode = EM85XXOSD_SetVideoMode; device->CreateYUVOverlay = NULL; device->SetColors = EM85XXOSD_SetColors; device->VideoQuit = EM85XXOSD_VideoQuit;#ifdef _LITE_VERSION device->RequestHWSurface = NULL;#endif device->AllocHWSurface = EM85XXOSD_AllocHWSurface; device->CheckHWBlit = NULL; device->FillHWRect = NULL; device->SetHWColorKey = NULL; device->SetHWAlpha = NULL; device->FreeHWSurface = EM85XXOSD_FreeHWSurface; device->UpdateRects = EM85XXOSD_UpdateRects; device->free = EM85XXOSD_DeleteDevice; return device;}VideoBootStrap EM85XXOSD_bootstrap = { EM85XXOSDVID_DRIVER_NAME, "EM85xx OSD video driver", EM85XXOSD_Available, EM85XXOSD_CreateDevice};static int EM85XXOSD_VideoInit(_THIS, GAL_PixelFormat *vformat){ unsigned long flicker; RUA_handle h; OSDBuffer osdbuffer; Wnd_type Wnd; evOutputDevice_type OutputDevice; evTvStandard_type TvStandard; evTvOutputFormat_type TvOutputFormat; fprintf (stderr, "NEWGAL EM85xxOSD WARNING: You are using the EM85xx OSD video driver!\n"); if ((h = RUA_OpenDevice (0)) == -1) { fprintf (stderr, "NEWGAL EM85xxOSD engine: Fatal error: can't open kernel module\n"); return -1; } /* set the tv output to be ntsc */ Wnd.x = 0; Wnd.y = 0; Wnd.w = 720; Wnd.h = 480; TvStandard = evTvStandard_NTSC; TvOutputFormat = evTvOutputFormat_COMPOSITE; OutputDevice = evOutputDevice_TV; RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evTvOutputFormat, sizeof(TvOutputFormat), &TvOutputFormat); RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evTvStandard, sizeof(TvStandard), &TvStandard); RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evOutputDevice, sizeof(OutputDevice), &OutputDevice); RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evDestinationWindow, sizeof(Wnd), &Wnd); /* XXX If we need to we can mmap the osdbuf from the device */ this->hidden->handle = h; if (RUA_OSDFB_REFRESH (this->hidden->handle, &osdbuffer) != 0) { fprintf (stderr, "NEWGAL EM85xxOSD engine: Error getting the OSD buffer.\n"); goto fail; } else { this->hidden->osd_buffer = osdbuffer.framebuffer; this->hidden->w = osdbuffer.width; this->hidden->h = osdbuffer.height; this->hidden->pitch = osdbuffer.width; this->hidden->fb = osdbuffer.framebuffer + 8 + 1024; } if (osdbuffer.bpp != 8) { GAL_SetError ("NEWGAL EM85xxOSD engine: Not supported depth: %d.\n", vformat->BitsPerPixel); return -1; } /* Setup the flicker filter * XXX - its also set in the kernel module, but it seems not to work very well * We reset it here, so that the microcode as already seen an osd frame. * 0 <= flicker <= 15 */ flicker = 15; RUA_DECODER_SET_PROPERTY (this->hidden->handle, DECODER_SET, edecOsdFlicker, sizeof(flicker), &flicker); /* * set the osd window destination * do not scale - just center the image */ Wnd.x = (720 - osdbuffer.width) / 2; Wnd.y = (480 - osdbuffer.height) / 2; Wnd.w = osdbuffer.width; Wnd.h = osdbuffer.height; RUA_DECODER_SET_PROPERTY (h, OSD_SET, eOsdDestinationWindow, sizeof(Wnd), &Wnd); vformat->BitsPerPixel = 8; vformat->BytesPerPixel = 1; vformat->Rmask = 0xE0; vformat->Gmask = 0x1C; vformat->Bmask = 0x03; this->hidden->status = 2; this->hidden->dirty = FALSE; /* We're done! */ return(0);fail: return -1;}static GAL_Rect **EM85XXOSD_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags){ return (GAL_Rect **) -1;}static GAL_Surface *EM85XXOSD_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags){ /* Set up the new mode framebuffer */ current->flags = GAL_HWSURFACE | GAL_FULLSCREEN | GAL_HWPALETTE; current->w = this->hidden->w; current->h = this->hidden->h; current->pitch = this->hidden->pitch; if (!GAL_ReallocFormat (current, 8, 0, 0, 0, 0) ) { return (NULL); } clone (task_do_update, stack_updater + 512, CLONE_VM | CLONE_FS | CLONE_FILES, this); /* We're done */ return (current);}/* We don't actually allow hardware surfaces other than the main one */static int EM85XXOSD_AllocHWSurface(_THIS, GAL_Surface *surface){ return(-1);}static void EM85XXOSD_FreeHWSurface(_THIS, GAL_Surface *surface){ surface->pixels = NULL;}#define START 0#define END 65536#define PRECISION 20/* This trick transform [0..255] range into [0..65535] range (instead of about 0..255*256) */#define RANGE8TO16(x) (((x)<<8)|(x))// see video demystified page 43static void gammacorrectedrgbtoyuv (Uint16 R, Uint16 G, Uint16 B, Uint16 *y, Uint16 *u, Uint16 *v){ long yraw, uraw, vraw; yraw = ( 257*R +504*G + 98*B)/1000 + RANGE8TO16(16); uraw = (-148*R -291*G +439*B)/1000 + RANGE8TO16(128); vraw = ( 439*R -368*G - 71*B)/1000 + RANGE8TO16(128); /* Obviously the computation of yraw garantees >= RANGE8TO16(16) ;-) This is also true for uraw and vraw */ *y = MAX(MIN(yraw,RANGE8TO16(235)),RANGE8TO16(16)); *u = MAX(MIN(uraw,RANGE8TO16(240)),RANGE8TO16(16)); *v = MAX(MIN(vraw,RANGE8TO16(240)),RANGE8TO16(16));}static int EM85XXOSD_SetColors(_THIS, int first, int count, GAL_Color *palette){ int i; Uint8* pal = this->hidden->osd_buffer + 8; GAL_Color* p; /* convert palette to quasar format*/ pal += first * 4; p = palette; for (i = first; i < (first + count); i++) { Uint16 Y, U, V; Uint16 R, G, B; /* RGB->YUVe computation. */ R = RANGE8TO16 (p->r); G = RANGE8TO16 (p->g); B = RANGE8TO16 (p->b); gammacorrectedrgbtoyuv (R, G, B, &Y, &U, &V); /* hardcode alpha blending values */ if (i == 0) pal[0] = 0x00; else if (i == 6) pal[0] = 0x66; else if (i == 15) pal[0] = 0x80; else if (i == 242) pal[0] = 0x80; else pal[0] = 0xff; pal[1] = (Uint8)(Y >> 8); pal[2] = (Uint8)(U >> 8); pal[3] = (Uint8)(V >> 8); pal += 4; p ++; } return 0;}static void EM85XXOSD_UpdateRects (_THIS, int numrects, GAL_Rect *rects){ this->hidden->dirty = TRUE;}static void EM85XXOSD_VideoQuit(_THIS){ if (this->hidden->status != 2) return; this->hidden->status = 1; RUA_ReleaseDevice (this->hidden->handle); return;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -