From 909983177fbf7cd97221c553425503dfdf033590 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 26 Nov 2011 22:18:41 +0200 Subject: [PATCH] mplayer: omapfb: rework doublebuffer handling use tripple buffering when possible so we can avoid waiting until pan finishes and go on with the next frame. Also allocate appropriate amount of vram for this automatically. --- recipes/mplayer/files/vo_omapfb.c | 131 +++++++++++++++++++++++------- recipes/mplayer/mplayer_svn.bb | 2 +- 2 files changed, 103 insertions(+), 30 deletions(-) diff --git a/recipes/mplayer/files/vo_omapfb.c b/recipes/mplayer/files/vo_omapfb.c index a3efc23e47..ef7c61b6b2 100644 --- a/recipes/mplayer/files/vo_omapfb.c +++ b/recipes/mplayer/files/vo_omapfb.c @@ -85,7 +85,7 @@ static vo_info_t info = { LIBVO_EXTERN(omapfb) static int fb_overlay_only = 0; // if set, we need only framebuffer overlay, but do not need any x11 code -static int dbl_buffer = 0; +static int dbl_buffer = 1; static int fullscreen_flag = 0; static int plane_ready = 0; static uint32_t drwX, drwY; @@ -95,7 +95,7 @@ static struct fb_var_screeninfo sinfo_p0; static struct fb_var_screeninfo sinfo; static struct fb_var_screeninfo sinfo2; static struct fb_fix_screeninfo finfo; -static struct omapfb_mem_info minfo; +static struct omapfb_mem_info minfo, minfo_old; static struct omapfb_plane_info pinfo; static int xoff, yoff; @@ -103,9 +103,9 @@ static struct { unsigned x; unsigned y; uint8_t *buf; -} fb_pages[2]; +} fb_pages[3]; /* 3 pages allow us not to wait for pan */ static int dev_fd = -1; -static int fb_page_flip = 0; +static int fb_page_count = 0; static int page = 0; static void omapfb_update(int x, int y, int out_w, int out_h, int show); @@ -146,7 +146,7 @@ static void getPrimaryPlaneInfo() if (dev_fd == -1) { mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Error /dev/fb0\n"); - return -1; + return; } ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo_p0); @@ -241,6 +241,7 @@ static int preinit(const char *arg) ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo); ioctl(dev_fd, OMAPFB_QUERY_PLANE, &pinfo); ioctl(dev_fd, OMAPFB_QUERY_MEM, &minfo); + memcpy(&minfo_old, &minfo, sizeof(minfo_old)); if (!fb_overlay_only && !vo_init()) { @@ -369,12 +370,26 @@ static void omapfb_update(int x, int y, int out_w, int out_h, int show) ioctl(dev_fd, OMAPFB_SETUP_PLANE, &pinfo); } +static int realloc_fb_vram(int size) +{ + int ret; + + minfo.size = size; + ret = ioctl(dev_fd, OMAPFB_SETUP_MEM, &minfo); + if (ret == 0) + return 0; + + // restore minfo + ioctl(dev_fd, OMAPFB_QUERY_MEM, &minfo); + return ret; +} + 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) { uint8_t *fbmem; - int i; + int i, ret, mem_needed; struct omapfb_color_key color_key; XVisualInfo vinfo; @@ -428,6 +443,48 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, vo_xv_draw_colorkey(drwX, drwY, vo_dwidth - 1, vo_dheight - 1); } + sinfo.xres = width & ~15; + sinfo.yres = height & ~15; + sinfo.xres_virtual = sinfo.xres; + sinfo.yres_virtual = sinfo.yres + 16; + sinfo.xoffset = 0; + sinfo.yoffset = 0; + sinfo.nonstd = OMAPFB_COLOR_YUY422; + + fb_page_count = 1; + if (dbl_buffer) { + struct omapfb_mem_info minfo_new; + memcpy(&minfo_new, &minfo, sizeof(minfo_new)); + fb_page_count = 3; + mem_needed = sinfo.xres_virtual * sinfo.yres_virtual * 2 * 3; + if (minfo.size < mem_needed) { + ret = realloc_fb_vram(mem_needed); + if (ret != 0) { + fb_page_count = 2; + mem_needed = sinfo.xres_virtual * sinfo.yres_virtual * 2 * 2; + if (minfo.size < mem_needed) { + ret = realloc_fb_vram(mem_needed); + if (ret != 0) { + fb_page_count = 1; + dbl_buffer = 0; + } + } + } + } + } + + mem_needed = sinfo.xres_virtual * sinfo.yres_virtual * 2 * fb_page_count; + if (minfo.size < mem_needed) { + ret = realloc_fb_vram(mem_needed); + if (ret != 0) { + mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Not enough vram, needed %d\n", mem_needed); + return -1; + } + } + + mp_msg(MSGT_VO, MSGL_V, "[omapfb] using %d buffers of %dx%d\n", + fb_page_count, sinfo.xres, sinfo.yres); + fbmem = mmap(NULL, minfo.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev_fd, 0); if (fbmem == MAP_FAILED) { mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Error mmap\n"); @@ -437,30 +494,26 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, for (i = 0; i < minfo.size / 4; i++) ((uint32_t*)fbmem)[i] = 0x80008000; - sinfo.xres = width & ~15; - sinfo.yres = height & ~15; - sinfo.xoffset = 0; - sinfo.yoffset = 0; - sinfo.nonstd = OMAPFB_COLOR_YUY422; - fb_pages[0].x = 0; fb_pages[0].y = 0; fb_pages[0].buf = fbmem; - - if (dbl_buffer && minfo.size >= sinfo.xres * sinfo.yres * 2) { - sinfo.xres_virtual = sinfo.xres; - sinfo.yres_virtual = sinfo.yres * 2; + if (fb_page_count > 1) { fb_pages[1].x = 0; - fb_pages[1].y = sinfo.yres; - fb_pages[1].buf = fbmem + sinfo.xres * sinfo.yres * 2; - fb_page_flip = 1; - } else { - sinfo.xres_virtual = sinfo.xres; - sinfo.yres_virtual = sinfo.yres; - fb_page_flip = 0; + fb_pages[1].y = sinfo.yres_virtual; + fb_pages[1].buf = fbmem + sinfo.xres_virtual * sinfo.yres_virtual * 2; } + if (fb_page_count > 2) { + fb_pages[2].x = 0; + fb_pages[2].y = sinfo.yres_virtual * 2; + fb_pages[2].buf = fbmem + sinfo.xres_virtual * sinfo.yres_virtual * 2 * 2; + } + sinfo.yres_virtual *= fb_page_count; - ioctl(dev_fd, FBIOPUT_VSCREENINFO, &sinfo); + ret = ioctl(dev_fd, FBIOPUT_VSCREENINFO, &sinfo); + if (ret != 0) { + mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] FBIOPUT_VSCREENINFO error\n"); + return -1; + } ioctl(dev_fd, FBIOGET_FSCREENINFO, &finfo); if (WinID <= 0) { @@ -507,19 +560,36 @@ static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y) if (!plane_ready) return 0; - ioctl(dev_fd, OMAPFB_SYNC_GFX); - - yuv420_to_yuv422(fb_pages[page].buf + y * finfo.line_length, src[0], src[1], src[2], w & ~15, h, stride[0], stride[1], finfo.line_length); + yuv420_to_yuv422(fb_pages[page].buf + y * finfo.line_length, src[0], src[1], src[2], w & ~15, h & ~15, stride[0], stride[1], finfo.line_length); return 0; } +#ifndef OMAPFB_WAITFORGO +#define OMAPFB_WAITFORGO OMAP_IO(60) +#endif + static void flip_page(void) { - if (fb_page_flip) { + ioctl(dev_fd, OMAPFB_SYNC_GFX); + + if (fb_page_count > 1) { sinfo.xoffset = fb_pages[page].x + xoff; sinfo.yoffset = fb_pages[page].y + yoff; ioctl(dev_fd, FBIOPAN_DISPLAY, &sinfo); - page ^= fb_page_flip; + if (fb_page_count == 2) { + // must sync so we don't overwrite currently dispayed buffer + int ret = ioctl(dev_fd, OMAPFB_WAITFORGO); + if (ret != 0) { + static int warned; + if (!warned) { + mp_msg(MSGT_VO, MSGL_ERR, "[omapfb] OMAPFB_WAITFORGO is broken\n"); + warned = 1; + } + } + } + page++; + if (page >= fb_page_count) + page = 0; } } @@ -541,6 +611,7 @@ static void uninit() { pinfo.enabled = 0; ioctl(dev_fd, OMAPFB_SETUP_PLANE, &pinfo); + ioctl(dev_fd, OMAPFB_SETUP_MEM, &minfo_old); if (!fb_overlay_only) { struct omapfb_color_key color_key; @@ -549,6 +620,8 @@ static void uninit() ioctl(dev_fd, OMAPFB_SET_COLOR_KEY, &color_key); } + munmap(fb_pages[0].buf, minfo.size); + fb_pages[0].buf = NULL; close(dev_fd); if (!fb_overlay_only) diff --git a/recipes/mplayer/mplayer_svn.bb b/recipes/mplayer/mplayer_svn.bb index dd94767167..f6efd238ca 100644 --- a/recipes/mplayer/mplayer_svn.bb +++ b/recipes/mplayer/mplayer_svn.bb @@ -39,7 +39,7 @@ RCONFLICTS_${PN} = "mplayer-atty" RREPLACES_${PN} = "mplayer-atty" PV = "0.0+1.0rc3+svnr${SRCPV}" -PR = "r19" +PR = "r20" DEFAULT_PREFERENCE = "-1" DEFAULT_PREFERENCE_angstrom = "1" DEFAULT_PREFERENCE_shr = "1" -- 2.39.5