+#ifdef MODULE_NAME_IS_xvmc
+
+#define XINE_IMGFMT_YV12 (('2'<<24)|('1'<<16)|('V'<<8)|'Y')
+
+/* called xlocked */
+static int xvmc_check_yv12( Display *display, XvPortID port )
+{
+ XvImageFormatValues *formatValues;
+ int formats;
+ int i;
+
+ formatValues = XvListImageFormats( display, port, &formats );
+
+ for( i = 0; i < formats; i++ )
+ {
+ if( ( formatValues[i].id == XINE_IMGFMT_YV12 ) &&
+ ( !( strncmp( formatValues[i].guid, "YV12", 4 ) ) ) )
+ {
+ XFree (formatValues);
+ return 0;
+ }
+ }
+
+ XFree (formatValues);
+ return 1;
+}
+
+static void xvmc_sync_surface( vout_thread_t *p_vout, XvMCSurface * srf )
+{
+ XvMCSyncSurface( p_vout->p_sys->p_display, srf );
+}
+
+static void xvmc_update_XV_DOUBLE_BUFFER( vout_thread_t *p_vout )
+{
+ Atom atom;
+ int xv_double_buffer;
+
+ xv_double_buffer = 1;
+
+ XLockDisplay( p_vout->p_sys->p_display );
+ atom = XInternAtom( p_vout->p_sys->p_display, "XV_DOUBLE_BUFFER", False );
+#if 0
+ XvSetPortAttribute (p_vout->p_sys->p_display, p_vout->p_sys->i_xvport, atom, xv_double_buffer);
+#endif
+ XvMCSetAttribute( p_vout->p_sys->p_display, &p_vout->p_sys->context, atom, xv_double_buffer );
+ XUnlockDisplay( p_vout->p_sys->p_display );
+
+ //xprintf(this->xine, XINE_VERBOSITY_DEBUG,
+ // "video_out_xxmc: double buffering mode = %d\n", xv_double_buffer);
+}
+
+static void RenderVideo( vout_thread_t *p_vout, picture_t *p_pic )
+{
+ vlc_xxmc_t *xxmc = NULL;
+
+ vlc_mutex_lock( &p_vout->p_sys->lock );
+ xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock );
+
+ xxmc = &p_pic->p_sys->xxmc_data;
+ if( (!xxmc->decoded ||
+ !xxmc_xvmc_surface_valid( p_vout, p_pic->p_sys->xvmc_surf )) )
+ {
+ vlc_mutex_unlock( &p_vout->p_sys->lock );
+ xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
+ return;
+ }
+
+ vlc_mutex_lock( &p_vout->lastsubtitle_lock );
+
+ if (p_vout->p_last_subtitle != NULL)
+ {
+ if( p_vout->p_sys->p_last_subtitle_save != p_vout->p_last_subtitle )
+ {
+ p_vout->p_sys->new_subpic =
+ xxmc_xvmc_alloc_subpicture( p_vout, &p_vout->p_sys->context,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height,
+ p_vout->p_sys->xvmc_cap[p_vout->p_sys->xvmc_cur_cap].subPicType.id );
+
+ if (p_vout->p_sys->new_subpic)
+ {
+ XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
+ XvMCClearSubpicture( p_vout->p_sys->p_display,
+ p_vout->p_sys->new_subpic,
+ 0,
+ 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height,
+ 0x00 );
+ XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
+ clear_xx44_palette( &p_vout->p_sys->palette );
+
+ if( sub_pic.p_sys == NULL )
+ {
+ sub_pic.p_sys = malloc( sizeof( picture_sys_t ) );
+ if( sub_pic.p_sys != NULL )
+ {
+ sub_pic.p_sys->p_vout = p_vout;
+ sub_pic.p_sys->xvmc_surf = NULL;
+ sub_pic.p_sys->p_image = p_vout->p_sys->subImage;
+ }
+ }
+ sub_pic.p_sys->p_image = p_vout->p_sys->subImage;
+ sub_pic.p->p_pixels = sub_pic.p_sys->p_image->data;
+ sub_pic.p->i_pitch = p_vout->output.i_width;
+
+ memset( p_vout->p_sys->subImage->data, 0,
+ (p_vout->p_sys->subImage->width * p_vout->p_sys->subImage->height) );
+
+ if (p_vout->p_last_subtitle != NULL)
+ {
+ blend_xx44( p_vout->p_sys->subImage->data,
+ p_vout->p_last_subtitle,
+ p_vout->p_sys->subImage->width,
+ p_vout->p_sys->subImage->height,
+ p_vout->p_sys->subImage->width,
+ &p_vout->p_sys->palette,
+ (p_vout->p_sys->subImage->id == FOURCC_IA44) );
+ }
+
+ XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
+ XvMCCompositeSubpicture( p_vout->p_sys->p_display,
+ p_vout->p_sys->new_subpic,
+ p_vout->p_sys->subImage,
+ 0, /* overlay->x */
+ 0, /* overlay->y */
+ p_vout->output.i_width, /* overlay->width, */
+ p_vout->output.i_height, /* overlay->height */
+ 0, /* overlay->x */
+ 0 ); /*overlay->y */
+ XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
+ if (p_vout->p_sys->old_subpic)
+ {
+ xxmc_xvmc_free_subpicture( p_vout,
+ p_vout->p_sys->old_subpic);
+ p_vout->p_sys->old_subpic = NULL;
+ }
+ if (p_vout->p_sys->new_subpic)
+ {
+ p_vout->p_sys->old_subpic = p_vout->p_sys->new_subpic;
+ p_vout->p_sys->new_subpic = NULL;
+ xx44_to_xvmc_palette( &p_vout->p_sys->palette,
+ p_vout->p_sys->xvmc_palette,
+ 0,
+ p_vout->p_sys->old_subpic->num_palette_entries,
+ p_vout->p_sys->old_subpic->entry_bytes,
+ p_vout->p_sys->old_subpic->component_order );
+ XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
+ XvMCSetSubpicturePalette( p_vout->p_sys->p_display,
+ p_vout->p_sys->old_subpic,
+ p_vout->p_sys->xvmc_palette );
+ XvMCFlushSubpicture( p_vout->p_sys->p_display,
+ p_vout->p_sys->old_subpic);
+ XvMCSyncSubpicture( p_vout->p_sys->p_display,
+ p_vout->p_sys->old_subpic );
+ XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
+ }
+
+ XVMCLOCKDISPLAY( p_vout->p_sys->p_display);
+ if (p_vout->p_sys->xvmc_backend_subpic )
+ {
+ XvMCBlendSubpicture( p_vout->p_sys->p_display,
+ p_pic->p_sys->xvmc_surf,
+ p_vout->p_sys->old_subpic,
+ 0,
+ 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height,
+ 0,
+ 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height );
+ }
+ else
+ {
+ XvMCBlendSubpicture2( p_vout->p_sys->p_display,
+ p_pic->p_sys->xvmc_surf,
+ p_pic->p_sys->xvmc_surf,
+ p_vout->p_sys->old_subpic,
+ 0,
+ 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height,
+ 0,
+ 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height );
+ }
+ XVMCUNLOCKDISPLAY(p_vout->p_sys->p_display);
+ }
+ }
+ else
+ {
+ XVMCLOCKDISPLAY( p_vout->p_sys->p_display );
+ if( p_vout->p_sys->xvmc_backend_subpic )
+ {
+ XvMCBlendSubpicture( p_vout->p_sys->p_display,
+ p_pic->p_sys->xvmc_surf,
+ p_vout->p_sys->old_subpic,
+ 0, 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height,
+ 0, 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height );
+ }
+ else
+ {
+ XvMCBlendSubpicture2( p_vout->p_sys->p_display,
+ p_pic->p_sys->xvmc_surf,
+ p_pic->p_sys->xvmc_surf,
+ p_vout->p_sys->old_subpic,
+ 0, 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height,
+ 0, 0,
+ p_vout->p_sys->xvmc_width,
+ p_vout->p_sys->xvmc_height );
+ }
+ XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
+ }
+ }
+ p_vout->p_sys->p_last_subtitle_save = p_vout->p_last_subtitle;
+
+ vlc_mutex_unlock( &p_vout->lastsubtitle_lock );
+ xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
+
+ vlc_mutex_unlock( &p_vout->p_sys->lock );
+}
+#endif
+
+#ifdef HAVE_XSP
+/*****************************************************************************
+ * EnablePixelDoubling: Enables pixel doubling
+ *****************************************************************************
+ * Checks if the double size image fits in current window, and enables pixel
+ * doubling accordingly. The i_hw_scale is the integer scaling factor.
+ *****************************************************************************/
+static void EnablePixelDoubling( vout_thread_t *p_vout )
+{
+ int i_hor_scale = ( p_vout->p_sys->p_win->i_width ) / p_vout->render.i_width;
+ int i_vert_scale = ( p_vout->p_sys->p_win->i_height ) / p_vout->render.i_height;
+ if ( ( i_hor_scale > 1 ) && ( i_vert_scale > 1 ) ) {
+ p_vout->p_sys->i_hw_scale = 2;
+ msg_Dbg( p_vout, "Enabling pixel doubling, scaling factor %d", p_vout->p_sys->i_hw_scale );
+ XSPSetPixelDoubling( p_vout->p_sys->p_display, 0, 1 );
+ }
+}
+
+/*****************************************************************************
+ * DisablePixelDoubling: Disables pixel doubling
+ *****************************************************************************
+ * The scaling factor i_hw_scale is reset to the no-scaling value 1.
+ *****************************************************************************/
+static void DisablePixelDoubling( vout_thread_t *p_vout )
+{
+ if ( p_vout->p_sys->i_hw_scale > 1 ) {
+ msg_Dbg( p_vout, "Disabling pixel doubling" );
+ XSPSetPixelDoubling( p_vout->p_sys->p_display, 0, 0 );
+ p_vout->p_sys->i_hw_scale = 1;
+ }
+}
+#endif
+
+
+