/*
* 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)) {
|