Mercurial > mplayer.hg
changeset 5189:c663455448e8
updates by Jiri.Svoboda@seznam.cz
author | arpi |
---|---|
date | Mon, 18 Mar 2002 23:20:13 +0000 |
parents | d127ec93d5d1 |
children | 59df6b778d78 |
files | libvo/vo_directfb.c |
diffstat | 1 files changed, 751 insertions(+), 237 deletions(-) [+] |
line wrap: on
line diff
--- a/libvo/vo_directfb.c Mon Mar 18 22:25:03 2002 +0000 +++ b/libvo/vo_directfb.c Mon Mar 18 23:20:13 2002 +0000 @@ -58,6 +58,8 @@ #include "fastmemcpy.h" #include "sub.h" #include "../postproc/rgb2rgb.h" +#include "aspect.h" +#include "../mp_image.h" LIBVO_EXTERN(directfb) @@ -82,8 +84,8 @@ static IDirectFBInputDevice *keyboard = NULL; static IDirectFBDisplayLayer *videolayer = NULL; static DFBDisplayLayerConfig dlc; -static int screen_width = 0; -static int screen_height = 0; +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; @@ -126,14 +128,16 @@ char *fb_dev_name; #endif +static int preinitdone=0; + static void (*draw_alpha_p)(int w, int h, unsigned char *src, unsigned char *srca, int stride, unsigned char *dst, int dstride); -static int in_width; -static int in_height; -static int out_width; -static int out_height; +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; @@ -145,9 +149,27 @@ int overx,overy; } modes [4]; static unsigned int best_bpp=5; -static unsigned int preinit_done=0; -static int no_yuy2=1; -static int no_uyvy_support=1; +// videolayer stuff +static int videolayeractive=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 DFBEnumerationResult enum_modes_callback( unsigned int width,unsigned int height,unsigned int bpp, void *data) @@ -156,7 +178,7 @@ unsigned int index=bpp/8-1; int allow_under=0; -//printf("Validator entered %i %i %i\n",width,height,bpp); +if (verbose) printf("DirectFB: Validator entered %i %i %i\n",width,height,bpp); overx=width-out_width; overy=height-out_height; @@ -175,7 +197,7 @@ modes[index].height=height; modes[index].overx=overx; modes[index].overy=overy; -// printf("Better mode added %i %i %i\n",width,height,bpp); + if (verbose) printf("DirectFB:Better mode added %i %i %i\n",width,height,bpp); }; }; @@ -188,8 +210,8 @@ void *data ) { IDirectFBDisplayLayer **layer = (IDirectFBDisplayLayer **)data; -/* - printf( "\nLayer %d:\n", id ); +if (verbose) { + printf("\nDirectFB: Layer %d:\n", id ); if (caps & DLCAPS_SURFACE) printf( " - Has a surface.\n" ); @@ -225,7 +247,7 @@ printf( " - Saturation can be adjusted.\n" ); printf("\n"); -*/ +} /* We take the first layer not being the primary */ if (id != DLID_PRIMARY) { DFBResult ret; @@ -246,28 +268,15 @@ DFBResult ret; DFBDisplayLayerConfigFlags failed; - - if (preinit_done) return 1; - /* * (Initialize) */ + +if (verbose) printf("DirectFB: Preinit entered\n"); -// if (!dfb) { + if (preinitdone) return 0; DFBCHECK (DirectFBInit (NULL,NULL)); - - if ((directfb_major_version >= 0) && - (directfb_minor_version >= 9) && - (directfb_micro_version >= 7)) - no_uyvy_support = 0; - else - { - no_uyvy_support = 1; - printf("vo_directfb: no UYVY support. Version: %d.%d.%d\n", - directfb_major_version, directfb_minor_version, - directfb_micro_version); - } if ((directfb_major_version >= 0) && (directfb_minor_version >= 9) && @@ -277,11 +286,24 @@ DFBCHECK (DirectFBSetOption ("fbdev",fb_dev_name)); } + // disable YV12 for dfb 0.9.9 - there is a bug in dfb! + if ((directfb_major_version <= 0) && + (directfb_minor_version <= 9) && + (directfb_micro_version <= 9)) { + buggyYV12BitBlt=1; + if (verbose) printf("DirectFB: Buggy YV12BitBlt!\n"); + } + // uncomment this if you do not wish to create a new vt for DirectFB -// DFBCHECK (DirectFBSetOption ("no-vt-switch",fb_dev_name)); + DFBCHECK (DirectFBSetOption ("no-vt-switch","")); // uncomment this if you want to allow vt switching -// DFBCHECK (DirectFBSetOption ("vt-switching",fb_dev_name)); + DFBCHECK (DirectFBSetOption ("vt-switching","")); +#ifdef HAVE_DIRECTFB099 +// uncomment this if you want to hide gfx cursor (req dfb >=0.9.9) + DFBCHECK (DirectFBSetOption ("no-cursor","")); +#endif + DFBCHECK (DirectFBSetOption ("bg-color","00000000")); DFBCHECK (DirectFBCreate (&dfb)); @@ -293,39 +315,112 @@ DFBCHECK (dfb->EnumDisplayLayers( dfb, enum_layers_callback, &videolayer )); if (!videolayer) { - // no yuy2 layer -> fallback to RGB + if (verbose) printf("DirectFB: No videolayer found\n"); + // no videolayer found // printf( "\nNo additional layers have been found.\n" ); - no_yuy2 = 1; -// preinit_done = 1; + videolayeractive=0; + } else { - // there is an additional layer so test it for YUV - dlc.flags = /*DLCONF_WIDTH | DLCONF_HEIGHT | */DLCONF_PIXELFORMAT; //| DLCONF_OPTIONS; - /* dlc.width = dsc.width; - dlc.height = dsc.height;*/ - dlc.pixelformat = DSPF_YUY2; - // dlc.options = DLOP_INTERLACED_VIDEO; + // there is an additional layer so test it for YUV formats + // some videolayers support RGB formats - not used now + if (verbose) printf("DirectFB: Testing videolayer caps\n"); + + dlc.flags = DLCONF_PIXELFORMAT; +#ifdef HAVE_DIRECTFB099 + dlc.pixelformat = DSPF_YV12; + ret = videolayer->TestConfiguration( videolayer, &dlc, &failed ); + if (ret==DFB_OK) { + videolayercaps.iv12=1; + if (verbose) printf("DirectFB: Videolayer supports YV12 format\n"); + } else { + videolayercaps.iv12=0; + if (verbose) printf("DirectFB: Videolayer doesn't support YV12 format\n"); + }; + + dlc.pixelformat = DSPF_I420; + ret = videolayer->TestConfiguration( videolayer, &dlc, &failed ); + if (ret==DFB_OK) { + videolayercaps.i420=1; + if (verbose) printf("DirectFB: Videolayer supports I420 format\n"); + } else { + videolayercaps.i420=0; + if (verbose) printf("DirectFB: Videolayer doesn't support I420 format\n"); + }; +#else + videolayercaps.yuy2=0; +#endif + + dlc.pixelformat = DSPF_YUY2; + ret = videolayer->TestConfiguration( videolayer, &dlc, &failed ); + if (ret==DFB_OK) { + videolayercaps.yuy2=1; + if (verbose) printf("DirectFB: Videolayer supports YUY2 format\n"); + } else { + videolayercaps.yuy2=0; + if (verbose) printf("DirectFB: Videolayer doesn't support YUY2 format\n"); + }; - /* Test the configuration, getting failed fields */ + dlc.pixelformat = DSPF_UYVY; ret = videolayer->TestConfiguration( videolayer, &dlc, &failed ); - if (ret == DFB_UNSUPPORTED && no_uyvy_support == 0) { -// printf("Videolayer does not support YUY2"); - dlc.pixelformat = DSPF_UYVY; - ret = videolayer->TestConfiguration( videolayer, &dlc, &failed ); - if (ret != DFB_UNSUPPORTED) { no_yuy2 = 0;} - } else { no_yuy2 = 0;} + if (ret==DFB_OK) { + videolayercaps.uyvy=1; + if (verbose) printf("DirectFB: Videolayer supports UYVY format\n"); + } else { + videolayercaps.uyvy=0; + if (verbose) printf("DirectFB: Videolayer doesn't support UYVY format\n"); + }; + + // test for color caps + { + DFBDisplayLayerCapabilities caps; + videolayer->GetCapabilities(videolayer,&caps); + if (caps & DLCAPS_BRIGHTNESS) { + videolayercaps.brightness=1; + } else { + videolayercaps.brightness=0; + }; + + if (caps & DLCAPS_CONTRAST) { + videolayercaps.contrast=1; + } else { + videolayercaps.contrast=0; + }; + + if (caps & DLCAPS_HUE) { + videolayercaps.hue=1; + } else { + videolayercaps.hue=0; + }; + + if (caps & DLCAPS_SATURATION) { + videolayercaps.saturation=1; + } else { + videolayercaps.saturation=0; + }; + + + } + + + // is there a working yuv ? if no we will not use videolayer + if ((videolayercaps.iv12==0)&&(videolayercaps.i420==0)&&(videolayercaps.yuy2==0)&&(videolayercaps.uyvy==0)) { + // videolayer doesn't work with yuv so release it + videolayeractive=0; + videolayer->SetOpacity(videolayer,0); + videolayer->Release(videolayer); + } else { + videolayeractive=1; + }; } - -// just look at RGB things +// just look at RGB things for main layer modes[0].valid=0; modes[1].valid=0; modes[2].valid=0; modes[3].valid=0; DFBCHECK (dfb->EnumVideoModes(dfb,enum_modes_callback,NULL)); -// printf("No YUY2 %i\n",no_yuy2); -// } - preinit_done=1; + preinitdone=1; return 0; } @@ -345,6 +440,8 @@ int vm = fullscreen & 0x02; int zoom = fullscreen & 0x04; + if (verbose) printf("DirectFB: Config entered [%ix%i]\n",width,height); + fs = fullscreen & 0x01; flip = fullscreen & 0x08; @@ -357,12 +454,16 @@ out_width = d_width; out_height = d_height; } else { - d_width = out_width = width; - d_height = out_height = height; + d_width = out_width = in_width; + d_height = out_height = in_height; } - -// if (!preinit(NULL)) return 1; +// just look at RGB things for main layer - once again - now we now desired screen size + modes[0].valid=0; + modes[1].valid=0; + modes[2].valid=0; + modes[3].valid=0; + DFBCHECK (dfb->EnumVideoModes(dfb,enum_modes_callback,NULL)); if (vm) { @@ -371,64 +472,104 @@ } - if (!no_yuy2) { + if (videolayeractive) { + videolayeractive=0; // will be enabled on succes later + // try to set proper w a h values matching image size - dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT;// | DLCONF_OPTIONS; + dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT; dlc.width = in_width; dlc.height = in_height; ret = videolayer->SetConfiguration( videolayer, &dlc ); -/* if (ret) { - printf("Set layer size failed\n"); + if (ret) { + if (verbose) printf("DirectFB: Set layer size failed\n"); }; + + // try to set correct pixel format (closest to required) + + dlc.flags = DLCONF_PIXELFORMAT; + dlc.pixelformat = 0; + switch (pixel_format) { + case IMGFMT_YV12: +#ifdef HAVE_DIRECTFB099 + if (videolayercaps.i420==1) { + dlc.pixelformat=DSPF_I420; + break; + } else if (videolayercaps.iv12==1) { + dlc.pixelformat=DSPF_YV12; + break; + }; + +#endif + case IMGFMT_YUY2: if (videolayercaps.yuy2==1) { + dlc.pixelformat=DSPF_YUY2; + break; +// temporary disabled - do not have conv tool to uyvy +/* } else if (videolayercaps.uyvy==1) { + dlc.pixelformat=DSPF_UYVY; + break; */ - dlc.flags = DLCONF_PIXELFORMAT;// | DLCONF_OPTIONS; - //dlc.pixelformat = DSPF_YUY2; should be set by preinit - //dlc.options = (vcaps & DVCAPS_INTERLACED) ? DLOP_INTERLACED_VIDEO : 0; - no_yuy2=1; -/* switch (dlc.pixelformat) { - case DSPF_ARGB: printf("Directfb frame format ARGB\n"); - frame_pixel_size = 4; - break; - case DSPF_RGB32: printf("Directfb frame format RGB32\n"); - frame_pixel_size = 4; - break; - case DSPF_RGB24: printf("Directfb frame format RGB24\n"); - frame_pixel_size = 3; +#ifdef HAVE_DIRECTFB099 + } else if (videolayercaps.i420==1) { + dlc.pixelformat=DSPF_I420; + break; + } else if (videolayercaps.iv12==1) { + dlc.pixelformat=DSPF_YV12; + break; +#endif + }; + // shouldn't happen - if it reaches here -> bug + dsc.pixelformat = DSPF_RGB24; break; + + case IMGFMT_RGB32: dsc.pixelformat = DSPF_ARGB; break; + case IMGFMT_BGR32: dsc.pixelformat = DSPF_ARGB; break; + case IMGFMT_RGB24: dsc.pixelformat = DSPF_RGB24; break; + case IMGFMT_BGR24: dsc.pixelformat = DSPF_RGB24; break; + case IMGFMT_RGB16: dsc.pixelformat = DSPF_RGB16; break; + case IMGFMT_BGR16: dsc.pixelformat = DSPF_RGB16; break; + case IMGFMT_RGB15: dsc.pixelformat = DSPF_RGB15; break; + case IMGFMT_BGR15: dsc.pixelformat = DSPF_RGB15; break; + default: dsc.pixelformat = DSPF_RGB24; break; + } + + if (verbose) switch (dlc.pixelformat) { + case DSPF_ARGB: printf("DirectFB: layer format ARGB\n"); break; - case DSPF_RGB16: printf("Directfb frame format RGB16\n"); - frame_pixel_size = 2; + case DSPF_RGB32: printf("DirectFB: layer format RGB32\n"); + break; + case DSPF_RGB24: printf("DirectFB: layer format RGB24\n"); + break; + case DSPF_RGB16: printf("DirectFB: layer format RGB16\n"); break; - case DSPF_RGB15: printf("Directfb frame format RGB15\n"); - frame_pixel_size = 2; + case DSPF_RGB15: printf("DirectFB: layer format RGB15\n"); break; - case DSPF_YUY2: printf("Directfb frame format YUY2\n"); - frame_pixel_size = 2; + case DSPF_YUY2: printf("DirectFB: layer format YUY2\n"); + break; + case DSPF_UYVY: printf("DirectFB: layer format UYVY\n"); break; - case DSPF_UYVY: printf("Directfb frame format UYVY\n"); - frame_pixel_size = 2; +#ifdef HAVE_DIRECTFB099 + case DSPF_YV12: printf("DirectFB: layer format YV12\n"); + break; + case DSPF_I420: printf("DirectFB: layer format I420\n"); break; - default: printf("Directfb - unknown format ->exit\n"); return 1; +#endif + default: printf("DirectFB: - unknown format ->exit\n"); return 1; } -*/ ret =videolayer->SetConfiguration( videolayer, &dlc ); + + ret =videolayer->SetConfiguration( videolayer, &dlc ); if (!ret) { -// printf("SetConfiguration for layer OK\n"); + if (verbose) printf("DirectFB: SetConfiguration for layer OK\n"); ret = videolayer->GetSurface( videolayer, &primary ); if (!ret){ - no_yuy2=0; -// printf("Get surface for layer OK\n"); -/* dsc.width=in_width; - dsc.height=in_height; - dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH; - dsc.caps = DSCAPS_VIDEOONLY;//| DSCAPS_FLIPPING; - primary->SetConfiguration(priamry,&dsc);*/ + videolayeractive=1; + if (verbose) printf("DirectFB: Get surface for layer OK\n"); }; }; } -// mam pro flip pouzit tenhle flip nebo bitblt +// for flipping we will use BitBlt not integrated directfb flip dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT; dsc.caps = DSCAPS_PRIMARY | DSCAPS_VIDEOONLY;//| DSCAPS_FLIPPING; @@ -444,33 +585,10 @@ default: dsc.pixelformat = DSPF_RGB24; source_pixel_size=2; break; //YUV formats }; - - - if (no_yuy2) { - DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary )); - } - else {// try to set pos for YUY2 layer and proper aspect ratio - - extern float monitor_aspect; - - float h=(float)out_height,w=(float)out_width/monitor_aspect; - float aspect=h/w; -// printf("in out d: %d %d, %d %d, %d %d\n",in_width,in_height,out_width,out_height,d_width,d_height); -// printf ("Aspect y/x=%f/%f=%f\n",h,w,aspect); + if (!videolayeractive) { + DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary )); -// if (fs) { - // scale fullscreen - if (aspect>1) { - aspect=w/h; - ret = videolayer->SetScreenLocation(videolayer,(1-aspect)/2,0,aspect,1); - } else { - ret = videolayer->SetScreenLocation(videolayer,0,(1-aspect)/2,1,aspect); - } -// } else { - // beacase I can't get real screen size values I can't scale properly in other way then fullscreen -// }; -// if (ret) printf("SetScreenLocation failed\n"); - } + } DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height)); @@ -478,29 +596,11 @@ // temporary buffer buffer dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_WIDTH; - dsc.caps = DSCAPS_SYSTEMONLY; dsc.width = in_width; dsc.height = in_height; // at this time use pixel req format or format of main disp -/* - switch (frame_format) { - case DSPF_ARGB: printf("Directfb frame format ARGB\n"); - break; - case DSPF_RGB32: printf("Directfb frame format RGB32\n"); - break; - case DSPF_RGB24: printf("Directfb frame format RGB24\n"); - break; - case DSPF_RGB16: printf("Directfb frame format RGB16\n"); - break; - case DSPF_RGB15: printf("Directfb frame format RGB15\n"); - break; - case DSPF_YUY2: printf("Directfb frame format YUY2\n"); - break; - default: printf("Directfb - unknown format ->exit\n"); return 1; - } - */ switch (format) { case IMGFMT_RGB32: dsc.pixelformat = DSPF_ARGB; break; @@ -518,57 +618,69 @@ /* * Create a surface based on the description of the source frame */ - DFBCHECK (dfb->CreateSurface( dfb, &dsc, &frame)); +#ifdef HAVE_DIRECTFB099 + if (((dsc.pixelformat==DSPF_YV12)||(dsc.pixelformat==DSPF_I420)) && buggyYV12BitBlt) { + memcpyBitBlt = 1; + } else { + memcpyBitBlt = 0; + }; +#else + memcpyBitBlt = 0; +#endif + // prevent from memcpy from videomemory to videomemory +/* if (memcpyBitBlt) { + dsc.caps = DSCAPS_SYSTEMONLY; + } else { + dsc.caps = DSCAPS_VIDEOONLY; + } + ret = dfb->CreateSurface( dfb, &dsc, &frame); + if (ret) { + if (verbose) printf ("DirectFB: Trying do create buffer in system memory (2)\n");*/ + dsc.caps = DSCAPS_SYSTEMONLY; + DFBCHECK (dfb->CreateSurface( dfb, &dsc, &frame)); +// } + DFBCHECK (frame->GetPixelFormat (frame, &frame_format)); switch (frame_format) { - case DSPF_ARGB: //printf("Directfb frame format ARGB\n"); + case DSPF_ARGB: if (verbose) printf("DirectFB: frame format ARGB\n"); frame_pixel_size = 4; break; - case DSPF_RGB32: //printf("Directfb frame format RGB32\n"); + case DSPF_RGB32: if (verbose) printf("DirectFB: frame format RGB32\n"); frame_pixel_size = 4; break; - case DSPF_RGB24: //printf("Directfb frame format RGB24\n"); + case DSPF_RGB24: if (verbose) printf("DirectFB: frame format RGB24\n"); frame_pixel_size = 3; break; - case DSPF_RGB16: //printf("Directfb frame format RGB16\n"); + case DSPF_RGB16: if (verbose) printf("DirectFB: frame format RGB16\n"); frame_pixel_size = 2; break; - case DSPF_RGB15: //printf("Directfb frame format RGB15\n"); + case DSPF_RGB15: if (verbose) printf("DirectFB: frame format RGB15\n"); frame_pixel_size = 2; break; - case DSPF_YUY2: //printf("Directfb frame format YUY2\n"); - frame_pixel_size = 2; - break; - case DSPF_UYVY: //printf("Directfb frame format UYVY\n"); + case DSPF_YUY2: if (verbose) printf("DirectFB: frame format YUY2\n"); frame_pixel_size = 2; break; - default: printf("Directfb - unknown format ->exit\n"); return 1; + case DSPF_UYVY: if (verbose) printf("DirectFB: frame format UYVY\n"); + frame_pixel_size = 2; + break; +#ifdef HAVE_DIRECTFB099 + case DSPF_YV12: if (verbose) printf("DirectFB: frame format YV12\n"); + frame_pixel_size = 1; + break; + case DSPF_I420: if (verbose) printf("DirectFB: frame format I420\n"); + frame_pixel_size = 1; + break; +#endif + default: printf("DirectFB: - unknown format ->exit\n"); return 1; } - - if (zoom) { - printf("-zoom is not yet supported\n"); -// return 1; - } -/* - if (fs) { - printf("-fs can degrade image and performance\n"); -// return 1; - } -*/ if ((out_width < in_width || out_height < in_height) && (!fs)) { printf("Screensize is smaller than video size !\n"); -// return 1; // doesn't matter we will +// return 1; // doesn't matter we will rescale } - if ((fs) && (no_yuy2)) { - // aspect ratio correction for fullscreen - out_height=d_height*screen_width/d_width; - if (out_height <= screen_height) {out_width=screen_width;} else {out_width=screen_width*screen_height/d_height; out_height=screen_height;}; -// printf("Going fullscreen !\n"); - } /* @@ -580,25 +692,71 @@ * Create an input buffer for the keyboard. */ #ifdef HAVE_DIRECTFB099 - DFBCHECK (keyboard->CreateEventBuffer (DICAPS_ALL, &buffer)); + DFBCHECK (keyboard->CreateEventBuffer (keyboard, &buffer)); #else DFBCHECK (keyboard->CreateInputBuffer (keyboard, &buffer)); #endif // yuv2rgb transform init - if (((format == IMGFMT_YV12) || (format == IMGFMT_YUY2)) && no_yuy2){ yuv2rgb_init(frame_pixel_size * 8,MODE_RGB);}; + if (((format == IMGFMT_YV12) || (format == IMGFMT_YUY2)) && (!videolayeractive)){ yuv2rgb_init(frame_pixel_size * 8,MODE_RGB);}; + +// picture size and position + + aspect_save_orig(in_width,in_height); + aspect_save_prescale(d_width,d_height); + if (videolayeractive) {// try to set pos for YUY2 layer and proper aspect ratio + aspect_save_screenres(10000,10000); + aspect(&out_width,&out_height,A_ZOOM); + + ret = videolayer->SetScreenLocation(videolayer,(1-(float)out_width/10000)/2,(1-(float)out_height/10000)/2,((float)out_width/10000),((float)out_height/10000)); - if (((out_width != in_width) || (out_height != in_height)) && (no_yuy2)) {stretch = 1;} else stretch=0; //yuy doesn't like strech and should not be needed + xoffset = 0; + yoffset = 0; + } else { + // aspect ratio correction for zoom to fullscreen + aspect_save_screenres(screen_width,screen_height); + + if(fs) /* -fs */ + aspect(&out_width,&out_height,A_ZOOM); + else + aspect(&out_width,&out_height,A_NOZOOM); + + + xoffset = (screen_width - out_width) / 2; + yoffset = (screen_height - out_height) / 2; + } - if (no_yuy2) { - xoffset = (screen_width - out_width) / 2; - yoffset = (screen_height - out_height) / 2; - } else { - xoffset = 0; - yoffset = 0; - } -// printf("in out d: %d %d, %d %d, %d %d\n",in_width,in_height,out_width,out_height,d_width,d_height); + if (((out_width != in_width) || (out_height != in_height)) && (!videolayeractive)) {stretch = 1;} else stretch=0; //yuy doesn't like strech and should not be needed + + if ((verbose)&&(memcpyBitBlt)) printf("DirectFB: Using memcpyBitBlt\n"); +#ifdef DIRECTRENDER +//direct rendering is enabled in case of sane buffer and im format + if ((format==IMGFMT_RGB32)&&(frame_format ==DSPF_ARGB) || + (format==IMGFMT_BGR32)&&(frame_format ==DSPF_ARGB) || + (format==IMGFMT_RGB24)&&(frame_format ==DSPF_RGB24) || + (format==IMGFMT_BGR24)&&(frame_format ==DSPF_RGB24) || + (format==IMGFMT_RGB16)&&(frame_format ==DSPF_RGB16) || + (format==IMGFMT_BGR16)&&(frame_format ==DSPF_RGB16) || + (format==IMGFMT_RGB15)&&(frame_format ==DSPF_RGB15) || + (format==IMGFMT_BGR15)&&(frame_format ==DSPF_RGB15) || +#ifdef HAVE_DIRECTFB099 + (format==IMGFMT_YUY2)&&(frame_format ==DSPF_YUY2) || + (format==IMGFMT_YV12)&&(frame_format ==DSPF_I420) || + (format==IMGFMT_YV12)&&(frame_format ==DSPF_YV12)){ +#else + (format==IMGFMT_YUY2)&&(frame_format ==DSPF_YUY2)){ +#endif + dr_enabled=1; + if (verbose) printf("DirectFB: Direct rendering supported\n"); + } else { + dr_enabled=0; + if (verbose) printf("DirectFB: Direct rendering not supported\n"); + }; +#endif + + + if (verbose) printf("DirectFB: Config finished [%ix%i]\n",out_width,out_height); return 0; } @@ -609,7 +767,7 @@ // preinit(NULL); -// printf("Format query: %s\n",vo_format_name(format)); + if (verbose ) printf("DirectFB: Format query: %s\n",vo_format_name(format)); switch (format) { // RGB mode works only if color depth is same as on screen and this driver doesn't know before init @@ -627,9 +785,17 @@ case IMGFMT_RGB15: case IMGFMT_BGR15: if (modes[1].valid) return ret|0x2; break; - case IMGFMT_YUY2: if (!no_yuy2) return ret|0x2; + case IMGFMT_YUY2: if (videolayeractive) { + if (videolayercaps.yuy2) { + return ret|0x2; + } else { + return ret|0x1; + }; + }; break; - case IMGFMT_YV12: if (!no_yuy2) return ret|0x2; else return ret|0x1; + case IMGFMT_YV12: if ((videolayeractive) && + (videolayercaps.i420 || videolayercaps.iv12)) + return ret|0x2; else return ret|0x1; break; // YV12 should work in all cases } @@ -649,6 +815,12 @@ int pitch; int len; +#ifdef DIRECTRENDER + if(framelocked) { + frame->Unlock(frame); + framelocked=0; + }; +#endif DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch)); switch(frame_format) { @@ -676,6 +848,13 @@ case DSPF_UYVY: vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + frame_pixel_size*x0 + 1,pitch); break; + +#ifdef HAVE_DIRECTFB099 + case DSPF_I420: + case DSPF_YV12: + vo_draw_alpha_yv12(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + frame_pixel_size*x0,pitch); + break; +#endif } DFBCHECK (frame->Unlock(frame)); } @@ -686,15 +865,23 @@ int pitch; int len; +// printf("Drawframe\n"); +#ifdef DIRECTRENDER + if(framelocked) { + frame->Unlock(frame); + framelocked=0; + }; +#endif + DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch)); switch (frame_format) { case DSPF_ARGB: case DSPF_RGB32: - case DSPF_RGB24: + case DSPF_RGB24: case DSPF_RGB16: - case DSPF_RGB15:switch (pixel_format) { - case IMGFMT_YV12: + case DSPF_RGB15: switch (pixel_format) { + case IMGFMT_YV12: yuv2rgb(dst,src[0],src[1],src[2],in_width,in_height,pitch,in_width,in_width/2); break; /* how to handle this? need conversion from YUY2 to RGB*/ @@ -703,26 +890,87 @@ yuv2rgb(dst+1,src[0]+2,src[0]+1,src[0]+3,1,in_height*in_width/2,frame_pixel_size*2,4,4); //even pixels break;*/ // RGB - just copy - default: if (source_pixel_size==frame_pixel_size) {memcpy(dst,src[0],in_width * in_height * frame_pixel_size);}; - - } - break; + default: if (source_pixel_size==frame_pixel_size) { + if (pitch==(in_width*frame_pixel_size)) { + memcpy(dst,src[0],in_width * in_height * source_pixel_size); + } else { + int i; + int sp=in_width*source_pixel_size; + int ll=min(sp,pitch); + for (i=0;i<in_height;i++) { + memcpy(dst+i*pitch,src[0]+i*sp,ll); + }; + }; + }; + }; + break; case DSPF_YUY2: switch (pixel_format) { case IMGFMT_YV12: yv12toyuy2(src[0],src[1],src[2],dst,in_width,in_height,in_width,in_width >>1,pitch); break; - case IMGFMT_YUY2: { - int i; - for (i=0;i<in_height;i++) { + case IMGFMT_YUY2: if (pitch==(in_width*2)) { + memcpy(dst,src[0],in_width * in_height * source_pixel_size); + } else { + int i; + for (i=0;i<in_height;i++) { memcpy(dst+i*pitch,src[0]+i*in_width*2,in_width*2); } - } - /*len = in_width * in_height * pitch; - memcpy(dst,src[0],len);*/ - break; + } + break; // hopefully there will be no RGB in this case otherwise convert - not implemented - } + }; break; + +#ifdef HAVE_DIRECTFB099 + case DSPF_YV12: + switch (pixel_format) { + case IMGFMT_YV12: { + int i; + int p=min(in_width,pitch); + for (i=0;i<in_height;i++) { + memcpy(dst+i*pitch,src[0]+i*in_width,p); + } + dst += pitch*in_height; + p = p/2; + for (i=0;i<in_height/2;i++) { + memcpy(dst+i*pitch/2,src[2]+i*in_width/2,p); + } + dst += pitch*in_height/4; + for (i=0;i<in_height/2;i++) { + memcpy(dst+i*pitch/2,src[1]+i*in_width/2,p); + } + }; + break; + case IMGFMT_YUY2: yuy2toyv12(src[0],dst,dst+pitch*in_height+pitch*in_height/4,dst+pitch*in_height,in_width,in_height,pitch,pitch/2,pitch/2); + break; + // hopefully there will be no RGB in this case otherwise convert - not implemented + } + break; + case DSPF_I420: + switch (pixel_format) { + case IMGFMT_YV12: { + int i; + int p=min(in_width,pitch); + for (i=0;i<in_height;i++) { + memcpy(dst+i*pitch,src[0]+i*in_width,p); + } + dst += pitch*in_height; + p = p/2; + for (i=0;i<in_height/2;i++) { + memcpy(dst+i*pitch/2,src[1]+i*in_width/2,p); + } + dst += pitch*in_height/4; + for (i=0;i<in_height/2;i++) { + memcpy(dst+i*pitch/2,src[2]+i*in_width/2,p); + } + }; + break; + case IMGFMT_YUY2: yuy2toyv12(src[0],dst,dst+pitch*in_height,dst+pitch*in_height+pitch*in_height/4,in_width,in_height,pitch,pitch/2,pitch/2); + break; + // hopefully there will be no RGB in this case otherwise convert - not implemented + } + break; +#endif } DFBCHECK (frame->Unlock(frame)); return 0; @@ -737,10 +985,22 @@ int pitch; int i; - err = frame->Lock(frame,DSLF_WRITE,&dst,&pitch); +#ifdef DIRECTRENDER + if(framelocked) { + frame->Unlock(frame); + framelocked=0; + }; +#endif -// printf("Drawslice\n"); + err = frame->Lock(frame,DSLF_WRITE,&dst,&pitch); +// err = primary->Lock(primary,DSLF_WRITE,&dst,&pitch); // for direct rendering + +// printf("Drawslice w=%i h=%i x=%i y=%i pitch=%i\n",w,h,x,y,pitch); + if (err) { + printf("DirectFB: Frame lock failed!"); + return 1; + }; switch (frame_format) { case DSPF_ARGB: case DSPF_RGB32: @@ -751,20 +1011,10 @@ case IMGFMT_YV12: yuv2rgb(dst+ y * pitch + frame_pixel_size*x ,src[0],src[1],src[2],w,h,pitch,stride[0],stride[1]); break; - // how to handle this? need conversion -/* case IMGFMT_YUY2: { - int i; - for (i=0;i<=h;i++) { - yuv2rgb(dst+ (i+y) * pitch + frame_pixel_size*x,src[0]+i*stride[0],src[0]+1+i*stride[0],src[0]+3+i*stride[0],1,(w+1)/2,frame_pixel_size*2,4,4); //odd pixels - yuv2rgb(dst+ (i+y) * pitch + frame_pixel_size*x +1,src[0]+i*stride[0]+2,src[0]+1+i*stride[0],src[0]+3+i*stride[0],1,(w)/2,frame_pixel_size*2,4,4); //odd pixels - }; - }; - break; - */ default: if (source_pixel_size==frame_pixel_size) { dst += x * frame_pixel_size; s = src[0]; - for (i=y;i<=(y+h);i++) { + for (i=y;i<(y+h);i++) { memcpy(dst,s,w); dst += (pitch); s += stride[0]; @@ -778,23 +1028,76 @@ switch (pixel_format) { case IMGFMT_YV12: yv12toyuy2(src[0],src[1],src[2],dst + pitch*y + frame_pixel_size*x ,w,h,stride[0],stride[1],pitch); break; - case IMGFMT_YUY2: { - dst += x * frame_pixel_size; - s = src[0]; - for (i=y;i<=(y+h);i++) { - memcpy(dst,s,w); - dst += (pitch); - s += stride[0]; - }; - }; - break; // hopefully there will be no RGB in this case otherwise convert - not implemented } break; + +#ifdef HAVE_DIRECTFB099 + case DSPF_YV12: + switch (pixel_format) { + case IMGFMT_YV12: { + int i; + dst += x; + for (i=y;i<(y+h);i++) { + memcpy(dst+i*pitch,src[0]+i*stride[0],w); + } + dst += pitch*in_height - (x)/2; + for (i=y/2;i<(y+h)/2;i++) { + memcpy(dst+i*pitch/2,src[2]+i*stride[2],w/2); + } + dst += pitch*in_height/4; + for (i=y/2;i<(y+h)/2;i++) { + memcpy(dst+i*pitch/2,src[1]+i*stride[1],w/2); + } + }; + break; +/* case IMGFMT_YUY2: { + int i; + for (i=y;i<(y+h);i++) { + yuy2toyv12(src[0]+i*stride[0],dst+i*pitch+x*frame_pixel_size,dst+pitch*(in_height+i/2)+x*frame_pixel_size/2,dst+pitch*(in_height+in_height/4+i/2)+x*frame_pixel_size/2,w,h,pitch,pitch/2,pitch/2); + } + } + + break; +*/ // hopefully there will be no RGB in this case otherwise convert - not implemented + } + break; + + case DSPF_I420: + switch (pixel_format) { + case IMGFMT_YV12: { + int i; + dst += x; + for (i=y;i<(y+h);i++) { + memcpy(dst+i*pitch,src[0]+i*stride[0],w); + } + dst += pitch*in_height - (x)/2; + for (i=y/2;i<(y+h)/2;i++) { + memcpy(dst+i*pitch/2,src[1]+i*stride[1],w/2); + } + dst += pitch*in_height/4; + for (i=y/2;i<(y+h)/2;i++) { + memcpy(dst+i*pitch/2,src[2]+i*stride[2],w/2); + } + }; + break; +/* case IMGFMT_YUY2: { + int i; + for (i=y;i<(y+h);i++) { + yuy2toyv12(src[0]+i*stride[0],dst+i*pitch+x*frame_pixel_size,dst+pitch*(in_height+in_height/4+i/2)+x*frame_pixel_size/2,dst+pitch*(in_height+i/2)+x*frame_pixel_size/2,w,h,pitch,pitch/2,pitch/2); + } + } + + break; +*/ // hopefully there will be no RGB in this case otherwise convert - not implemented + } + break; +#endif }; frame->Unlock(frame); - +// primary->Unlock(primary); + return 0; } @@ -806,11 +1109,8 @@ { DFBInputEvent event; -#ifdef HAVE_DIRECTFB099 -if (buffer->GetEvent (buffer, DFB_EVENT(&event)) == DFB_OK) { -#else -if (buffer->GetEvent (buffer, &event) == DFB_OK) { -#endif +//if (verbose) printf ("DirectFB: Check events entered\n"); +if (buffer->GetEvent(buffer, &event) == DFB_OK) { if (event.type == DIET_KEYPRESS) { switch (event.keycode) { case DIKC_ESCAPE: @@ -842,6 +1142,7 @@ // temporary workabout should be solved in the future buffer->Reset(buffer); +//if (verbose) printf ("DirectFB: Check events finished\n"); } @@ -854,8 +1155,16 @@ { DFBSurfaceBlittingFlags flags=DSBLIT_NOFX; +// if (verbose) printf("DirectFB: Flip page entered"); + DFBCHECK (primary->SetBlittingFlags(primary,flags)); +#ifdef DIRECTRENDER + if(framelocked) { + frame->Unlock(frame); + framelocked=0; + }; +#endif if (stretch) { DFBRectangle rect; rect.x=xoffset; @@ -866,45 +1175,250 @@ DFBCHECK (primary->StretchBlit(primary,frame,NULL,&rect)); } else { - DFBCHECK (primary->Blit(primary,frame,NULL,xoffset,yoffset)); +#ifdef HAVE_DIRECTFB099 + if (!memcpyBitBlt) { +#endif + DFBCHECK (primary->Blit(primary,frame,NULL,xoffset,yoffset)); +#ifdef HAVE_DIRECTFB099 + } else { + + int err,err2; + void *dst,*src; + int pitch,pitch2; + +// printf("MemcpyBlit"); + + err = frame->Lock(frame,DSLF_READ,&src,&pitch); + err2 = primary->Lock(primary,DSLF_WRITE,&dst,&pitch2); + +// printf("DirectFB: pitch=%i pitch2=%i\n",pitch,pitch2); + + + if (pitch==pitch2) { + memcpy(dst,src,in_height * pitch * 1.5); + } else + { + int i; + int p=min(pitch,pitch2); + for (i=0;i<in_height;i++) { + memcpy (dst+i*pitch2,src+i*pitch,p); + }; + dst+= in_height * pitch2; + src+= in_height * pitch; + p=p/2; + for (i=0;i<in_height/2;i++) { + memcpy (dst+i*pitch2/2,src+i*pitch/2,p); + }; + dst+= in_height * pitch2/4; + src+= in_height * pitch/4; + for (i=0;i<in_height/2;i++) { + memcpy (dst+i*pitch2/2,src+i*pitch/2,p); + }; + } + frame->Unlock(frame); + primary->Unlock(primary); + }; +#endif }; // DFBCHECK (primary->Flip (primary, NULL, DSFLIP_WAITFORSYNC)); } static void uninit(void) { - if (verbose > 0) - printf("uninit\n"); - + if (verbose ) printf("DirectFB: uninit entered\n"); /* * (Release) */ -// printf("Release buffer\n"); + if (verbose ) printf("DirectFB: Release buffer\n"); buffer->Release (buffer); -// printf("Release keyb\n"); + if (verbose ) printf("DirectFB: Release keyboard\n"); keyboard->Release (keyboard); -// printf("Release frame\n"); + if (verbose ) printf("DirectFB: Release frame\n"); frame->Release (frame); // we will not release dfb and layer because there could be a new film -// printf("Release primary\n"); + if (verbose ) printf("DirectFB: Release primary\n"); primary->Release (primary); // switch off BES if (videolayer) videolayer->SetOpacity(videolayer,0); -// printf("Release videolayer\n"); -// if (videolayer) videolayer->Release(videolayer); -// printf("Release dfb\n"); -// dfb->Release (dfb); -// preinit_done=0; + +#ifdef HAVE_DIRECTFB099 + if (verbose&&videolayer ) printf("DirectFB: Release videolayer\n"); + if (videolayer) videolayer->Release(videolayer); + + if (verbose ) printf("DirectFB: Release DirectFB library\n"); + dfb->Release (dfb); + preinitdone=0; +#endif + + if (verbose ) printf("DirectFB: Uninit done.\n"); +} + +static int directfb_set_video_eq( const vidix_video_eq_t *info) +{ + if (videolayeractive) { + DFBColorAdjustment ca; + float factor = (float)0xffff / 2000.0; + + ca.flags=DCAF_NONE; + + if ((videolayercaps.brightness)&&(info->cap&VEQ_CAP_BRIGHTNESS)) { + ca.brightness = info->brightness * factor +0x8000; + ca.flags |= DCAF_BRIGHTNESS; + if (verbose) printf("DirectFB: SetVEq Brightness 0x%X %i\n",ca.brightness,info->brightness); + } + + if ((videolayercaps.contrast)&&(info->cap&VEQ_CAP_CONTRAST)) { + ca.contrast = info->contrast * factor + 0x8000; + ca.flags |= DCAF_CONTRAST; + if (verbose) printf("DirectFB: SetVEq Contrast 0x%X %i\n",ca.contrast,info->contrast); + } + + if ((videolayercaps.hue)&&(info->cap&VEQ_CAP_HUE)) { + ca.hue = info->hue * factor + 0x8000; + ca.flags |= DCAF_HUE; + if (verbose) printf("DirectFB: SetVEq Hue 0x%X %i\n",ca.hue,info->hue); + } + + if ((videolayercaps.saturation)&&(info->cap&VEQ_CAP_HUE)) { + ca.saturation = info->saturation * factor + 0x8000; + ca.flags |= DCAF_SATURATION; + if (verbose) printf("DirectFB: SetVEq Saturation 0x%X %i\n",ca.saturation,info->saturation); + } + + videolayer->SetColorAdjustment(videolayer,&ca); + }; + return 0; } +static int directfb_get_video_eq( vidix_video_eq_t *info) +{ + if (videolayeractive) { + DFBColorAdjustment ca; + float factor = 2000.0 / (float)0xffff; + videolayer->GetColorAdjustment(videolayer,&ca); + + if ((videolayercaps.brightness)&&(ca.flags&DCAF_BRIGHTNESS)) { + info->brightness = (ca.brightness-0x8000) * factor; + info->cap |= VEQ_CAP_BRIGHTNESS; + if (verbose) printf("DirectFB: GetVEq Brightness 0x%X %i\n",ca.brightness,info->brightness); + } + + if ((videolayercaps.contrast)&&(ca.flags&DCAF_CONTRAST)) { + info->contrast = (ca.contrast-0x8000) * factor; + info->cap |= VEQ_CAP_CONTRAST; + if (verbose) printf("DirectFB: GetVEq Contrast 0x%X %i\n",ca.contrast,info->contrast); + } + + if ((videolayercaps.hue)&&(ca.flags&DCAF_HUE)) { + info->hue = (ca.hue-0x8000) * factor; + info->cap |= VEQ_CAP_HUE; + if (verbose) printf("DirectFB: GetVEq Hue 0x%X %i\n",ca.hue,info->hue); + } + + if ((videolayercaps.saturation)&&(ca.flags&DCAF_SATURATION)) { + info->saturation = (ca.saturation-0x8000) * factor; + info->cap |= VEQ_CAP_SATURATION; + if (verbose) printf("DirectFB: GetVEq Saturation 0x%X %i\n",ca.saturation,info->saturation); + } + + }; + return 0; +} +static void query_vaa(vo_vaa_t *vaa) +{ + memset(vaa,0,sizeof(vo_vaa_t)); + vaa->get_video_eq = directfb_get_video_eq; + vaa->set_video_eq = directfb_set_video_eq; +} + +#ifdef DIRECTRENDER +static uint32_t get_image(mp_image_t *mpi){ + int err; + void *dst; + uint8_t *s; + int pitch; + int i; + +// printf("DirectFB: get_image() called\n"); + +// now we are always in system memory (in this version - mybe will change in future) +// if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // slow video ram + +// printf("width=%d vs. pitch=%d, flags=0x%X \n",mpi->width,pitch,mpi->flags); + if((mpi->width==pitch/frame_pixel_size) || + (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH))){ + // we're lucky or codec accepts stride => ok, let's go! + if(mpi->flags&MP_IMGFLAG_PLANAR){ + +#ifdef HAVE_DIRECTFB099 + err = frame->Lock(frame,DSLF_WRITE/*|DSLF_READ*/,&dst,&pitch); +// err = primary->Lock(primary,DSLF_WRITE,&dst,&pitch); // for real direct rendering + + if (err) { + printf("DirectFB: Frame lock failed!"); + return VO_FALSE; + }; + framelocked=1; + + //YV12 format + mpi->planes[0]=dst; + switch(frame_format) { + case DSPF_I420: mpi->planes[1]=dst + pitch*in_height; + mpi->planes[2]=mpi->planes[1] + pitch*in_height/4; + break; + case DSPF_YV12: mpi->planes[2]=dst + pitch*in_height; + mpi->planes[1]=mpi->planes[1] + pitch*in_height/4; + break; + + } + mpi->width=mpi->stride[0]=pitch; + mpi->stride[1]=mpi->stride[2]=pitch/2; +#else + return VO_FALSE; +#endif + } else { + err = frame->Lock(frame,DSLF_WRITE/*|DSLF_READ*/,&dst,&pitch); +// err = primary->Lock(primary,DSLF_WRITE,&dst,&pitch); // for real direct rendering + + if (err) { + printf("DirectFB: Frame lock failed!"); + return VO_FALSE; + }; + framelocked=1; + //YUY2 and RGB formats + mpi->planes[0]=dst; + mpi->width=pitch/frame_pixel_size; + mpi->stride[0]=pitch; + } + mpi->flags|=MP_IMGFLAG_DIRECT; +// printf("DirectFB: get_image() SUCCESS -> Direct Rendering ENABLED\n"); + return VO_TRUE; + } + + if(framelocked) { + frame->Unlock(frame); + framelocked=0; + }; + return VO_FALSE; +} +#endif + static uint32_t control(uint32_t request, void *data, ...) { switch (request) { + case VOCTRL_QUERY_VAA: + query_vaa((vo_vaa_t*)data); + return VO_TRUE; case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); +#ifdef DIRECTRENDER + case VOCTRL_GET_IMAGE: +// printf("DirectFB: control(VOCTRL_GET_IMAGE) called\n"); + if (dr_enabled) return get_image(data); +#endif } return VO_NOTIMPL; }