diff options
Diffstat (limited to 'libvo/Attic')
-rw-r--r-- | libvo/Attic/SHIT/video_out_gl.c.V3-sux | 538 | ||||
-rw-r--r-- | libvo/Attic/SHIT/video_out_gl.c.diff | 64 | ||||
-rw-r--r-- | libvo/Attic/SHIT/video_out_odivx.c.OLD | 183 | ||||
-rw-r--r-- | libvo/Attic/SHIT/video_out_sdl.c-1.1.4 | 574 | ||||
-rw-r--r-- | libvo/Attic/SHIT/video_out_x11.c.OLD | 518 | ||||
-rw-r--r-- | libvo/Attic/SHIT/video_out_x11.c.thread | 466 |
6 files changed, 2343 insertions, 0 deletions
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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + + +LIBVO_EXTERN(gl) + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +//#include <X11/keysym.h> +#include <GL/glx.h> +#include <errno.h> +#include "yuv2rgb.h" + +#include <GL/gl.h> + +static vo_info_t vo_info = +{ + "X11 (OpenGL)", + "gl", + "Arpad Gereoffy <arpi@esp-team.scene.hu>", + "" +}; + +/* 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_width<image_width) texture_width*=2; + while(texture_width<image_height) texture_width*=2; + if(texture_width>256)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<image_height;i++){ + for(i=0;i<MIN(image_height,texture_height);i++){ + glTexSubImage2D( GL_TEXTURE_2D, // target + 0, // level + 0, // x offset + i, // y offset +// image_width, // width + MIN(image_width,texture_width), // width + 1, // height + (BYTES_PP==4)?GL_RGBA:GL_RGB, // format + GL_UNSIGNED_BYTE, // type + ImageData+i*BYTES_PP*image_width ); // *pixels + } + +// Display_Image(ImageData); +// FlipImage(); + return 0; +} + + +static inline uint32_t +draw_frame_x11_bgr(uint8_t *src[]) +{ +int i; +uint8_t *s=src[0]; +uint8_t *de=&ImageData[3*image_width]; + + for(i=0;i<image_height;i++){ + int j; + uint8_t *d=ImageData; + while(d<de){ + d[0]=s[2]; + d[1]=s[1]; + d[2]=s[0]; + s+=3;d+=3; + } + glTexSubImage2D( GL_TEXTURE_2D, // target + 0, // level + 0, // x offset + image_height-1-i, // y offset + image_width<texture_width?image_width:texture_width, // width +// image_width, // width + 1, // height + (image_bytes==4)?GL_RGBA:GL_RGB, // format + GL_UNSIGNED_BYTE, // type + ImageData); // *pixels + } + +// Display_Image(ImageData); + FlipImage(); + return 0; +} + +static inline uint32_t +draw_frame_x11_rgb(uint8_t *src[]) +{ +int i; +uint8_t *ImageData=src[0]; + + for(i=0;i<image_height;i++){ + glTexSubImage2D( GL_TEXTURE_2D, // target + 0, // level + 0, // x offset + image_height-1-i, // y offset +// image_width, // width + image_width<texture_width?image_width:texture_width, // width + 1, // height + (image_bytes==4)?GL_RGBA:GL_RGB, // format + GL_UNSIGNED_BYTE, // type + ImageData+i*image_bytes*image_width ); // *pixels + } + +// Display_Image(ImageData); + FlipImage(); + return 0; +} + + +static uint32_t +draw_frame(uint8_t *src[]) +{ + if(image_format==IMGFMT_YV12) + return draw_frame_x11_yv12(src); + else + if((image_format&IMGFMT_RGB_MASK)==IMGFMT_RGB) + return draw_frame_x11_rgb(src); + else + return draw_frame_x11_bgr(src); +} + +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; +} diff --git a/libvo/Attic/SHIT/video_out_gl.c.diff b/libvo/Attic/SHIT/video_out_gl.c.diff new file mode 100644 index 0000000000..dece59b7fd --- /dev/null +++ b/libvo/Attic/SHIT/video_out_gl.c.diff @@ -0,0 +1,64 @@ +8,10d7 +< // Hmm. Enabling this makes about 20% speedup too! (Celeron2+G400+UtahGLX) +< //#define TEXSUBIMAGE_BUG_WORKAROUND +< +369,370c366,367 +< static inline uint32_t +< draw_slice_x11(uint8_t *src[], uint32_t slice_num) +--- +> //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<h;i++){ +387,389c382,384 +< 0, // x offset +< 16*slice_num+i, // y offset +< image_width, // width +--- +> 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +LIBVO_EXTERN(odivx) + +#include <sys/ioctl.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> + +#include "../encore/encore.h" + +static vo_info_t vo_info = +{ + "OpenDivX AVI File writer", + "odivx", + "Arpad Gereoffy <arpi@esp-team.scene.hu>", + "" +}; + +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 <icculus@lokigames.com> - 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 <dominik@schnitzer.at> - 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 <dominik@schnitzer.at> - November 11, 2000. + * - Cleanup code, more comments + * - Better error handling + * Bruno Barreyra <barreyra@ufl.edu> - December 10, 2000. + * - Eliminated memcpy's for entire frames + * Arpad Gereoffy <arpi@esp-team.scene.hu> - Jan 13, 2001. + * - Ported to MPlayer + * - small changes about keys and fullscreen mode + * Jeffrey Boser <verin@lvcm.com> - Jan 16, 2001. + * - type casting fixes, clip rect fix + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> + +#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 <icculus@lokigames.com>", + "" +}; + +#include <SDL/SDL.h> + +/** 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 (w |