vo_directfb2.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,516 行 · 第 1/3 页
C
1,516 行
/* MPlayer video driver for DirectFramebuffer device (C) 2002 Written by Jiri Svoboda <Jiri.Svoboda@seznam.cz> 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.*/// directfb includes#include <directfb.h>#define DFB_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c))// other things#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#ifdef __linux__#include <sys/kd.h>#else#include <linux/kd.h>#endif#include "config.h"#include "video_out.h"#include "video_out_internal.h"#include "fastmemcpy.h"#include "sub.h"#include "mp_msg.h"#include "aspect.h"#include "subopt-helper.h"#include "mp_fifo.h"#ifndef min#define min(x,y) (((x)<(y))?(x):(y))#endif#if DIRECTFBVERSION > DFB_VERSION(0,9,17)// triple buffering#define TRIPLE 1#endifstatic vo_info_t info = { "Direct Framebuffer Device", "directfb", "Jiri Svoboda Jiri.Svoboda@seznam.cz", "v 2.0 (for DirectFB version >=0.9.13)"};LIBVO_EXTERN(directfb)/******************************* vo_directfb globals *******************************/#define DFBCHECK(x...) \ { \ DFBResult err = x; \ \ if (err != DFB_OK) \ { \ fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ DirectFBErrorFatal( #x, err ); \ } \ } /* * filled by preinit */// main DirectFB handlestatic IDirectFB *dfb = NULL;// keyboard handlestatic IDirectFBInputDevice *keyboard = NULL;// A buffer for input events.static IDirectFBEventBuffer *buffer = NULL; /* * filled during config */// handle of used layerstatic IDirectFBDisplayLayer *layer = NULL;// surface of used layerstatic IDirectFBSurface *primary = NULL;static int primarylocked = 0;// handle of temporary surface (if used)static IDirectFBSurface *frame = NULL;static int framelocked = 0;// flipping mode flag (layer/surface)static int flipping = 0; // scaling flagstatic int stretch = 0;// pictrure positionstatic int xoffset=0,yoffset=0;// picture sizestatic int out_width=0,out_height=0;// frame/primary sizestatic int width=0,height=0;// frame primary formatDFBSurfacePixelFormat pixel_format;/*static void (*draw_alpha_p)(int w, int h, unsigned char *src, unsigned char *srca, int stride, unsigned char *dst, int dstride);*//******************************* cmd line parameteres *******************************//* command line/config file options */static int layer_id = -1;static int buffer_mode = 1;static int use_input = 1;static int field_parity = -1;/******************************* implementation *******************************/void unlock(void) {if (frame && framelocked) frame->Unlock(frame);if (primary && primarylocked) primary->Unlock(primary);}static int get_parity(strarg_t *arg) { if (strargcmp(arg, "top") == 0) return 0; if (strargcmp(arg, "bottom") == 0) return 1; return -1;}static int check_parity(void *arg) { return get_parity(arg) != -1;}static int get_mode(strarg_t *arg) { if (strargcmp(arg, "single") == 0) return 1; if (strargcmp(arg, "double") == 0) return 2; if (strargcmp(arg, "triple") == 0) return 3; return 0;}static int check_mode(void *arg) { return get_mode(arg) != 0;}static int preinit(const char *arg){ DFBResult ret; strarg_t mode_str = {0, NULL}; strarg_t par_str = {0, NULL}; strarg_t dfb_params = {0, NULL}; opt_t subopts[] = { {"input", OPT_ARG_BOOL, &use_input, NULL}, {"buffermode", OPT_ARG_STR, &mode_str, check_mode}, {"fieldparity", OPT_ARG_STR, &par_str, check_parity}, {"layer", OPT_ARG_INT, &layer_id, NULL}, {"dfbopts", OPT_ARG_STR, &dfb_params, NULL}, {NULL} }; mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Preinit entered\n"); if (dfb) return 0; // we are already inited! // set defaults buffer_mode = 1 + vo_doublebuffering; // honor -double switch layer_id = -1; use_input = 1; field_parity = -1; if (subopt_parse(arg, subopts) != 0) { mp_msg( MSGT_VO, MSGL_ERR, "\n-vo directfb command line help:\n" "Example: mplayer -vo directfb:layer=1:buffermode=single\n" "\nOptions (use 'no' prefix to disable):\n" " input Use DirectFB for keyboard input\n" "\nOther options:\n" " layer=n\n" " n=0..xx Use layer with id n for output (0=primary)\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" " dfbopts=<str>\n" " Specify a parameter list for DirectFB\n" "\n" ); return -1; } if (mode_str.len) buffer_mode = get_mode(&mode_str); if (par_str.len) field_parity = get_parity(&par_str); if (dfb_params.len > 0) { int argc = 2; char arg0[10] = "mplayer"; char *arg1 = malloc(dfb_params.len + 7); char* argv[3]; char ** a; a = &argv[0]; strcpy(arg1, "--dfb:"); strncat(arg1, dfb_params.str, dfb_params.len); argv[0]=arg0; argv[1]=arg1; argv[2]=NULL; DFBCHECK (DirectFBInit (&argc,&a)); free(arg1); } else { DFBCHECK (DirectFBInit (NULL,NULL)); } if (((directfb_major_version <= 0) && (directfb_minor_version <= 9) && (directfb_micro_version < 13))) { mp_msg(MSGT_VO, MSGL_ERR,"DirectFB: Unsupported DirectFB version\n"); return 1; } /* * (set options) */ // uncomment this if you do not wish to create a new vt for DirectFB// DFBCHECK (DirectFBSetOption ("no-vt-switch",""));// uncomment this if you want to allow vt switching// DFBCHECK (DirectFBSetOption ("vt-switching",""));// uncomment this if you want to hide gfx cursor (req dfb >=0.9.9) DFBCHECK (DirectFBSetOption ("no-cursor",""));// bg color fix DFBCHECK (DirectFBSetOption ("bg-color","00000000")); /* * (Initialize) */ DFBCHECK (DirectFBCreate (&dfb));#if DIRECTFBVERSION < DFB_VERSION(0,9,17) if (DFB_OK != dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN)) { mp_msg(MSGT_VO, MSGL_WARN,"DirectFB: Warning - cannot swith to fullscreen mode"); };#endif /* * (Get keyboard) */ if (use_input) { ret = dfb->GetInputDevice (dfb, DIDID_KEYBOARD, &keyboard); if (ret==DFB_OK) { mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Keyboard init OK\n"); } else { keyboard = NULL; mp_msg(MSGT_VO, MSGL_ERR,"DirectFB: Keyboard init FAILED\n"); } } /* * Create an input buffer for the keyboard. */ if (keyboard) DFBCHECK (keyboard->CreateEventBuffer (keyboard, &buffer)); // just to start with clean ... if (buffer) buffer->Reset(buffer); mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Preinit OK\n"); return 0;}DFBSurfacePixelFormat convformat(uint32_t format){// add more formats !!! switch (format) { case IMGFMT_RGB32: return DSPF_RGB32; break; case IMGFMT_BGR32: return DSPF_RGB32; break; case IMGFMT_RGB24: return DSPF_RGB24; break; case IMGFMT_BGR24: return DSPF_RGB24; break; case IMGFMT_RGB16: return DSPF_RGB16; break; case IMGFMT_BGR16: return DSPF_RGB16; break;#if DIRECTFBVERSION > DFB_VERSION(0,9,15) case IMGFMT_RGB15: return DSPF_ARGB1555; break; case IMGFMT_BGR15: return DSPF_ARGB1555; break;#else case IMGFMT_RGB15: return DSPF_RGB15; break; case IMGFMT_BGR15: return DSPF_RGB15; break;#endif case IMGFMT_YUY2: return DSPF_YUY2; break; case IMGFMT_UYVY: return DSPF_UYVY; break; case IMGFMT_YV12: return DSPF_YV12; break; case IMGFMT_I420: return DSPF_I420; break;// case IMGFMT_IYUV: return DSPF_IYUV; break; case IMGFMT_RGB8: return DSPF_RGB332; break; case IMGFMT_BGR8: return DSPF_RGB332; break; default: return 0; }return 0; }typedef struct enum1_s {uint32_t format;int scale;int result;unsigned int id;unsigned int width;unsigned int height;int setsize;} enum1_t;DFBEnumerationResult test_format_callback( unsigned int id, DFBDisplayLayerDescription desc, void *data){ enum1_t *params =(enum1_t *)data; IDirectFBDisplayLayer *layer; DFBResult ret; if ((layer_id == -1 )||(layer_id == id)) { ret = dfb->GetDisplayLayer( dfb, id, &layer); if (ret) { DirectFBError( "dfb->GetDisplayLayer failed", ret ); return DFENUM_OK; } else { DFBDisplayLayerConfig dlc; if (params->setsize) { dlc.flags = DLCONF_WIDTH |DLCONF_HEIGHT; dlc.width = params->width; dlc.height = params->height; layer->SetConfiguration(layer,&dlc); } dlc.flags = DLCONF_PIXELFORMAT; dlc.pixelformat = convformat(params->format); layer->SetOpacity(layer,0); ret = layer->TestConfiguration(layer,&dlc,NULL); layer->Release(layer); mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Test format - layer %i scale/pos %i\n",id,(desc.caps & DLCAPS_SCREEN_LOCATION)); if (ret==DFB_OK) {// printf("Test OK\n"); if (params->result) { if ((!params->scale) && (desc.caps & DLCAPS_SCREEN_LOCATION)) { params->scale=1; params->id=id; mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Test format - added layer %i scale/pos %i\n",id,(desc.caps & DLCAPS_SCREEN_LOCATION)); } } else { params->result=1; params->id=id; if (desc.caps & DLCAPS_SCREEN_LOCATION) params->scale=1; mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Test format - added layer %i scale/pos %i\n",id,(desc.caps & DLCAPS_SCREEN_LOCATION)); }; }; }; }; return DFENUM_OK;}static int query_format(uint32_t format){ int ret = VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_OSD; // osd should be removed in future -> will be handled outside... enum1_t params; if (!convformat(format)) return 0;// temporary disable YV12// if (format == IMGFMT_YV12) return 0;// if (format == IMGFMT_I420) return 0; if (format == IMGFMT_IYUV) return 0; mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Format query: %s\n",vo_format_name(format)); params.format=format; params.scale=0; params.result=0; params.setsize=0; DFBCHECK (dfb->EnumDisplayLayers(dfb,test_format_callback,¶ms)); if (params.result) { if (params.scale) ret |=VFCAP_HWSCALE_UP|VFCAP_HWSCALE_DOWN; return ret; } return 0;}typedef struct videomode_s {int width;int height;int out_width;int out_height;int overx;int overy;int bpp;} videomode_t;DFBEnumerationResult video_modes_callback( unsigned int width,unsigned int height,unsigned int bpp, void *data){ videomode_t *params =(videomode_t *)data;int overx=0,overy=0,closer=0,over=0;int we_are_under=0;mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Validator entered %i %i %i\n",width,height,bpp);overx=width-params->out_width;overy=height-params->out_height;if (!params->width) { params->width=width; params->height=height; params->overx=overx; params->overy=overy; mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Mode added %i %i %i\n",width,height,bpp);}if ((params->overy<0)||(params->overx<0)) we_are_under=1; // stored mode is smaller than req modeif (abs(overx*overy)<abs(params->overx * params->overy)) closer=1; // current mode is closer to desired resif ((overx>=0)&&(overy>=0)) over=1; // current mode is bigger or equaul to desired resif ((closer && (over || we_are_under)) || (we_are_under && over)) { params->width=width; params->height=height; params->overx=overx; params->overy=overy; mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Better mode added %i %i %i\n",width,height,bpp); };return DFENUM_OK;}#define CONFIG_ERROR -1static int config(uint32_t s_width, uint32_t s_height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format){ /* * (Locals) */// decode flags int fs = flags & VOFLAG_FULLSCREEN; int vm = flags & VOFLAG_MODESWITCHING; DFBSurfaceDescription dsc; DFBResult ret; DFBDisplayLayerConfig dlc; DFBSurfaceCapabilities caps; enum1_t params; mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Config entered [%ix%i]\n",s_width,s_height);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?