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,&params));	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 + -
显示快捷键?