From d34041569e71fc9bd772354e94dc9d16061072a5 Mon Sep 17 00:00:00 2001 From: arpi_esp Date: Sat, 24 Feb 2001 20:28:24 +0000 Subject: Initial revision git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/vo_syncfb.c | 446 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 446 insertions(+) create mode 100644 libvo/vo_syncfb.c (limited to 'libvo/vo_syncfb.c') diff --git a/libvo/vo_syncfb.c b/libvo/vo_syncfb.c new file mode 100644 index 0000000000..d705fb1725 --- /dev/null +++ b/libvo/vo_syncfb.c @@ -0,0 +1,446 @@ + +// How many MegaBytes of RAM is on your G200/G400 card? +#define RAM_SIZE 16 + +/* + * video_out_syncfb.c + * + * Copyright (C) Aaron Holtzman - Aug 1999 + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec 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, or (at your option) + * any later version. + * + * mpeg2dec 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +LIBVO_EXTERN(syncfb) + +#include +#include +#include +#include +#include + +#include "drivers/syncfb/syncfb.h" + +static vo_info_t vo_info = +{ + "Matrox G200/G400 Synchronous framebuffer (/dev/syncfb)", + "syncfb", + "Matthias Oelmann ", + "" +}; + +/* deinterlacing on? looks only good in 50 Hz(PAL) or 60 Hz(NTSC) modes */ +static int vo_conf_deinterlace = 0; + +/* 72/75 Hz Monitor frequency for progressive output */ +static int vo_conf_cinemode = 0; + + +static syncfb_config_t config; +static syncfb_capability_t sfb_caps; + +static syncfb_buffer_info_t bufinfo; + +static uint_8 *vid_data; +static uint_8 *frame_mem; + +static int debug_skip_first = 250; +static int dbg_singleframe = 0; + +static int conf_palette; + +static int f; + + + +/* + it seems that mpeg2dec never calls + draw_frame, so i could not test it.... +*/ + +static void +write_frame_YUV422(uint_8 *y,uint_8 *cr, uint_8 *cb) +{ + uint_8 *crp, *cbp; + uint_32 *dest32; + uint_32 bespitch,h,w; + + + bespitch = config.src_pitch; + dest32 = (uint_32 *)vid_data; + + for(h=0; h < config.src_height/2; h++) + { + cbp = cb; + crp = cr; + for(w=0; w < config.src_width/2; w++) + { + *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); + y++; y++; cb++; cr++; + } + dest32 += (bespitch - config.src_width) / 2; + + for(w=0; w < config.src_width/2; w++) + { + *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); + y++; y++; cbp++; crp++; + } + dest32 += (bespitch - config.src_width) / 2; + } +} + + +static void +write_frame_YUV420P2(uint_8 *y,uint_8 *cr, uint_8 *cb) +{ + uint_8 *dest, *tmp; + uint_32 bespitch,h,w; + + bespitch = config.src_pitch; + dest = frame_mem + bufinfo.offset; + + for(h=0; h < config.src_height; h++) + { + memcpy(dest, y, config.src_width); + y += config.src_width; + dest += bespitch; + } + + dest = frame_mem + bufinfo.offset_p2; + for(h=0; h < config.src_height/2; h++) + { + tmp = dest; + for(w=0; w < config.src_width/2; w++) + { + *tmp++ = *cr++; + *tmp++ = *cb++; + } + dest += bespitch; + } +} + +static void +write_frame_YUV420P3(uint_8 *y,uint_8 *cr, uint_8 *cb) +{ +} + +static void +write_slice_YUV420P2(uint_8 *y,uint_8 *cr, uint_8 *cb,uint_32 slice_num) +{ + uint_8 *dest, *tmp; + uint_32 bespitch,h,w; + + bespitch = config.src_pitch; + dest = frame_mem + bufinfo.offset + (bespitch * 16 * slice_num); + + for(h=0; h < 16; h++) + { + memcpy(dest, y, config.src_width); + y += config.src_width; + dest += bespitch; + } + + dest = frame_mem + bufinfo.offset_p2 + (bespitch * 16 * slice_num) /2; + for(h=0; h < 8; h++) + { + tmp = dest; + for(w=0; w < config.src_width/2; w++) + { + *tmp++ = *cr++; + *tmp++ = *cb++; + } + dest += bespitch; + } +} + +static void +write_slice_YUV420P3(uint_8 *y,uint_8 *cr, uint_8 *cb,int stride[],uint_32 ypos,uint_32 xsize,uint_32 ysize) +{ + uint_8 *dest; + uint_32 bespitch,h; + + bespitch = config.src_pitch; + + dest = frame_mem + bufinfo.offset + (bespitch * ypos); + for(h=0; h < ysize; h++) + { + memcpy(dest, y, xsize); + y += stride[0]; + dest += bespitch; + } + + xsize/=2; + ysize/=2; + + dest = frame_mem + bufinfo.offset_p2 + (bespitch * ypos)/4; + for(h=0; h < ysize; h++) + { + memcpy(dest, cr, xsize); + cr += stride[1]; + dest += bespitch/2; + } + + dest = frame_mem + bufinfo.offset_p3 + (bespitch * ypos)/4; + for(h=0; h < ysize; h++) + { + memcpy(dest, cb, xsize); + cb += stride[2]; + dest += bespitch/2; + } + + +} + + +static void +write_slice_YUV422(uint_8 *y,uint_8 *cr, uint_8 *cb,uint_32 slice_num) +{ + uint_8 *crp, *cbp; + uint_32 *dest32; + uint_32 bespitch,h,w; + + + bespitch = config.src_pitch; + dest32 = (uint_32 *)(vid_data + (bespitch * 16 * slice_num) * 2); + + for(h=0; h < 8; h++) + { + cbp = cb; + crp = cr; + for(w=0; w < config.src_width/2; w++) + { + *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); + y++; y++; cb++; cr++; + } + dest32 += (bespitch - config.src_width) / 2; + + for(w=0; w < config.src_width/2; w++) + { + *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); + y++; y++; cbp++; crp++; + } + dest32 += (bespitch - config.src_width) / 2; + } +} + +//static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num) +static uint32_t +draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y) +{ + + if ( vid_data == NULL ) return 0; + + write_slice_YUV420P3(src[0],src[1], src[2],stride,y,w,h); + + //printf("sorry, not syncfb/draw_slice() implemented yet...\n"); + +#if 0 + + if ( conf_palette == VIDEO_PALETTE_YUV422 ) { + write_slice_YUV422(src[0],src[1], src[2],slice_num); + } else if ( conf_palette == VIDEO_PALETTE_YUV420P2 ) { + write_slice_YUV420P2(src[0],src[1], src[2],slice_num); + } else if ( conf_palette == VIDEO_PALETTE_YUV420P3 ) { + write_slice_YUV420P3(src[0],src[1], src[2],slice_num); + } +#endif + + return 0; +} + + + + +static void +flip_page(void) +{ + +// memset(frame_mem + bufinfo.offset_p2, 0x80, config.src_width*config.src_height); + ioctl(f,SYNCFB_COMMIT_BUFFER,&bufinfo); + + if ( dbg_singleframe ) { + if ( debug_skip_first == 0 ) { + printf( "Press 'anykey' for field 1\n" ); + getchar(); + ioctl(f,SYNCFB_VBI,0); + } + + if ( debug_skip_first > 0 ) { + debug_skip_first--; + // debug_skip_first = 0; + if ( debug_skip_first == 0 ) { + ioctl(f,SYNCFB_VBI,0); + ioctl(f,SYNCFB_VBI,0); + ioctl(f,SYNCFB_VBI,0); + } + } + + if ( debug_skip_first == 0 ) { + printf( "Press 'anykey' for field 2\n" ); + getchar(); + ioctl(f,SYNCFB_VBI,0); + } + } + + ioctl(f,SYNCFB_REQUEST_BUFFER,&bufinfo); + if ( bufinfo.id == -1 ) printf( "Got buffer #%d\n", bufinfo.id ); + + vid_data = (uint_8 *)(frame_mem + bufinfo.offset); + if ( bufinfo.id == -1 ) { + //vid_data = frame_mem; + vid_data = NULL; + } +// printf("Flip %d\n", bufinfo.offset); + +} + +static uint32_t draw_frame(uint8_t *src[]) +{ + printf("DRAW FRAME!!!\n"); + if ( conf_palette == VIDEO_PALETTE_YUV422 ) { + write_frame_YUV422(src[0],src[1], src[2]); + } else if ( conf_palette == VIDEO_PALETTE_YUV420P2 ) { + write_frame_YUV420P2(src[0],src[1], src[2]); + } else if ( conf_palette == VIDEO_PALETTE_YUV420P3 ) { + write_frame_YUV420P3(src[0],src[1], src[2]); + } + + flip_page(); + return 0; +} + +static uint32_t +query_format(uint32_t format) +{ + switch(format){ + case IMGFMT_YV12: +// case IMGFMT_RGB|24: +// case IMGFMT_BGR|24: + return 1; + } + return 0; +} + +static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format) +{ + uint_32 frame_size; + + f = open("/dev/syncfb",O_RDWR); + + if(f == -1) + { + f = open("/dev/mga_vid",O_RDWR); + if(f == -1) + { + fprintf(stderr,"Couldn't open /dev/syncfb or /dev/mga_vid\n"); + return(-1); + } + } + + if (ioctl(f,SYNCFB_GET_CAPS,&sfb_caps)) perror("Error in mga_vid_config ioctl"); + if (ioctl(f,SYNCFB_GET_CONFIG,&config)) perror("Error in mga_vid_config ioctl"); + + if (sfb_caps.palettes & (1<