Index: libvo/video_out.c =================================================================== --- libvo/video_out.c (revision 24089) +++ libvo/video_out.c (working copy) @@ -96,6 +96,9 @@ #ifdef HAVE_DIRECTX extern vo_functions_t video_out_directx; #endif +#ifdef HAVE_KVA +extern vo_functions_t video_out_kva; +#endif #ifdef HAVE_DXR2 extern vo_functions_t video_out_dxr2; #endif @@ -159,6 +162,9 @@ #ifdef HAVE_DIRECTX &video_out_directx, #endif +#ifdef HAVE_KVA + &video_out_kva, +#endif #ifdef MACOSX #ifdef MACOSX_COREVIDEO &video_out_macosx, Index: libvo/vo_kva.c =================================================================== --- libvo/vo_kva.c (revision 0) +++ libvo/vo_kva.c (revision 0) @@ -0,0 +1,889 @@ +/* + * vo_kva.c + * + * Copyright (c) 2007 by KO Myung-Hun (komh@chollian.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Changes : + * KO Myung-Hun 2007/06/11 + * - Added workaround for T23 laptop with S3 Video + * + * KO Myung-Hun 2007/06/17 + * - Implemented VOCTRL_SET_EQUALIZER and VOCTRL_GET_EQUALIZER + * - Added YV12 as a supported image format + * - Added process VK_ENTER and VK_NEWLINE + * + * KO Myung-Hun 2007/07/08 + * - Call fast_memcpy() instead of memcpy() + * + */ + +#define INCL_WIN +#include + +#include + +#include +#include +#include +#include + +#include "config.h" +#include "mp_msg.h" +#include "help_mp.h" +#include "video_out.h" +#include "video_out_internal.h" + +#include "fastmemcpy.h" +#include "osdep/keycodes.h" +#include "input/input.h" +#include "input/mouse.h" +#include "subopt-helper.h" +#include "sub.h" + +#include "cpudetect.h" +#include "libswscale/swscale.h" +#include "libmpcodecs/vf_scale.h" + +#include "kva.h" + +static vo_info_t info = +{ + "DIVE/WarpOverlay! video output", + "kva", + "KO Myung-Hun ", + "" +}; + +LIBVO_EXTERN( kva ) + +#define WC_MPLAYER "WC_MPLAYER" +#define COLOR_OVERLAY 0x000008 + +#define SRC_WIDTH m_int.kvas.szlSrcSize.cx +#define SRC_HEIGHT m_int.kvas.szlSrcSize.cy + +#define SCREEN_WIDTH m_int.kvac.cxScreen +#define SCREEN_HEIGHT m_int.kvac.cyScreen + +typedef struct tagVOKVAINTERNAL +{ + HAB hab; + HMQ hmq; + HWND hwndFrame; + HWND hwndClient; + HWND hwndSysMenu; + HWND hwndTitleBar; + HWND hwndMinMax; + BOOL fFullScreen; + FOURCC fcc; + INT iImageFormat; + KVASETUP kvas; + KVACAPS kvac; + RECTL rclDst; + INT bpp; + LONG lStride; + PBYTE pbImage; + BOOL fFixT23; + PFNWP pfnwpOldFrame; + uint8_t *yv12Planes[ 3 ]; // use as YUV420P format unlike name + int yv12Stride[ 3 ]; + struct SwsContext *sws; +} VOKVAINTERNAL, *PVOKVAINTERNAL; + +static VOKVAINTERNAL m_int; + +extern void mplayer_put_key( int code ); // let mplayer handel the keyevents + +static PBYTE imgCreate( VOID ) +{ + int size; + + size = SRC_HEIGHT * m_int.lStride; + + if( m_int.iImageFormat == IMGFMT_YV12 ) + size += size / 2; + + return malloc( size ); +} + +static VOID imgFree( PBYTE pbImage ) +{ + if( pbImage ) + free( pbImage ); +} + +static VOID imgDisplay( PBYTE pbImage ) +{ + PVOID pBuffer; + ULONG ulBPL; + + if( !kvaLockBuffer( &pBuffer, &ulBPL )) + { + if( m_int.iImageFormat == IMGFMT_YV12 ) + { + sws_scale( m_int.sws, m_int.yv12Planes, m_int.yv12Stride, 0, SRC_HEIGHT, + &pBuffer, &ulBPL ); + + if( gCpuCaps.hasMMX ) + asm volatile ("emms\n\t"); + } + else + fast_memcpy( pBuffer, pbImage, SRC_HEIGHT * ulBPL ); + + kvaUnlockBuffer(); + } +} + +#define MRETURN( ret ) return ( MRESULT )( ret ) + +static MRESULT EXPENTRY NewFrameWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) +{ + switch( msg ) + { + case WM_QUERYTRACKINFO : + { + //USHORT ustflags = SHORT1FROMMP( mp1 ); + PTRACKINFO pti = ( PTRACKINFO )mp2; + RECTL rcl; + + if( m_int.fFullScreen ) + break; + + m_int.pfnwpOldFrame( hwnd, msg, mp1, mp2 ); + + //if( ustflags & ( TF_LEFT | TF_RIGHT | TF_TOP | TF_BOTTOM | TF_SETPOINTERPOS )) + { + #if 0 + pti->rclBoundary.xLeft = 0; + pti->rclBoundary.yBottom = 0; + pti->rclBoundary.xRight = SCREEN_WIDTH; + pti->rclBoundary.yTop = SCREEN_HEIGHT; + #endif + + rcl.xLeft = 0; + rcl.yBottom = 0; + rcl.xRight = SRC_WIDTH + 1 ; + rcl.yTop = SRC_HEIGHT + 1; + + WinCalcFrameRect( hwnd, &rcl, FALSE ); + + pti->ptlMinTrackSize.x = rcl.xRight - rcl.xLeft; + pti->ptlMinTrackSize.y = rcl.yTop - rcl.yBottom; + + pti->ptlMaxTrackSize.x = SCREEN_WIDTH; + pti->ptlMaxTrackSize.y = SCREEN_HEIGHT; + } + + MRETURN( TRUE ); + } + + case WM_ADJUSTWINDOWPOS : + { + PSWP pswp = ( PSWP )mp1; + RECTL rcl; + + if( m_int.fFullScreen ) + break; + + if( pswp->fl & SWP_SIZE ) + { + rcl.xLeft = pswp->x; + rcl.yBottom = pswp->y; + rcl.xRight = rcl.xLeft + pswp->cx; + rcl.yTop = rcl.yBottom + pswp->cy; + + WinCalcFrameRect( hwnd, &rcl, TRUE ); + + if( rcl.xRight - rcl.xLeft <= SRC_WIDTH ) + rcl.xRight = rcl.xLeft + ( SRC_WIDTH + 1 ); + + if( rcl.yTop - rcl.yBottom <= SRC_HEIGHT ) + rcl.yTop = rcl.yBottom + ( SRC_HEIGHT + 1 ); + + WinCalcFrameRect( hwnd, &rcl, FALSE ); + + if( rcl.xRight - rcl.xLeft > SCREEN_WIDTH ) + { + rcl.xLeft = 0; + rcl.xRight = SCREEN_WIDTH; + } + + if( rcl.yTop - rcl.yBottom > SCREEN_HEIGHT ) + { + rcl.yBottom = 0; + rcl.yTop = SCREEN_HEIGHT; + } + + pswp->fl |= SWP_MOVE; + pswp->x = rcl.xLeft; + pswp->y = rcl.yBottom; + + pswp->cx = rcl.xRight - rcl.xLeft; + pswp->cy = rcl.yTop - rcl.yBottom; + } + + break; + } + } + + MRETURN( m_int.pfnwpOldFrame( hwnd, msg, mp1, mp2 )); +} + +static MRESULT EXPENTRY WndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) +{ + switch( msg ) + { + case WM_CLOSE : + mplayer_put_key( KEY_CLOSE_WIN ); + + MRETURN( 0 ); + + case WM_CHAR : + { + USHORT fsFlags = SHORT1FROMMP( mp1 ); + USHORT usCh = SHORT1FROMMP( mp2 ); + USHORT usVk = SHORT2FROMMP( mp2 ); + + if( fsFlags & KC_KEYUP ) + break; + + if( fsFlags & KC_VIRTUALKEY ) + { + switch( usVk ) + { + case VK_LEFT : + mplayer_put_key( KEY_LEFT ); + break; + + case VK_UP : + mplayer_put_key( KEY_UP ); + break; + + case VK_RIGHT : + mplayer_put_key( KEY_RIGHT ); + break; + + case VK_DOWN : + mplayer_put_key( KEY_DOWN ); + break; + + case VK_TAB : + mplayer_put_key( KEY_TAB ); + break; + + case VK_BACKSPACE : + mplayer_put_key( KEY_BS ); + break; + + case VK_DELETE : + mplayer_put_key( KEY_DELETE ); + break; + + case VK_INSERT : + mplayer_put_key( KEY_INSERT ); + break; + + case VK_HOME : + mplayer_put_key( KEY_HOME ); + break; + + case VK_END : + mplayer_put_key( KEY_END ); + break; + + case VK_PAGEUP : + mplayer_put_key( KEY_PAGE_UP ); + break; + + case VK_PAGEDOWN : + mplayer_put_key( KEY_PAGE_DOWN ); + break; + + case VK_ESC : + mplayer_put_key( KEY_ESC ); + break; + + case VK_SPACE : + mplayer_put_key(' '); + break; + + //case VK_ENTER : + case VK_NEWLINE : + mplayer_put_key( KEY_ENTER ); + break; + } + } + else if(( fsFlags & KC_CHAR ) && !HIBYTE( usCh )) + mplayer_put_key( usCh ); + + MRETURN( TRUE ); + } + + case WM_BUTTON1DOWN : + if( WinQueryFocus( HWND_DESKTOP ) != hwnd ) + { + WinSetFocus( HWND_DESKTOP, hwnd ); + MRETURN( TRUE ); + } + + if( !vo_nomouse_input ) + mplayer_put_key( MOUSE_BTN0 ); + + MRETURN( TRUE ); + + case WM_BUTTON3DOWN : + if( WinQueryFocus( HWND_DESKTOP ) != hwnd ) + { + WinSetFocus( HWND_DESKTOP, hwnd ); + MRETURN( TRUE ); + } + + if( !vo_nomouse_input ) + mplayer_put_key( MOUSE_BTN1 ); + + MRETURN( TRUE ); + + case WM_BUTTON2DOWN : + if( WinQueryFocus( HWND_DESKTOP ) != hwnd ) + { + WinSetFocus( HWND_DESKTOP, hwnd ); + MRETURN( TRUE ); + } + + if( !vo_nomouse_input ) + mplayer_put_key( MOUSE_BTN2 ); + + MRETURN( TRUE ); + + case WM_BUTTON1DBLCLK : + if( !vo_nomouse_input ) + mplayer_put_key( MOUSE_BTN0_DBL ); + + MRETURN( TRUE ); + + case WM_BUTTON3DBLCLK : + if( !vo_nomouse_input ) + mplayer_put_key( MOUSE_BTN1_DBL ); + + MRETURN( TRUE ); + + case WM_BUTTON2DBLCLK : + if( !vo_nomouse_input) + mplayer_put_key( MOUSE_BTN2_DBL ); + + MRETURN( TRUE ); + } + + MRETURN( WinDefWindowProc( hwnd, msg, mp1, mp2 )); +} + +static int preinit( const char *arg ) +{ + ULONG flFrameFlags; + + BOOL fUseDive = FALSE; + BOOL fFixT23 = FALSE; + + opt_t subopts[] = { + {"dive", OPT_ARG_BOOL, &fUseDive, NULL, 0 }, + {"t23", OPT_ARG_BOOL, &fFixT23, NULL, 0 }, + { NULL, 0, NULL, NULL, 0 } + }; + + if( subopt_parse( arg, subopts ) != 0 ) + return -1; + + memset( &m_int, 0, sizeof( VOKVAINTERNAL )); + + m_int.hab = WinInitialize( 0 ); + m_int.hmq = WinCreateMsgQueue( m_int.hab, 0); + + WinRegisterClass( + m_int.hab, + WC_MPLAYER, + WndProc, + CS_SIZEREDRAW | CS_MOVENOTIFY, + sizeof( PVOID ) + ); + + flFrameFlags = FCF_SYSMENU | FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | + FCF_TASKLIST; + + m_int.hwndFrame = + WinCreateStdWindow( + HWND_DESKTOP, // parent window handle + WS_VISIBLE, // frame window style + &flFrameFlags, // window style + WC_MPLAYER, // class name + "", // window title + 0L, // default client style + NULLHANDLE, // resource in exe file + 1, // frame window id + &m_int.hwndClient // client window handle + ); + + if( m_int.hwndFrame == NULLHANDLE ) + return -1; + + m_int.hwndSysMenu = WinWindowFromID( m_int.hwndFrame, FID_SYSMENU ); + m_int.hwndTitleBar = WinWindowFromID( m_int.hwndFrame, FID_TITLEBAR ); + m_int.hwndMinMax = WinWindowFromID( m_int.hwndFrame, FID_MINMAX ); + + m_int.fFullScreen = FALSE; + + m_int.fFixT23 = fFixT23; + + if( m_int.fFixT23 ) + m_int.pfnwpOldFrame = WinSubclassWindow( m_int.hwndFrame, NewFrameWndProc ); + + if( kvaInit( fUseDive, m_int.hwndClient, COLOR_OVERLAY )) + return -1; + + kvaCaps( &m_int.kvac ); + + switch( m_int.kvac.ulMode ) + { + case KVAM_WO : + m_int.fcc = FOURCC_Y422; + m_int.iImageFormat = IMGFMT_YUY2; + m_int.bpp = 2; + break; + + case KVAM_DIVE : + default : + switch( m_int.kvac.fccScreen ) + { + case FOURCC_BGR4 : + case FOURCC_BGR3 : + case FOURCC_LUT8 : // maybe best T.T + m_int.fcc = FOURCC_BGR3; + m_int.iImageFormat = IMGFMT_BGR24; + m_int.bpp = 3; + break; + + case FOURCC_R565 : + m_int.fcc = FOURCC_R565; + m_int.iImageFormat = IMGFMT_BGR16; + m_int.bpp = 2; + break; + + case FOURCC_R555 : + m_int.fcc = FOURCC_R555; + m_int.iImageFormat = IMGFMT_BGR15; + m_int.bpp = 2; + break; + } + break; + } + + return 0; +} + +static void uninit( void ) +{ + if( m_int.pbImage ) + imgFree( m_int.pbImage ); + + if( m_int.sws ) + sws_freeContext( m_int.sws ); + + if( m_int.hwndFrame != NULLHANDLE ) + { + if( m_int.fFixT23 ) + WinSubclassWindow( m_int.hwndFrame, m_int.pfnwpOldFrame ); + + kvaResetAttr(); + kvaDone(); + WinDestroyWindow( m_int.hwndFrame ); + } + + WinDestroyMsgQueue( m_int.hmq ); + WinTerminate( m_int.hab ); +} + +static int config( uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format ) +{ + RECTL rcl; + + if( format != m_int.iImageFormat ) + { + mp_msg( MSGT_VO, MSGL_ERR, "KVA : Unsupported image format 0x%X(%s)\n", format, vo_format_name(format)); + return -1; + } + + if( mp_msg_test( MSGT_VO, MSGL_V )) + mp_msg( MSGT_VO, MSGL_V, "KVA: Using 0x%X (%s) image format\n", format, vo_format_name(format)); + + if( m_int.pbImage ) + imgFree( m_int.pbImage ); + + m_int.kvas.ulLength = sizeof( KVASETUP ); + m_int.kvas.szlSrcSize.cx = width; + m_int.kvas.szlSrcSize.cy = height; + m_int.kvas.rclSrcRect.xLeft = 0; + m_int.kvas.rclSrcRect.yTop = 0; + m_int.kvas.rclSrcRect.xRight = width; + m_int.kvas.rclSrcRect.yBottom = height; + m_int.kvas.ulRatio = KVAR_ORIGINAL; + m_int.kvas.fccSrcColor = m_int.fcc; + + kvaSetup( &m_int.kvas ); + + m_int.lStride = width * m_int.bpp; + + m_int.pbImage = imgCreate(); + + if( m_int.iImageFormat == IMGFMT_YV12 ) + { + int dstFormat; + + if( m_int.sws ) + sws_freeContext( m_int.sws ); + + m_int.yv12Planes[ 0 ] = m_int.pbImage; + m_int.yv12Planes[ 1 ] = m_int.yv12Planes[ 0 ] + ( m_int.lStride * height ); + m_int.yv12Planes[ 2 ] = m_int.yv12Planes[ 1 ] + ( m_int.lStride * height ) / 4; + + m_int.yv12Stride[ 0 ] = m_int.lStride; + m_int.yv12Stride[ 1 ] = m_int.lStride / 2; + m_int.yv12Stride[ 2 ] = m_int.lStride / 2; + + switch( m_int.fcc ) + { + case FOURCC_Y422 : + dstFormat = PIX_FMT_YUYV422; + break; + + case FOURCC_BGR3 : + dstFormat = PIX_FMT_BGR24; + break; + + case FOURCC_R565 : + dstFormat = PIX_FMT_BGR565; + break; + + case FOURCC_R555 : + dstFormat = PIX_FMT_BGR555; + break; + } + + m_int.sws = sws_getContext( width, height, PIX_FMT_YUV420P, + width, height, dstFormat, + SWS_FAST_BILINEAR | SWS_PRINT_INFO | get_sws_cpuflags(), + NULL, NULL, NULL ); + } + + WinSetWindowText( m_int.hwndFrame, title ); + + if( !d_width ) + d_width = width; + + if( !d_height ) + d_height = height; + + m_int.fFullScreen = flags & VOFLAG_FULLSCREEN; + + // workaround for T23 laptop with S3 Video by Franz Bakan + if( !m_int.fFullScreen && m_int.fFixT23 ) + { + d_width++; + d_height++; + } + + m_int.rclDst.xLeft = (( LONG )SCREEN_WIDTH - ( LONG )d_width ) / 2; + m_int.rclDst.yBottom = (( LONG )SCREEN_HEIGHT - ( LONG )d_height ) /2 ; + m_int.rclDst.xRight = m_int.rclDst.xLeft + d_width; + m_int.rclDst.yTop = m_int.rclDst.yBottom + d_height; + + if( m_int.fFullScreen ) + { + d_width = SCREEN_WIDTH; + d_height = SCREEN_HEIGHT; + + // when -fs option is used without this, title bar is not highlighted + WinSetActiveWindow( HWND_DESKTOP, m_int.hwndFrame ); + + WinSetParent( m_int.hwndSysMenu, HWND_OBJECT, FALSE ); + WinSetParent( m_int.hwndTitleBar, HWND_OBJECT, FALSE ); + WinSetParent( m_int.hwndMinMax, HWND_OBJECT, FALSE ); + } + + rcl.xLeft = (( LONG )SCREEN_WIDTH - ( LONG )d_width ) / 2; + rcl.yBottom = (( LONG )SCREEN_HEIGHT - ( LONG )d_height ) /2 ; + rcl.xRight = rcl.xLeft + d_width; + rcl.yTop = rcl.yBottom + d_height; + + WinCalcFrameRect( m_int.hwndFrame, &rcl, FALSE ); + + WinSetWindowPos( m_int.hwndFrame, HWND_TOP, + rcl.xLeft, rcl.yBottom, + rcl.xRight - rcl.xLeft, rcl.yTop - rcl.yBottom, + SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_SHOW | SWP_ACTIVATE ); + + return 0; +} + +static uint32_t get_image( mp_image_t *mpi ) +{ + if( mpi->imgfmt != m_int.iImageFormat ) + return VO_FALSE; + + if( m_int.iImageFormat == IMGFMT_YV12 ) + { + mpi->planes[ 1 ] = m_int.yv12Planes[ 1 ]; + mpi->planes[ 2 ] = m_int.yv12Planes[ 2 ]; + + mpi->stride[ 1 ] = m_int.yv12Stride[ 1 ]; + mpi->stride[ 2 ] = m_int.yv12Stride[ 2 ]; + } + + mpi->planes[0] = m_int.pbImage; + mpi->stride[0] = m_int.lStride; + mpi->flags |= MP_IMGFLAG_DIRECT; + + return VO_TRUE; +} + +static int query_format( uint32_t format ) +{ + int res = 0; + + // here, modify image format and bpp in case of YV12 + if( format == IMGFMT_YV12 ) + { + m_int.iImageFormat = IMGFMT_YV12; + m_int.bpp = 1; + } + + if( format == m_int.iImageFormat ) + { + res = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | + VFCAP_HWSCALE_UP; + + if( !m_int.fFixT23 ) + res |= VFCAP_HWSCALE_DOWN; + } + + return res; +} + +static uint32_t color_ctrl_set( char *what, int value ) +{ + ULONG ulAttr; + ULONG ulValue; + + if( !strcmp( what, "brightness")) + ulAttr = KVAA_BRIGHTNESS; + else if( !strcmp( what, "contrast")) + ulAttr = KVAA_CONTRAST; + else if( !strcmp( what, "hue")) + ulAttr = KVAA_HUE; + else if( !strcmp( what, "saturation")) + ulAttr = KVAA_SATURATION; + else + return VO_NOTIMPL; + + ulValue = ( value + 100 ) * 255 / 200; + + if( kvaSetAttr( ulAttr, &ulValue )) + return VO_NOTIMPL; + + return VO_TRUE; +} + +static uint32_t color_ctrl_get( char *what, int *value ) +{ + ULONG ulAttr; + ULONG ulValue; + + if( !strcmp( what, "brightness")) + ulAttr = KVAA_BRIGHTNESS; + else if( !strcmp( what, "contrast")) + ulAttr = KVAA_CONTRAST; + else if( !strcmp( what, "hue")) + ulAttr = KVAA_HUE; + else if( !strcmp( what, "saturation")) + ulAttr = KVAA_SATURATION; + else + return VO_NOTIMPL; + + if( kvaQueryAttr( ulAttr, &ulValue )) + return VO_NOTIMPL; + + // add 1 to adjust range + *value = (( ulValue + 1 ) * 200 / 255 ) - 100; + + return VO_TRUE; +} + +static int control( uint32_t request, void *data, ... ) +{ + switch( request ) + { + case VOCTRL_GET_IMAGE : + return get_image( data ); + + case VOCTRL_QUERY_FORMAT : + return query_format( *(( uint32_t * )data )); + + case VOCTRL_FULLSCREEN : + { + RECTL rcl; + + m_int.fFullScreen = !m_int.fFullScreen; + + if( m_int.fFullScreen ) + { + WinSetParent( m_int.hwndSysMenu, HWND_OBJECT, FALSE ); + WinSetParent( m_int.hwndTitleBar, HWND_OBJECT, FALSE ); + WinSetParent( m_int.hwndMinMax, HWND_OBJECT, FALSE ); + + rcl.xLeft = 0; + rcl.yBottom = 0; + rcl.xRight = SCREEN_WIDTH; + rcl.yTop = SCREEN_HEIGHT; + } + else + { + WinSetParent( m_int.hwndSysMenu, m_int.hwndFrame, FALSE ); + WinSetParent( m_int.hwndTitleBar, m_int.hwndFrame, FALSE ); + WinSetParent( m_int.hwndMinMax, m_int.hwndFrame, FALSE ); + + rcl = m_int.rclDst; + } + + WinCalcFrameRect( m_int.hwndFrame, &rcl, FALSE ); + + WinSetWindowPos( m_int.hwndFrame, HWND_TOP, + rcl.xLeft, rcl.yBottom, + rcl.xRight - rcl.xLeft, rcl.yTop - rcl.yBottom, + SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_SHOW | SWP_ACTIVATE ); + + return VO_TRUE; + } + + case VOCTRL_SET_EQUALIZER : + { + va_list ap; + int value; + + va_start( ap, data ); + value = va_arg( ap, int ); + va_end( ap ); + + return color_ctrl_set( data, value ); + } + + case VOCTRL_GET_EQUALIZER : + { + va_list ap; + int *value; + + va_start( ap, data ); + value = va_arg( ap, int * ); + va_end( ap ); + + return color_ctrl_get( data, value ); + } + } + + return VO_NOTIMPL; +} + +static int draw_frame( uint8_t *src[] ) +{ + fast_memcpy( m_int.pbImage, src[ 0 ], SRC_HEIGHT * m_int.lStride ); + + return 0; +} + +static int draw_slice( uint8_t *src[], int stride[], int w, int h, int x, int y ) +{ + uint8_t *s; + uint8_t *d; + + // copy Y + d = m_int.yv12Planes[ 0 ] + m_int.yv12Stride[ 0 ] * y + x; + s = src[ 0 ]; + mem2agpcpy_pic( d, s, w, h, m_int.yv12Stride[ 0 ], stride[ 0 ]); + + w /= 2; h /= 2; x /= 2; y /= 2; + + // copy U + d = m_int.yv12Planes[ 1 ] + m_int.yv12Stride[ 1 ] * y + x; + s = src[ 1 ]; + mem2agpcpy_pic( d, s, w, h, m_int.yv12Stride[ 1 ], stride[ 1 ]); + + // copy V + d = m_int.yv12Planes[ 2 ] + m_int.yv12Stride[ 2 ] * y + x; + s = src[ 2 ]; + mem2agpcpy_pic( d, s, w, h, m_int.yv12Stride[ 2 ], stride[ 2 ]); + + return 0; +} + +#define vo_draw_alpha( imgfmt ) \ + vo_draw_alpha_##imgfmt( w, h, src, srca, stride, \ + m_int.pbImage + m_int.lStride * y0 + m_int.bpp * x0 , \ + m_int.lStride ) + +static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, + unsigned char *srca, int stride) +{ + switch( m_int.iImageFormat ) + { + case IMGFMT_YV12 : + vo_draw_alpha( yv12 ); + break; + + case IMGFMT_YUY2 : + vo_draw_alpha( yuy2 ); + break; + + case IMGFMT_BGR24 : + vo_draw_alpha( rgb24 ); + break; + + case IMGFMT_BGR16 : + vo_draw_alpha( rgb16 ); + break; + + case IMGFMT_BGR15 : + vo_draw_alpha( rgb15 ); + break; + } +} + +static void draw_osd( void ) +{ + vo_draw_text( SRC_WIDTH, SRC_HEIGHT, draw_alpha ); +} + +static void flip_page( void ) +{ + imgDisplay( m_int.pbImage ); +} + +static void check_events( void ) +{ + QMSG qm; + + while( WinPeekMsg( m_int.hab, &qm, NULLHANDLE, 0, 0, PM_REMOVE )) + WinDispatchMsg( m_int.hab, &qm ); +} + + Index: configure =================================================================== --- configure (revision 24089) +++ configure (working copy) @@ -351,6 +352,7 @@ --enable-vesa enable VESA video output [autodetect] --enable-svga enable SVGAlib video output [autodetect] --enable-sdl enable SDL video output [autodetect] + --enable-kva enable KVA (DIVE/WarpOverlay!) video output [autodetect] --enable-aa enable AAlib video output [autodetect] --enable-caca enable CACA video output [autodetect] --enable-ggi enable GGI video output [autodetect] @@ -524,6 +528,7 @@ _xv=auto _xvmc=no #auto when complete _sdl=auto +_kva=auto _directx=auto _win32waveout=auto _nas=auto @@ -819,6 +825,8 @@ --disable-xvmc) _xvmc=no ;; --enable-sdl) _sdl=yes ;; --disable-sdl) _sdl=no ;; + --enable-kva) _kva=yes ;; + --disable-kva) _kva=no ;; --enable-directx) _directx=yes ;; --disable-directx) _directx=no ;; --enable-win32waveout) _win32waveout=yes ;; @@ -4782,6 +4821,28 @@ echores "$_sdl" +echocheck "KVA (DIVE/WarpOverlay!)" +if test "$_kva" = auto; then + cat > $TMPC << EOF +#include +#include +int main( void ) { return 0; } +EOF + _kva=no; + cc_check -lkva -lmmpm2 && _kva=yes +fi +if test "$_kva" = yes ; then + _def_kva='#define HAVE_KVA 1' + _libs_mplayer="$_libs_mplayer -lkva" + _vosrc="$_vosrc vo_kva.c" + _vomodules="kva $_vomodules" +else + _def_kva='#undef HAVE_KVA' + _novomodules="kva $_novomodules" +fi +echores "$_kva" + + if win32; then echocheck "Windows waveout" @@ -8385,6 +8474,7 @@ $_def_sdl /* defined for SDLlib with keyrepeat bugs (before 1.2.1) */ $_def_sdlbuggy +$_def_kva $_def_directx $_def_ggi $_def_ggiwmh