⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unichrome_vid.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Driver for VIA CLE266 Unichrome - Version 0.1.0    Copyright (C) 2004 by Timothy Lee    Based on Cyberblade/i driver by Alastair M. Robison.    Thanks to Gilles Frattini for bugfixes    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    Changes:    2004-03-10      Initial version    To Do:*/#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <inttypes.h>#include <unistd.h>#include "vidix.h"#include "fourcc.h"#include "libdha.h"#include "pci_ids.h"#include "pci_names.h"#include "unichrome_regs.h"pciinfo_t pci_info;uint8_t *uc_mem;static vidix_grkey_t uc_grkey;static int frames[VID_PLAY_MAXFRAMES];uint8_t *vio;uint8_t mclk_save[3];#define VIA_OUT(hwregs, reg, val)	*(volatile uint32_t *)((hwregs) + (reg)) = (val)#define VIA_IN(hwregs, reg)		*(volatile uint32_t *)((hwregs) + (reg))#define VGA_OUT8(hwregs, reg, val)	*(volatile uint8_t *)((hwregs) + (reg) + 0x8000) = (val)#define VGA_IN8(hwregs, reg)		*(volatile uint8_t *)((hwregs) + (reg) + 0x8000)#define VIDEO_OUT(hwregs, reg, val)	VIA_OUT((hwregs)+0x200, reg, val)#define VIDEO_IN(hwregs, reg)		VIA_IN((hwregs)+0x200, reg)#define outb(val,reg)	OUTPORT8(reg,val)#define inb(reg)	INPORT8(reg)#define ALIGN_TO(v, n) (((v) + (n-1)) & ~(n-1))#define UC_MAP_V1_FIFO_CONTROL(depth, pre_thr, thr) \    (((depth)-1) | ((thr) << 8) | ((pre_thr) << 24))#define FRAMEBUFFER_START	0x600000#define FRAMEBUFFER_SIZE	0x200000#ifdef DEBUG_LOGFILEFILE *logfile=0;#define LOGWRITE(x) {if(logfile) fprintf(logfile,x);}#else#define LOGWRITE(x)#endifstatic vidix_capability_t uc_cap ={	"VIA CLE266 Unichrome driver",	"Timothy Lee <timothy@siriushk.com>",	TYPE_OUTPUT,	{ 0, 0, 0, 0 },	4096,	4096,	4,	4,	-1,	FLAG_UPSCALER|FLAG_DOWNSCALER,	VENDOR_VIA2,	-1,	{ 0, 0, 0, 0 }};unsigned int vixGetVersion(void){	return(VIDIX_VERSION);}static unsigned short uc_card_ids[] ={	DEVICE_VIA2_VT8623_APOLLO_CLE266};static int find_chip(unsigned chip_id){	unsigned i;	for(i = 0;i < sizeof(uc_card_ids)/sizeof(unsigned short);i++)	{		if(chip_id == uc_card_ids[i]) return i;	}	return -1;}/** * Map hw settings for vertical scaling. * * @param sh        source height * @param dh        destination height * @param zoom      will hold vertical setting of zoom register. * @param mini      will hold vertical setting of mini register. * * @returns 1 if successful. *          0 if the zooming factor is too large or small. * * @note Derived from VIA's V4L driver. *       See ddover.c, DDOVER_HQVCalcZoomHeight() */static int uc_ovl_map_vzoom(int sh, int dh, uint32_t* zoom, uint32_t* mini){	uint32_t sh1, tmp, d;	int zoom_ok = 1;	if (sh == dh) { // No zoom		// Do nothing	}	else if (sh < dh) { // Zoom in		tmp = (sh * 0x0400) / dh;		zoom_ok = !(tmp > 0x3ff);		*zoom |= (tmp & 0x3ff) | V1_Y_ZOOM_ENABLE;		*mini |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY;	}	else { // sw > dh - Zoom out		// Find a suitable divider (1 << d) = {2, 4, 8 or 16}		sh1 = sh;		for (d = 1; d < 5; d++) {			sh1 >>= 1;			if (sh1 <= dh) break;		}		if (d == 5) { // Too small.			d = 4;			zoom_ok = 0;		}		*mini |= ((d<<1)-1) << 16;  // <= {1,3,5,7} << 16		// Add scaling		if (sh1 < dh)  {			tmp = (sh1 * 0x400) / dh;			*zoom |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE);			*mini |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY;		}	}	return zoom_ok;}/** * Map hw settings for horizontal scaling. * * @param sw        source width * @param dw        destination width * * @param zoom      will hold horizontal setting of zoom register. * @param mini      will hold horizontal setting of mini register. * @param falign    will hold fetch aligment * @param dcount    will hold display count * * @returns 1 if successful. *          0 if the zooming factor is too large or small. * * @note Derived from VIA's V4L driver. *       See ddover.c, DDOVER_HQVCalcZoomWidth() and DDOver_GetDisplayCount() */static int uc_ovl_map_hzoom(int sw, int dw,  uint32_t* zoom, uint32_t* mini,	int* falign, int* dcount){	uint32_t tmp, sw1, d;	int md; // Minify-divider	int zoom_ok = 1;	md = 1;	*falign = 0;	if (sw == dw) { // No zoom		// Do nothing	}	else if (sw < dw) { // Zoom in		tmp = (sw * 0x0800) / dw;		zoom_ok = !(tmp > 0x7ff);		*zoom |= ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;		*mini |= V1_X_INTERPOLY;	}	else { // sw > dw - Zoom out		// Find a suitable divider (1 << d) = {2, 4, 8 or 16}		sw1 = sw;		for (d = 1; d < 5; d++) {			sw1 >>= 1;			if (sw1 <= dw) break;		}		if (d == 5) { // Too small.			d = 4;			zoom_ok = 0;		}		md = 1 << d;                    // <= {2,4,8,16}		*falign = ((md<<1)-1) & 0xf;    // <= {3,7,15,15}		*mini |= V1_X_INTERPOLY;		*mini |= ((d<<1)-1) << 24;      // <= {1,3,5,7} << 24		// Add scaling		if (sw1 < dw) {			//CLE bug			//tmp = sw1*0x0800 / dw;			tmp = (sw1 - 2) * 0x0800 / dw;			*zoom |= ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;		}	}	*dcount = sw - md;	return zoom_ok;}/** * @param format    overlay pixel format * @param sw        source width * * @returns qword fetch register setting * * @note Derived from VIA's V4L driver. See ddover.c, DDOver_GetFetch() * @note Only call after uc_ovl_map_hzoom() */static uint32_t uc_ovl_map_qwfetch(uint32_t format, int sw){	uint32_t fetch = 0;	switch (format) {	case IMGFMT_YV12:	case IMGFMT_I420:		fetch = ALIGN_TO(sw, 32) >> 4;		break;	case IMGFMT_UYVY:	case IMGFMT_YVYU:	case IMGFMT_YUY2:		fetch = (ALIGN_TO(sw << 1, 16) >> 4) + 1;		break;	case IMGFMT_BGR15:	case IMGFMT_BGR16:		fetch = (ALIGN_TO(sw << 1, 16) >> 4) + 1;		break;	case IMGFMT_BGR32:		fetch = (ALIGN_TO(sw << 2, 16) >> 4) + 1;		break;	default:		printf("[unichrome] Unexpected pixelformat!");		break;	}	if (fetch < 4)		fetch = 4;	return fetch;}/** * Map pixel format. * * @note Derived from VIA's V4L driver. See ddover.c, DDOver_GetV1Format() */static uint32_t uc_ovl_map_format(uint32_t format){	switch (format) {	case IMGFMT_UYVY:	case IMGFMT_YVYU:	case IMGFMT_YUY2:		return V1_COLORSPACE_SIGN | V1_YUV422;	case IMGFMT_IYUV:		return V1_COLORSPACE_SIGN | V1_YCbCr420 | V1_SWAP_SW;	case IMGFMT_YV12:	case IMGFMT_I420:		return V1_COLORSPACE_SIGN | V1_YCbCr420;	case IMGFMT_BGR15:		return V1_RGB15;	case IMGFMT_BGR16:		return V1_RGB16;	case IMGFMT_BGR32:		return V1_RGB32;	default :		printf("[unichrome] Unexpected pixelformat!");		return V1_YUV422;	}}/** * Calculate V1 control and fifo-control register values * @param format        pixel format * @param sw            source width * @param hwrev         CLE266 hardware revision * @param extfifo_on    set this 1 if the extended FIFO is enabled * @param control       will hold value for V1_CONTROL * @param fifo          will hold value for V1_FIFO_CONTROL */static void uc_ovl_map_v1_control(uint32_t format, int sw,	int hwrev, int extfifo_on,	uint32_t* control, uint32_t* fifo){	*control = V1_BOB_ENABLE | uc_ovl_map_format(format);	if (hwrev == 0x10) {		*control |= V1_EXPIRE_NUM_F;	}	else {		if (extfifo_on) {			*control |= V1_EXPIRE_NUM_A | V1_FIFO_EXTENDED;		}		else {			*control |= V1_EXPIRE_NUM;		}	}	if ((format == IMGFMT_YV12) || (format == IMGFMT_I420)) {		//Minified video will be skewed without this workaround.		if (sw <= 80) { //Fetch count <= 5			*fifo = UC_MAP_V1_FIFO_CONTROL(16,0,0);		}		else {			if (hwrev == 0x10)				*fifo = UC_MAP_V1_FIFO_CONTROL(64,56,56);			else				*fifo = UC_MAP_V1_FIFO_CONTROL(16,12,8);		}	}	else {		if (hwrev == 0x10) {			*fifo = UC_MAP_V1_FIFO_CONTROL(64,56,56);   // Default rev 0x10		}		else {			if (extfifo_on)				*fifo = UC_MAP_V1_FIFO_CONTROL(48,40,40);			else				*fifo = UC_MAP_V1_FIFO_CONTROL(32,29,16);   // Default		}	}}static void uc_ovl_setup_fifo(int *extfifo_on, int dst_w){	if (dst_w <= 1024)	{		// Disable extended FIFO		outb(0x16, 0x3c4); outb(mclk_save[0], 0x3c5);		outb(0x17, 0x3c4); outb(mclk_save[1], 0x3c5);		outb(0x18, 0x3c4); outb(mclk_save[2], 0x3c5);		*extfifo_on = 0;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -