[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