Xvideo initial window size bug-fix
Shane Harper
shanegh at optusnet.com.au
Fri Apr 13 04:34:57 CEST 2001
Samuel Hocevar wrote:
> - it only works if the stream size equals the initial window size (most
> of the time, 720x576). this is rather a limitation of video output,
> but if a quick hack can be found until it gets fixed, I don't think
> it will hurt
I hope I've fixed it.
Shane.
-- Attached file included as plaintext by Listar --
-- File: vlc-xvideo-size-fix.diff
--- vlc/plugins/x11/vout_xvideo.c Wed Apr 11 12:01:24 2001
+++ vlc-xvideo-fix/plugins/x11/vout_xvideo.c Fri Apr 13 12:04:17 2001
@@ -71,9 +71,7 @@
* vout_sys_t: video output X11 method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
- * It describes the X11 specific properties of an output thread. X11 video
- * output is performed through regular resizable windows. Windows can be
- * dynamically resized to adapt to the size of the streams.
+ * It describes the XVideo specific properties of an output thread.
*****************************************************************************/
typedef struct vout_sys_s
{
@@ -91,16 +89,23 @@
int xv_port;
/* Display buffers and shared memory information */
- /* Note: only 1 buffer (I don't know why the X11 plugin had 2.) */
+ /* Note: only 1 buffer... Xv ext does double buffering. */
XvImage * p_xvimage;
+ int i_image_width;
+ int i_image_height;
+ /* i_image_width & i_image_height reflect the
+ * size of the XvImage. They are used by
+ * vout_Display() to check if the image to be
+ * displayed can use the current XvImage. */
XShmSegmentInfo shm_info; /* shared memory zone information */
/* X11 generic properties */
Atom wm_protocols;
Atom wm_delete_window;
- int i_width; /* width of main window */
- int i_height; /* height of main window */
+ int i_window_width; /* width of main window */
+ int i_window_height; /* height of main window */
+
/* Screen saver properties */
int i_ss_timeout; /* timeout */
@@ -129,14 +134,17 @@
static void vout_SetPalette( vout_thread_t *, u16 *, u16 *, u16 *, u16 * );
static int XVideoCreateWindow ( vout_thread_t * );
-static int XVideoCreateShmImage ( vout_thread_t *, XvImage **,
- XShmSegmentInfo *p_shm_info );
+static int XVideoUpdateImgSizeIfRequired( vout_thread_t *p_vout );
+static int XVideoCreateShmImage ( Display* dpy, int xv_port,
+ XvImage **pp_xvimage,
+ XShmSegmentInfo *p_shm_info,
+ int i_width, int i_height );
static void XVideoDestroyShmImage ( vout_thread_t *, XvImage *,
XShmSegmentInfo * );
static void XVideoTogglePointer ( vout_thread_t * );
static void XVideoEnableScreenSaver ( vout_thread_t * );
static void XVideoDisableScreenSaver ( vout_thread_t * );
-static void XVideoSetAttribute ( vout_thread_t *, char *, float );
+/*static void XVideoSetAttribute ( vout_thread_t *, char *, float );*/
static int XVideoCheckForXv ( Display * );
static int XVideoGetPort ( Display * );
@@ -179,9 +187,9 @@
/*****************************************************************************
* vout_Create: allocate XVideo video thread output method
*****************************************************************************
- * This function allocate and initialize a X11 vout method. It uses some of the
- * vout properties to choose the window size, and change them according to the
- * actual properties of the display.
+ * This function allocate and initialize a XVideo vout method. It uses some of
+ * the vout properties to choose the window size, and change them according to
+ * the actual properties of the display.
*****************************************************************************/
static int vout_Create( vout_thread_t *p_vout )
{
@@ -228,10 +236,12 @@
if( (p_vout->p_sys->xv_port = XVideoGetPort( p_vout->p_sys->p_display ))<0 )
return 1;
+#if 0
/* XXX The brightness and contrast values should be read from environment
* XXX variables... */
XVideoSetAttribute( p_vout, "XV_BRIGHTNESS", 0.5 );
XVideoSetAttribute( p_vout, "XV_CONTRAST", 0.5 );
+#endif
p_vout->p_sys->b_mouse = 1;
@@ -243,56 +253,24 @@
/*****************************************************************************
* vout_Init: initialize XVideo video thread output method
- *****************************************************************************
- * This function creates the XvImage needed by the output thread. It is called
- * at the beginning of the thread, but also each time the window is resized.
*****************************************************************************/
static int vout_Init( vout_thread_t *p_vout )
{
- int i_err;
-
#ifdef SYS_DARWIN1_3
/* FIXME : As of 2001-03-16, XFree4 for MacOS X does not support Xshm. */
p_vout->p_sys->b_shm = 0;
#endif
-
- /* Create XvImage using XShm extension */
- i_err = XVideoCreateShmImage( p_vout, &p_vout->p_sys->p_xvimage,
- &p_vout->p_sys->shm_info );
- if( i_err )
- {
- intf_Msg( "vout: XShm video extension unavailable" );
- /* p_vout->p_sys->b_shm = 0; */
- }
p_vout->b_need_render = 0;
+ p_vout->p_sys->i_image_width = p_vout->p_sys->i_image_height = 0;
- /* Set bytes per line and initialize buffers */
- p_vout->i_bytes_per_line =
- (p_vout->p_sys->p_xvimage->data_size) /
- (p_vout->p_sys->p_xvimage->height);
-
- /* vout_SetBuffers( p_vout, p_vout->p_sys->p_xvimage[0]->data,
- * p_vout->p_sys->p_xvimage[1]->data ); */
- p_vout->p_buffer[0].i_pic_x = 0;
- p_vout->p_buffer[0].i_pic_y = 0;
- p_vout->p_buffer[0].i_pic_width = 0;
- p_vout->p_buffer[0].i_pic_height = 0;
-
- /* The first area covers all the screen */
- p_vout->p_buffer[0].i_areas = 1;
- p_vout->p_buffer[0].pi_area_begin[0] = 0;
- p_vout->p_buffer[0].pi_area_end[0] = p_vout->i_height - 1;
-
- /* Set addresses */
- p_vout->p_buffer[0].p_data = p_vout->p_sys->p_xvimage->data;
return( 0 );
}
/*****************************************************************************
* vout_End: terminate XVideo video thread output method
*****************************************************************************
- * Destroy the XVideo xImages created by vout_Init. It is called at the end of
- * the thread, but also each time the window is resized.
+ * Destroy the XvImage. It is called at the end of the thread, but also each
+ * time the image is resized.
*****************************************************************************/
static void vout_End( vout_thread_t *p_vout )
{
@@ -334,7 +312,6 @@
static int vout_Manage( vout_thread_t *p_vout )
{
XEvent xevent; /* X11 event */
- boolean_t b_resized; /* window has been resized */
char i_key; /* ISO Latin-1 key */
KeySym x_key_symbol;
@@ -342,7 +319,6 @@
* output window's size changed, MapNotify and UnmapNotify to know if the
* window is mapped (and if the display is useful), and ClientMessages
* to intercept window destruction requests */
- b_resized = 0;
while( XCheckWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
StructureNotifyMask | KeyPressMask |
ButtonPressMask | ButtonReleaseMask |
@@ -351,15 +327,12 @@
{
/* ConfigureNotify event: prepare */
if( (xevent.type == ConfigureNotify)
- && ((xevent.xconfigure.width != p_vout->p_sys->i_width)
- || (xevent.xconfigure.height != p_vout->p_sys->i_height)) )
+ /*&& ((xevent.xconfigure.width != p_vout->p_sys->i_window_width)
+ || (xevent.xconfigure.height != p_vout->p_sys->i_window_height))*/ )
{
/* Update dimensions */
-/* XXX XXX
- b_resized = 1;
- p_vout->p_sys->i_width = xevent.xconfigure.width;
- p_vout->p_sys->i_height = xevent.xconfigure.height;
- XXX XXX */
+ p_vout->p_sys->i_window_width = xevent.xconfigure.width;
+ p_vout->p_sys->i_window_height = xevent.xconfigure.height;
}
/* MapNotify event: change window status and disable screen saver */
else if( xevent.type == MapNotify)
@@ -401,7 +374,6 @@
if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
{
- /* FIXME: handle stuff here */
switch( i_key )
{
case 'q':
@@ -510,17 +482,6 @@
}
}
- if( (p_vout->i_width != p_vout->p_sys->i_width) ||
- (p_vout->i_height != p_vout->p_sys->i_height) )
- {
- /* If video output size has changed, change interface window size */
- intf_DbgMsg( "resizing output window" );
- p_vout->p_sys->i_width = p_vout->i_width;
- p_vout->p_sys->i_height = p_vout->i_height;
- XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
- p_vout->p_sys->i_width, p_vout->p_sys->i_height );
- }
-
if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE))
{
/* FIXME: clear flags ?? */
@@ -533,49 +494,81 @@
{
intf_DbgMsg( "vout: resizing window" );
p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
+ /* Noting to do here...
+ * vout_Display() detects size changes of the image to be displayed and
+ * re-creates the XvImage.*/
+ intf_Msg( "vout: video display resized (%dx%d)",
+ p_vout->i_width, p_vout->i_height );
+ }
+
+ /* Autohide Cursor */
+ if( p_vout->p_sys->b_mouse &&
+ mdate() - p_vout->p_sys->i_lastmoved > 2000000 )
+ XVideoTogglePointer( p_vout );
+
+ return 0;
+}
+
+/*****************************************************************************
+ * XVideoUpdateImgSizeIfRequired
+ *****************************************************************************
+ * This function checks to see if the image to be displayed is of a different
+ * size to the last image displayed. If so, the old shm block must be
+ * destroyed and a new one created.
+ * Note: the "image size" is the size of the image to be passed to the Xv
+ * extension (which is probably different to the size of the output window).
+ *****************************************************************************/
+static int XVideoUpdateImgSizeIfRequired( vout_thread_t *p_vout )
+{
+ int i_img_width = p_vout->p_rendered_pic->i_width;
+ int i_img_height = p_vout->p_rendered_pic->i_height;
- /* Resize window */
- XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
- p_vout->i_width, p_vout->i_height );
+ if( p_vout->p_sys->i_image_width != i_img_width
+ || p_vout->p_sys->i_image_height != i_img_height )
+ {
+ p_vout->p_sys->i_image_width = i_img_width;
+ p_vout->p_sys->i_image_height = i_img_height;
- /* Destroy XImages to change their size */
+ /* Destroy XvImage to change its size */
vout_End( p_vout );
+ /* Note: vout_End does nothing if no XvImage to destroy. */
- /* Recreate XImages. If SysInit failed, the thread cannot go on. */
- if( vout_Init( p_vout ) )
+ /* Create XvImage using XShm extension */
+ if( XVideoCreateShmImage( p_vout->p_sys->p_display,
+ p_vout->p_sys->xv_port,
+ &p_vout->p_sys->p_xvimage,
+ &p_vout->p_sys->shm_info,
+ i_img_width, i_img_height ) )
{
- intf_ErrMsg( "vout error: cannot resize display" );
+ intf_Msg( "vout: failed to create xvimage." );
+ p_vout->p_sys->i_image_width = 0;
return( 1 );
- }
+ }
- intf_Msg( "vout: video display resized (%dx%d)",
- p_vout->i_width, p_vout->i_height );
- }
+ /* Set bytes per line and initialize buffers */
+ p_vout->i_bytes_per_line =
+ (p_vout->p_sys->p_xvimage->data_size) /
+ (p_vout->p_sys->p_xvimage->height);
- /* Autohide Cursour */
- if( mdate() - p_vout->p_sys->i_lastmoved > 2000000 )
- {
- /* Hide the mouse automatically */
- if( p_vout->p_sys->b_mouse )
- {
- XVideoTogglePointer( p_vout );
- }
+ /* vout_SetBuffers( p_vout, p_vout->p_sys->p_xvimage->data ); */
}
-
- return 0;
+ return( 0 );
}
-
/*****************************************************************************
* vout_Display: displays previously rendered output
*****************************************************************************
- * This function send the currently rendered image to X11 server, wait until
- * it is displayed and switch the two rendering buffer, preparing next frame.
+ * This function sends the currently rendered image to X11 server.
+ * (The Xv extension takes care of "double-buffering".)
*****************************************************************************/
static void vout_Display( vout_thread_t *p_vout )
{
boolean_t b_draw = 1;
- const int i_size = p_vout->i_width * p_vout->i_height;
+ int i_size = p_vout->p_rendered_pic->i_width *
+ p_vout->p_rendered_pic->i_height;
+
+ if( XVideoUpdateImgSizeIfRequired( p_vout ) )
+ return;
switch( p_vout->p_rendered_pic->i_type )
{
@@ -601,18 +594,24 @@
if( b_draw )
{
- int i_dummy, i_src_width, i_src_height,
+ int i_dummy,
+ i_window_width = p_vout->p_sys->i_window_width,
+ i_window_height = p_vout->p_sys->i_window_height,
i_dest_width, i_dest_height, i_dest_x, i_dest_y;
Window window;
- /* Could use p_vout->p_sys->i_width and p_vout->p_sys->i_height
- *instead of calling XGetGeometry? */
+#if 1
+ /* If I change the line above to "#if 0" I find on resizing the window
+ * that blue rectangles (used to specify where part of the YUV overlay
+ * used to be drawn) may remain around the edge of the video output. */
XGetGeometry( p_vout->p_sys->p_display, p_vout->p_sys->window,
&window, &i_dummy, &i_dummy,
- &i_src_width, &i_src_height, &i_dummy, &i_dummy );
+ &i_window_width, &i_window_height, &i_dummy, &i_dummy );
+#endif
XVideoOutputCoords( p_vout->p_rendered_pic, p_vout->b_scale,
- i_src_width, i_src_height, &i_dest_x, &i_dest_y,
+ i_window_width, i_window_height,
+ &i_dest_x, &i_dest_y,
&i_dest_width, &i_dest_height);
XvShmPutImage( p_vout->p_sys->p_display, p_vout->p_sys->xv_port,
@@ -674,14 +673,14 @@
boolean_t b_map_notify;
/* Set main window's size */
- p_vout->p_sys->i_width = main_GetIntVariable( VOUT_WIDTH_VAR,
+ p_vout->p_sys->i_window_width = main_GetIntVariable( VOUT_WIDTH_VAR,
VOUT_WIDTH_DEFAULT );
- p_vout->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR,
+ p_vout->p_sys->i_window_height = main_GetIntVariable( VOUT_HEIGHT_VAR,
VOUT_HEIGHT_DEFAULT );
/* Prepare window manager hints and properties */
- xsize_hints.base_width = p_vout->p_sys->i_width;
- xsize_hints.base_height = p_vout->p_sys->i_height;
+ xsize_hints.base_width = p_vout->p_sys->i_window_width;
+ xsize_hints.base_height = p_vout->p_sys->i_window_height;
xsize_hints.flags = PSize;
p_vout->p_sys->wm_protocols = XInternAtom( p_vout->p_sys->p_display,
"WM_PROTOCOLS", True );
@@ -701,7 +700,8 @@
XCreateWindow( p_vout->p_sys->p_display,
DefaultRootWindow( p_vout->p_sys->p_display ),
0, 0,
- p_vout->p_sys->i_width, p_vout->p_sys->i_height, 1,
+ p_vout->p_sys->i_window_width,
+ p_vout->p_sys->i_window_height, 1,
0, InputOutput, 0,
CWBackingStore | CWBackPixel | CWEventMask,
&xwindow_attributes );
@@ -757,8 +757,8 @@
&& (xevent.xconfigure.window == p_vout->p_sys->window) )
{
b_configure_notify = 1;
- p_vout->p_sys->i_width = xevent.xconfigure.width;
- p_vout->p_sys->i_height = xevent.xconfigure.height;
+ p_vout->p_sys->i_window_width = xevent.xconfigure.width;
+ p_vout->p_sys->i_window_height = xevent.xconfigure.height;
}
} while( !( b_expose && b_configure_notify && b_map_notify ) );
@@ -780,15 +780,16 @@
* document by J.Corbet and K.Packard. Most of the parameters were copied from
* there.
*****************************************************************************/
-static int XVideoCreateShmImage( vout_thread_t *p_vout, XvImage **pp_xvimage,
- XShmSegmentInfo *p_shm_info)
+static int XVideoCreateShmImage( Display* dpy, int xv_port,
+ XvImage **pp_xvimage,
+ XShmSegmentInfo *p_shm_info,
+ int i_width, int i_height )
{
#define GUID_YUV12_PLANAR 0x32315659
- *pp_xvimage = XvShmCreateImage( p_vout->p_sys->p_display,
- p_vout->p_sys->xv_port,
+ *pp_xvimage = XvShmCreateImage( dpy, xv_port,
GUID_YUV12_PLANAR, 0,
- p_vout->i_width, p_vout->i_height,
+ i_width, i_height,
p_shm_info );
p_shm_info->shmid = shmget( IPC_PRIVATE, (*pp_xvimage)->data_size,
@@ -799,7 +800,7 @@
shmctl( p_shm_info->shmid, IPC_RMID, 0 ); /* XXX */
- if( !XShmAttach(p_vout->p_sys->p_display, p_shm_info) )
+ if( !XShmAttach( dpy, p_shm_info ) )
{
intf_ErrMsg( "vout error: XShmAttach failed" );
return( -1 );
@@ -807,7 +808,7 @@
/* Send image to X server. This instruction is required, since having
* built a Shm XImage and not using it causes an error on XCloseDisplay */
- XFlush( p_vout->p_sys->p_display );
+ XFlush( dpy );
return( 0 );
}
@@ -830,9 +831,7 @@
XShmDetach( p_vout->p_sys->p_display, p_shm_info );/* detach from server */
#if 0
- XDestroyImage( p_ximage );
-#else
-/* XvDestroyImage( p_xvimage ); XXX */
+ XDestroyImage( p_ximage ); /* XXX */
#endif
if( shmdt( p_shm_info->shmaddr ) ) /* detach shared memory from process */
@@ -1008,6 +1007,7 @@
}
+#if 0
/*****************************************************************************
* XVideoSetAttribute
*****************************************************************************
@@ -1028,7 +1028,7 @@
{
i_attrib--;
- if( !strcmp( p_attrib[ i_attrib ].name, attr_name ) )
+ if( i_attrib >= 0 && !strcmp( p_attrib[ i_attrib ].name, attr_name ) )
{
int i_sv = f_value * ( p_attrib[ i_attrib ].max_value
- p_attrib[ i_attrib ].min_value + 1 )
@@ -1041,4 +1041,4 @@
} while( i_attrib > 0 );
}
-
+#endif
More information about the vlc-devel
mailing list