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/Attic/SHIT/video_out_gl.c.V3-sux | 538 ++++++++++++++++++++++++ libvo/Attic/SHIT/video_out_gl.c.diff | 64 +++ libvo/Attic/SHIT/video_out_odivx.c.OLD | 183 +++++++++ libvo/Attic/SHIT/video_out_sdl.c-1.1.4 | 574 ++++++++++++++++++++++++++ libvo/Attic/SHIT/video_out_x11.c.OLD | 518 +++++++++++++++++++++++ libvo/Attic/SHIT/video_out_x11.c.thread | 466 +++++++++++++++++++++ libvo/Makefile | 37 ++ libvo/config.mak | 6 + libvo/mga_common.c | 220 ++++++++++ libvo/mmx.h | 706 ++++++++++++++++++++++++++++++++ libvo/rgb15to16mmx.c | 42 ++ libvo/video_out.c | 201 +++++++++ libvo/video_out.h | 195 +++++++++ libvo/video_out_internal.h | 43 ++ libvo/vo_3dfx.c | 478 +++++++++++++++++++++ libvo/vo_gl.c | 515 +++++++++++++++++++++++ libvo/vo_md5.c | 106 +++++ libvo/vo_mga.c | 127 ++++++ libvo/vo_null.c | 85 ++++ libvo/vo_odivx.c | 234 +++++++++++ libvo/vo_pgm.c | 115 ++++++ libvo/vo_sdl.c | 607 +++++++++++++++++++++++++++ libvo/vo_syncfb.c | 446 ++++++++++++++++++++ libvo/vo_syncfb.c.OLD | 434 ++++++++++++++++++++ libvo/vo_x11.c | 476 +++++++++++++++++++++ libvo/vo_xmga.c | 319 +++++++++++++++ libvo/vo_xv.c | 457 +++++++++++++++++++++ libvo/wskeys.h | 103 +++++ libvo/yuv2rgb.c | 414 +++++++++++++++++++ libvo/yuv2rgb.h | 43 ++ libvo/yuv2rgb_mlib.c | 87 ++++ libvo/yuv2rgb_mmx.c | 419 +++++++++++++++++++ 32 files changed, 9258 insertions(+) create mode 100644 libvo/Attic/SHIT/video_out_gl.c.V3-sux create mode 100644 libvo/Attic/SHIT/video_out_gl.c.diff create mode 100644 libvo/Attic/SHIT/video_out_odivx.c.OLD create mode 100644 libvo/Attic/SHIT/video_out_sdl.c-1.1.4 create mode 100644 libvo/Attic/SHIT/video_out_x11.c.OLD create mode 100644 libvo/Attic/SHIT/video_out_x11.c.thread create mode 100644 libvo/Makefile create mode 100644 libvo/config.mak create mode 100644 libvo/mga_common.c create mode 100644 libvo/mmx.h create mode 100644 libvo/rgb15to16mmx.c create mode 100644 libvo/video_out.c create mode 100644 libvo/video_out.h create mode 100644 libvo/video_out_internal.h create mode 100644 libvo/vo_3dfx.c create mode 100644 libvo/vo_gl.c create mode 100644 libvo/vo_md5.c create mode 100644 libvo/vo_mga.c create mode 100644 libvo/vo_null.c create mode 100644 libvo/vo_odivx.c create mode 100644 libvo/vo_pgm.c create mode 100644 libvo/vo_sdl.c create mode 100644 libvo/vo_syncfb.c create mode 100644 libvo/vo_syncfb.c.OLD create mode 100644 libvo/vo_x11.c create mode 100644 libvo/vo_xmga.c create mode 100644 libvo/vo_xv.c create mode 100644 libvo/wskeys.h create mode 100644 libvo/yuv2rgb.c create mode 100644 libvo/yuv2rgb.h create mode 100644 libvo/yuv2rgb_mlib.c create mode 100644 libvo/yuv2rgb_mmx.c (limited to 'libvo') diff --git a/libvo/Attic/SHIT/video_out_gl.c.V3-sux b/libvo/Attic/SHIT/video_out_gl.c.V3-sux new file mode 100644 index 0000000000..459995d9d4 --- /dev/null +++ b/libvo/Attic/SHIT/video_out_gl.c.V3-sux @@ -0,0 +1,538 @@ +#define DISP + +// this can be 3 or 4 (regarding 24bpp and 32bpp) +#define BYTES_PP 3 + +#define TEXTUREFORMAT_32BPP + +// Hmm. Enabling this makes about 20% speedup too! (Celeron2+G400+UtahGLX) +//#define TEXSUBIMAGE_BUG_WORKAROUND + +/* + * video_out_gl.c, X11/OpenGL interface + * based on video_out_x11 by Aaron Holtzman, + * and WS opengl window manager by Pontscho/Fresh! + */ + +#include +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + + +LIBVO_EXTERN(gl) + +#include +#include +//#include +#include +#include +#include "yuv2rgb.h" + +#include + +static vo_info_t vo_info = +{ + "X11 (OpenGL)", + "gl", + "Arpad Gereoffy ", + "" +}; + +/* private prototypes */ +static void Display_Image (unsigned char *ImageData); + +/* local data */ +static unsigned char *ImageData=NULL; + +/* X11 related variables */ +static Display *mydisplay; +static Window mywindow; +//static GC mygc; +//static XImage *myximage; +//static int depth,mode; +static XWindowAttributes attribs; +static int X_already_started = 0; + +static int texture_id=1; + +static GLXContext wsGLXContext; +//XVisualInfo * wsVisualInfo; +int wsGLXAttrib[] = { GLX_RGBA, + GLX_RED_SIZE,1, + GLX_GREEN_SIZE,1, + GLX_BLUE_SIZE,1, +// GLX_DEPTH_SIZE,16, + GLX_DOUBLEBUFFER, + None }; + + +static uint32_t image_width; +static uint32_t image_height; +static uint32_t image_format; +static uint32_t image_bpp; +static uint32_t image_bytes; + +static uint32_t texture_width; +static uint32_t texture_height; + +static resize(int x,int y){ + printf("Resize: %dx%d\n",x,y); + glViewport( 0, 0, x, y ); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, image_width, image_height, 0, -1,1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +/* connect to server, create and map window, + * allocate colors and (shared) memory + */ +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) +{ + int screen; + unsigned int fg, bg; + char *hello = (title == NULL) ? "OpenGL rulez" : title; + char *name = ":0.0"; + XSizeHints hint; + XVisualInfo *vinfo; + XEvent xev; + + XGCValues xgcv; + XSetWindowAttributes xswa; + unsigned long xswamask; + + image_height = height; + image_width = width; + image_format = format; + + if (X_already_started) return -1; + + if(getenv("DISPLAY")) name = getenv("DISPLAY"); + + mydisplay = XOpenDisplay(name); + + if (mydisplay == NULL) + { + fprintf(stderr,"Can not open display\n"); + return -1; + } + + screen = DefaultScreen(mydisplay); + + hint.x = 0; + hint.y = 0; + hint.width = d_width; + hint.height = d_height; + hint.flags = PPosition | PSize; + + /* Get some colors */ + + bg = WhitePixel(mydisplay, screen); + fg = BlackPixel(mydisplay, screen); + + /* Make the window */ + + XGetWindowAttributes(mydisplay, DefaultRootWindow(mydisplay), &attribs); + +#if 0 + /* + * + * depth in X11 terminology land is the number of bits used to + * actually represent the colour. + * + * bpp in X11 land means how many bits in the frame buffer per + * pixel. + * + * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit + * color is 24 bit depth, but can be 24 bpp or 32 bpp. + */ + + depth = attribs.depth; + + if (depth != 15 && depth != 16 && depth != 24 && depth != 32) + { + /* The root window may be 8bit but there might still be + * visuals with other bit depths. For example this is the + * case on Sun/Solaris machines. + */ + depth = 24; + } + //BEGIN HACK + //mywindow = XCreateSimpleWindow(mydisplay, DefaultRootWindow(mydisplay), + //hint.x, hint.y, hint.width, hint.height, 4, fg, bg); + // +#endif + +// XMatchVisualInfo(mydisplay, screen, depth, TrueColor, &vinfo); + vinfo=glXChooseVisual( mydisplay,screen,wsGLXAttrib ); + + xswa.background_pixel = 0; + xswa.border_pixel = 1; +// xswa.colormap = XCreateColormap(mydisplay, RootWindow(mydisplay,screen), vinfo.visual, AllocNone); + xswa.colormap = XCreateColormap(mydisplay, RootWindow(mydisplay,screen), vinfo->visual, AllocNone); + xswamask = CWBackPixel | CWBorderPixel | CWColormap; +// xswamask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect | CWSaveUnder | CWX | CWY | CWWidth | CWHeight; + + mywindow = XCreateWindow(mydisplay, RootWindow(mydisplay,screen), + hint.x, hint.y, hint.width, hint.height, 4, vinfo->depth,CopyFromParent,vinfo->visual,xswamask,&xswa); + + wsGLXContext=glXCreateContext( mydisplay,vinfo,NULL,True ); +// XStoreName( wsDisplay,wsMyWin,wsSysName ); + + printf("GLXcontect ok\n"); + + XSelectInput(mydisplay, mywindow, StructureNotifyMask); + + /* Tell other applications about this window */ + + XSetStandardProperties(mydisplay, mywindow, hello, hello, None, NULL, 0, &hint); + + /* Map window. */ + + XMapWindow(mydisplay, mywindow); + + /* Wait for map. */ + do + { + XNextEvent(mydisplay, &xev); + } + while (xev.type != MapNotify || xev.xmap.event != mywindow); + + XSelectInput(mydisplay, mywindow, NoEventMask); + + glXMakeCurrent( mydisplay,mywindow,wsGLXContext ); + + XFlush(mydisplay); + XSync(mydisplay, False); + +// mygc = XCreateGC(mydisplay, mywindow, 0L, &xgcv); + +// myximage = XGetImage(mydisplay, mywindow, 0, 0, +// width, image_height, AllPlanes, ZPixmap); +// ImageData = myximage->data; +// bpp = myximage->bits_per_pixel; + + XSelectInput(mydisplay, mywindow, StructureNotifyMask); // !!!! + + printf("Window setup ok\n"); + +#if 0 + // If we have blue in the lowest bit then obviously RGB + mode = ((myximage->blue_mask & 0x01) != 0) ? MODE_RGB : MODE_BGR; +#ifdef WORDS_BIGENDIAN + if (myximage->byte_order != MSBFirst) +#else + if (myximage->byte_order != LSBFirst) +#endif + { + fprintf( stderr, "No support fon non-native XImage byte order!\n" ); + return -1; + } + + printf("DEPTH=%d BPP=%d\n",depth,bpp); +#endif + + /* + * If depth is 24 then it may either be a 3 or 4 byte per pixel + * format. We can't use bpp because then we would lose the + * distinction between 15/16bit depth (2 byte formate assumed). + * + * FIXME - change yuv2rgb_init to take both depth and bpp + * parameters + */ + + texture_width=32; + while(texture_width256)texture_width=256; // voodoo3 hack + texture_height=texture_width; + + if(format==IMGFMT_YV12){ + yuv2rgb_init(8*BYTES_PP, MODE_RGB); + printf("YUV init OK!\n"); + image_bpp=8*BYTES_PP; + image_bytes=BYTES_PP; + } else { + image_bpp=format&0xFF; + image_bytes=(image_bpp+7)/8; + } + + ImageData=malloc(texture_width*texture_height*image_bytes); + memset(ImageData,128,texture_width*texture_height*image_bytes); + + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_CULL_FACE); + + printf("Creating %dx%d texture...\n",texture_width,texture_height); + +#if 1 +// glBindTexture(GL_TEXTURE_2D, texture_id); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); +#ifdef TEXTUREFORMAT_32BPP + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture_width, texture_height, 0, +#else + glTexImage2D(GL_TEXTURE_2D, 0, BYTES_PP, texture_width, texture_height, 0, +#endif + (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, ImageData); +#endif + + resize(d_width,d_height); + + glClearColor( 1.0f,1.0f,1.0f,0.0f ); + glClear( GL_COLOR_BUFFER_BIT ); + + printf("OpenGL setup OK!\n"); + + X_already_started++; + return 0; +} + +static const vo_info_t* +get_info(void) +{ + return &vo_info; +} + +static void +Terminate_Display_Process(void) +{ + getchar(); /* wait for enter to remove window */ + XDestroyWindow(mydisplay, mywindow); + XCloseDisplay(mydisplay); + X_already_started = 0; +} + +static void +FlipImage() +{ +// XPutImage(mydisplay, mywindow, mygc, myximage, 0, 0, 0, 0, myximage->width, myximage->height); +// XFlush(mydisplay); +int i; +XEvent wsEvent; +XEvent xev; + + while ( XPending( mydisplay ) ) { + XNextEvent( mydisplay,&wsEvent ); + switch( wsEvent.type ) { +// case Expose: if ( wsReDraw ) wsReDraw( wsDisplay,wsEvent.xany.window ); break; + case ConfigureNotify: //wsWindowWidth=wsEvent.xconfigure.width; + //wsWindowHeight=wsEvent.xconfigure.height; +#if 0 + XUnmapWindow( mydisplay,mywindow ); + XMapWindow( mydisplay,mywindow ); + /* Wait for map. */ + do { XNextEvent(mydisplay, &xev);} + while (xev.type != MapNotify || xev.xmap.event != mywindow); +#endif + resize( wsEvent.xconfigure.width, wsEvent.xconfigure.height ); + break; + } + } + + glEnable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, texture_id); + + glColor3f(1,1,1); + glBegin(GL_QUADS); + glTexCoord2f(0,0);glVertex2i(0,0); + glTexCoord2f(0,1);glVertex2i(0,texture_height); + glTexCoord2f(1,1);glVertex2i(texture_width,texture_height); + glTexCoord2f(1,0);glVertex2i(texture_width,0); + glEnd(); + +// glFlush(); + glFinish(); + glXSwapBuffers( mydisplay,mywindow ); + +} + +static inline void +flip_page_x11(void) +{ +// Display_Image(myximage, ImageData); +// Display_Image(ImageData); + FlipImage(); +} + + +static void +flip_page(void) +{ + return flip_page_x11(); +} + +static inline uint32_t +draw_slice_x11(uint8_t *src[], uint32_t slice_num) +{ + uint8_t *dst; + int i; + + dst = ImageData;// + image_width * 16 * BYTES_PP * slice_num; + + yuv2rgb(dst , src[0], src[1], src[2], + image_width, 16, + image_width*BYTES_PP, image_width, image_width/2 ); + +// emms (); + +#ifdef TEXSUBIMAGE_BUG_WORKAROUND + for(i=0;i<16;i++){ + glTexSubImage2D( GL_TEXTURE_2D, // target + 0, // level + 0, // x offset + 16*slice_num+i, // y offset + image_width, // width + 1, // height + (BYTES_PP==4)?GL_RGBA:GL_RGB, // format + GL_UNSIGNED_BYTE, // type + ImageData+i*BYTES_PP*image_width ); // *pixels + } +#else +//printf("uploading slice \n"); + glTexSubImage2D( GL_TEXTURE_2D, // target + 0, // level + 0, // x offset + 16*slice_num, // y offset + image_width, // width + 16, // height + (BYTES_PP==4)?GL_RGBA:GL_RGB, // format + GL_UNSIGNED_BYTE, // type + ImageData ); // *pixels +#endif + + return 0; +} + +static uint32_t +draw_slice(uint8_t *src[], uint32_t slice_num) +{ + return draw_slice_x11(src,slice_num); +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +static inline uint32_t +draw_frame_x11_yv12(uint8_t *src[]) +{ +int i; +// printf("Converting YUV->RGB...\n"); + yuv2rgb(ImageData, src[0], src[1], src[2], + image_width, image_height, + image_width*BYTES_PP, image_width, image_width/2 ); +// printf("Ready!\n"); + +// emms (); + +// for(i=0;i //static inline uint32_t draw_slice_x11(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) +372,375c369,372 +< uint8_t *dst; +< int i; +< +< dst = ImageData;// + image_width * 16 * BYTES_PP * slice_num; +--- +> int i; +> int dstride=w*BYTES_PP; +> +> dstride=(dstride+15)&(~15); +377,379c374,375 +< yuv2rgb(dst , src[0], src[1], src[2], +< image_width, 16, +< image_width*BYTES_PP, image_width, image_width/2 ); +--- +> yuv2rgb(ImageData, src[0], src[1], src[2], +> w,h, dstride, stride[0],stride[1]); +383,384c379 +< #ifdef TEXSUBIMAGE_BUG_WORKAROUND +< for(i=0;i<16;i++){ +--- +> for(i=0;i x, // x offset +> y+i, // y offset +> w, // width +393c388 +< ImageData+i*BYTES_PP*image_width ); // *pixels +--- +> ImageData+i*dstride ); // *pixels +395,406d389 +< #else +< //printf("uploading slice \n"); +< glTexSubImage2D( GL_TEXTURE_2D, // target +< 0, // level +< 0, // x offset +< 16*slice_num, // y offset +< image_width, // width +< 16, // height +< (BYTES_PP==4)?GL_RGBA:GL_RGB, // format +< GL_UNSIGNED_BYTE, // type +< ImageData ); // *pixels +< #endif +409,414d391 +< } +< +< static uint32_t +< draw_slice(uint8_t *src[], uint32_t slice_num) +< { +< return draw_slice_x11(src,slice_num); diff --git a/libvo/Attic/SHIT/video_out_odivx.c.OLD b/libvo/Attic/SHIT/video_out_odivx.c.OLD new file mode 100644 index 0000000000..83f3fe2e61 --- /dev/null +++ b/libvo/Attic/SHIT/video_out_odivx.c.OLD @@ -0,0 +1,183 @@ +/* + * OpenDivX AVI file writer + */ + +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +LIBVO_EXTERN(odivx) + +#include +#include +#include +#include + +#include "../encore/encore.h" + +static vo_info_t vo_info = +{ + "OpenDivX AVI File writer", + "odivx", + "Arpad Gereoffy ", + "" +}; + +static uint8_t *image=NULL; +static int image_width=0; +static int image_height=0; +static char *buffer=NULL; +static int frameno=0; + +extern char* encode_name; +extern char* encode_index_name; + +static uint32_t +draw_slice(uint8_t *src[], uint32_t slice_num) +{ + uint8_t *d; + + // copy Y + d=image; + memcpy(d+(slice_num<<4)*image_width,src[0],image_width*16); + // copy U + d+=image_width*image_height; + memcpy(d+(slice_num<<2)*image_width,src[1],image_width*4); + // copy V + d+=image_width*image_height/4; + memcpy(d+(slice_num<<2)*image_width,src[2],image_width*4); + + return 0; +} + +static uint32_t +draw_frame(uint8_t *src[]) +{ + uint8_t *d; + + // copy Y + d=image; + memcpy(d,src[0],image_width*image_height); + // copy U + d+=image_width*image_height; + memcpy(d,src[1],image_width*image_height/4); + // copy V + d+=image_width*image_height/4; + memcpy(d,src[2],image_width*image_height/4); + + return 0; +} + +typedef unsigned int DWORD; + +typedef struct +{ + DWORD ckid; + DWORD dwFlags; + DWORD dwChunkOffset; // Position of chunk + DWORD dwChunkLength; // Length of chunk +} AVIINDEXENTRY; + +static void +flip_page(void) +{ + +// we are rady to encode this frame +ENC_FRAME enc_frame; +ENC_RESULT enc_result; + +if(++frameno<10) return; + +enc_frame.bmp=image; +enc_frame.bitstream=buffer; +enc_frame.length=0; +encore(0x123,0,&enc_frame,&enc_result); + +printf("coded length: %d \n",enc_frame.length); + +if(encode_name){ + AVIINDEXENTRY i; + FILE *file; + i.ckid=('c'<<24)|('d'<<16)|('0'<<8)|'0'; // "00dc" + i.dwFlags=enc_result.isKeyFrame?0x10:0; + i.dwChunkLength=enc_frame.length; + // Write AVI chunk: + if((file=fopen(encode_name,"ab"))){ + unsigned char zerobyte=0; + i.dwChunkOffset=ftell(file); + fwrite(&i.ckid,4,1,file); + fwrite(&enc_frame.length,4,1,file); + fwrite(buffer,enc_frame.length,1,file); + if(enc_frame.length&1) fwrite(&zerobyte,1,1,file); // padding + fclose(file); + } + // Write AVI index: + if(encode_index_name && (file=fopen(encode_index_name,"ab"))){ + fwrite(&i,sizeof(i),1,file); + fclose(file); + } +} + + +} + +static uint32_t +query_format(uint32_t format) +{ + switch(format){ + case IMGFMT_YV12: +// case IMGFMT_YUY2: +// 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) +{ + uint32_t frame_size; + ENC_PARAM enc_param; + + buffer=malloc(0x100000); + if(!buffer) return -1; + +// file = fopen("encoded.odvx","wb"); +// if(!file) return -1; + + frame_size=width*height+width*height/2; + image_width=width; + image_height=height; + image=malloc(frame_size); + + //clear the buffer + memset(image,0x80,frame_size); + +// encoding parameters: +enc_param.framerate=25.0; +enc_param.bitrate=400000; //780000; +enc_param.rc_period=300; +enc_param.max_quantizer=15; +enc_param.min_quantizer=1; +enc_param.search_range=128; + +// init codec: +enc_param.x_dim=width; +enc_param.y_dim=height; +enc_param.flip=2; // 0=RGB 1=flippedRGB 2=planarYUV format +encore(0x123,ENC_OPT_INIT,&enc_param,NULL); + + return 0; +} + +static const vo_info_t* +get_info(void) +{ + return &vo_info; +} + diff --git a/libvo/Attic/SHIT/video_out_sdl.c-1.1.4 b/libvo/Attic/SHIT/video_out_sdl.c-1.1.4 new file mode 100644 index 0000000000..a0f307beba --- /dev/null +++ b/libvo/Attic/SHIT/video_out_sdl.c-1.1.4 @@ -0,0 +1,574 @@ +/* + * video_out_sdl.c + * + * Copyright (C) Ryan C. Gordon - April 22, 2000. + * + * A mpeg2dec display driver that does output through the + * Simple DirectMedia Layer (SDL) library. This effectively gives us all + * sorts of output options: X11, SVGAlib, fbcon, AAlib, GGI. Win32, MacOS + * and BeOS support, too. Yay. SDL info, source, and binaries can be found + * at http://slouken.devolution.com/SDL/ + * + * 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, + * + * Changes: + * Dominik Schnitzer - November 08, 2000. + * - Added resizing support, fullscreen: chnaged the sdlmodes selection + * routine. + * - SDL bugfixes: removed the atexit(SLD_Quit), SDL_Quit now resides in + * the plugin_exit routine. + * - Commented the source :) + * - Shortcuts: for switching between Fullscreen/Windowed mode and for + * cycling between the different Fullscreen modes. + * - Small bugfixes: proper width/height of movie + * Dominik Schnitzer - November 11, 2000. + * - Cleanup code, more comments + * - Better error handling + * Bruno Barreyra - December 10, 2000. + * - Eliminated memcpy's for entire frames + * Arpad Gereoffy - Jan 13, 2001. + * - Ported to MPlayer + * - small changes about keys and fullscreen mode + * Jeffrey Boser - Jan 16, 2001. + * - type casting fixes, clip rect fix + */ + +#include +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +LIBVO_EXTERN(sdl) + +//#include "log.h" +//#define LOG if(0)printf + +static vo_info_t vo_info = +{ + "SDL YUV overlay", + "sdl", + "Ryan C. Gordon ", + "" +}; + +#include + +/** Private SDL Data structure **/ + +static struct sdl_priv_s { + + /* SDL YUV surface & overlay */ + SDL_Surface *surface; + SDL_Overlay *overlay; +// SDL_Overlay *current_frame; + + /* available fullscreen modes */ + SDL_Rect **fullmodes; + + /* surface attributes for fullscreen and windowed mode */ + Uint32 sdlflags, sdlfullflags; + + /* save the windowed output extents */ + SDL_Rect windowsize; + + /* Bits per Pixel */ + Uint8 bpp; + + /* current fullscreen mode, 0 = highest available fullscreen mode */ + int fullmode; + + /* YUV ints */ + int framePlaneY, framePlaneUV; + int slicePlaneY, slicePlaneUV; + int width,height; + int format; +} sdl_priv; + + +/** OMS Plugin functions **/ + + +/** + * Take a null-terminated array of pointers, and find the last element. + * + * params : array == array of which we want to find the last element. + * returns : index of last NON-NULL element. + **/ + +static inline int findArrayEnd (SDL_Rect **array) +{ + int i = 0; + while ( array[i++] ); /* keep loopin' ... */ + + /* return the index of the last array element */ + return i - 1; +} + + +/** + * Open and prepare SDL output. + * + * params : *plugin == + * *name == + * returns : 0 on success, -1 on failure + **/ + +static int sdl_open (void *plugin, void *name) +{ + struct sdl_priv_s *priv = &sdl_priv; + const SDL_VideoInfo *vidInfo = NULL; + static int opened = 0; + + if (opened) + return 0; + opened = 1; + +// LOG (LOG_DEBUG, "SDL video out: Opened Plugin"); + + /* default to no fullscreen mode, we'll set this as soon we have the avail. mdoes */ + priv->fullmode = -2; + /* other default values */ + priv->sdlflags = SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT; + priv->sdlfullflags = SDL_HWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF|SDL_ASYNCBLIT; + priv->surface = NULL; + priv->overlay = NULL; + priv->fullmodes = NULL; + + /* initialize the SDL Video system */ + if (SDL_Init (SDL_INIT_VIDEO)) { +// LOG (LOG_ERROR, "SDL video out: Initializing of SDL failed (SDL_Init). Please use the latest version of SDL."); + return -1; + } + + /* No Keyrepeats! */ + SDL_EnableKeyRepeat(0,0); + + /* get information about the graphics adapter */ + vidInfo = SDL_GetVideoInfo (); + + /* collect all fullscreen & hardware modes available */ + if (!(priv->fullmodes = SDL_ListModes (vidInfo->vfmt, priv->sdlfullflags))) { + + /* non hardware accelerated fullscreen modes */ + priv->sdlfullflags &= ~SDL_HWSURFACE; + priv->fullmodes = SDL_ListModes (vidInfo->vfmt, priv->sdlfullflags); + } + + /* test for normal resizeable & windowed hardware accellerated surfaces */ + if (!SDL_ListModes (vidInfo->vfmt, priv->sdlflags)) { + + /* test for NON hardware accelerated resizeable surfaces - poor you. + * That's all we have. If this fails there's nothing left. + * Theoretically there could be Fullscreenmodes left - we ignore this for now. + */ + priv->sdlflags &= ~SDL_HWSURFACE; + if ((!SDL_ListModes (vidInfo->vfmt, priv->sdlflags)) && (!priv->fullmodes)) { +// LOG (LOG_ERROR, "SDL video out: Couldn't get any acceptable SDL Mode for output. (SDL_ListModes failed)"); + return -1; + } + } + + + /* YUV overlays need at least 16-bit color depth, but the + * display might less. The SDL AAlib target says it can only do + * 8-bits, for example. So, if the display is less than 16-bits, + * we'll force the BPP to 16, and pray that SDL can emulate for us. + */ + priv->bpp = vidInfo->vfmt->BitsPerPixel; + if (priv->bpp < 16) { +/* + LOG (LOG_WARNING, "SDL video out: Your SDL display target wants to be at a color depth of (%d), but we need it to be at\ +least 16 bits, so we need to emulate 16-bit color. This is going to slow things down; you might want to\ +increase your display's color depth, if possible", priv->bpp); +*/ + priv->bpp = 16; + } + + /* We dont want those in out event queue */ + SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); + SDL_EventState(SDL_KEYUP, SDL_IGNORE); + SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); + SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE); + SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE); + SDL_EventState(SDL_QUIT, SDL_IGNORE); + SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); + SDL_EventState(SDL_USEREVENT, SDL_IGNORE); + + /* Success! */ + return 0; +} + + +/** + * Close SDL, Cleanups, Free Memory + * + * params : *plugin + * returns : non-zero on success, zero on error. + **/ + +static int sdl_close (void *plugin) +{ + struct sdl_priv_s *priv = &sdl_priv; + +// LOG (LOG_DEBUG, "SDL video out: Closed Plugin"); +// LOG (LOG_INFO, "SDL video out: Closed Plugin"); + + /* Cleanup YUV Overlay structure */ + if (priv->overlay) + SDL_FreeYUVOverlay(priv->overlay); + + /* Free our blitting surface */ + if (priv->surface) + SDL_FreeSurface(priv->surface); + + /* TODO: cleanup the full_modes array */ + + /* Cleanup SDL */ + SDL_Quit(); + + return 0; +} + + +/** + * Sets the specified fullscreen mode. + * + * params : mode == index of the desired fullscreen mode + * returns : doesn't return + **/ + +static void set_fullmode (int mode) +{ + struct sdl_priv_s *priv = &sdl_priv; + SDL_Surface *newsurface = NULL; + + + /* if we haven't set a fullmode yet, default to the lowest res fullmode first */ + if (mode < 0) + mode = priv->fullmode = findArrayEnd(priv->fullmodes) - 1; + + /* change to given fullscreen mode and hide the mouse cursor*/ + newsurface = SDL_SetVideoMode(priv->fullmodes[mode]->w, priv->fullmodes[mode]->h, priv->bpp, priv->sdlfullflags); + + /* if we were successfull hide the mouse cursor and save the mode */ + if (newsurface) { + priv->surface = newsurface; + SDL_ShowCursor(0); + } +} + + +/** + * Initialize an SDL surface and an SDL YUV overlay. + * + * params : width == width of video we'll be displaying. + * height == height of video we'll be displaying. + * fullscreen == want to be fullscreen? + * title == Title for window titlebar. + * returns : non-zero on success, zero on error. + **/ + +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) +//static int sdl_setup (int width, int height) +{ + struct sdl_priv_s *priv = &sdl_priv; + unsigned int sdl_format; + + switch(format){ + case IMGFMT_YV12: sdl_format=SDL_YV12_OVERLAY;break; + case IMGFMT_YUY2: sdl_format=SDL_YUY2_OVERLAY;break; + default: + printf("SDL: Unsupported image format (0x%X)\n",format); + return -1; + } + + sdl_open (NULL, NULL); + + /* Save the original Image size */ + + priv->width = width; + priv->height = height; + priv->format = format; + + if(fullscreen){ + priv->windowsize.w = width; + priv->windowsize.h = height; + priv->surface=NULL; + set_fullmode(priv->fullmode); + } else { + priv->windowsize.w = d_width; + priv->windowsize.h = d_height; + priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlflags); + } + if(!priv->surface) return -1; // cannot SetVideoMode + + /* Initialize and create the YUV Overlay used for video out */ + if (!(priv->overlay = SDL_CreateYUVOverlay (width, height, sdl_format, priv->surface))) { + printf ("SDL video out: Couldn't create an SDL-based YUV overlay\n"); + return -1; + } + priv->framePlaneY = width * height; + priv->framePlaneUV = (width * height) >> 2; + priv->slicePlaneY = width << 4; + priv->slicePlaneUV = width << 2; + + return 0; +} + + +/** + * Draw a frame to the SDL YUV overlay. + * + * params : *src[] == the Y, U, and V planes that make up the frame. + * returns : non-zero on success, zero on error. + **/ + +//static int sdl_draw_frame (frame_t *frame) +static uint32_t draw_frame(uint8_t *src[]) +{ + struct sdl_priv_s *priv = &sdl_priv; + uint8_t *dst; + +// priv->current_frame = (SDL_Overlay*) frame->private; +// SDL_UnlockYUVOverlay (priv->current_frame); + + if (SDL_LockYUVOverlay (priv->overlay)) { +// LOG (LOG_ERROR, "SDL video out: Couldn't lock SDL-based YUV overlay"); + return -1; + } + + switch(priv->format){ + case IMGFMT_YV12: + dst = (uint8_t *) *( (uint8_t **) priv->overlay->pixels); + memcpy (dst, src[0], priv->framePlaneY); + dst += priv->framePlaneY; + memcpy (dst, src[2], priv->framePlaneUV); + dst += priv->framePlaneUV; + memcpy (dst, src[1], priv->framePlaneUV); + break; + case IMGFMT_YUY2: + dst = (uint8_t *) *( (uint8_t **) priv->overlay->pixels); + memcpy (dst, src[0], priv->width*priv->height*2); + break; + } + + SDL_UnlockYUVOverlay (priv->overlay); + + return 0; +} + + +/** + * Draw a slice (16 rows of image) to the SDL YUV overlay. + * + * params : *src[] == the Y, U, and V planes that make up the slice. + * returns : non-zero on error, zero on success. + **/ + +static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num) +{ + struct sdl_priv_s *priv = &sdl_priv; + uint8_t *dst; + + //priv->current_frame = priv->overlay; + + if (SDL_LockYUVOverlay (priv->overlay)) { +// LOG (LOG_ERROR, "SDL video out: Couldn't lock SDL-based YUV overlay"); + return -1; + } + + dst = (uint8_t *) *( (uint8_t **) priv->overlay->pixels) + (priv->slicePlaneY * slice_num); + memcpy (dst, src[0], priv->slicePlaneY); + dst = (uint8_t *) *( (uint8_t **) priv->overlay->pixels) + priv->framePlaneY + (priv->slicePlaneUV * slice_num); + memcpy (dst, src[2], priv->slicePlaneUV); + dst += priv->framePlaneUV; + memcpy (dst, src[1], priv->slicePlaneUV); + + SDL_UnlockYUVOverlay (priv->overlay); + + return 0; +} + + + +/** + * Checks for SDL keypress and window resize events + * + * params : none + * returns : doesn't return + **/ + +#include "../linux/keycodes.h" +extern void mplayer_put_key(int code); + +static void check_events (void) +{ + struct sdl_priv_s *priv = &sdl_priv; + SDL_Event event; + SDLKey keypressed; + + /* Poll the waiting SDL Events */ + while ( SDL_PollEvent(&event) ) { + switch (event.type) { + + /* capture window resize events */ + case SDL_VIDEORESIZE: + priv->surface = SDL_SetVideoMode(event.resize.w, event.resize.h, priv->bpp, priv->sdlflags); + + /* save video extents, to restore them after going fullscreen */ + //if(!(priv->surface->flags & SDL_FULLSCREEN)) { + priv->windowsize.w = priv->surface->w; + priv->windowsize.h = priv->surface->h; + //} +// LOG (LOG_DEBUG, "SDL video out: Window resize"); + break; + + + /* graphics mode selection shortcuts */ + case SDL_KEYDOWN: + keypressed = event.key.keysym.sym; + + /* plus key pressed. plus cycles through available fullscreenmodes, if we have some */ + if ( ((keypressed == SDLK_PLUS) || (keypressed == SDLK_KP_PLUS)) && (priv->fullmodes) ) { + /* select next fullscreen mode */ + priv->fullmode++; + if (priv->fullmode > (findArrayEnd(priv->fullmodes) - 1)) priv->fullmode = 0; + set_fullmode(priv->fullmode); + +// LOG (LOG_DEBUG, "SDL video out: Set next available fullscreen mode."); + } + + /* return or escape key pressed toggles/exits fullscreenmode */ + else if ( (keypressed == SDLK_RETURN) || (keypressed == SDLK_ESCAPE) ) { + if (priv->surface->flags & SDL_FULLSCREEN) { + priv->surface = SDL_SetVideoMode(priv->windowsize.w, priv->windowsize.h, priv->bpp, priv->sdlflags); + SDL_ShowCursor(1); + +// LOG (LOG_DEBUG, "SDL video out: Windowed mode"); + } + else if (priv->fullmodes){ + set_fullmode(priv->fullmode); + +// LOG (LOG_DEBUG, "SDL video out: Set fullscreen mode."); + } + } + + else switch(keypressed){ + case SDLK_q: if(!(priv->surface->flags & SDL_FULLSCREEN))mplayer_put_key('q');break; +// case SDLK_p: mplayer_put_key('p');break; + case SDLK_SPACE: mplayer_put_key(' ');break; + case SDLK_UP: mplayer_put_key(KEY_UP);break; + case SDLK_DOWN: mplayer_put_key(KEY_DOWN);break; + case SDLK_LEFT: mplayer_put_key(KEY_LEFT);break; + case SDLK_RIGHT: mplayer_put_key(KEY_RIGHT);break; + case SDLK_PLUS: + case SDLK_KP_PLUS: mplayer_put_key('+');break; + case SDLK_MINUS: + case SDLK_KP_MINUS: mplayer_put_key('-');break; + } + + break; + } + } +} + + +/** + * Display the surface we have written our data to and check for events. + * + * params : mode == index of the desired fullscreen mode + * returns : doesn't return + **/ + +static void flip_page (void) +{ + struct sdl_priv_s *priv = &sdl_priv; + SDL_Rect blat; + + /* check and react on keypresses and window resizes */ + check_events(); + + /* blit to the YUV overlay */ + blat.x =priv->surface->clip_minx; + blat.y =priv->surface->clip_miny; + blat.w =priv->surface->clip_maxx - priv->surface->clip_minx; + blat.h =priv->surface->clip_maxy - priv->surface->clip_miny; + SDL_DisplayYUVOverlay (priv->overlay, &blat); + + /* check if we have a double buffered surface and flip() if we do. */ + if ( priv->surface->flags & SDL_DOUBLEBUF ) + SDL_Flip(priv->surface); + + SDL_LockYUVOverlay (priv->overlay); +} + +#if 0 +static frame_t* sdl_allocate_image_buffer(int width, int height) +{ + struct sdl_priv_s *priv = &sdl_priv; + frame_t *frame; + + if (!(frame = malloc (sizeof (frame_t)))) + return NULL; + + if (!(frame->private = (void*) SDL_CreateYUVOverlay (width, height, + SDL_IYUV_OVERLAY, priv->surface))) + { +// LOG (LOG_ERROR, "SDL video out: Couldn't create an SDL-based YUV overlay"); + return NULL; + } + + frame->base[0] = (uint8_t*) ((SDL_Overlay*) (frame->private))->pixels[0]; + frame->base[1] = (uint8_t*) ((SDL_Overlay*) (frame->private))->pixels[1]; + frame->base[2] = (uint8_t*) ((SDL_Overlay*) (frame->private))->pixels[2]; + + SDL_LockYUVOverlay ((SDL_Overlay*) frame->private); + return frame; +} + +static void sdl_free_image_buffer(frame_t* frame) +{ + SDL_FreeYUVOverlay((SDL_Overlay*) frame->private); + free(frame); +} +#endif + +static uint32_t +query_format(uint32_t format) +{ + switch(format){ + case IMGFMT_YV12: + case IMGFMT_YUY2: +// case IMGFMT_RGB|24: +// case IMGFMT_BGR|24: + return 1; + } + return 0; +} + +static const vo_info_t* +get_info(void) +{ + return &vo_info; +} + + diff --git a/libvo/Attic/SHIT/video_out_x11.c.OLD b/libvo/Attic/SHIT/video_out_x11.c.OLD new file mode 100644 index 0000000000..b7057be6b9 --- /dev/null +++ b/libvo/Attic/SHIT/video_out_x11.c.OLD @@ -0,0 +1,518 @@ +#define DISP + +/* + * video_out_x11.c, X11 interface + * + * + * Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. + * + * Hacked into mpeg2dec by + * + * Aaron Holtzman + * + * 15 & 16 bpp support added by Franck Sicard + * + */ + +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +LIBVO_EXTERN(x11) + +#include +#include +#include +#include +#include "yuv2rgb.h" + +static vo_info_t vo_info = +{ + "X11 (XImage/Shm)", + "x11", + "Aaron Holtzman ", + "" +}; + +/* private prototypes */ +static void Display_Image (XImage * myximage, unsigned char *ImageData); + +/* since it doesn't seem to be defined on some platforms */ +int XShmGetEventBase(Display*); + +/* local data */ +static unsigned char *ImageData; + +/* X11 related variables */ +static Display *mydisplay; +static Window mywindow; +static GC mygc; +static XImage *myximage; +static int depth, bpp, mode; +static XWindowAttributes attribs; +static int X_already_started = 0; + +#define SH_MEM + +#ifdef SH_MEM + +#include +#include +#include + +//static int HandleXError _ANSI_ARGS_((Display * dpy, XErrorEvent * event)); +static void InstallXErrorHandler (void); +static void DeInstallXErrorHandler (void); + +static int Shmem_Flag; +static int Quiet_Flag; +static XShmSegmentInfo Shminfo[1]; +static int gXErrorFlag; +static int CompletionType = -1; + +static void InstallXErrorHandler() +{ + //XSetErrorHandler(HandleXError); + XFlush(mydisplay); +} + +static void DeInstallXErrorHandler() +{ + XSetErrorHandler(NULL); + XFlush(mydisplay); +} + +#endif + +static uint32_t image_width; +static uint32_t image_height; +static uint32_t image_format; + +extern void vo_decoration( Display * vo_Display,Window w,int d ); + +/* connect to server, create and map window, + * allocate colors and (shared) memory + */ +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) +{ + int screen; + unsigned int fg, bg; + char *hello = (title == NULL) ? "I hate X11" : title; + char *name = ":0.0"; + XSizeHints hint; + XVisualInfo vinfo; + XEvent xev; + XGCValues xgcv; + Colormap theCmap; + XSetWindowAttributes xswa; + unsigned long xswamask; + + image_height = height; + image_width = width; + image_format=format; + + if (X_already_started) return -1; + if(!vo_init()) return 0; // Can't open X11 + + if(getenv("DISPLAY")) name = getenv("DISPLAY"); + + mydisplay = XOpenDisplay(name); + + if (mydisplay == NULL) + { + fprintf(stderr,"Can not open display\n"); + return -1; + } + + screen = DefaultScreen(mydisplay); + + hint.x = 0; + hint.y = 0; + hint.width = image_width; + hint.height = image_height; + hint.flags = PPosition | PSize; + + /* Get some colors */ + + bg = WhitePixel(mydisplay, screen); + fg = BlackPixel(mydisplay, screen); + + XGetWindowAttributes(mydisplay, DefaultRootWindow(mydisplay), &attribs); + depth = attribs.depth; +// depth = vo_depthonscreen; + + if (depth != 15 && depth != 16 && depth != 24 && depth != 32) + { + /* The root window may be 8bit but there might still be + * visuals with other bit depths. For example this is the + * case on Sun/Solaris machines. + */ + depth = 24; + } + //BEGIN HACK + //mywindow = XCreateSimpleWindow(mydisplay, DefaultRootWindow(mydisplay), + //hint.x, hint.y, hint.width, hint.height, 4, fg, bg); + // + XMatchVisualInfo(mydisplay, screen, depth, TrueColor, &vinfo); + + theCmap = XCreateColormap(mydisplay, RootWindow(mydisplay,screen), + vinfo.visual, AllocNone); + + xswa.background_pixel = 0; + xswa.border_pixel = 1; + xswa.colormap = theCmap; + xswamask = CWBackPixel | CWBorderPixel |CWColormap; + + + mywindow = XCreateWindow(mydisplay, RootWindow(mydisplay,screen), + hint.x, hint.y, hint.width, hint.height, 4, depth,CopyFromParent,vinfo.visual,xswamask,&xswa); + + if ( fullscreen ) vo_decoration( mydisplay,mywindow,0 ); + + XSelectInput(mydisplay, mywindow, StructureNotifyMask); + + /* Tell other applications about this window */ + + XSetStandardProperties(mydisplay, mywindow, hello, hello, None, NULL, 0, &hint); + + /* Map window. */ + + XMapWindow(mydisplay, mywindow); + + /* Wait for map. */ + do + { + XNextEvent(mydisplay, &xev); + } + while (xev.type != MapNotify || xev.xmap.event != mywindow); + + XSelectInput(mydisplay, mywindow, NoEventMask); + + XFlush(mydisplay); + XSync(mydisplay, False); + + mygc = XCreateGC(mydisplay, mywindow, 0L, &xgcv); + +#ifdef SH_MEM + if (XShmQueryExtension(mydisplay)) + Shmem_Flag = 1; + else + { + Shmem_Flag = 0; + if (!Quiet_Flag) + fprintf(stderr, "Shared memory not supported\nReverting to normal Xlib\n"); + } + if (Shmem_Flag) + CompletionType = XShmGetEventBase(mydisplay) + ShmCompletion; + + InstallXErrorHandler(); + + if (Shmem_Flag) + { + myximage = XShmCreateImage(mydisplay, vinfo.visual, + depth, ZPixmap, NULL, &Shminfo[0], width, image_height); + + /* If no go, then revert to normal Xlib calls. */ + + if (myximage == NULL ) + { + if (myximage != NULL) + XDestroyImage(myximage); + if (!Quiet_Flag) + fprintf(stderr, "Shared memory error, disabling (Ximage error)\n"); + + goto shmemerror; + } + /* Success here, continue. */ + + Shminfo[0].shmid = shmget(IPC_PRIVATE, + myximage->bytes_per_line * myximage->height , + IPC_CREAT | 0777); + if (Shminfo[0].shmid < 0 ) + { + XDestroyImage(myximage); + if (!Quiet_Flag) + { + printf("%s\n",strerror(errno)); + perror(strerror(errno)); + fprintf(stderr, "Shared memory error, disabling (seg id error)\n"); + } + goto shmemerror; + } + Shminfo[0].shmaddr = (char *) shmat(Shminfo[0].shmid, 0, 0); + + if (Shminfo[0].shmaddr == ((char *) -1)) + { + XDestroyImage(myximage); + if (Shminfo[0].shmaddr != ((char *) -1)) + shmdt(Shminfo[0].shmaddr); + if (!Quiet_Flag) + fprintf(stderr, "Shared memory error, disabling (address error)\n"); + goto shmemerror; + } + myximage->data = Shminfo[0].shmaddr; + ImageData = (unsigned char *) myximage->data; + Shminfo[0].readOnly = False; + XShmAttach(mydisplay, &Shminfo[0]); + + XSync(mydisplay, False); + + if (gXErrorFlag) + { + /* Ultimate failure here. */ + XDestroyImage(myximage); + shmdt(Shminfo[0].shmaddr); + if (!Quiet_Flag) + fprintf(stderr, "Shared memory error, disabling.\n"); + gXErrorFlag = 0; + goto shmemerror; + } + else + { + shmctl(Shminfo[0].shmid, IPC_RMID, 0); + } + + if (!Quiet_Flag) + { + fprintf(stderr, "Sharing memory.\n"); + } + } + else + { + shmemerror: + Shmem_Flag = 0; +#endif + myximage = XGetImage(mydisplay, mywindow, 0, 0, + width, image_height, AllPlanes, ZPixmap); + ImageData = myximage->data; +#ifdef SH_MEM + } + + DeInstallXErrorHandler(); +#endif + + bpp = myximage->bits_per_pixel; + + printf("X11 color mask: R:%X G:%X B:%X\n", + myximage->red_mask,myximage->green_mask,myximage->blue_mask); + + // If we have blue in the lowest bit then obviously RGB + mode = ((myximage->blue_mask & 0x01) != 0) ? MODE_RGB : MODE_BGR; +// mode = ((myximage->blue_mask & 0x01) == 0) ? MODE_RGB : MODE_BGR; +#ifdef WORDS_BIGENDIAN + if (myximage->byte_order != MSBFirst) +#else + if (myximage->byte_order != LSBFirst) +#endif + { + fprintf( stderr, "No support fon non-native XImage byte order!\n" ); + return -1; + } + + /* + * If depth is 24 then it may either be a 3 or 4 byte per pixel + * format. We can't use bpp because then we would lose the + * distinction between 15/16bit depth (2 byte formate assumed). + * + * FIXME - change yuv2rgb_init to take both depth and bpp + * parameters + */ + if(format==IMGFMT_YV12) yuv2rgb_init((depth == 24) ? bpp : depth, mode); + + XSelectInput(mydisplay, mywindow, StructureNotifyMask | KeyPressMask ); + X_already_started++; + return 0; +} + +static const vo_info_t* +get_info(void) +{ + return &vo_info; +} + + +static void +Terminate_Display_Process(void) +{ + getchar(); /* wait for enter to remove window */ +#ifdef SH_MEM + if (Shmem_Flag) + { + XShmDetach(mydisplay, &Shminfo[0]); + XDestroyImage(myximage); + shmdt(Shminfo[0].shmaddr); + } +#endif + XDestroyWindow(mydisplay, mywindow); + XCloseDisplay(mydisplay); + X_already_started = 0; +} + +static void +Display_Image(XImage *myximage, uint8_t *ImageData) +{ +#ifdef DISP +#ifdef SH_MEM + if (Shmem_Flag) + { + XShmPutImage(mydisplay, mywindow, mygc, myximage, + 0, 0, 0, 0, myximage->width, myximage->height, True); + XFlush(mydisplay); + } + else +#endif + { + XPutImage(mydisplay, mywindow, mygc, myximage, 0, 0, 0, 0, + myximage->width, myximage->height); + XFlush(mydisplay); + } +#endif +} + + +static void +flip_page(void) +{ + + int i; + XEvent Event; + char buf[100]; + KeySym keySym; + XComposeStatus stat; + unsigned long vo_KeyTable[512]; + + while ( XPending( mydisplay ) ) + { + XNextEvent( mydisplay,&Event ); + switch( Event.type ) + { + case ConfigureNotify: +// windowwidth = Event.xconfigure.width; +// windowheight = Event.xconfigure.height; + break; + case KeyPress: + XLookupString( &Event.xkey,buf,sizeof(buf),&keySym,&stat ); + vo_keyboard( ( (keySym&0xff00) != 0?( (keySym&0x00ff) + 256 ):( keySym ) ) ); + break; + } + } + + Display_Image(myximage, ImageData); +} + + +static uint32_t +draw_slice(uint8_t *src[], uint32_t slice_num) +{ + uint8_t *dst; + + dst = ImageData + image_width * 16 * (bpp/8) * slice_num; + + yuv2rgb(dst , src[0], src[1], src[2], + image_width, 16, + image_width*(bpp/8), image_width, image_width/2 ); + return 0; +} + +void rgb15to16_mmx(char* s0,char* d0,int count); + +#if 1 +static uint32_t +draw_frame(uint8_t *src[]) +{ + if(image_format==IMGFMT_YV12){ + yuv2rgb(ImageData, src[0], src[1], src[2], + image_width, image_height, + image_width*(bpp/8), image_width, image_width/2 ); + } else { + int sbpp=((image_format&0xFF)+7)/8; + int dbpp=(bpp+7)/8; + char *d=ImageData; + char *s=src[0]; + //printf("sbpp=%d dbpp=%d depth=%d bpp=%d\n",sbpp,dbpp,depth,bpp); +#if 0 + // flipped BGR + int i; +// printf("Rendering flipped BGR frame bpp=%d src=%d dst=%d\n",bpp,sbpp,dbpp); + s+=sbpp*image_width*image_height; + for(i=0;i16bpp +#ifdef HAVE_MMX + rgb15to16_mmx(s,d,2*image_width*image_height); +#else + unsigned short *s1=(unsigned short *)s; + unsigned short *d1=(unsigned short *)d; + unsigned short *e=s1+image_width*image_height; + while(s132bpp conversion\n"); + while(s + * + * 15 & 16 bpp support added by Franck Sicard + * + */ + +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +LIBVO_EXTERN( x11 ) + +#include +#include +#include +#include +#include "yuv2rgb.h" + +static vo_info_t vo_info = +{ + "X11 ( XImage/Shm )", + "x11", + "Aaron Holtzman ", + "" +}; + +/* private prototypes */ +static void Display_Image ( XImage * myximage,unsigned char *ImageData ); + +/* since it doesn't seem to be defined on some platforms */ +int XShmGetEventBase( Display* ); + +/* local data */ +static unsigned char *ImageData; + +/* X11 related variables */ +static Display *mDisplay; +static Window mywindow; +static GC mygc; +static XImage *myximage; +static int depth,bpp,mode; +static XWindowAttributes attribs; +static int X_already_started=0; + +static int windowwidth,windowheight; + +#define SH_MEM + +#ifdef SH_MEM + +#include +#include +#include + +//static int HandleXError _ANSI_ARGS_( ( Display * dpy,XErrorEvent * event ) ); +static void InstallXErrorHandler ( void ); +static void DeInstallXErrorHandler ( void ); + +static int Shmem_Flag; +static int Quiet_Flag; +static XShmSegmentInfo Shminfo[1]; +static int gXErrorFlag; +static int CompletionType=-1; + +static void InstallXErrorHandler() +{ + //XSetErrorHandler( HandleXError ); + XFlush( mDisplay ); +} + +static void DeInstallXErrorHandler() +{ + XSetErrorHandler( NULL ); + XFlush( mDisplay ); +} + +#endif + +static uint32_t image_width; +static uint32_t image_height; +static uint32_t image_format; + +extern void vo_decoration( Display * vo_Display,Window w,int d ); + +static Bool mEvents( Display * display,XEvent * Event,XPointer arg ) +{ + int i; + char buf[100]; + KeySym keySym; + XComposeStatus stat; + unsigned long vo_KeyTable[512]; + + switch( Event->type ) + { + case ConfigureNotify: + windowwidth=Event->xconfigure.width; + windowheight=Event->xconfigure.height; + break; + case KeyPress: + XLookupString( &Event->xkey,buf,sizeof(buf),&keySym,&stat ); + vo_keyboard( ( (keySym&0xff00) != 0?( (keySym&0x00ff) + 256 ):( keySym ) ) ); + break; + } + return 0; +} + +static XEvent mEvent; + +static void mThread( void ) +{ +printf("thread okey!\n"); + XIfEvent( mDisplay,&mEvent,mEvents,NULL ); +} + +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 ) +{ + int screen; + unsigned int fg,bg; + char *hello=( title == NULL ) ? "X11 render" : title; + char *name=":0.0"; + XSizeHints hint; + XVisualInfo vinfo; + XEvent xev; + XGCValues xgcv; + Colormap theCmap; + XSetWindowAttributes xswa; + unsigned long xswamask; + + image_height=height; + image_width=width; + image_format=format; + + if ( X_already_started ) return -1; + if( !vo_init() ) return 0; // Can't open X11 + + if( getenv( "DISPLAY" ) ) name=getenv( "DISPLAY" ); + + mDisplay=XOpenDisplay( name ); + + if ( mDisplay == NULL ) + { + fprintf( stderr,"Can not open display\n" ); + return -1; + } + + screen=DefaultScreen( mDisplay ); + + hint.x=0; + hint.y=0; + hint.width=image_width; + hint.height=image_height; + if ( fullscreen ) + { + hint.width=vo_screenwidth; + hint.height=vo_screenheight; + } + windowwidth=hint.width; + windowheight=hint.height; + hint.flags=PPosition | PSize; + + bg=WhitePixel( mDisplay,screen ); + fg=BlackPixel( mDisplay,screen ); + + XGetWindowAttributes( mDisplay,DefaultRootWindow( mDisplay ),&attribs ); + depth=attribs.depth; + + if ( depth != 15 && depth != 16 && depth != 24 && depth != 32 ) depth=24; + XMatchVisualInfo( mDisplay,screen,depth,TrueColor,&vinfo ); + + theCmap =XCreateColormap( mDisplay,RootWindow( mDisplay,screen ), + vinfo.visual,AllocNone ); + + xswa.background_pixel=0; + xswa.border_pixel=1; + xswa.colormap=theCmap; + xswamask=CWBackPixel | CWBorderPixel |CWColormap; + + mywindow=XCreateWindow( mDisplay,RootWindow( mDisplay,screen ), + hint.x,hint.y, + hint.width,hint.height, + xswa.border_pixel,depth,CopyFromParent,vinfo.visual,xswamask,&xswa ); + + if ( fullscreen ) vo_decoration( mDisplay,mywindow,0 ); + XSelectInput( mDisplay,mywindow,StructureNotifyMask ); + XSetStandardProperties( mDisplay,mywindow,hello,hello,None,NULL,0,&hint ); + XMapWindow( mDisplay,mywindow ); + do { XNextEvent( mDisplay,&xev ); } while ( xev.type != MapNotify || xev.xmap.event != mywindow ); + + XSelectInput( mDisplay,mywindow,NoEventMask ); + + XFlush( mDisplay ); + XSync( mDisplay,False ); + + mygc=XCreateGC( mDisplay,mywindow,0L,&xgcv ); + +#ifdef SH_MEM + if ( XShmQueryExtension( mDisplay ) ) Shmem_Flag=1; + else + { + Shmem_Flag=0; + if ( !Quiet_Flag ) fprintf( stderr,"Shared memory not supported\nReverting to normal Xlib\n" ); + } + if ( Shmem_Flag ) CompletionType=XShmGetEventBase( mDisplay ) + ShmCompletion; + + InstallXErrorHandler(); + + if ( Shmem_Flag ) + { + myximage=XShmCreateImage( mDisplay,vinfo.visual,depth,ZPixmap,NULL,&Shminfo[0],width,image_height ); + if ( myximage == NULL ) + { + if ( myximage != NULL ) XDestroyImage( myximage ); + if ( !Quiet_Flag ) fprintf( stderr,"Shared memory error,disabling ( Ximage error )\n" ); + goto shmemerror; + } + Shminfo[0].shmid=shmget( IPC_PRIVATE, + myximage->bytes_per_line * myximage->height , + IPC_CREAT | 0777 ); + if ( Shminfo[0].shmid < 0 ) + { + XDestroyImage( myximage ); + if ( !Quiet_Flag ) + { + printf( "%s\n",strerror( errno ) ); + perror( strerror( errno ) ); + fprintf( stderr,"Shared memory error,disabling ( seg id error )\n" ); + } + goto shmemerror; + } + Shminfo[0].shmaddr=( char * ) shmat( Shminfo[0].shmid,0,0 ); + + if ( Shminfo[0].shmaddr == ( ( char * ) -1 ) ) + { + XDestroyImage( myximage ); + if ( Shminfo[0].shmaddr != ( ( char * ) -1 ) ) shmdt( Shminfo[0].shmaddr ); + if ( !Quiet_Flag ) fprintf( stderr,"Shared memory error,disabling ( address error )\n" ); + goto shmemerror; + } + myximage->data=Shminfo[0].shmaddr; + ImageData=( unsigned char * ) myximage->data; + Shminfo[0].readOnly=False; + XShmAttach( mDisplay,&Shminfo[0] ); + + XSync( mDisplay,False ); + + if ( gXErrorFlag ) + { + XDestroyImage( myximage ); + shmdt( Shminfo[0].shmaddr ); + if ( !Quiet_Flag ) fprintf( stderr,"Shared memory error,disabling.\n" ); + gXErrorFlag=0; + goto shmemerror; + } + else + shmctl( Shminfo[0].shmid,IPC_RMID,0 ); + + if ( !Quiet_Flag ) fprintf( stderr,"Sharing memory.\n" ); + } + else + { + shmemerror: + Shmem_Flag=0; +#endif + myximage=XGetImage( mDisplay,mywindow,0,0, + width,image_height,AllPlanes,ZPixmap ); + ImageData=myximage->data; +#ifdef SH_MEM + } + + DeInstallXErrorHandler(); +#endif + + bpp=myximage->bits_per_pixel; + + fprintf( stderr,"X11 color mask: R:%X G:%X B:%X\n",myximage->red_mask,myximage->green_mask,myximage->blue_mask ); + + // If we have blue in the lowest bit then obviously RGB + mode=( ( myximage->blue_mask & 0x01 ) != 0 ) ? MODE_RGB : MODE_BGR; +#ifdef WORDS_BIGENDIAN + if ( myximage->byte_order != MSBFirst ) +#else + if ( myximage->byte_order != LSBFirst ) +#endif + { + fprintf( stderr,"No support fon non-native XImage byte order!\n" ); + return -1; + } + + if( format==IMGFMT_YV12 ) yuv2rgb_init( ( depth == 24 ) ? bpp : depth,mode ); + + XSelectInput( mDisplay,mywindow,StructureNotifyMask | KeyPressMask ); + X_already_started++; + + printf("init thread!\n"); + vo_initthread( mThread ); + + return 0; +} + +static const vo_info_t* get_info( void ) +{ return &vo_info; } + +static void Terminate_Display_Process( void ) +{ + getchar(); /* wait for enter to remove window */ +#ifdef SH_MEM + if ( Shmem_Flag ) + { + XShmDetach( mDisplay,&Shminfo[0] ); + XDestroyImage( myximage ); + shmdt( Shminfo[0].shmaddr ); + } +#endif + XDestroyWindow( mDisplay,mywindow ); + XCloseDisplay( mDisplay ); + X_already_started=0; +} + +static void Display_Image( XImage *myximage,uint8_t *ImageData ) +{ +#ifdef DISP +#ifdef SH_MEM + if ( Shmem_Flag ) + { + XShmPutImage( mDisplay,mywindow,mygc,myximage, + 0,0, + ( windowwidth - myximage->width ) / 2,( windowheight - myximage->height ) / 2, + myximage->width,myximage->height,True ); + XFlush( mDisplay ); + } + else +#endif + { + XPutImage( mDisplay,mywindow,mygc,myximage, + 0,0, + ( windowwidth - myximage->width ) / 2,( windowheight - myximage->height ) / 2, + myximage->width,myximage->height ); + XFlush( mDisplay ); + } +#endif +} + +static void flip_page( void ) +{ Display_Image( myximage,ImageData ); } + +static uint32_t draw_slice( uint8_t *src[],int stride[],int w,int h,int x,int y ) +{ + uint8_t *dst; + + dst=ImageData + ( image_width * y + x ) * ( bpp/8 ); + yuv2rgb( dst,src[0],src[1],src[2],w,h,image_width*( bpp/8 ),stride[0],stride[1] ); + return 0; +} + +void rgb15to16_mmx( char* s0,char* d0,int count ); + +#if 1 +static uint32_t draw_frame( uint8_t *src[] ) +{ + if( image_format==IMGFMT_YV12 ) + { + yuv2rgb( ImageData,src[0],src[1],src[2],image_width,image_height,image_width*( bpp/8 ),image_width,image_width/2 ); + } + else + { + int sbpp=( ( image_format&0xFF )+7 )/8; + int dbpp=( bpp+7 )/8; + char *d=ImageData; + char *s=src[0]; + //printf( "sbpp=%d dbpp=%d depth=%d bpp=%d\n",sbpp,dbpp,depth,bpp ); +#if 0 + // flipped BGR + int i; + //printf( "Rendering flipped BGR frame bpp=%d src=%d dst=%d\n",bpp,sbpp,dbpp ); +