static uint32_t get_image(mp_image_t * mpi) { if (zoomFlag || !IMGFMT_IS_BGR(mpi->imgfmt) || (IMGFMT_BGR_DEPTH(mpi->imgfmt) != vo_depthonscreen) || ((mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) || (mpi->flags & MP_IMGFLAG_PLANAR) || (mpi->flags & MP_IMGFLAG_YUV) || (mpi->width != image_width) || (mpi->height != image_height)) return VO_FALSE; if (Flip_Flag) { mpi->stride[0] = -image_width * ((bpp + 7) / 8); mpi->planes[0] = ImageData - mpi->stride[0] * (image_height - 1); } else { mpi->stride[0] = image_width * ((bpp + 7) / 8); mpi->planes[0] = ImageData; } mpi->flags |= MP_IMGFLAG_DIRECT; return VO_TRUE; }
static int query_format(uint32_t format) { mp_msg(MSGT_VO, MSGL_DBG2, "vo_x11: query_format was called: %x (%s)\n", format, vo_format_name(format)); if (IMGFMT_IS_BGR(format)) { if (IMGFMT_BGR_DEPTH(format) <= 8) return 0; // TODO 8bpp not yet fully implemented if (IMGFMT_BGR_DEPTH(format) == vo_depthonscreen) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_SWSCALE | VFCAP_FLIP | VFCAP_ACCEPT_STRIDE; else return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_SWSCALE | VFCAP_FLIP | VFCAP_ACCEPT_STRIDE; } switch (format) { // case IMGFMT_BGR8: // case IMGFMT_BGR15: // case IMGFMT_BGR16: // case IMGFMT_BGR24: // case IMGFMT_BGR32: // return 0x2; // case IMGFMT_YUY2: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YV12: return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_SWSCALE | VFCAP_ACCEPT_STRIDE; } return 0; }
static uint32_t get_image(mp_image_t * mpi) { if (!IMGFMT_IS_BGR(mpi->imgfmt) || (IMGFMT_BGR_DEPTH(mpi->imgfmt) != vo_dga_modes[vo_dga_hw_mode].vdm_mplayer_depth) || (mpi->type == MP_IMGTYPE_STATIC && vo_dga_nr_video_buffers > 1) || (mpi->type == MP_IMGTYPE_IP && vo_dga_nr_video_buffers < 2) || (mpi->type == MP_IMGTYPE_IPB)) return (VO_FALSE); if ((mpi->flags & MP_IMGFLAG_ACCEPT_STRIDE) || (mpi->flags & MP_IMGFLAG_ACCEPT_WIDTH && ((vo_dga_bytes_per_line + vo_dga_vp_skip) % (mpi->bpp / 8)) == 0) || (mpi->width * (mpi->bpp / 8) == (vo_dga_bytes_per_line + vo_dga_vp_skip))) { mpi->planes[0] = CURRENT_VIDEO_BUFFER.data + vo_dga_vp_offset; mpi->stride[0] = vo_dga_bytes_per_line + vo_dga_vp_skip; mpi->width = (vo_dga_bytes_per_line + vo_dga_vp_skip) / (mpi->bpp / 8); mpi->flags |= MP_IMGFLAG_DIRECT; return (VO_TRUE); } return (VO_FALSE); }
// // This function is called to init the video driver for specific mode // static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { int32_t req_w = width;// (d_width > 0 ? d_width : width); int32_t req_h = height;// (d_height > 0 ? d_height : height); uint16_t vid_mode = 0; int32_t req_bpp; uint32_t accflags; mp_msg(MSGT_VO,MSGL_V, "vo_svga: config(%i, %i, %i, %i, %08x, %s, %08x)\n", width, height, d_width, d_height, flags, title, format); //Only RGB modes supported if (!IMGFMT_IS_RGB(format) && !IMGFMT_IS_BGR(format)) { assert(0); return -1; } req_bpp = IMGFMT_BGR_DEPTH(format); if( vo_dbpp!=0 && vo_dbpp!=req_bpp) { assert(0); return-1; } if(!force_vm) { mp_msg(MSGT_VO,MSGL_V, "vo_svga: Looking for the best resolution...\n"); mp_msg(MSGT_VO,MSGL_V, "vo_svga: req_w: %d, req_h: %d, bpp: %d\n",req_w,req_h,req_bpp); vid_mode=find_best_svga_mode(req_w,req_h,req_bpp); if(vid_mode==0) return 1; modeinfo=vga_getmodeinfo(vid_mode); } else { //force_vm vid_mode=force_vm; if(vga_hasmode(vid_mode) == 0) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_ForcedVidmodeNotAvailable, vid_mode,vga_getmodename(vid_mode)); return 1; //error; } modeinfo=vga_getmodeinfo(vid_mode); if( (modeinfo->width < req_w) || (modeinfo->height < req_h) ) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_ForcedVidmodeTooSmall, vid_mode,vga_getmodename(vid_mode)); return 1; } } mode_bpp=bpp_from_vminfo(modeinfo); mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_Vidmode, vid_mode,modeinfo->width,modeinfo->height,mode_bpp); if (vga_setmode(vid_mode) == -1) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_VgasetmodeFailed,vid_mode); uninit(); return 1; // error } /* set 332 palette for 8 bpp */ if(mode_bpp==8) { int i; for(i=0; i<256; i++) vga_setpalette(i, ((i>>5)&7)*9, ((i>>2)&7)*9, (i&3)*21); }
static int set_format(struct vf_instance *vf, unsigned int fmt) { if (!force_fourcc) mux_v->bih->biCompression = fmt; mux_v->bih->biPlanes = 1; if (IMGFMT_IS_RGB(fmt)) { if (IMGFMT_RGB_DEPTH(fmt) < 8 && !(fmt&128)) mux_v->bih->biBitCount = IMGFMT_RGB_DEPTH(fmt); else mux_v->bih->biBitCount = (IMGFMT_RGB_DEPTH(fmt)+7)&(~7); return 1; } if (IMGFMT_IS_BGR(fmt)) { if (IMGFMT_BGR_DEPTH(fmt) < 8 && !(fmt&128)) mux_v->bih->biBitCount = IMGFMT_BGR_DEPTH(fmt); else mux_v->bih->biBitCount = (IMGFMT_BGR_DEPTH(fmt)+7)&(~7); return 1; } switch (fmt) { case IMGFMT_NV12: case IMGFMT_NV21: case IMGFMT_HM12: mux_v->bih->biPlanes = 2; mux_v->bih->biBitCount = 12; break; case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YV12: case IMGFMT_411P: mux_v->bih->biPlanes = 3; mux_v->bih->biBitCount = 12; break; case IMGFMT_444P: mux_v->bih->biPlanes = 3; mux_v->bih->biBitCount = 24; break; case IMGFMT_422P: mux_v->bih->biPlanes = 3; mux_v->bih->biBitCount = 16; break; case IMGFMT_IF09: mux_v->bih->biPlanes = 4; case IMGFMT_YVU9: mux_v->bih->biBitCount = 9; break; case IMGFMT_UYVY: case IMGFMT_YUY2: mux_v->bih->biBitCount = 16; break; case IMGFMT_Y8: mux_v->bih->biBitCount = 8; break; default: mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_MPCODECS_OutputWithFourccNotSupported, fmt); mux_v->bih->biCompression = 0; return 0; } return 1; }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: dmpi=vf_get_image(vf->next,vf->priv->fmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->w, mpi->h); if (!mpi->planes[1]) { if(!vf->priv->pal_msg){ mp_msg(MSGT_VFILTER,MSGL_V,"[%s] no palette given, assuming builtin grayscale one\n",vf->info->name); vf->priv->pal_msg=1; } mpi->planes[1] = (unsigned char*)gray_pal; } if(mpi->w==mpi->stride[0] && dmpi->w*(dmpi->bpp>>3)==dmpi->stride[0]){ // no stride conversion needed switch(IMGFMT_RGB_DEPTH(dmpi->imgfmt)){ case 15: if (IMGFMT_IS_BGR(dmpi->imgfmt)) palette8tobgr15(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); else palette8torgb15(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); break; case 16: if (IMGFMT_IS_BGR(dmpi->imgfmt)) palette8tobgr16(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); else palette8torgb16(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); break; case 24: if (IMGFMT_IS_BGR(dmpi->imgfmt)) palette8tobgr24(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); else palette8torgb24(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); break; case 32: if (IMGFMT_IS_BGR(dmpi->imgfmt)) palette8tobgr32(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); else palette8torgb32(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); break; } } else {
static int query_format(uint32_t format) { ggi_mode mode; uint32_t vfcap; vfcap = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_ACCEPT_STRIDE; if ((!vo_depthonscreen || !vo_dbpp) && ggi_conf.vis) { if (ggiGetMode(ggi_conf.vis, &mode) == 0) { vo_depthonscreen = GT_DEPTH(mode.graphtype); vo_dbpp = GT_SIZE(mode.graphtype); } if (GT_SCHEME(mode.graphtype) == GT_AUTO) { ggiCheckMode(ggi_conf.vis, &mode); } if (GT_SCHEME(mode.graphtype) != GT_TRUECOLOR) { mode.graphtype = GT_32BIT; vo_depthonscreen = GT_DEPTH(mode.graphtype); vo_dbpp = GT_SIZE(mode.graphtype); } } if ((IMGFMT_IS_BGR(format) && (IMGFMT_BGR_DEPTH(format) == vo_dbpp)) || (IMGFMT_IS_RGB(format) && (IMGFMT_RGB_DEPTH(format) == vo_dbpp))) { return vfcap; } if (IMGFMT_IS_BGR(format) || IMGFMT_IS_RGB(format)) { set_graphtype(format, &mode); if (ggiCheckMode(ggi_conf.drawvis, &mode) < 0) { return 0; } else { return vfcap; } } return (0); }
static uint32_t get_image(mp_image_t *mpi) { if (!IMGFMT_IS_BGR(mpi->imgfmt) || IMGFMT_BGR_DEPTH(mpi->imgfmt) != fb_bpp || (mpi->type != MP_IMGTYPE_STATIC && mpi->type != MP_IMGTYPE_TEMP) || (mpi->flags & MP_IMGFLAG_PLANAR) || (mpi->flags & MP_IMGFLAG_YUV) || mpi->width != in_width || mpi->height != in_height ) return VO_FALSE; mpi->planes[0] = center; mpi->stride[0] = fb_line_len; mpi->flags |= MP_IMGFLAG_DIRECT; return VO_TRUE; }
static int query_format(struct vf_instance_s *vf, unsigned int fmt) { if (IMGFMT_IS_RGB(fmt) || IMGFMT_IS_BGR(fmt)) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; switch (fmt) { case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YV12: case IMGFMT_411P: case IMGFMT_444P: case IMGFMT_422P: case IMGFMT_UYVY: case IMGFMT_YUY2: case IMGFMT_YVU9: case IMGFMT_IF09: return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; } return 0; }
static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ // calculate the missing parameters: if(vf->priv->crop_w<=0 || vf->priv->crop_w>width) vf->priv->crop_w=width; if(vf->priv->crop_h<=0 || vf->priv->crop_h>height) vf->priv->crop_h=height; if(vf->priv->crop_x<0) vf->priv->crop_x=(width-vf->priv->crop_w)/2; if(vf->priv->crop_y<0) vf->priv->crop_y=(height-vf->priv->crop_h)/2; // rounding: if(!IMGFMT_IS_RGB(outfmt) && !IMGFMT_IS_BGR(outfmt)){ switch(outfmt){ case IMGFMT_444P: case IMGFMT_Y800: case IMGFMT_Y8: break; case IMGFMT_YVU9: case IMGFMT_IF09: vf->priv->crop_y&=~3; case IMGFMT_411P: vf->priv->crop_x&=~3; break; case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: vf->priv->crop_y&=~1; default: vf->priv->crop_x&=~1; } } // check: if(vf->priv->crop_w+vf->priv->crop_x>width || vf->priv->crop_h+vf->priv->crop_y>height){ mp_msg(MSGT_VFILTER, MSGL_WARN, MSGTR_MPCODECS_CropBadPositionWidthHeight); return 0; } if(!opt_screen_size_x && !opt_screen_size_y){ d_width=d_width*vf->priv->crop_w/width; d_height=d_height*vf->priv->crop_h/height; } return vf_next_config(vf,vf->priv->crop_w,vf->priv->crop_h,d_width,d_height,flags,outfmt); }
static int query_format(uint32_t format) { // open the device, etc. if (fb_preinit(0)) return 0; // At least IntelFB silently ignores nonstd value, // so we can run the ioctl check only if already // determined we are running on OMAPFB if (fb_omap && (format == IMGFMT_YUY2 || format == IMGFMT_UYVY)) { fb_vinfo.xres_virtual = fb_vinfo.xres; fb_vinfo.yres_virtual = fb_vinfo.yres; fb_vinfo.nonstd = format == IMGFMT_YUY2 ? 8 : 1; if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo) == 0) return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_ACCEPT_STRIDE; return 0; } if (IMGFMT_IS_BGR(format)) { int bpp; int fb_target_bpp = format & 0xff; set_bpp(&fb_vinfo, fb_target_bpp); fb_vinfo.xres_virtual = fb_vinfo.xres; fb_vinfo.yres_virtual = fb_vinfo.yres; fb_vinfo.nonstd = 0; if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) // Needed for Intel framebuffer with 32 bpp fb_vinfo.transp.length = fb_vinfo.transp.offset = 0; if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { mp_msg(MSGT_VO, MSGL_ERR, "[fbdev2] Can't put VSCREENINFO: %s\n", strerror(errno)); return 0; } bpp = fb_vinfo.bits_per_pixel; if (bpp == 16) bpp = fb_vinfo.red.length + fb_vinfo.green.length + fb_vinfo.blue.length; if (bpp == fb_target_bpp) return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_ACCEPT_STRIDE; } return 0; }
static uint32_t get_image(mp_image_t *mpi) { /* GGI DirectRendering supports (yet) only BGR/RGB modes */ if (!((IMGFMT_IS_BGR(mpi->imgfmt)) && (IMGFMT_BGR_DEPTH(mpi->imgfmt) == vo_dbpp))) { return (VO_FALSE); } if (!((IMGFMT_IS_RGB(mpi->imgfmt)) && (IMGFMT_RGB_DEPTH(mpi->imgfmt) == vo_dbpp))) { return (VO_FALSE); } if (!((mpi->width == ggi_conf.srcwidth) && (mpi->height == ggi_conf.srcheight))) { return (VO_FALSE); } mpi->planes[1] = mpi->planes[2] = NULL; mpi->stride[1] = mpi->stride[2] = 0; mpi->planes[0] = NULL; mpi->stride[0] = ggi_conf.srcwidth * ggi_conf.srcbpp; mpi->flags |= MP_IMGFLAG_DIRECT; #ifdef GGI_FLIP if (ggi_conf.voflags & VOFLAG_FLIPPING) { mpi->stride[0] = -mpi->stride[0]; } #endif return (VO_TRUE); }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { ggi_mode mode = { 1, /* frames */ {width, height}, /* visible */ {GGI_AUTO, GGI_AUTO}, /* virt */ {GGI_AUTO, GGI_AUTO}, /* size */ GT_AUTO, /* graphtype */ {GGI_AUTO, GGI_AUTO} /* dots per pixel */ }; set_graphtype(format, &mode); #if 0 printf("[ggi] mode: "); ggiPrintMode(&mode); printf("\n"); #endif ggiCheckMode(ggi_conf.vis, &mode); if (ggiSetMode(ggi_conf.vis, &mode) < 0) { mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to set display mode\n"); return (-1); } if (ggiGetMode(ggi_conf.vis, &mode) < 0) { mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to get display mode\n"); return (-1); } if ((mode.graphtype == GT_INVALID) || (mode.graphtype == GT_AUTO)) { mp_msg(MSGT_VO, MSGL_ERR, "[ggi] not supported depth/bpp\n"); return (-1); } #if 0 printf("[ggi] mode: "); ggiPrintMode(&mode); printf("\n"); #endif #ifdef HAVE_GGIWMH ggiWmhSetTitle(ggi_conf.vis, title); if (vo_ontop) window_ontop(); #endif ggiSetFlags(ggi_conf.vis, GGIFLAG_ASYNC); if (GT_SCHEME(mode.graphtype) == GT_PALETTE) ggiSetColorfulPalette(ggi_conf.vis); if (GT_SCHEME(mode.graphtype) != GT_TRUECOLOR) { ggi_mode drawmode; ggi_conf.drawvis = ggiOpen("display-memory", NULL); if (ggi_conf.drawvis == NULL) { mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to get backbuffer for conversion\n"); return -1; } memcpy(&drawmode, &mode, sizeof(ggi_mode)); drawmode.graphtype = GT_32BIT; drawmode.size.x = GGI_AUTO; drawmode.size.y = GGI_AUTO; ggiCheckMode(ggi_conf.drawvis, &drawmode); if (ggiSetMode(ggi_conf.drawvis, &drawmode) < 0) { mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to set backbuffer mode\n"); return -1; } mode.graphtype = drawmode.graphtype; ggiSetFlags(ggi_conf.drawvis, GGIFLAG_ASYNC); } vo_depthonscreen = GT_DEPTH(mode.graphtype); vo_screenwidth = mode.virt.x; vo_screenheight = mode.virt.y; vo_dwidth = width; vo_dheight = height; vo_dbpp = GT_SIZE(mode.graphtype); /* calculate top, left corner */ vo_dx = (vo_screenwidth - vo_dwidth) / 2; vo_dy = (vo_screenheight - vo_dheight) / 2; ggi_conf.srcwidth = width; ggi_conf.srcheight = height; ggi_conf.srcformat = format; ggi_conf.voflags = flags; if (IMGFMT_IS_RGB(ggi_conf.srcformat)) { ggi_conf.srcdepth = IMGFMT_RGB_DEPTH(ggi_conf.srcformat); } else if (IMGFMT_IS_BGR(ggi_conf.srcformat)) { ggi_conf.srcdepth = IMGFMT_BGR_DEPTH(ggi_conf.srcformat); } else { mp_msg(MSGT_VO, MSGL_FATAL, "[ggi] Unknown image format: %s\n", vo_format_name(ggi_conf.srcformat)); return (-1); } mp_msg(MSGT_VO, MSGL_INFO, "[ggi] input: %dx%dx%d, output: %dx%dx%d\n", ggi_conf.srcwidth, ggi_conf.srcheight, ggi_conf.srcdepth, mode.virt.x, mode.virt.y, vo_dbpp); ggi_conf.srcbpp = (ggi_conf.srcdepth + 7) / 8; ggi_conf.flushregion.x1 = vo_dx; ggi_conf.flushregion.y1 = vo_dy; ggi_conf.flushregion.x2 = vo_dwidth; ggi_conf.flushregion.y2 = vo_dheight; return (0); }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { // int screen; // int interval, prefer_blank, allow_exp, nothing; Colormap theCmap; const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt; #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; #endif Flip_Flag = flags & VOFLAG_FLIPPING; zoomFlag = flags & VOFLAG_SWSCALE; old_vo_dwidth = -1; old_vo_dheight = -1; int_pause = 0; if (!title) title = "MPlayer X11 (XImage/Shm) render"; in_format = format; srcW = width; srcH = height; XGetWindowAttributes(mDisplay, mRootWin, &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) { Visual *visual; depth = vo_find_depth_from_visuals(mDisplay, mScreen, &visual); } if (!XMatchVisualInfo(mDisplay, mScreen, depth, DirectColor, &vinfo) || (WinID > 0 && vinfo.visualid != XVisualIDFromVisual(attribs.visual))) XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); /* set image size (which is indeed neither the input nor output size), if zoom is on it will be changed during draw_slice anyway so we don't duplicate the aspect code here */ image_width = (width + 7) & (~7); image_height = height; { #ifdef CONFIG_XF86VM if (vm) { vo_vm_switch(); } #endif theCmap = vo_x11_create_colormap(&vinfo); vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, vo_dwidth, vo_dheight, flags, theCmap, "x11", title); if (WinID > 0) depth = vo_x11_update_geometry(); #ifdef CONFIG_XF86VM if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) XGrabPointer(mDisplay, vo_window, True, 0, GrabModeAsync, GrabModeAsync, vo_window, None, CurrentTime); XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); } #endif } if (myximage) { freeMyXImage(); sws_freeContext(swsContext); } getMyXImage(); while (fmte->mpfmt) { int depth = IMGFMT_RGB_DEPTH(fmte->mpfmt); /* bits_per_pixel in X seems to be set to 16 for 15 bit formats => force depth to 16 so that only the color masks are used for the format check */ if (depth == 15) depth = 16; if (depth == myximage->bits_per_pixel && fmte->byte_order == myximage->byte_order && fmte->red_mask == myximage->red_mask && fmte->green_mask == myximage->green_mask && fmte->blue_mask == myximage->blue_mask) break; fmte++; } if (!fmte->mpfmt) { mp_msg(MSGT_VO, MSGL_ERR, "X server image format not supported, please contact the developers\n"); return -1; } out_format = fmte->mpfmt; switch ((bpp = myximage->bits_per_pixel)) { case 24: draw_alpha_fnc = draw_alpha_24; break; case 32: draw_alpha_fnc = draw_alpha_32; break; case 15: case 16: if (depth == 15) draw_alpha_fnc = draw_alpha_15; else draw_alpha_fnc = draw_alpha_16; break; default: draw_alpha_fnc = draw_alpha_null; } out_offset = 0; // for these formats conversion is currently not support and // we can easily "emulate" them. if (out_format & 64 && (IMGFMT_IS_RGB(out_format) || IMGFMT_IS_BGR(out_format))) { out_format &= ~64; #if HAVE_BIGENDIAN out_offset = 1; #else out_offset = -1; #endif } /* always allocate swsContext as size could change between frames */ swsContext = sws_getContextFromCmdLine(width, height, in_format, width, height, out_format); if (!swsContext) return -1; dst_width = width; //printf( "X11 bpp: %d color mask: R:%lX G:%lX B:%lX\n",bpp,myximage->red_mask,myximage->green_mask,myximage->blue_mask ); return 0; }
static void draw_osd(struct vo *vo, struct osd_state *osd) { struct priv *p = vo->priv; struct mp_image img = get_x_buffer(p); struct mp_osd_res res = { .w = img.w, .h = img.h, .display_par = vo->monitor_par, .video_par = vo->aspdat.par, }; osd_draw_on_image_bk(osd, res, osd->vo_pts, 0, p->osd_backup, &img); } static mp_image_t *get_screenshot(struct vo *vo) { struct priv *p = vo->priv; struct mp_image img = get_x_buffer(p); struct mp_image *res = alloc_mpi(img.w, img.h, img.imgfmt); copy_mpi(res, &img); mp_draw_sub_backup_restore(p->osd_backup, res); return res; } static int redraw_frame(struct vo *vo) { struct priv *p = vo->priv; struct mp_image img = get_x_buffer(p); mp_draw_sub_backup_restore(p->osd_backup, &img); return true; } static void flip_page(struct vo *vo) { struct priv *p = vo->priv; Display_Image(p, p->myximage, p->ImageData); XSync(vo->x11->display, False); } static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y) { struct priv *p = vo->priv; uint8_t *dst[MP_MAX_PLANES] = {NULL}; int dstStride[MP_MAX_PLANES] = {0}; if ((p->old_vo_dwidth != vo->dwidth || p->old_vo_dheight != vo->dheight) /*&& y==0 */ && p->zoomFlag) { int newW = vo->dwidth; int newH = vo->dheight; struct SwsContext *oldContext = p->swsContext; p->old_vo_dwidth = vo->dwidth; p->old_vo_dheight = vo->dheight; if (vo_fs) aspect(vo, &newW, &newH, A_ZOOM); if (sws_flags == 0) newW &= (~31); // not needed but, if the user wants the FAST_BILINEAR SCALER, then its needed p->swsContext = sws_getContextFromCmdLine(p->srcW, p->srcH, p->in_format, newW, newH, p->out_format); if (p->swsContext) { p->image_width = (newW + 7) & (~7); p->image_height = newH; freeMyXImage(p); getMyXImage(p); sws_freeContext(oldContext); } else p->swsContext = oldContext; p->dst_width = newW; } dstStride[0] = p->image_width * ((p->bpp + 7) / 8); dst[0] = p->ImageData; if (p->Flip_Flag) { dst[0] += dstStride[0] * (p->image_height - 1); dstStride[0] = -dstStride[0]; } sws_scale(p->swsContext, (const uint8_t **)src, stride, y, h, dst, dstStride); mp_draw_sub_backup_reset(p->osd_backup); return 0; } static int query_format(struct vo *vo, uint32_t format) { mp_msg(MSGT_VO, MSGL_DBG2, "vo_x11: query_format was called: %x (%s)\n", format, vo_format_name(format)); if (IMGFMT_IS_BGR(format)) { if (IMGFMT_BGR_DEPTH(format) <= 8) return 0; // TODO 8bpp not yet fully implemented if (IMGFMT_BGR_DEPTH(format) == vo->x11->depthonscreen) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_FLIP | VFCAP_ACCEPT_STRIDE; else return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_FLIP | VFCAP_ACCEPT_STRIDE; } switch (format) { case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YV12: return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_ACCEPT_STRIDE; } return 0; }
void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED); mpi->imgfmt=out_fmt; // compressed formats if(out_fmt == IMGFMT_MPEGPES || IMGFMT_IS_HWACCEL(out_fmt)){ mpi->bpp=0; return; } mpi->num_planes=1; if (IMGFMT_IS_RGB(out_fmt)) { if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128)) mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt); else mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7); return; } if (IMGFMT_IS_BGR(out_fmt)) { if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128)) mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt); else mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7); mpi->flags|=MP_IMGFLAG_SWAPPED; return; } mpi->flags|=MP_IMGFLAG_YUV; mpi->num_planes=3; if (mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) { mpi->flags|=MP_IMGFLAG_PLANAR; mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL); mpi->chroma_width = mpi->width >> mpi->chroma_x_shift; mpi->chroma_height = mpi->height >> mpi->chroma_y_shift; } switch(out_fmt){ case IMGFMT_I420: case IMGFMT_IYUV: mpi->flags|=MP_IMGFLAG_SWAPPED; case IMGFMT_YV12: return; case IMGFMT_420A: case IMGFMT_IF09: mpi->num_planes=4; case IMGFMT_YVU9: case IMGFMT_444P: case IMGFMT_422P: case IMGFMT_411P: case IMGFMT_440P: case IMGFMT_444P16_LE: case IMGFMT_444P16_BE: case IMGFMT_444P10_LE: case IMGFMT_444P10_BE: case IMGFMT_444P9_LE: case IMGFMT_444P9_BE: case IMGFMT_422P16_LE: case IMGFMT_422P16_BE: case IMGFMT_422P10_LE: case IMGFMT_422P10_BE: case IMGFMT_420P16_LE: case IMGFMT_420P16_BE: case IMGFMT_420P10_LE: case IMGFMT_420P10_BE: case IMGFMT_420P9_LE: case IMGFMT_420P9_BE: return; case IMGFMT_Y800: case IMGFMT_Y8: /* they're planar ones, but for easier handling use them as packed */ mpi->flags&=~MP_IMGFLAG_PLANAR; mpi->num_planes=1; return; case IMGFMT_UYVY: mpi->flags|=MP_IMGFLAG_SWAPPED; case IMGFMT_YUY2: mpi->bpp=16; mpi->num_planes=1; return; case IMGFMT_NV12: mpi->flags|=MP_IMGFLAG_SWAPPED; case IMGFMT_NV21: mpi->flags|=MP_IMGFLAG_PLANAR; mpi->bpp=12; mpi->num_planes=2; mpi->chroma_width=(mpi->width>>0); mpi->chroma_height=(mpi->height>>1); mpi->chroma_x_shift=0; mpi->chroma_y_shift=1; return; } mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt); mpi->bpp=0; }