diff options
Diffstat (limited to 'libvo/vo_dfbmga.c')
-rw-r--r-- | libvo/vo_dfbmga.c | 1536 |
1 files changed, 0 insertions, 1536 deletions
diff --git a/libvo/vo_dfbmga.c b/libvo/vo_dfbmga.c deleted file mode 100644 index 57b798040e..0000000000 --- a/libvo/vo_dfbmga.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* - * MPlayer video driver for DirectFB / Matrox G200/G400/G450/G550 - * - * copyright (C) 2002-2008 Ville Syrjala <syrjala@sci.fi> - * Originally based on vo_directfb.c by Jiri Svoboda <Jiri.Svoboda@seznam.cz>. - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * MPlayer 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <directfb.h> -#include <directfb_version.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "config.h" -#include "video_out.h" -#include "video_out_internal.h" -#include "fastmemcpy.h" -#include "sub/sub.h" -#include "mp_msg.h" -#include "aspect.h" -#include "mp_fifo.h" -#include "input/keycodes.h" - -static const vo_info_t info = { - "DirectFB / Matrox G200/G400/G450/G550", - "dfbmga", - "Ville Syrjala <syrjala@sci.fi>", - "" -}; - -const LIBVO_EXTERN(dfbmga) - -static IDirectFB *dfb; - -static IDirectFBDisplayLayer *crtc1; -static IDirectFBDisplayLayer *bes; -static IDirectFBDisplayLayer *crtc2; -static IDirectFBDisplayLayer *spic; - -static int num_bufs; -static int current_buf; -static int current_ip_buf; -static IDirectFBSurface *bufs[3]; - -static IDirectFBSurface *frame; -static IDirectFBSurface *subframe; - -static IDirectFBSurface *besframe; -static IDirectFBSurface *c1frame; -static IDirectFBSurface *c2frame; -static IDirectFBSurface *spicframe; - -static DFBSurfacePixelFormat frame_format; -static DFBSurfacePixelFormat subframe_format; - -static DFBRectangle besrect; -static DFBRectangle c1rect; -static DFBRectangle c2rect; -static DFBRectangle *subrect; - -static IDirectFBInputDevice *keyboard; -static IDirectFBInputDevice *remote; -static IDirectFBEventBuffer *buffer; - -static int blit_done; -static int c1stretch; -static int c2stretch; - -static int use_bes; -static int use_crtc1; -static int use_crtc2; -static int use_spic; -static int use_input; -static int use_remote; -static int field_parity; -static int flipping; -static DFBDisplayLayerBufferMode buffermode; -static int tvnorm; - -static int osd_changed; -static int osd_dirty; -static int osd_current; -static int osd_max; - -static int is_g200; - -static uint32_t in_width; -static uint32_t in_height; -static uint32_t buf_height; -static uint32_t screen_width; -static uint32_t screen_height; -static uint32_t sub_width; -static uint32_t sub_height; - -static char * -pixelformat_name( DFBSurfacePixelFormat format ) -{ - switch(format) { - case DSPF_ARGB: - return "ARGB"; - case DSPF_RGB32: - return "RGB32"; - case DSPF_RGB16: - return "RGB16"; - case DSPF_ARGB1555: - return "ARGB1555"; - case DSPF_YUY2: - return "YUY2"; - case DSPF_UYVY: - return "UYVY"; - case DSPF_YV12: - return "YV12"; - case DSPF_I420: - return "I420"; - case DSPF_ALUT44: - return "ALUT44"; - case DSPF_NV12: - return "NV12"; - case DSPF_NV21: - return "NV21"; - default: - return "Unknown pixel format"; - } -} - -static DFBSurfacePixelFormat -imgfmt_to_pixelformat( uint32_t format ) -{ - switch (format) { - case IMGFMT_BGR32: - return DSPF_RGB32; - case IMGFMT_BGR16: - return DSPF_RGB16; - case IMGFMT_BGR15: - return DSPF_ARGB1555; - case IMGFMT_YUY2: - return DSPF_YUY2; - case IMGFMT_UYVY: - return DSPF_UYVY; - case IMGFMT_YV12: - return DSPF_YV12; - case IMGFMT_I420: - case IMGFMT_IYUV: - return DSPF_I420; - case IMGFMT_NV12: - return DSPF_NV12; - case IMGFMT_NV21: - return DSPF_NV21; - default: - return DSPF_UNKNOWN; - } -} - -struct layer_enum -{ - const char *name; - IDirectFBDisplayLayer **layer; - DFBResult res; -}; - -static DFBEnumerationResult -get_layer_by_name( DFBDisplayLayerID id, - DFBDisplayLayerDescription desc, - void *data ) -{ - struct layer_enum *l = (struct layer_enum *) data; - - if (!strcmp( l->name, desc.name )) - if ((l->res = dfb->GetDisplayLayer( dfb, id, l->layer )) == DFB_OK) - return DFENUM_CANCEL; - - return DFENUM_OK; -} - -static int -preinit( const char *arg ) -{ - DFBResult res; - int force_input = -1; - - /* Some defaults */ - use_bes = 0; - use_crtc1 = 0; - use_crtc2 = 1; - use_spic = 1; - field_parity = -1; - buffermode = DLBM_TRIPLE; - osd_max = 4; - flipping = 1; - tvnorm = -1; - - use_input = !getenv( "DISPLAY" ); - - if (vo_subdevice) { - int show_help = 0; - int opt_no = 0; - while (*vo_subdevice != '\0') { - if (!strncmp(vo_subdevice, "bes", 3)) { - use_bes = !opt_no; - vo_subdevice += 3; - opt_no = 0; - } else if (!strncmp(vo_subdevice, "crtc1", 5)) { - use_crtc1 = !opt_no; - vo_subdevice += 5; - opt_no = 0; - } else if (!strncmp(vo_subdevice, "crtc2", 5)) { - use_crtc2 = !opt_no; - vo_subdevice += 5; - opt_no = 0; - } else if (!strncmp(vo_subdevice, "spic", 4)) { - use_spic = !opt_no; - vo_subdevice += 4; - opt_no = 0; - } else if (!strncmp(vo_subdevice, "input", 5)) { - force_input = !opt_no; - vo_subdevice += 5; - opt_no = 0; - } else if (!strncmp(vo_subdevice, "remote", 6)) { - use_remote = !opt_no; - vo_subdevice += 6; - opt_no = 0; - } else if (!strncmp(vo_subdevice, "buffermode=", 11)) { - if (opt_no) { - show_help = 1; - break; - } - vo_subdevice += 11; - if (!strncmp(vo_subdevice, "single", 6)) { - buffermode = DLBM_FRONTONLY; - osd_max = 1; - flipping = 0; - vo_subdevice += 6; - } else if (!strncmp(vo_subdevice, "double", 6)) { - buffermode = DLBM_BACKVIDEO; - osd_max = 2; - flipping = 1; - vo_subdevice += 6; - } else if (!strncmp(vo_subdevice, "triple", 6)) { - buffermode = DLBM_TRIPLE; - osd_max = 4; - flipping = 1; - vo_subdevice += 6; - } else { - show_help = 1; - break; - } - opt_no = 0; - } else if (!strncmp(vo_subdevice, "fieldparity=", 12)) { - if (opt_no) { - show_help = 1; - break; - } - vo_subdevice += 12; - if (!strncmp(vo_subdevice, "top", 3)) { - field_parity = 0; - vo_subdevice += 3; - } else if (!strncmp(vo_subdevice, "bottom", 6)) { - field_parity = 1; - vo_subdevice += 6; - } else { - show_help = 1; - break; - } - opt_no = 0; - } else if (!strncmp(vo_subdevice, "tvnorm=", 7)) { - if (opt_no) { - show_help = 1; - break; - } - vo_subdevice += 7; - if (!strncmp(vo_subdevice, "pal", 3)) { - tvnorm = 0; - vo_subdevice += 3; - } else if (!strncmp(vo_subdevice, "ntsc" , 4)) { - tvnorm = 1; - vo_subdevice += 4; - } else if (!strncmp(vo_subdevice, "auto" , 4)) { - tvnorm = 2; - vo_subdevice += 4; - } else { - show_help = 1; - break; - } - opt_no = 0; - } else if (!strncmp(vo_subdevice, "no", 2)) { - if (opt_no) { - show_help = 1; - break; - } - vo_subdevice += 2; - opt_no = 1; - } else if (*vo_subdevice == ':') { - if (opt_no) { - show_help = 1; - break; - } - vo_subdevice++; - opt_no = 0; - } else { - show_help = 1; - break; - } - } - if (show_help) { - mp_msg( MSGT_VO, MSGL_ERR, - "\nvo_dfbmga command line help:\n" - "Example: mplayer -vo dfbmga:nocrtc2:bes:buffermode=single\n" - "\nOptions (use 'no' prefix to disable):\n" - " bes Use Backend Scaler\n" - " crtc1 Use CRTC1\n" - " crtc2 Use CRTC2\n" - " spic Use hardware sub-picture for OSD\n" - " input Use DirectFB for keyboard input\n" - " remote Use DirectFB for remote control input\n" - "\nOther options:\n" - " buffermode=(single|double|triple)\n" - " single Use single buffering\n" - " double Use double buffering\n" - " triple Use triple buffering\n" - " fieldparity=(top|bottom)\n" - " top Top field first\n" - " bottom Bottom field first\n" - " tvnorm=(pal|ntsc|auto)\n" - " pal Force PAL\n" - " ntsc Force NTSC\n" - " auto Select according to FPS\n" - "\n" ); - return -1; - } - } - if (!use_bes && !use_crtc1 && !use_crtc2) { - mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: No output selected\n" ); - return -1; - } - if (use_bes && use_crtc1) { - mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Both BES and CRTC1 outputs selected\n" ); - return -1; - } - - if ((res = DirectFBInit( NULL, NULL )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: DirectFBInit() failed - %s\n", - DirectFBErrorString( res ) ); - return -1; - } - - switch (tvnorm) { - case 0: - DirectFBSetOption( "matrox-tv-standard", "pal" ); - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Forced TV standard to PAL\n" ); - break; - case 1: - DirectFBSetOption( "matrox-tv-standard", "ntsc" ); - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Forced TV standard to NTSC\n" ); - break; - case 2: - if (vo_fps > 27) { - DirectFBSetOption( "matrox-tv-standard", "ntsc" ); - mp_msg( MSGT_VO, MSGL_INFO, - "vo_dfbmga: Selected TV standard based upon FPS: NTSC\n" ); - } else { - DirectFBSetOption( "matrox-tv-standard", "pal" ); - mp_msg( MSGT_VO, MSGL_INFO, - "vo_dfbmga: Selected TV standard based upon FPS: PAL\n" ); - } - break; - } - - if ((res = DirectFBCreate( &dfb )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: DirectFBCreate() failed - %s\n", - DirectFBErrorString( res ) ); - return -1; - } - - if (use_crtc1 || use_bes) { - struct layer_enum l = { - "FBDev Primary Layer", - &crtc1, - DFB_UNSUPPORTED - }; - dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); - if (l.res != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get CRTC1 layer - %s\n", - DirectFBErrorString( l.res ) ); - uninit(); - return -1; - } - if ((res = crtc1->SetCooperativeLevel( crtc1, DLSCL_EXCLUSIVE )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to CRTC1 layer - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - use_input = 1; - } - - if (force_input != -1) - use_input = force_input; - - if (use_bes) { - DFBDisplayLayerConfig dlc; - DFBDisplayLayerConfigFlags failed; - struct layer_enum l = { - "Matrox Backend Scaler", - &bes, - DFB_UNSUPPORTED - }; - - dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); - if (l.res != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "Can't get BES layer - %s\n", - DirectFBErrorString( l.res ) ); - uninit(); - return -1; - } - if ((res = bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to BES - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - dlc.flags = DLCONF_PIXELFORMAT; - dlc.pixelformat = DSPF_RGB16; - if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) { - is_g200 = 1; - use_crtc2 = 0; - } - } - - if (use_crtc2) { - struct layer_enum l = { - "Matrox CRTC2 Layer", - &crtc2, - DFB_UNSUPPORTED - }; - - dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); - if (l.res != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "Can't get CRTC2 layer - %s\n", - DirectFBErrorString( l.res ) ); - uninit(); - return -1; - } - if ((res = crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to CRTC2 - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - } - - if (use_input || use_remote) { - if ((res = dfb->CreateEventBuffer( dfb, &buffer )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Can't create event buffer - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - } - - if (use_input) { - if ((res = dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Can't get keyboard - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - if ((res = keyboard->AttachEventBuffer( keyboard, buffer )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Can't attach event buffer to keyboard - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - } - if (use_remote) { - if ((res = dfb->GetInputDevice( dfb, DIDID_REMOTE, &remote )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Can't get remote control - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - if ((res = remote->AttachEventBuffer( remote, buffer )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Can't attach event buffer to remote control - %s\n", - DirectFBErrorString( res ) ); - uninit(); - return -1; - } - } - - return 0; -} - -static void release_config( void ) -{ - if (spicframe) - spicframe->Release( spicframe ); - if (spic) - spic->Release( spic ); - if (c2frame) - c2frame->Release( c2frame ); - if (c1frame) - c1frame->Release( c1frame ); - if (besframe) - besframe->Release( besframe ); - if (bufs[0]) - bufs[0]->Release( bufs[0] ); - if (bufs[1]) - bufs[1]->Release( bufs[1] ); - if (bufs[2]) - bufs[2]->Release( bufs[2] ); - - spicframe = NULL; - spic = NULL; - c2frame = NULL; - c1frame = NULL; - besframe = NULL; - bufs[0] = NULL; - bufs[1] = NULL; - bufs[2] = NULL; -} - -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 ) -{ - DFBResult res; - - DFBDisplayLayerConfig dlc; - DFBDisplayLayerConfigFlags failed; - - uint32_t out_width; - uint32_t out_height; - - release_config(); - - in_width = width; - in_height = height; - - aspect_save_orig(width, height); - aspect_save_prescale(d_width, d_height); - - dlc.pixelformat = imgfmt_to_pixelformat( format ); - - { - /* Draw to a temporary surface */ - DFBSurfaceDescription dsc; - - dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | - DSDESC_PIXELFORMAT; - dsc.width = (in_width + 15) & ~15; - dsc.height = (in_height + 15) & ~15; - dsc.pixelformat = dlc.pixelformat; - - /* Don't waste video memory since we don't need direct stretchblit */ - if (use_bes) { - dsc.flags |= DSDESC_CAPS; - dsc.caps = DSCAPS_SYSTEMONLY; - } - - for (num_bufs = 0; num_bufs < 3; num_bufs++) { - if ((res = dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] )) != DFB_OK) { - if (num_bufs == 0) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Can't create surfaces - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - break; - } - } - frame = bufs[0]; - current_buf = 0; - current_ip_buf = 0; - buf_height = dsc.height; - } - frame->GetPixelFormat( frame, &frame_format ); - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s\n", - in_width, in_height, - pixelformat_name( frame_format ) ); - - - /* - * BES - */ - if (use_bes) { - aspect_save_screenres( 0x10000, 0x10000 ); - aspect( &out_width, &out_height, A_ZOOM ); - besrect.x = (0x10000 - out_width) * in_width / out_width / 2; - besrect.y = (0x10000 - out_height) * in_height / out_height / 2; - besrect.w = in_width; - besrect.h = in_height; - - dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; - dlc.width = besrect.w + besrect.x * 2; - dlc.height = besrect.h + besrect.y * 2; - dlc.buffermode = buffermode; - - if ((res = bes->TestConfiguration( bes, &dlc, &failed )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Invalid BES configuration - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - if ((res = bes->SetConfiguration( bes, &dlc )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: BES configuration failed - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - bes->GetSurface( bes, &besframe ); - besframe->SetBlittingFlags( besframe, DSBLIT_NOFX ); - - bes->SetScreenLocation( bes, 0.0, 0.0, 1.0, 1.0 ); - - besframe->Clear( besframe, 0, 0, 0, 0xff ); - besframe->Flip( besframe, NULL, 0 ); - besframe->Clear( besframe, 0, 0, 0, 0xff ); - besframe->Flip( besframe, NULL, 0 ); - besframe->Clear( besframe, 0, 0, 0, 0xff ); - - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: BES using %s buffering\n", - dlc.buffermode == DLBM_TRIPLE ? "triple" : - dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" ); - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: BES surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) ); - } - - /* - * CRTC1 - */ - if (use_crtc1) { - dlc.flags = DLCONF_BUFFERMODE; - dlc.buffermode = buffermode; - - if ((res = crtc1->TestConfiguration( crtc1, &dlc, &failed )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Invalid CRTC1 configuration - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - if ((res = crtc1->SetConfiguration( crtc1, &dlc )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: CRTC1 configuration failed - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - if ((res = crtc1->GetConfiguration( crtc1, &dlc )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Getting CRTC1 configuration failed - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - - crtc1->GetSurface( crtc1, &c1frame ); - c1frame->SetBlittingFlags( c1frame, DSBLIT_NOFX ); - c1frame->SetColor( c1frame, 0, 0, 0, 0xff ); - - c1frame->GetSize( c1frame, &screen_width, &screen_height ); - - aspect_save_screenres( screen_width, screen_height ); - aspect( &out_width, &out_height, (flags & VOFLAG_FULLSCREEN) ? A_ZOOM : A_NOZOOM ); - - if (in_width != out_width || in_height != out_height) - c1stretch = 1; - else - c1stretch = 0; - - c1rect.x = (screen_width - out_width) / 2; - c1rect.y = (screen_height - out_height) / 2; - c1rect.w = out_width; - c1rect.h = out_height; - - c1frame->Clear( c1frame, 0, 0, 0, 0xff ); - c1frame->Flip( c1frame, NULL, 0 ); - c1frame->Clear( c1frame, 0, 0, 0, 0xff ); - c1frame->Flip( c1frame, NULL, 0 ); - c1frame->Clear( c1frame, 0, 0, 0, 0xff ); - - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC1 using %s buffering\n", - dlc.buffermode == DLBM_TRIPLE ? "triple" : - dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" ); - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC1 surface %dx%d %s\n", screen_width, screen_height, pixelformat_name( dlc.pixelformat ) ); - } - - /* - * CRTC2 - */ - if (use_crtc2) { - dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS; - dlc.buffermode = buffermode; - dlc.options = DLOP_NONE; - - if (field_parity != -1) { - dlc.options |= DLOP_FIELD_PARITY; - } - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Field parity set to: "); - switch (field_parity) { - case -1: - mp_msg( MSGT_VO, MSGL_INFO, "Don't care\n"); - break; - case 0: - mp_msg( MSGT_VO, MSGL_INFO, "Top field first\n"); - break; - case 1: - mp_msg( MSGT_VO, MSGL_INFO, "Bottom field first\n"); - break; - } - - switch (dlc.pixelformat) { - case DSPF_I420: - case DSPF_YV12: - /* sub-picture supported */ - break; - - case DSPF_YUY2: - case DSPF_UYVY: - /* Blit to YUY2/UYVY not supported */ - dlc.pixelformat = DSPF_ARGB; - - /* fall through */ - default: - /* sub-picture not supported */ - use_spic = 0; - } - - if ((res = crtc2->TestConfiguration( crtc2, &dlc, &failed )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Invalid CRTC2 configuration - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - if ((res = crtc2->SetConfiguration( crtc2, &dlc )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: CRTC2 configuration failed - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - - if (field_parity != -1) - crtc2->SetFieldParity( crtc2, field_parity ); - - crtc2->GetSurface( crtc2, &c2frame ); - c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX ); - c2frame->SetColor( c2frame, 0, 0, 0, 0xff ); - - c2frame->GetSize( c2frame, &screen_width, &screen_height ); - - /* Don't stretch only slightly smaller videos */ - if ((in_width > (0.95 * screen_width)) && - (in_width < screen_width)) - out_width = in_width; - else - out_width = screen_width; - if ((in_height > (0.95 * screen_height)) && - (in_height < screen_height)) - out_height = in_height; - else - out_height = screen_height; - - aspect_save_screenres( out_width, out_height ); - aspect( &out_width, &out_height, (flags & VOFLAG_FULLSCREEN) ? A_ZOOM : A_NOZOOM ); - - if (in_width != out_width || - in_height != out_height) - c2stretch = 1; - else - c2stretch = 0; - - c2rect.x = (screen_width - out_width) / 2; - c2rect.y = (screen_height - out_height) / 2; - c2rect.w = out_width; - c2rect.h = out_height; - - c2frame->Clear( c2frame, 0, 0, 0, 0xff ); - c2frame->Flip( c2frame, NULL, 0 ); - c2frame->Clear( c2frame, 0, 0, 0, 0xff ); - c2frame->Flip( c2frame, NULL, 0 ); - c2frame->Clear( c2frame, 0, 0, 0, 0xff ); - - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 using %s buffering\n", - dlc.buffermode == DLBM_TRIPLE ? "triple" : - dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" ); - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 surface %dx%d %s\n", screen_width, screen_height, pixelformat_name( dlc.pixelformat ) ); - } else { - use_spic = 0; - } - - /* - * Sub-picture - */ - if (use_spic) { - /* Draw OSD to sub-picture surface */ - IDirectFBPalette *palette; - DFBColor color; - int i; - struct layer_enum l = { - "Matrox CRTC2 Sub-Picture", - &spic, - DFB_UNSUPPORTED - }; - dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l ); - if (l.res != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get sub-picture layer - %s\n", - DirectFBErrorString( l.res ) ); - return -1; - } - if ((res = spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to sub-picture - %s\n", - DirectFBErrorString( res ) ); - return -1; - } - - dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; - dlc.pixelformat = DSPF_ALUT44; - dlc.buffermode = buffermode; - dlc.flags |= DLCONF_OPTIONS; - dlc.options = DLOP_ALPHACHANNEL; - - if ((res = spic->TestConfiguration( spic, &dlc, &failed )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Invalid sub-picture configuration - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - if ((res = spic->SetConfiguration( spic, &dlc )) != DFB_OK) { - mp_msg( MSGT_VO, MSGL_ERR, - "vo_dfbmga: Sub-picture configuration failed - %s!\n", - DirectFBErrorString( res ) ); - return -1; - } - - spic->GetSurface( spic, &spicframe ); - - spicframe->GetPalette( spicframe, &palette ); - color.a = 0xff; - for (i = 0; i < 16; i++) { - color.r = i * 17; - color.g = i * 17; - color.b = i * 17; - palette->SetEntries( palette, &color, 1, i ); - } - palette->Release( palette ); - - spicframe->Clear( spicframe, 0, 0, 0, 0 ); - spicframe->Flip( spicframe, NULL, 0 ); - spicframe->Clear( spicframe, 0, 0, 0, 0 ); - spicframe->Flip( spicframe, NULL, 0 ); - spicframe->Clear( spicframe, 0, 0, 0, 0 ); - - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture layer using %s buffering\n", - dlc.buffermode == DLBM_TRIPLE ? "triple" : - dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" ); - - subframe = spicframe; - subrect = NULL; - } else if (use_crtc2) { - /* Draw OSD to CRTC2 surface */ - subframe = c2frame; - subrect = &c2rect; - } else if (use_crtc1) { - /* Draw OSD to CRTC1 surface */ - subframe = c1frame; - subrect = &c1rect; - } else { - /* Draw OSD to BES surface */ - subframe = besframe; - subrect = &besrect; - } - - subframe->GetSize( subframe, &sub_width, &sub_height ); - subframe->GetPixelFormat( subframe, &subframe_format ); - mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n", - sub_width, sub_height, - pixelformat_name( subframe_format ), - use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") : - use_crtc1 ? "CRTC1" : "BES" ); - - osd_dirty = 0; - osd_current = 1; - blit_done = 0; - - return 0; -} - -static int -query_format( uint32_t format ) -{ - switch (format) { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - if (is_g200 || use_crtc1) - return 0; - break; - case IMGFMT_BGR32: - case IMGFMT_BGR16: - case IMGFMT_BGR15: - if (is_g200 && use_bes) - return 0; - break; - case IMGFMT_UYVY: - if (is_g200) - return 0; - break; - case IMGFMT_YUY2: - break; - case IMGFMT_NV12: - case IMGFMT_NV21: - if (use_crtc1 || use_crtc2) - return 0; - break; - default: - return 0; - } - - return VFCAP_HWSCALE_UP | - VFCAP_HWSCALE_DOWN | - VFCAP_CSP_SUPPORTED_BY_HW | - VFCAP_CSP_SUPPORTED | - VFCAP_OSD; -} - -static void -vo_draw_alpha_alut44( int w, int h, - unsigned char* src, - unsigned char *srca, - int srcstride, - unsigned char* dst, - int dststride ) -{ - int x; - - while (h--) { - for (x = 0; x < w; x++) { - if (srca[x]) - dst[x] = ((255 - srca[x]) & 0xF0) | (src[x] >> 4); - } - src += srcstride; - srca += srcstride; - dst += dststride; - } -} - -static void -clear_alpha( int x0, int y0, - int w, int h ) -{ - if (use_spic && !flipping && vo_osd_changed_flag) - subframe->FillRectangle( subframe, x0, y0, w, h ); -} - -static void -draw_alpha( int x0, int y0, - int w, int h, - unsigned char *src, - unsigned char *srca, - int stride ) -{ - uint8_t *dst; - void *ptr; - int pitch; - - if (use_spic) { - if (!osd_changed || (!flipping && !vo_osd_changed_flag)) - return; - osd_dirty |= osd_current; - } else { - if (x0 < subrect->x || - y0 < subrect->y || - x0 + w > subrect->x + subrect->w || - y0 + h > subrect->y + subrect->h) - osd_dirty |= osd_current; - } - - if (subframe->Lock( subframe, DSLF_READ | DSLF_WRITE, &ptr, &pitch ) != DFB_OK) - return; - dst = ptr; - - switch (subframe_format) { - case DSPF_ALUT44: - vo_draw_alpha_alut44( w, h, src, srca, stride, - dst + pitch * y0 + x0, - pitch ); - break; - case DSPF_RGB32: - case DSPF_ARGB: - vo_draw_alpha_rgb32( w, h, src, srca, stride, - dst + pitch * y0 + 4 * x0, - pitch ); - break; - case DSPF_RGB16: - vo_draw_alpha_rgb16( w, h, src, srca, stride, - dst + pitch * y0 + 2 * x0, - pitch ); - break; - case DSPF_ARGB1555: - vo_draw_alpha_rgb15( w, h, src, srca, stride, - dst + pitch * y0 + 2 * x0, - pitch ); - break; |