vo_vesa.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,140 行 · 第 1/3 页
C
1,140 行
/* * video_out_vesa.c * * Copyright (C) Nick Kurshev <nickols_k@mail.ru> - Oct 2001 * * You can redistribute this file under terms and conditions * of GNU General Public licence v2. * This file is partly based on vbetest.c from lrmi distributive. *//* TODO: - hw YUV support (need volunteers who have corresponding hardware) - triple buffering (if it will really speedup playback). note: triple buffering requires VBE 3.0 - need volunteers.*/#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "gtf.h"#include <mplaylib.h>#ifdef HAVE_MALLOC_H#include <uclib.h>#endif#include <mplaylib.h>#include <mplaylib.h>#include <stddef.h>#include <mplaylib.h>#include <pwd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <vbe.h>#include "video_out.h"#include "video_out_internal.h"#include "fastmemcpy.h"#include "sub.h"#include "libavutil/common.h"#include "mpbswap.h"#include "aspect.h"#include "vesa_lvo.h"#ifdef CONFIG_VIDIX#include "vosub_vidix.h"#endif#include "mp_msg.h"#include "libswscale/swscale.h"#include "libmpcodecs/vf_scale.h"#ifdef HAVE_PNGextern vo_functions_t video_out_png;#endifextern char *monitor_hfreq_str;extern char *monitor_vfreq_str;extern char *monitor_dotclock_str;#define MAX_BUFFERS 3#ifndef max#define max(a,b) ((a)>(b)?(a):(b))#endif#ifndef min#define min(a,b) ((a)<(b)?(a):(b))#endif#define UNUSED(x) ((void)(x)) /**< Removes warning about unused arguments */static vo_info_t info = { "VESA VBE 2.0 video output", "vesa", "Nick Kurshev <nickols_k@mail.ru>", "Requires ROOT privileges"};LIBVO_EXTERN(vesa)/* driver data */struct win_frame{ uint8_t *ptr; /* pointer to window's frame memory */ uint32_t low; /* lowest boundary of frame */ uint32_t high; /* highest boundary of frame */ char idx; /* indicates index of relocatable frame (A=0 or B=1) special case for DGA: idx=-1 idx=-2 indicates invalid frame, exists only in init() */};static void (*cpy_blk_fnc)(unsigned long,uint8_t *,unsigned long) = NULL;static uint32_t srcW=0,srcH=0,srcBpp,srcFourcc; /* source image description */static uint32_t dstBpp,dstW, dstH,dstFourcc; /* destinition image description */static struct SwsContext * sws = NULL;static int32_t x_offset,y_offset; /* to center image on screen */static unsigned init_mode=0; /* mode before run of mplayer */static void *init_state = NULL; /* state before run of mplayer */static struct win_frame win; /* real-mode window to video memory */static uint8_t *dga_buffer = NULL; /* for yuv2rgb and sw_scaling */static unsigned video_mode; /* selected video mode for playback */static struct VesaModeInfoBlock video_mode_info;static int flip_trigger = 0;static void (*draw_alpha_fnc)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride);/* multibuffering */uint8_t* video_base; /* should be never changed */uint32_t multi_buff[MAX_BUFFERS]; /* contains offsets of buffers */uint8_t multi_size=0; /* total number of buffers */uint8_t multi_idx=0; /* active buffer *//* Linux Video Overlay */static const char *lvo_name = NULL;static int lvo_opened = 0;#ifdef CONFIG_VIDIXstatic const char *vidix_name = NULL;static int vidix_opened = 0;static vidix_grkey_t gr_key;#endif/* Neomagic TV out */static int neomagic_tvout = 0;static int neomagic_tvnorm = NEO_PAL; #define HAS_DGA() (win.idx == -1)#define MOVIE_MODE (MODE_ATTR_COLOR | MODE_ATTR_GRAPHICS)#define FRAME_MODE (MODE_WIN_RELOCATABLE | MODE_WIN_WRITEABLE)static char * vbeErrToStr(int err){ char *retval; static char sbuff[80]; if((err & VBE_VESA_ERROR_MASK) == VBE_VESA_ERROR_MASK) { sprintf(sbuff,"VESA failed = 0x4f%02x",(err & VBE_VESA_ERRCODE_MASK)>>8); retval = sbuff; } else switch(err) { case VBE_OK: retval = "No error"; break; case VBE_VM86_FAIL: retval = "vm86() syscall failed"; break; case VBE_OUT_OF_DOS_MEM: retval = "Out of DOS memory"; break; case VBE_OUT_OF_MEM: retval = "Out of memory"; break; case VBE_BROKEN_BIOS: retval = "Broken BIOS or DOS TSR"; break; default: sprintf(sbuff,"Unknown or internal error: %i",err); retval=sbuff; break; } return retval;}#define PRINT_VBE_ERR(name,err) { mp_msg(MSGT_VO,MSGL_WARN, "vo_vesa: %s returns: %s\n",name,vbeErrToStr(err)); fflush(stdout); }static void vesa_term( void ){ int err; if(lvo_opened) { vlvo_term(); lvo_opened = 0; }#ifdef CONFIG_VIDIX else if(vidix_opened) { vidix_term(); vidix_opened = 0; }#endif if(init_state) if((err=vbeRestoreState(init_state)) != VBE_OK) PRINT_VBE_ERR("vbeRestoreState",err); init_state=NULL; if(init_mode) if((err=vbeSetMode(init_mode,NULL)) != VBE_OK) PRINT_VBE_ERR("vbeSetMode",err); init_mode=0; if(HAS_DGA()) vbeUnmapVideoBuffer((unsigned long)win.ptr,win.high); if(dga_buffer && !HAS_DGA()) free(dga_buffer); vbeDestroy(); if(sws) sws_freeContext(sws); sws=NULL;}#define VALID_WIN_FRAME(offset) (offset >= win.low && offset < win.high)#define VIDEO_PTR(offset) (win.ptr + offset - win.low)static inline void __vbeSwitchBank(unsigned long offset){ unsigned long gran; unsigned new_offset; int err; gran = video_mode_info.WinGranularity*1024; new_offset = offset / gran; if(HAS_DGA()) { err = -1; goto show_err; } if((err=vbeSetWindow(win.idx,new_offset)) != VBE_OK) { show_err: vesa_term(); PRINT_VBE_ERR("vbeSetWindow",err); mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_FatalErrorOccurred); abort(); } win.low = new_offset * gran; win.high = win.low + video_mode_info.WinSize*1024;}static void __vbeSetPixel(int x, int y, int r, int g, int b){ int x_res = video_mode_info.XResolution; int y_res = video_mode_info.YResolution; int shift_r = video_mode_info.RedFieldPosition; int shift_g = video_mode_info.GreenFieldPosition; int shift_b = video_mode_info.BlueFieldPosition; int pixel_size = (dstBpp+7)/8; int bpl = video_mode_info.BytesPerScanLine; int color; unsigned offset; if (x < 0 || x >= x_res || y < 0 || y >= y_res) return; r >>= 8 - video_mode_info.RedMaskSize; g >>= 8 - video_mode_info.GreenMaskSize; b >>= 8 - video_mode_info.BlueMaskSize; color = (r << shift_r) | (g << shift_g) | (b << shift_b); offset = y * bpl + (x * pixel_size); if(!VALID_WIN_FRAME(offset)) __vbeSwitchBank(offset); memcpy(VIDEO_PTR(offset), &color, pixel_size);}/* Copies part of frame to video memory. Data should be in the same format as video memory.*/static void __vbeCopyBlockFast(unsigned long offset,uint8_t *image,unsigned long size){ fast_memcpy(&win.ptr[offset],image,size);}static void __vbeCopyBlock(unsigned long offset,uint8_t *image,unsigned long size){ unsigned long delta,src_idx = 0; while(size) { if(!VALID_WIN_FRAME(offset)) __vbeSwitchBank(offset); delta = min(size,win.high - offset); fast_memcpy(VIDEO_PTR(offset),&image[src_idx],delta); src_idx += delta; offset += delta; size -= delta; }}/* Copies frame to video memory. Data should be in the same format as video memory.*/#define PIXEL_SIZE() ((dstBpp+7)/8)#define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) )#define IMAGE_LINE_SIZE(pixel_size) (dstW*(pixel_size))static void __vbeCopyData(uint8_t *image){ unsigned long i,j,image_offset,offset; unsigned pixel_size,image_line_size,screen_line_size,x_shift; pixel_size = PIXEL_SIZE(); screen_line_size = SCREEN_LINE_SIZE(pixel_size); image_line_size = IMAGE_LINE_SIZE(pixel_size); if(dstW == video_mode_info.XResolution) { /* Special case for zooming */ (*cpy_blk_fnc)(y_offset*screen_line_size,image,image_line_size*dstH); } else { x_shift = x_offset*pixel_size; for(j=0,i=y_offset;j<dstH;i++,j++) { offset = i*screen_line_size+x_shift; image_offset = j*image_line_size; (*cpy_blk_fnc)(offset,&image[image_offset],image_line_size); } }}/* is called for yuv only */static int draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y){ int dstride=HAS_DGA()?video_mode_info.XResolution:dstW; uint8_t *dst[3]= {dga_buffer, NULL, NULL}; int dstStride[3]; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_vesa: draw_slice was called: w=%u h=%u x=%u y=%u\n",w,h,x,y); dstStride[0]=dstride*((dstBpp+7)/8); dstStride[1]= dstStride[2]=dstStride[0]>>1; if(HAS_DGA()) dst[0] += y_offset*SCREEN_LINE_SIZE(PIXEL_SIZE())+x_offset*PIXEL_SIZE(); sws_scale_ordered(sws,image,stride,y,h,dst,dstStride); flip_trigger = 1; return 0;}/* Please comment it out if you want have OSD within movie *//*#define OSD_OUTSIDE_MOVIE 1*/static void draw_alpha_32(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ int dstride=HAS_DGA()?video_mode_info.XResolution:dstW;#ifndef OSD_OUTSIDE_MOVIE if(HAS_DGA()) { x0 += x_offset; y0 += y_offset; }#endif vo_draw_alpha_rgb32(w,h,src,srca,stride,dga_buffer+4*(y0*dstride+x0),4*dstride);}static void draw_alpha_24(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ int dstride=HAS_DGA()?video_mode_info.XResolution:dstW;#ifndef OSD_OUTSIDE_MOVIE if(HAS_DGA()) { x0 += x_offset; y0 += y_offset; }#endif vo_draw_alpha_rgb24(w,h,src,srca,stride,dga_buffer+3*(y0*dstride+x0),3*dstride);}static void draw_alpha_16(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ int dstride=HAS_DGA()?video_mode_info.XResolution:dstW;#ifndef OSD_OUTSIDE_MOVIE if(HAS_DGA()) { x0 += x_offset; y0 += y_offset; }#endif vo_draw_alpha_rgb16(w,h,src,srca,stride,dga_buffer+2*(y0*dstride+x0),2*dstride);}static void draw_alpha_15(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ int dstride=HAS_DGA()?video_mode_info.XResolution:dstW;#ifndef OSD_OUTSIDE_MOVIE if(HAS_DGA()) { x0 += x_offset; y0 += y_offset; }#endif vo_draw_alpha_rgb15(w,h,src,srca,stride,dga_buffer+2*(y0*dstride+x0),2*dstride);}static void draw_alpha_null(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ UNUSED(x0); UNUSED(y0); UNUSED(w); UNUSED(h); UNUSED(src); UNUSED(srca); UNUSED(stride);}static void draw_osd(void){ uint32_t w,h; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_vesa: draw_osd was called\n"); {#ifdef OSD_OUTSIDE_MOVIE w = HAS_DGA()?video_mode_info.XResolution:dstW; h = HAS_DGA()?video_mode_info.YResolution:dstH;#else w = dstW; h = dstH;#endif if(dga_buffer) vo_draw_text(w,h,draw_alpha_fnc); }}static void flip_page(void)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?