[MPlayer-dev-eng] *SUGGESTED* libvo2 patch
David Holm
dholm at telia.com
Sun Nov 18 16:14:43 CET 2001
David Holm wrote:
>Hi,
>here is a suggested libvo2 patch, perhaps arpi should read it through first?
>
>
>------------------------------------------------------------------------
>
>diff -Naur -x CVS -x .* -x *.o -x config.h -x *.mak main/configure main-dxr3/configure
>--- main/configure Sun Nov 18 15:34:00 2001
>+++ main-dxr3/configure Sun Nov 18 16:00:16 2001
>@@ -1854,6 +1843,7 @@
> echo "Checking for X11 headers ... $_x11incdir"
> if test "$_vo2" = yes ; then
> echo "Checking for libvo2 ... $_vo2"
>+ echo "Checking for dxr3 ... $_dxr3"
> else
> echo "Checking mga_vid device ... $_mga"
> echo "Checking for xmga ... $_xmga"
>diff -Naur -x CVS -x .* -x *.o -x config.h -x *.mak 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 Sun Nov 18 12:27:13 2001
>@@ -38,6 +38,8 @@
> case IMGFMT_CLJR: return("Packed CLJR");
> case IMGFMT_YUVP: return("Packed YUVP");
> case IMGFMT_UYVP: return("Packed UYVP");
>+ case IMGFMT_MPEGPES: return("MPEG-PES");
>+ case IMGFMT_MPEG12: return("MPEG-(1/2)");
> }
> return("Unknown");
> }
>diff -Naur -x CVS -x .* -x *.o -x config.h -x *.mak 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 Sun Nov 18 12:26:45 2001
>@@ -50,6 +50,18 @@
> #define IMGFMT_YUVP 0x50565559
> #define IMGFMT_UYVP 0x50565955
>
>+/* Compressed Formats */
>+#define IMGFMT_MPEGPES (('M'<<24)|('P'<<16)|('E'<<8)|('S'))
>+#define IMGFMT_MPEG12 (('M'<<24)|('G'<<16)|('1'<<8)|('2'))
>+
> 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 .* -x *.o -x config.h -x *.mak 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 Sun Nov 18 15:30:04 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,7 @@
> 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 {
>@@ -83,19 +64,24 @@
> 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);
>+int vo2_query_format(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);
>+// Save and load device options, if load returns NULL set to default
>+int vo2_save_devoptions(void);
>+int vo2_load_devoptions(void);
>
> // HACK
> typedef struct {
>@@ -122,3 +108,79 @@
>
> 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][0]="Outdevice\t[5]" means the
>+ option has 5 different choices, which are read
>+ through options[optionnum][choicenum]
>+ i.e. options[0][2]="/dev/dev3"
>+ the last choice _MUST_ be =NULL
>+
>+ 2. options[1][0]="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[2][0]="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 .* -x *.o -x config.h -x *.mak main/libvo2/vo2_def.h main-dxr3/libvo2/vo2_def.h
>--- main/libvo2/vo2_def.h Tue Jul 31 02:30:15 2001
>+++ main-dxr3/libvo2/vo2_def.h Sun Nov 18 15:06:14 2001
>@@ -16,12 +16,11 @@
> flip_image
> };
>
>-static vo2_handle_t* new_handle(){
>+static vo2_handle_t* new_handle( priv_t *handle )
>+{
> vo2_handle_t* h=malloc(sizeof(vo2_handle_t));
> if(!h) return NULL;
>- h->priv=malloc(sizeof(priv_t));
>- if(!h->priv){ free(h); return NULL; }
>- memset(h->priv,0,sizeof(priv_t));
>+ h->priv=handle;
> h->info=&info;
> h->functions=&functions;
> h->surface=NULL;
>diff -Naur -x CVS -x .* -x *.o -x config.h -x *.mak 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 Sun Nov 18 15:43:44 2001
>@@ -0,0 +1,184 @@
>+
>+#include <stdio.h>
>+#include <stdlib.h>
>+
>+#include "libvo2.h"
>+#include "img_format.h"
>+
>+// Driver info:
>+static vo2_info_t info =
>+{
>+ "DXR3/Hollywood Plus VO2 Device",
>+ "dxr3",
>+ "David Holm <dholm at iname.com>",
>+ "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;
>+
>+static priv_t dxr3;
>+
>+#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
>+vo2_handle_t* vo2_init_dxr3()
>+{
>+ int ioval;
>+ printf("VO2_DXR3: init()\n");
>+ /* 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( (dxr3.fd_control = open( "/dev/em8300", O_WRONLY )) < 0 )
>+ {
>+ printf( "VO2_DXR3: unable to open /dev/em8300\n" );
>+ return 0;
>+ }
>+ if( (dxr3.fd_video = open( "/dev/em8300_mv", O_WRONLY )) < 0 )
>+ {
>+ printf( "VO2_DXR3: unable to open /dev/em8300_mv\n" );
>+ return 0;
>+ }
>+ if( (dxr3.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( dxr3.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( dxr3.fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval ) < 0 )
>+ printf( "VO2_DXR3: unable to set playmode\n" );
>+
>+ dxr3.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 */
>+ dxr3.config.numoptions = 0;
>+ dxr3.config.options = NULL;
>+ dxr3.option_types = NULL;
>+ dxr3.values = NULL;
>+
>+ return new_handle(&dxr3);
>+}
>+
>+// 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_MPEG12;
>+ 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)
>+{
>+
>+ // open window / switch vidmode, set up surfaces etc...
>+ printf("vo2_sample: start() %dx%d %s %d 0x%X\n",w,h,vo_format_name(format),buffering,flags);
>+ dxr3.width = w;
>+ dxr3.height = h;
>+ dxr3.format = format;
>+
>+ dxr3.surface.w = w;
>+ dxr3.surface.h = h;
>+ dxr3.surface.format = IMGFMT_MPEG12;
>+ dxr3.surface.img[0] = malloc((w*h*3)/2); /* YUV420 Size */
>+ dxr3.surface.img[1] = dxr3.surface.img[0] + (w*h);
>+ dxr3.surface.img[2] = dxr3.surface.img[1} + (w*h)/4;
>+ dxr3.surface.stride[0] = w;
>+ dxr3.surface.stride[1] = w/2;
>+ dxr3.surface.stride[2] = dxr3.surface.stride[1];
>+ return 1;
>+}
>+
>+static int stop(void *p)
>+{
>+ // stop rendering, close device
>+ printf("VO2_DXR3: stop()\n");
>+ delete dxr3.spubuf;
>+ close( dxr3.fd_control );
>+ close( dxr3.fd_video );
>+ close( dxr3.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 &dxr3.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( dxr3.fd_video, EM8300_IOCTL_VIDEO_SETPS, &dxr3.surface.pts ) < 0 )
>+ printf( "VO2_DXR3: Unable to set frame pts\n" );
>+ write( dxr3.fd_video, dxr3.surface.img[0], dxr3.surface.w*dxr3.surface.h );
>+}
>+
>+
>+
>
Since Arpi didn't like my new_handle(...) proposal remove that part...
(This one:
diff -Naur -x CVS -x .* -x *.o -x config.h -x *.mak main/libvo2/vo2_def.h main-dxr3/libvo2/vo2_def.h
--- main/libvo2/vo2_def.h Tue Jul 31 02:30:15 2001
+++ main-dxr3/libvo2/vo2_def.h Sun Nov 18 15:06:14 2001
@@ -16,12 +16,11 @@
flip_image
};
-static vo2_handle_t* new_handle(){
+static vo2_handle_t* new_handle( priv_t *handle )
+{
vo2_handle_t* h=malloc(sizeof(vo2_handle_t));
if(!h) return NULL;
- h->priv=malloc(sizeof(priv_t));
- if(!h->priv){ free(h); return NULL; }
- memset(h->priv,0,sizeof(priv_t));
+ h->priv=handle;
h->info=&info;
h->functions=&functions;
h->surface=NULL;
)
I'll fix vo2_dxr3.c in the next patch, it isn't that important that it's
correctly implemented now anyway...
//David
More information about the MPlayer-dev-eng
mailing list