/*
MPlayer video driver for DirectFramebuffer device
(C) 2001
Written by Jiri Svoboda <Jiri.Svoboda@seznam.cz>
Inspired by vo_sdl and vo_fbdev.
To get second head working delete line 120
from fbdev.c (from DirectFB sources version 0.9.7)
Line contains following:
fbdev->fd = open( "/dev/fb0", O_RDWR );
Parts of this code taken from DirectFB examples:
(c) Copyright 2000 convergence integrated media GmbH.
All rights reserved.
This library 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 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
// directfb includes
#include <directfb.h>
// other things
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
#include <linux/fb.h>
#include "config.h"
#include "video_out.h"
#include "video_out_internal.h"
#include "fastmemcpy.h"
#include "sub.h"
#include "../postproc/rgb2rgb.h"
#include "aspect.h"
#ifndef min
#define min(x,y) (((x)<(y))?(x):(y))
#endif
LIBVO_EXTERN(directfb)
static vo_info_t vo_info = {
"Direct Framebuffer Device",
"directfb",
"Jiri Svoboda Jiri.Svoboda@seznam.cz",
""
};
extern int verbose;
/******************************
* directfb *
******************************/
/*
* (Globals)
*/
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static IDirectFBInputDevice *keyboard = NULL;
static IDirectFBDisplayLayer *videolayer = NULL;
static DFBDisplayLayerConfig dlc;
static unsigned int screen_width = 0;
static unsigned int screen_height = 0;
static DFBSurfacePixelFormat frame_format;
static unsigned int frame_pixel_size = 0;
static unsigned int source_pixel_size = 0;
static int xoffset=0,yoffset=0;
#define DFBCHECK(x...) \
{ \
DFBResult err = x; \
\
if (err != DFB_OK) \
{ \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
}
/*
* The frame is to be loaded into a surface that we can blit from.
*/
static IDirectFBSurface *frame = NULL;
/*
* A buffer for input events.
*/
#ifdef HAVE_DIRECTFB099
static IDirectFBEventBuffer *buffer = NULL;
#else
static IDirectFBInputBuffer *buffer = NULL;
#endif
/******************************
* vo_directfb *
******************************/
/* command line/config file options */
#ifdef HAVE_FBDEV
extern char *fb_dev_name;
#else
char *fb_dev_name;
#endif
static void (*draw_alpha_p)(int w, int h, unsigned char *src,
unsigned char *srca, int stride, unsigned char *dst,
int dstride);
static uint32_t in_width;
static uint32_t in_height;
static uint32_t out_width=1;
static uint32_t out_height=1;
static uint32_t pixel_format;
static int fs;
static int flip;
static int stretch=0;
struct modes_t {
int valid;
unsigned int width;
unsigned int height;
int overx,overy;
} modes [4];
static unsigned int best_bpp=5;
// videolayer stuff
static int videolayeractive=0;
static int videolayerpresent=0;
//some info about videolayer - filled on preinit
struct vlayer_t {
int iv12;
int i420;
int yuy2;
int uyvy;
int brightness;
int saturation;
int contrast;
int hue;
} videolayercaps;
// workabout for DirectFB bug
static int buggyYV12BitBlt=0;
static int memcpyBitBlt=0;
#define DIRECTRENDER
#ifdef DIRECTRENDER
static int dr_enabled=0;
static int framelocked=0;
#endif
// primary & frame stuff
static int frameallocated=0;
static int primaryallocated=0;
DFBEnumerationResult enum_modes_callback( unsigned int width,unsigned int height,unsigned int bpp, void *data)
{
int overx=0,overy=0,closer=0,over=0;
unsigned int index=bpp/8-1;
int we_are_under=0;
if (verbose) printf("DirectFB: Validator entered %i %i %i\n",width,height,bpp);
overx=width-out_width;
overy=height-out_height;
if (!modes[index].valid) {
modes[index].valid=1;
modes[index].width=width;
modes[index].height=height;
modes[index].overx=overx;
modes[index].overy=overy;
}
if ((modes[index].overy<0)||(modes[index].overx<0)) we_are_under=1; // stored mode is smaller than req mode
if (abs(overx*overy)<abs(modes[index].overx * modes[index].overy)) closer=1; // current mode is closer to desired res
if ((overx>=0)&&(overy>=0)) over=1; // current mode is bigger or equaul to desired res
if ((closer && (over || we_are_under)) || (we_are_under && over)) {
modes[index].valid=1;
modes[index].width=width;
modes[index].height=height;
modes[index].overx=overx;
modes[index].overy=overy;
if (verbose) printf("DirectFB:Better mode added %i %i %i\n",width,height,bpp);
};
return DFENUM_OK;
}
DFBEnumerationResult enum_layers_callback( unsigned int id,
DFBDisplayLayerCapabilities caps,
void *data )
{
IDirectFBDisplayLayer **laye
|