Mercurial > mplayer.hg
changeset 2869:107d9e9e5bd1
New video output technique Linux Video Overlay:
-vo vesa:lvo:drv_name
(for example -vo vesa:lvo:/dev/radeon_vid or -vo vesa:lvo:/dev/mga_vid)
Note: You don't need to have graphics screen before loading xxx_vid driver
vo_vesa will switch to graphics mode before using of xxx_vid driver.
So you can traditional start it from text-mode.
author | nick |
---|---|
date | Tue, 13 Nov 2001 17:13:33 +0000 |
parents | 4a1802c5bbee |
children | f46c5556f1e6 |
files | libvo/Makefile libvo/vesa_lvo.c libvo/vesa_lvo.h libvo/vo_vesa.c |
diffstat | 4 files changed, 258 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/libvo/Makefile Tue Nov 13 17:11:26 2001 +0000 +++ b/libvo/Makefile Tue Nov 13 17:13:33 2001 +0000 @@ -8,7 +8,7 @@ ifeq ($(TARGET_ARCH_X86),yes) ifeq ($(TARGET_OS),Linux) -SRCS += vo_vesa.c +SRCS += vo_vesa.c vesa_lvo.c endif endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libvo/vesa_lvo.c Tue Nov 13 17:13:33 2001 +0000 @@ -0,0 +1,197 @@ +/* + * vesa_lvo.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 contains vo_vesa interface to Linux Video Overlay. + * (Partly based on vo_mga.c from mplayer's package) + */ + +#include <inttypes.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "vesa_lvo.h" +#include "img_format.h" +#include "../drivers/mga_vid.h" /* <- should be changed to "linux/'something'.h" */ +#include "fastmemcpy.h" +#include "../mmx_defs.h" + +#define WIDTH_ALIGN 32 /* should be 16 for radeons */ +#define NUM_FRAMES 2 +static uint8_t *frames[NUM_FRAMES]; + +static int lvo_handler = -1; +static uint8_t *lvo_mem = NULL; +static uint8_t next_frame; +static mga_vid_config_t mga_vid_config; +static unsigned image_bpp,image_height,image_width; + + +#define PIXEL_SIZE() ((video_mode_info.BitsPerPixel+7)/8) +#define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) ) +#define IMAGE_LINE_SIZE(pixel_size) (image_width*(pixel_size)) + +int vlvo_init(const char *drvname,unsigned src_width,unsigned src_height, + unsigned x_org,unsigned y_org,unsigned dst_width, + unsigned dst_height,unsigned format,unsigned dest_bpp) +{ + size_t i,awidth; + lvo_handler = open(drvname,O_RDWR); + if(lvo_handler == -1) + { + printf("Couldn't open %s\n",drvname); + return -1; + } + image_width = src_width; + image_height = src_height; + mga_vid_config.version=MGA_VID_VERSION; + mga_vid_config.format=format; + awidth = (src_width + (WIDTH_ALIGN-1)) & ~(WIDTH_ALIGN-1); + switch(format){ + case IMGFMT_YV12: + case IMGFMT_I420: + case IMGFMT_IYUV: + image_bpp=16; + mga_vid_config.frame_size = awidth*src_height+(awidth*src_height)/2; + break; + case IMGFMT_YUY2: + case IMGFMT_UYVY: + image_bpp=16; + mga_vid_config.frame_size = awidth*src_height*2; + break; + case IMGFMT_RGB15: + case IMGFMT_BGR15: + case IMGFMT_RGB16: + case IMGFMT_BGR16: + image_bpp=16; + mga_vid_config.frame_size = awidth*src_height*2; + break; + case IMGFMT_RGB24: + case IMGFMT_BGR24: + image_bpp=24; + mga_vid_config.frame_size = awidth*src_height*3; + break; + case IMGFMT_RGB32: + case IMGFMT_BGR32: + image_bpp=32; + mga_vid_config.frame_size = awidth*src_height*4; + break; + default: + printf("vesa_lvo: invalid output format %s(%0X)\n",vo_format_name(format),format); + return -1; + } + mga_vid_config.colkey_on=0; + mga_vid_config.src_width = src_width; + mga_vid_config.src_height= src_height; + mga_vid_config.dest_width = dst_width; + mga_vid_config.dest_height= dst_height; + mga_vid_config.x_org=x_org; + mga_vid_config.y_org=y_org; + mga_vid_config.num_frames=NUM_FRAMES; + if (ioctl(lvo_handler,MGA_VID_CONFIG,&mga_vid_config)) + { + perror("Error in mga_vid_config ioctl()"); + printf("Your mga_vid driver version is incompatible with this MPlayer version!\n"); + return -1; + } + ioctl(lvo_handler,MGA_VID_ON,0); + + frames[0] = (char*)mmap(0,mga_vid_config.frame_size*mga_vid_config.num_frames,PROT_WRITE,MAP_SHARED,lvo_handler,0); + for(i=1;i<NUM_FRAMES;i++) + frames[i] = frames[i-1] + mga_vid_config.frame_size; + next_frame = 0; + lvo_mem = frames[next_frame]; + + /*clear the buffer*/ + memset(frames[0],0x80,mga_vid_config.frame_size*mga_vid_config.num_frames); + return 0; +} + +void vlvo_term( void ) +{ + ioctl( lvo_handler,MGA_VID_OFF,0 ); + munmap(frames[0],mga_vid_config.frame_size*mga_vid_config.num_frames); + if(lvo_handler != -1) close(lvo_handler); +} + +uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) +{ + uint8_t *src; + uint8_t *dest; + uint32_t bespitch,bespitch2; + int i; + + bespitch = (mga_vid_config.src_width + (WIDTH_ALIGN-1)) & ~(WIDTH_ALIGN-1); + bespitch2 = bespitch/2; + + dest = lvo_mem + bespitch * y + x; + src = image[0]; + for(i=0;i<h;i++){ + memcpy(dest,src,w); + src+=stride[0]; + dest += bespitch; + } + + w/=2;h/=2;x/=2;y/=2; + + dest = lvo_mem + bespitch*mga_vid_config.src_height + bespitch2 * y + x; + src = image[1]; + for(i=0;i<h;i++){ + memcpy(dest,src,w); + src+=stride[1]; + dest += bespitch2; + } + + dest = lvo_mem + bespitch*mga_vid_config.src_height + + bespitch*mga_vid_config.src_height / 4 + + bespitch2 * y + x; + src = image[2]; + for(i=0;i<h;i++){ + memcpy(dest,src,w); + src+=stride[2]; + dest += bespitch2; + } + +} + +uint32_t vlvo_draw_frame(uint8_t *src[]) +{ + size_t i, ssize; + uint8_t *dest; + const uint8_t *sptr; + ssize = IMAGE_LINE_SIZE((image_bpp+7)/8); + dest = lvo_mem; + sptr = src[0]; + for(i=0;i<image_height;i++) + { + memcpy(dest,sptr,ssize); + sptr += ssize; + dest += ssize; + } +} + +void vlvo_flip_page(void) +{ + ioctl(lvo_handler,MGA_VID_FSEL,&next_frame); + next_frame=(next_frame+1)%mga_vid_config.num_frames; + lvo_mem=frames[next_frame]; +} + +void vlvo_draw_osd(void) +{ + /* TODO: hw support */ +} + +uint32_t vlvo_query_info(uint32_t format) +{ + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libvo/vesa_lvo.h Tue Nov 13 17:13:33 2001 +0000 @@ -0,0 +1,26 @@ +/* + * vesa_lvo.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 contains vo_vesa interface to Linux Video Overlay. + */ + +#ifndef __VESA_LVO_INCLUDED +#define __VESA_LVO_INCLUDED + +int vlvo_init(const char *drvname,unsigned src_width,unsigned src_height, + unsigned x_org,unsigned y_org,unsigned dst_width, + unsigned dst_height,unsigned format,unsigned dest_bpp); +void vlvo_term( void ); +uint32_t vlvo_query_info(unsigned format); + +uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y); +uint32_t vlvo_draw_frame(uint8_t *src[]); +void vlvo_flip_page(void); +void vlvo_draw_osd(void); + +#endif
--- a/libvo/vo_vesa.c Tue Nov 13 17:11:26 2001 +0000 +++ b/libvo/vo_vesa.c Tue Nov 13 17:13:33 2001 +0000 @@ -96,6 +96,9 @@ 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; + #define HAS_DGA() (win.idx == -1) #define MOVIE_MODE (MODE_ATTR_COLOR | MODE_ATTR_GRAPHICS) #define FRAME_MODE (MODE_WIN_RELOCATABLE | MODE_WIN_WRITEABLE) @@ -127,6 +130,7 @@ static void vesa_term( void ) { int err; + if(lvo_name) vlvo_term(); if((err=vbeRestoreState(init_state)) != VBE_OK) PRINT_VBE_ERR("vbeRestoreState",err); if((err=vbeSetMode(init_mode,NULL)) != VBE_OK) PRINT_VBE_ERR("vbeSetMode",err); if(HAS_DGA()) vbeUnmapVideoBuffer((unsigned long)win.ptr,win.high); @@ -240,6 +244,8 @@ { if(verbose > 2) printf("vo_vesa: draw_slice was called: w=%u h=%u x=%u y=%u\n",w,h,x,y); + if(lvo_name) return vlvo_draw_slice(image,stride,w,h,x,y); + else if(vesa_zoom) { uint8_t *dst[3]= {dga_buffer, NULL, NULL}; @@ -307,21 +313,27 @@ uint32_t w,h; if(verbose > 2) printf("vo_vesa: draw_osd was called\n"); - w = HAS_DGA()?video_mode_info.XResolution:image_width; - h = HAS_DGA()?video_mode_info.YResolution:image_height; - if(dga_buffer) vo_draw_text(w,h,draw_alpha_fnc); + if(lvo_name) vlvo_draw_osd(); + else + { + w = HAS_DGA()?video_mode_info.XResolution:image_width; + h = HAS_DGA()?video_mode_info.YResolution:image_height; + if(dga_buffer) vo_draw_text(w,h,draw_alpha_fnc); + } } static void flip_page(void) { if(verbose > 2) printf("vo_vesa: flip_page was called\n"); + if(lvo_name) vlvo_flip_page(); + else if(flip_trigger) { if(!HAS_DGA()) __vbeCopyData(dga_buffer); flip_trigger = 0; } - if(vo_doublebuffering && multi_size > 1) + if(vo_doublebuffering && multi_size > 1 && !lvo_name) { int err; if((err=vbeSetDisplayStart(multi_buff[multi_idx],1)) != VBE_OK) @@ -352,6 +364,8 @@ uint8_t *data = src[0]; if(verbose > 2) printf("vo_vesa: draw_frame was called\n"); + if(lvo_name) return vlvo_draw_frame(src); + else if(rgb2rgb_fnc) { if(HAS_DGA()) @@ -379,7 +393,7 @@ if(verbose > 2) printf("vo_vesa: rgb2rgb_fnc was called\n"); } - if(!rgb2rgb_fnc || !HAS_DGA()) __vbeCopyData(data); + if((!rgb2rgb_fnc || !HAS_DGA()) && !lvo_name) __vbeCopyData(data); return 0; } @@ -487,6 +501,8 @@ if(strcmp(sd,"nodga") == 0) { flags |= SUBDEV_NODGA; flags &= ~(SUBDEV_FORCEDGA); } else if(strcmp(sd,"dga") == 0) { flags &= ~(SUBDEV_NODGA); flags |= SUBDEV_FORCEDGA; } + else + if(memcmp(sd,"lvo:",4) == 0) lvo_name = &sd[4]; /* lvo_name will be valid within init() */ else if(verbose) printf("vo_vesa: Unknown subcommand: %s\n", sd); return flags; } @@ -684,7 +700,7 @@ } scale_xinc=(width << 16) / image_width - 2; /* needed for proper rounding */ scale_yinc=(height << 16) / image_height + 2; - SwScale_Init(); + if(!lvo_name) SwScale_Init(); if(verbose) printf("vo_vesa: Using SCALE\n"); } else @@ -693,7 +709,7 @@ return -1; } } - if(format != IMGFMT_YV12 && image_bpp != video_mode_info.BitsPerPixel) + if(format != IMGFMT_YV12 && image_bpp != video_mode_info.BitsPerPixel && !lvo_name) { if(image_bpp == 24 && video_mode_info.BitsPerPixel == 32) rgb2rgb_fnc = rgb24to32; else @@ -789,7 +805,7 @@ else { cpy_blk_fnc = __vbeCopyBlock; - if(yuv_fmt || rgb2rgb_fnc) + if((yuv_fmt || rgb2rgb_fnc) && !lvo_name) { if(!(dga_buffer = memalign(64,video_mode_info.XResolution*video_mode_info.YResolution*video_mode_info.BitsPerPixel))) { @@ -816,6 +832,16 @@ printf("vo_vesa: Graphics mode was activated\n"); fflush(stdout); } + if(lvo_name) + { + if(vlvo_init(lvo_name,width,height,x_offset,y_offset,image_width,image_height,format,video_mode_info.BitsPerPixel) != 0) + { + printf("vo_vesa: Can't initialize Linux Video Overlay\n"); + vesa_term(); + return -1; + } + else printf("vo_vesa: Using video overlay: %s\n",lvo_name); + } } else {