diff -Naur -x CVS -x .* main/libvo2/img_format.c main-dxr3/libvo2/img_format.c --- main/libvo2/img_format.c Tue Jul 31 02:29:22 2001 +++ main-dxr3/libvo2/img_format.c Tue Nov 20 17:34:55 2001 @@ -38,6 +38,7 @@ case IMGFMT_CLJR: return("Packed CLJR"); case IMGFMT_YUVP: return("Packed YUVP"); case IMGFMT_UYVP: return("Packed UYVP"); + case IMGFMT_MPEGPES: return("MPEG-PES"); } return("Unknown"); } diff -Naur -x CVS -x .* main/libvo2/img_format.h main-dxr3/libvo2/img_format.h --- main/libvo2/img_format.h Tue Jul 31 02:29:22 2001 +++ main-dxr3/libvo2/img_format.h Tue Nov 20 17:34:55 2001 @@ -50,6 +50,17 @@ #define IMGFMT_YUVP 0x50565559 #define IMGFMT_UYVP 0x50565955 +/* Compressed Formats */ +#define IMGFMT_MPEGPES (('M'<<24)|('P'<<16)|('E'<<8)|('S')) + char *vo_format_name(int format); + +typedef struct +{ + void *data; + int size; + int id; + int timestamp; +} vo_mpeg_t; #endif diff -Naur -x CVS -x .* main/libvo2/libvo2.h main-dxr3/libvo2/libvo2.h --- main/libvo2/libvo2.h Tue Jul 31 02:24:28 2001 +++ main-dxr3/libvo2/libvo2.h Tue Nov 20 17:45:08 2001 @@ -4,25 +4,6 @@ #define VO2_NA -1 #define VO2_UNKNOWN -2 -// return true if surface is in fast system ram, false if slow (video?) memory -// USED for storing mpeg2 I/P frames only if it's fast enough -#define VO2CTRL_QUERY_SURFACE_FAST 0x101 - -// return true if surface is direct rendered, false if indirect (copied first) -// Note: it's usually same as VO2CTRL_GET_SURFACE_SPEED, except for some -// special cases, when video card does the copy from video ram (opengl...) -// USED for deciding external double buffering mode (using 2 surfaces) -#define VO2CTRL_QUERY_SURFACE_DIRECT 0x102 - -// Get the upper hardware/Driver limitation (used for double buffering) -#define VO2CTRL_GET_MAX_SURFACES 0x103 - -// Query support of a given video pixel format (use IMGFMT_ constants) -#define VO2CTRL_QUERY_FORMAT 0x111 - -// Query that software and/or hardware scaling is supported by driver -#define VO2CTRL_QUERY_SWSCALE 0x121 -#define VO2CTRL_QUERY_HWSCALE 0x122 typedef struct vo2_info_s @@ -43,7 +24,8 @@ unsigned char* img[3]; // pointer to frame/planes int stride[3]; // strides (bytes per line) for frame/planes int format; // RGB / BGR / YUV_PACKED / YUV_PLANAR int bpp; // bits per pixel (15/16/24/32) or YUV fourcc + int pts; // Picture Time Stamp of current frame } vo2_surface_t; typedef struct vo2_functions_s { @@ -79,24 +61,48 @@ } vo2_functions_t; -typedef struct vo2_handle_s { +typedef struct vo2_handle_s +{ vo2_info_t* info; vo2_functions_t* functions; vo2_surface_t* surface; - void* priv; + void* priv; /* Device private data, don't use globals! */ } vo2_handle_t; // Opens a new driver by name, returns the handle (vo2_handle_t) // returns NULL if failed (no such driver/device, etc) vo2_handle_t* vo2_new(char *drvname); +// format is the input format, which is automagically converted to the required +// output format when drawn int vo2_start(vo2_handle_t* vo, int w,int h,int format,int buffering,int flags); int vo2_query_format(vo2_handle_t* vo); int vo2_close(vo2_handle_t* vo); void vo2_draw_slice_start(vo2_handle_t *vo,int field); void vo2_draw_slice(vo2_handle_t *vo,unsigned char* img[3],int stride[3],int w,int h,int x,int y); void vo2_draw_frame(vo2_handle_t *vo,unsigned char* img,int stride,int w,int h); void vo2_flip(vo2_handle_t *vo,int num); + /* Handlers to speed up device development and stay + clear of sigsegv traps etc */ +/* Load and save config structs */ +/* returns NULL upon failure */ +int vo2_save_devoptions(vo2_handle_t*); +int vo2_load_devoptions(vo2_handle_t*); +/* Makes it easier to fill the config struct, also a great way of setting default + values upon first execution of device */ +int vo2_add_option( vo2_handle_t*, char **new_option, char **option_types, char **default_values ); + +/* The swiss army knife for libvo2 core */ +typedef struct vo2_gadget_s +{ + /* Preferred format (see vo2_query_format(...) */ + int format; + /* If format conversion need to be done, i.e. YUV420->RGB24, or BGR24->MPEGPES etc */ + int (*format_conversion)(int format, unsigned char* src[3], int stride[3] ); + /* If it needs software scaling */ + int (*scale_frame)(int format, unsigned char* src[3], int stride[3], int w, int h ); +} vo2_gadget_t; + // HACK typedef struct { int dummy; @@ -122,3 +128,78 @@ extern char *vo_subdevice; + +/* It's quite possible there'll be ALOT of these, so it's better to put + them at the end of the file to make it more readable */ + +// return true if surface is in fast system ram, false if slow (video?) memory +// USED for storing mpeg2 I/P frames only if it's fast enough +#define VO2CTRL_QUERY_SURFACE_FAST 0x101 + +// return true if surface is direct rendered, false if indirect (copied first) +// Note: it's usually same as VO2CTRL_GET_SURFACE_SPEED, except for some +// special cases, when video card does the copy from video ram (opengl...) +// USED for deciding external double buffering mode (using 2 surfaces) +#define VO2CTRL_QUERY_SURFACE_DIRECT 0x102 + +// Get the upper hardware/Driver limitation (used for double buffering) +#define VO2CTRL_GET_MAX_SURFACES 0x103 + +// Query support of a given video pixel format (use IMGFMT_ constants) +#define VO2CTRL_QUERY_FORMAT 0x111 + +// Query whether software and/or hardware scaling is supported by driver +#define VO2CTRL_QUERY_SWSCALE 0x121 +#define VO2CTRL_QUERY_HWSCALE 0x122 + +// Device configuration-options interface +// GET_OPTIONS should return a copy and not the original!! +// SET_OPTIONS takes only char **values +typedef struct +{ + int numoptions; /* Number of options for this device */ + char **options; /* List of optionnames + optionally option-mode + + Option Modes: (always preceeded by \t) + + 1. i.e. options[0]="Outdevice\t[5]" means the + option has 5 different choices, which are read + through options[optionnum+1 through optionnum+5] + i.e. options[1]="/dev/dev3" + + 2. options[2]="Flags\t[5,5]" means the option + has 5 different choices of which up to 5 may + be selected (at one time, like a multiple choice + listbox) + choices are specified like in mode 1 + + 3. options[3]="Buffersize\t{128-512} means the + option is a value in the range of 128-512 + */ + char **option_types;/* Option type: (\0 terminated strings) + "b" = byte (8-bits) + "s" = short (16-bits) + "l" = long (32-bits) + "i" = int + "ub" = unsigned byte (8-bits) + "us" = unsigned short (16-bits) + "ul" = unsigned long (32-bits) + "ui" = unsigned int + "s" = \0 terminated string + "c" = character + */ + char **values; /* Option value: + mode: form: + 1 use the int of the selected option (not the string) + 2 as mode 1 but a \t separated list of selected options + 3 option_type + */ +} vo2_devconfig_t; +#define VO2CTRL_GET_OPTIONS 0x131 +#define VO2CTRL_SET_OPTIONS 0x132 + +//Query the overlay mode (used for osd and sub) +#define VO2CTRL_QUERY_OVERLAY 0x141 + //Return values +#define VO2OVERLAY_SUPERIMPOSE 0x142 //Let libvo2 core superimpose it on the frame +#define VO2OVERLAY_SUBPICTURE 0x143 //The device wants it as a subpicture channel diff -Naur -x CVS -x .* main/libvo2/vo2_dxr3.c main-dxr3/libvo2/vo2_dxr3.c --- main/libvo2/vo2_dxr3.c Thu Jan 1 01:00:00 1970 +++ main-dxr3/libvo2/vo2_dxr3.c Tue Nov 20 17:34:55 2001 @@ -0,0 +1,182 @@ + +#include +#include + +#include "libvo2.h" +#include "img_format.h" + +// Driver info: +static vo2_info_t info = +{ + "DXR3/Hollywood Plus VO2 Device", + "dxr3", + "David Holm ", + "in development" +}; + +// Local, driver-dependent data: (do not use globals! -> reentrancy) +typedef struct +{ + int width, height, format; + int fd_control; + int fd_video; + int fd_spu; + unsigned char *spubuf; + vo2_devconfig_t config; + vo2_surface_t surface; +} priv_t; + +#include "vo2_def.h" + +// open hardware/lib, get capabilities +// this function will be called first, before any other control() or start() calls +// return: 1=success 0=failed +/* if possible this _SHOULD_ check thath this particular hardware actually + exists unless of course it isn't a hw-device */ +vo2_handle_t* vo2_init_dxr3() +{ + printf("VO2_DXR3: init()\n"); + return new_handle( ); +} + +// control (get/set/query) device parameters +// for example: query supported pixel formats, en/disable double buffering, +// query hw/sw scaling capabilities, switch window/fullscreen, +// get best matching resolution for a given image size etc... +static int control(void *p, int cmd, void* param) +{ + switch( cmd ) + { + case VO2CTRL_QUERY_SURFACE_FAST: + case VO2CTRL_QUERY_SURFACE_DIRECT: + return VO2_FALSE; //Surface has to be pushed... + break; + case VO2CTRL_GET_MAX_SURFACES: + *((int*)param) = 1; + break; + case VO2CTRL_QUERY_FORMAT: + *((int*)param) = IMGFMT_MPEGPES; + break; + case VO2CTRL_QUERY_SWSCALE: + case VO2CTRL_QUERY_HWSCALE: + return VO2_TRUE; + break; + case VO2CTRL_GET_OPTIONS: + vo2_devconfig_t returnconf; + returnconf.numoptions = 0; + (vo2_devconfig_t*)param = &vo2_devconfig_t; + break; + case VO2CTRL_SET_OPTIONS: + dxr3.config.values = (char**)*param; + break; + case VO2CTRL_QUERY_OVERLAY: + return VO2OVERLAY_SUBPICTURE; + break; /* yeah, I'm pedantic ;) */ + default: + return VO2_UNKNOWN; + } + + return VO2_UNKNOWN; +} + +// start drawing (set video mode, allocate image buffers etc.) +// w,h: requested surface size (actual size may be larger!!!) +// format: IMGFMT_* requested surface pixel format +// buffering: 0 - single temporary frame buffer (for draw_* stuff) +// 1 - single static buffer (for win32 direct rendering) +// 2 - 2 static + 1 temp buffer (for mpeg direct rendering) +// flags: various things, like fullscreen, sw/hw zoom and vidmode change +// return: 1=success 0=fail (fail if pixel format or buffering not supported) +static int start( void *p, int w,int h,int format,int buffering,int flags) +{ + int ioval; + // open window / switch vidmode, set up surfaces etc... + printf("VO2_DXR3: start() %dx%d %s %d 0x%X\n",w,h,vo_format_name(format),buffering,flags); + /* fd_control is only opened when needed and must be closed before the end + of the function so that ao_dxr3 may use it as well */ + if( (p->priv->fd_control = open( "/dev/em8300", O_WRONLY )) < 0 ) + { + printf( "VO2_DXR3: unable to open /dev/em8300\n" ); + return 0; + } + if( (p->priv->fd_video = open( "/dev/em8300_mv", O_WRONLY )) < 0 ) + { + printf( "VO2_DXR3: unable to open /dev/em8300_mv\n" ); + return 0; + } + if( (p->priv->fd_spu = open( "/dev/em8300_sp", O_WRONLY )) < 0 ) + { + printf( "VO2_DXR3: unable to open /dev/em8300_sp\n" ); + return 0; + } + + ioval = EM8300_SPUMODE_OFF; + if( ioctl( p->priv->fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval ) < 0 ) + { + printf( "VO2_DXR3: unable to set subpicture mode\n" ); + return 0; + } + + ioval = EM8300_PLAYMODE_PLAY; + if( ioctl( p->priv->fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval ) < 0 ) + printf( "VO2_DXR3: unable to set playmode\n" ); + + p->priv->spubuf = malloc( 53220 ); + + /* Yeah, I know you are anxious to see how the hell this is implemented + but hold your breath, I'll do it soon */ + vo2_add_option( p, { "Device\t[1]", "/dev/em8300", "Audio Output\t[2]", "Analog", "Digital" }, { "ub", "ub" }, { "1", "1" } ); + + p->priv->width = w; + p->priv->height = h; + p->priv->format = format; + + p->priv->surface.w = w; + p->priv->surface.h = h; + p->priv->surface.format = IMGFMT_MPEG12; + p->priv->surface.bpp = 420; /* I Guess? */ + p->priv->surface.img[0] = malloc((w*h*3)/2); /* YUV420 Size */ + p->priv->surface.img[1] = p->priv->surface.img[0] + (w*h); + p->priv->surface.img[2] = p->priv->surface.img[1} + (w*h)/4; + p->priv->surface.stride[0] = w; + p->priv->surface.stride[1] = w/2; + p->priv->surface.stride[2] = p->priv->surface.stride[1]; + return 1; +} + +static int stop(void *p) +{ + // stop rendering, close device + printf("VO2_DXR3: stop()\n"); + delete p->priv->config; + delete p->priv->spubuf; + close( p->priv->fd_control ); + close( p->priv->fd_video ); + close( p->priv->fd_spu ); + return 1; +} + +// get destination surface (for direct rendering or generic draw_ functions) +// num: number of frame. 0 = temporary frame - can be dropped/modified +// 1-2 = static frames - should not be modified +// Note: mpeg will use 0,1,2 frames for B,Pf,Pb (or fallback to 0-only) +// win32 will use only 0 +static vo2_surface_t* get_surface(void *p, int num) +{ + printf("VO2_DXR3: get_surface(%d)\n",num); + return &p->priv->surface; +} + +static void flip_image(void *p, int num) +{ + // we can assume that num is valid (get_surface(num) will return non-NULL) + printf("VO2_DXR3: flip_image(%d)\n",num); + + // Direct rendering is not available with a dxr3 so we use push instead... + if( ioctl( p->priv->fd_video, EM8300_IOCTL_VIDEO_SETPS, &p->priv->surface.pts ) < 0 ) + printf( "VO2_DXR3: Unable to set frame pts\n" ); + write( p->priv->fd_video, p->priv->surface.img[0], p->priv->surface.w*p->priv->surface.h ); +} + + +