mplayer svn: add vo_omapfb for the overlay found in omap2/omap3 chips
authorGregoire Gentil <gregoire@gentil.com>
Sun, 23 Nov 2008 21:59:23 +0000 (22:59 +0100)
committerKoen Kooi <koen@openembedded.org>
Sun, 23 Nov 2008 21:59:23 +0000 (22:59 +0100)
packages/mplayer/files/omapfb.patch [new file with mode: 0644]
packages/mplayer/files/vo_omapfb.c [new file with mode: 0644]
packages/mplayer/files/yuv.S [new file with mode: 0644]
packages/mplayer/mplayer_svn.bb

diff --git a/packages/mplayer/files/omapfb.patch b/packages/mplayer/files/omapfb.patch
new file mode 100644 (file)
index 0000000..5c9bca7
--- /dev/null
@@ -0,0 +1,29 @@
+--- a/libvo/video_out.c        2008-11-07 11:59:48.000000000 -0800
++++ b/libvo/video_out.c        2008-11-07 12:01:52.000000000 -0800
+@@ -86,6 +86,7 @@
+ extern vo_functions_t video_out_bl;
+ extern vo_functions_t video_out_fbdev;
+ extern vo_functions_t video_out_fbdev2;
++extern vo_functions_t video_out_omapfb;
+ extern vo_functions_t video_out_svga;
+ extern vo_functions_t video_out_png;
+ extern vo_functions_t video_out_ggi;
+@@ -172,6 +173,7 @@
+ #ifdef CONFIG_FBDEV
+       &video_out_fbdev,
+       &video_out_fbdev2,
++      &video_out_omapfb,
+ #endif
+ #ifdef CONFIG_SVGALIB
+       &video_out_svga,
+--- a/configure        2008-11-07 12:00:32.000000000 -0800
++++ b/configure        2008-11-07 12:13:31.000000000 -0800
+@@ -4558,7 +4558,7 @@
+ fi
+ if test "$_fbdev" = yes ; then
+   _def_fbdev='#define CONFIG_FBDEV 1'
+-  _vosrc="$_vosrc vo_fbdev.c vo_fbdev2.c"
++  _vosrc="$_vosrc vo_fbdev.c vo_fbdev2.c vo_omapfb.c yuv.S"
+   _vomodules="fbdev $_vomodules"
+ else
+   _def_fbdev='#undef CONFIG_FBDEV'
diff --git a/packages/mplayer/files/vo_omapfb.c b/packages/mplayer/files/vo_omapfb.c
new file mode 100644 (file)
index 0000000..5a43404
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+Copyright (C) 2008 Gregoire Gentil <gregoire@gentil.com>
+This file adds an optimized vo output to mplayer for the OMAP platform. This is a first pass and an attempt to help to improve
+media playing on the OMAP platform. The usual disclaimer comes here: this code is provided without any warranty.
+Many bugs and issues still exist. Feed-back is welcome.
+
+This output uses the yuv420_to_yuv422 conversion from Mans Rullgard, and is heavily inspired from the work of Siarhei Siamashka.
+I would like to thank those two persons here, without them this code would certainly not exist.
+
+Two options of the output are available:
+fb_overlay_only (disabled by default): only the overlay is drawn. X11 stuff is ignored.
+dbl_buffer (disabled by default): add double buffering. Some tearsync flags are probably missing in the code.
+
+Syntax is the following:
+mplayer -ao alsa -vo omapfb /test.avi
+mplayer -nosound -vo omapfb:fb_overlay_only:dbl_buffer /test.avi
+
+You need to have two planes on your system. On beagleboard, it means something like: video=omapfb:vram:2M,vram:4M
+
+Known issues:
+1) A green line or some vertical lines (if mplayer decides to draw bands instead of frame) may appear.
+It's an interpolation bug in the color conversion that needs to be fixed
+
+2) The color conversion accepts only 16-pixel multiple for width and height.
+
+3) The scaling down is disabled as the scaling down kernel patch for the OMAP3 platform doesn't seem to work yet.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+
+#include "config.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "fastmemcpy.h"
+#include "sub.h"
+#include "mp_msg.h"
+
+#include "omapfb.h"
+
+#include "libswscale/swscale.h"
+#include "libmpcodecs/vf_scale.h"
+#include "libavcodec/avcodec.h"
+
+#include "aspect.h"
+
+#include "subopt-helper.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include "wskeys.h"
+
+static vo_info_t info = {
+       "omapfb video driver",
+       "omapfb",
+       "",
+       ""
+};
+
+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 fullscreen_flag = 0;
+static int plane_ready = 0;
+
+extern void yuv420_to_yuv422(uint8_t *yuv, uint8_t *y, uint8_t *u, uint8_t *v, int w, int h, int yw, int cw, int dw);
+static struct fb_var_screeninfo sinfo_p0;
+static struct fb_var_screeninfo sinfo;
+static struct omapfb_mem_info minfo;
+static struct omapfb_plane_info pinfo;
+static struct {
+    unsigned x;
+    unsigned y;
+    uint8_t *buf;
+} fb_pages[2];
+static int dev_fd = -1;
+static int fb_page_flip = 0;
+static int page = 0;
+static void omapfb_update(int x, int y, int out_w, int out_h, int show);
+
+extern void mplayer_put_key( int code );
+#include "osdep/keycodes.h"
+
+#define TRANSPARENT_COLOR_KEY 0xff0
+
+static Display *display = NULL; // pointer to X Display structure.
+static int screen_num; // number of screen to place the window on.
+static Window win = 0;
+static Window parent = 0; // pointer to the newly created window.
+
+/* This is used to intercept window closing requests.  */
+static Atom wm_delete_window;
+
+/**
+ * Function to get the offset to be used when in windowed mode
+ * or when using -wid option
+ */
+static void x11_get_window_abs_position(Display *display, Window window,
+                                             int *wx, int *wy, int *ww, int *wh)
+{
+    Window root, parent;
+    Window *child;
+    unsigned int n_children;
+    XWindowAttributes attribs;
+
+    /* Get window attributes */
+    XGetWindowAttributes(display, window, &attribs);
+
+    /* Get relative position of given window */
+    *wx = attribs.x;
+    *wy = attribs.y;
+    if (ww)
+        *ww = attribs.width;
+    if (wh)
+        *wh = attribs.height;
+
+    /* Query window tree information */
+    XQueryTree(display, window, &root, &parent, &child, &n_children);
+    if (parent)
+    {
+      int x, y;
+      /* If we have a parent we must go there and discover his position*/
+      x11_get_window_abs_position(display, parent, &x, &y, NULL, NULL);
+      *wx += x;
+      *wy += y;
+    }
+
+    /* If we had children, free it */
+    if(n_children)
+        XFree(child);
+}
+
+
+/**
+ * Function that controls fullscreen state for x11 window
+ * action = 1 (set fullscreen)
+ * action = 0 (set windowed mode)
+ */
+static void x11_set_fullscreen_state(Display *display, Window window, int action)
+{
+    XEvent xev;
+
+    /* init X event structure for _NET_WM_FULLSCREEN client msg */
+    xev.xclient.type = ClientMessage;
+    xev.xclient.serial = 0;
+    xev.xclient.send_event = True;
+    xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", False);
+    xev.xclient.window = window;
+    xev.xclient.format = 32;
+    xev.xclient.data.l[0] = action;
+    xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
+    xev.xclient.data.l[2] = 0;
+    xev.xclient.data.l[3] = 0;
+    xev.xclient.data.l[4] = 0;
+
+    /* finally send that damn thing */
+    if (!XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev)) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[omapfb] failure in x11_set_fullscreen_state\n");
+        exit(1);
+    }
+    XSync(display, False);
+}
+
+
+XClassHint classhint = {"mediaplayer-ui", "mediaplayer-ui"};
+
+
+/**
+ * Initialize x11 window (it is used to allocate some screen area for framebuffer overlay)
+ */
+static void x11_init()
+{
+    display = XOpenDisplay(getenv("DISPLAY"));
+    if (display == NULL) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[omapfb] failure in x11_init, can't open display\n");
+        exit(1);
+    }
+
+    screen_num = DefaultScreen(display);
+
+    if (WinID > 0)
+    {
+        Window root;
+        Window *child;
+        unsigned int n_children;
+
+        win = WinID;
+
+        /* Query window tree information */
+        XQueryTree(display, win, &root, &parent, &child, &n_children);
+        if (n_children)
+            XFree(child);
+
+        XUnmapWindow(display, win);
+        if (parent)
+            XSelectInput(display, parent, StructureNotifyMask);
+        XMapWindow(display, win);
+
+        wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
+        XSetWMProtocols(display, win, &wm_delete_window, 1);
+    } else {
+        win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
+                                  sinfo_p0.xres / 2 - sinfo.xres / 2, sinfo_p0.yres / 2 - sinfo.yres / 2, sinfo.xres, sinfo.yres, 0,
+                                  WhitePixel(display, screen_num),
+                                  TRANSPARENT_COLOR_KEY);
+
+        XSetClassHint(display, win, &classhint);
+
+        XStoreName(display, win, "MPlayer");
+        XMapWindow(display, win);
+
+        /* Set WM_DELETE_WINDOW atom in WM_PROTOCOLS property (to get window_delete requests).  */
+        wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
+        XSetWMProtocols(display, win, &wm_delete_window, 1);
+        XSelectInput(display, win, StructureNotifyMask | KeyPressMask);
+    }
+}
+
+
+void print_properties(Window win2)
+{
+       Atom *p;
+       int num, j;
+       char *aname;
+       Atom type;
+       int format;
+       unsigned long nitems, bytes_after;
+       unsigned char *ret = NULL;
+
+       p = XListProperties(display, win2, &num);
+       printf("found %d properties for window %d\n", num, (int)win2);
+       for (j = 0; j < num; j++) {
+               aname = XGetAtomName(display, p[j]);
+               if (aname) {
+                       if(Success == XGetWindowProperty(display, win2, XInternAtom(display, aname, False),
+                                               0L, ~0L, False, XA_STRING,
+                                               &type, &format, &nitems,
+                                               &bytes_after, &ret))
+                       {
+/*                             printf("format = %d, nitems = %d, bytes_after = %d\n", format, nitems, bytes_after);*/
+                               printf("%s = %s\n", aname, ret);
+                               XFree(ret);
+                       }
+                       XFree(aname);
+               } else printf("NULL\n");
+       }
+       XFree(p);
+}
+
+
+static int x11_check_events()
+{
+    if (!display) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[omapfb] 'x11_check_events' called out of sequence\n");
+        exit(1);
+    }
+
+    int ret = 0;
+    XEvent Event;
+    while (XPending(display)) {
+        XNextEvent(display, &Event);
+        if (Event.type == UnmapNotify)
+            omapfb_update(0, 0, 0, 0, 0);
+        else if ((Event.type == MapNotify) || (Event.type == ConfigureNotify))
+            omapfb_update(0, 0, 0, 0, 1);
+        else if (Event.type == KeyPress) {
+            int key;
+            KeySym keySym = XKeycodeToKeysym(display, Event.xkey.keycode, 0);
+            key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym));
+            ret |= VO_EVENT_KEYPRESS;
+            vo_x11_putkey(key);
+        } else if (Event.type == ClientMessage) {
+            if ((Atom)Event.xclient.data.l[0] == wm_delete_window) {
+                mplayer_put_key(KEY_ESC);
+            }
+        }
+    }
+    return ret;
+}
+
+
+static void x11_uninit()
+{
+    if (display) {
+        XCloseDisplay(display);
+        display = NULL;
+    }
+}
+
+
+/**
+ * Initialize framebuffer
+ */
+static int preinit(const char *arg)
+{
+
+    opt_t subopts[] = {
+        {"fb_overlay_only", OPT_ARG_BOOL, &fb_overlay_only, NULL},
+        {"dbl_buffer", OPT_ARG_BOOL, &dbl_buffer, NULL},
+        {NULL}
+    };
+
+    if (subopt_parse(arg, subopts) != 0) {
+        mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] unknown suboptions: %s\n", arg);
+        return -1;
+    }
+
+    dev_fd = open("/dev/fb0", O_RDWR);
+
+    if (dev_fd == -1) {
+        mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Error /dev/fb0\n");
+        return -1;
+    }
+
+    ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo_p0);
+    close(dev_fd);
+
+    dev_fd = open("/dev/fb1", O_RDWR);
+
+    if (dev_fd == -1) {
+        mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Error /dev/fb1\n");
+        return -1;
+    }
+
+    ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo);
+    ioctl(dev_fd, OMAPFB_QUERY_PLANE, &pinfo);
+    ioctl(dev_fd, OMAPFB_QUERY_MEM, &minfo);
+
+    if (!fb_overlay_only)
+        x11_init();
+
+    return 0;
+}
+
+
+static void omapfb_update(int x, int y, int out_w, int out_h, int show)
+{
+    if (!fb_overlay_only)
+        x11_get_window_abs_position(display, win, &x, &y, &out_w, &out_h);
+
+    if ((x < 0) || (y < 0)
+
+// If you develop the right scaling-down patch in kernel, uncomment the line below and comment the next one
+//        || (out_w < sinfo.xres / 4) || (out_h < sinfo.yres / 4)
+        || (out_w < sinfo.xres) || (out_h < sinfo.yres)
+
+// If you don't have the right scaling-up patch in kernel, comment the line below and uncomment the next one
+/* Kernel patch to enable scaling up on the omap3
+======================================================
+--- a/drivers/video/omap/dispc.c       2008-11-01 20:08:04.000000000 -0700
++++ b/drivers/video/omap/dispc.c       2008-11-01 20:09:02.000000000 -0700
+@@ -523,9 +523,6 @@
+       if ((unsigned)plane > OMAPFB_PLANE_NUM)
+               return -ENODEV;
+-      if (out_width != orig_width || out_height != orig_height)
+-              return -EINVAL;
+-
+       enable_lcd_clocks(1);
+       if (orig_width < out_width) {
+               /*
+======================================================
+*/
+        || (out_w > sinfo.xres * 8) || (out_h > sinfo.yres * 8)
+//        || (out_w > sinfo.xres) || (out_h > sinfo.yres)
+
+        || (x + out_w > sinfo_p0.xres) || (y + out_h > sinfo_p0.yres)) {
+        pinfo.enabled = 0;
+        pinfo.pos_x = 0;
+        pinfo.pos_y = 0;
+        ioctl(dev_fd, OMAPFB_SETUP_PLANE, &pinfo);
+        return;
+    }
+
+    pinfo.enabled = show;
+    pinfo.pos_x = x;
+    pinfo.pos_y = y;
+    pinfo.out_width  = out_w;
+    pinfo.out_height = out_h;
+    ioctl(dev_fd, OMAPFB_SETUP_PLANE, &pinfo);
+}
+
+
+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;
+    struct omapfb_color_key color_key;
+
+    fullscreen_flag = flags & VOFLAG_FULLSCREEN;
+
+    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");
+        return -1;
+    }
+
+    for (i = 0; i < minfo.size / 4; i++)
+        ((uint32_t*)fbmem)[i] = 0x80008000;
+
+    sinfo.xres = FFMIN(sinfo_p0.xres, width)  & ~15;
+    sinfo.yres = FFMIN(sinfo_p0.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;
+        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;
+    }
+
+    ioctl(dev_fd, FBIOPUT_VSCREENINFO, &sinfo);
+
+    if (WinID <= 0) {
+        if (fullscreen_flag) {
+            if (!fb_overlay_only)
+                x11_set_fullscreen_state(display, win, 1);
+            omapfb_update(0, 0, sinfo_p0.xres, sinfo_p0.yres, 1);
+        } else {
+            if (!fb_overlay_only)
+                x11_set_fullscreen_state(display, win, 0);
+            omapfb_update(sinfo_p0.xres / 2 - sinfo.xres / 2, sinfo_p0.yres / 2 - sinfo.yres / 2, sinfo.xres, sinfo.yres, 1);
+        }
+    }
+
+    color_key.channel_out = OMAPFB_CHANNEL_OUT_LCD;
+    color_key.background = 0x0;
+    color_key.trans_key = TRANSPARENT_COLOR_KEY;
+    if (fb_overlay_only)
+        color_key.key_type = OMAPFB_COLOR_KEY_DISABLED;
+    else
+        color_key.key_type = OMAPFB_COLOR_KEY_GFX_DST;
+    ioctl(dev_fd, OMAPFB_SET_COLOR_KEY, &color_key);
+
+    plane_ready = 1;
+    return 0;
+}
+
+
+static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride)
+{
+    vo_draw_alpha_yuy2(w, h, src, srca, stride, fb_pages[page].buf + sinfo.xres * y0 * 2 + x0 * 2, sinfo.xres);
+}
+
+
+static void draw_osd(void)
+{
+    vo_draw_text(sinfo.xres, sinfo.yres, draw_alpha);
+}
+
+
+static int draw_frame(uint8_t *src[])
+{
+    return 1;
+}
+
+
+static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
+{
+    if (x!=0)
+        return 0;
+
+    if (!plane_ready)
+        return 0;
+
+    ioctl(dev_fd, OMAPFB_SYNC_GFX);
+
+    yuv420_to_yuv422(fb_pages[page].buf + 2 * sinfo.xres * y, src[0], src[1], src[2], w & ~15, h, stride[0], stride[1], 2 * sinfo.xres_virtual);
+
+    return 0;
+}
+
+
+static void flip_page(void)
+{
+    if (fb_page_flip) {
+        sinfo.xoffset = fb_pages[page].x;
+        sinfo.yoffset = fb_pages[page].y;
+        ioctl(dev_fd, FBIOPAN_DISPLAY, &sinfo);
+        page ^= fb_page_flip;
+    }
+}
+
+
+static int query_format(uint32_t format)
+{
+    // For simplicity pretend that we can only do YV12, support for
+    // other formats can be added quite easily if/when needed
+    if (format != IMGFMT_YV12)
+        return 0;
+
+    return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_SWSCALE | VFCAP_ACCEPT_STRIDE;
+}
+
+
+/**
+ * Uninitialize framebuffer
+ */
+static void uninit()
+{
+    pinfo.enabled = 0;
+    ioctl(dev_fd, OMAPFB_SETUP_PLANE, &pinfo);
+
+    if (!fb_overlay_only) {
+        struct omapfb_color_key color_key;
+        color_key.channel_out = OMAPFB_CHANNEL_OUT_LCD;
+        color_key.key_type = OMAPFB_COLOR_KEY_DISABLED;
+        ioctl(dev_fd, OMAPFB_SET_COLOR_KEY, &color_key);
+    }
+
+    close(dev_fd);
+
+    if (!fb_overlay_only)
+        x11_uninit();
+}
+
+
+static int control(uint32_t request, void *data, ...)
+{
+    switch (request) {
+        case VOCTRL_QUERY_FORMAT:
+            return query_format(*((uint32_t*)data));
+        case VOCTRL_FULLSCREEN: {
+            if (WinID > 0) return VO_FALSE;
+            if (fullscreen_flag) {
+                if (!fb_overlay_only)
+                    x11_set_fullscreen_state(display, win, 0);
+                fullscreen_flag = 0;
+                omapfb_update(sinfo_p0.xres / 2 - sinfo.xres / 2, sinfo_p0.yres / 2 - sinfo.yres / 2, sinfo.xres, sinfo.yres, 1);
+            } else {
+                if (!fb_overlay_only)
+                    x11_set_fullscreen_state(display, win, 1);
+                fullscreen_flag = 1;
+                omapfb_update(0, 0, sinfo_p0.xres, sinfo_p0.yres, 1);
+            }
+            return VO_TRUE;
+        }
+    }
+    return VO_NOTIMPL;
+}
+
+
+static void check_events(void)
+{
+    if (!fb_overlay_only)
+        x11_check_events();
+}
diff --git a/packages/mplayer/files/yuv.S b/packages/mplayer/files/yuv.S
new file mode 100644 (file)
index 0000000..3eaf284
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+    Copyright (C) 2008 Mans Rullgard
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+ */
+
+        .fpu neon
+        .text
+
+@ yuv420_to_yuv422(uint8_t *yuv, uint8_t *y, uint8_t *u, uint8_t *v,
+@                  int w, int h, int yw, int cw, int dw)
+
+#define yuv  r0
+#define y    r1
+#define u    r2
+#define v    r3
+#define w    r4
+#define h    r5
+#define yw   r6
+#define cw   r7
+#define dw   r8
+
+#define tyuv r9
+#define ty   r10
+#define tu   r11
+#define tv   r12
+#define i    lr
+
+        .global yuv420_to_yuv422
+        .func   yuv420_to_yuv422
+yuv420_to_yuv422:
+        push            {r4-r11,lr}
+        add             r4,  sp,  #36
+        ldm             r4, {r4-r8}
+        dmb
+1:
+        mov             tu,   u
+        mov             tv,   v
+        vld1.64         {d2}, [u,:64], cw               @ u0
+        vld1.64         {d3}, [v,:64], cw               @ v0
+        mov             tyuv, yuv
+        mov             ty,   y
+        vzip.8          d2,   d3                        @ u0v0
+        mov             i,    #16
+2:                      
+        pld             [y, #64]
+        vld1.64         {d0, d1},   [y,:128], yw        @ y0
+        pld             [u, #64]
+        subs            i,    i,    #4
+        vld1.64         {d6},       [u,:64],  cw        @ u2
+        pld             [y, #64]
+        vld1.64         {d4, d5},   [y,:128], yw        @ y1
+        pld             [v, #64]
+        vld1.64         {d7},       [v,:64],  cw        @ v2
+        pld             [y, #64]
+        vld1.64         {d16,d17},  [y,:128], yw        @ y2
+        vzip.8          d6,   d7                        @ u2v2
+        pld             [u, #64]
+        vld1.64         {d22},      [u,:64],  cw        @ u4
+        pld             [v, #64]
+        vld1.64         {d23},      [v,:64],  cw        @ v4
+        pld             [y, #64]
+        vld1.64         {d20,d21},  [y,:128], yw        @ y3
+        vmov            q9,   q3                        @ u2v2
+        vzip.8          d22,  d23                       @ u4v4
+        vrhadd.u8       q3,   q1,   q3                  @ u1v1
+        vzip.8          q0,   q1                        @ y0u0y0v0
+        vmov            q12,  q11                       @ u4v4
+        vzip.8          q2,   q3                        @ y1u1y1v1
+        vrhadd.u8       q11,  q9,   q11                 @ u3v3
+        vst1.64         {d0-d3},    [yuv,:128], dw      @ y0u0y0v0
+        vzip.8          q8,   q9                        @ y2u2y2v2
+        vst1.64         {d4-d7},    [yuv,:128], dw      @ y1u1y1v1
+        vzip.8          q10,  q11                       @ y3u3y3v3
+        vst1.64         {d16-d19},  [yuv,:128], dw      @ y2u2y2v2
+        vmov            q1,   q12
+        vst1.64         {d20-d23},  [yuv,:128], dw      @ y3u3y3v3
+        bgt             2b
+
+        subs            w,    w,    #16
+        add             yuv,  tyuv, #32
+        add             y,    ty,   #16
+        add             u,    tu,   #8
+        add             v,    tv,   #8
+        bgt             1b
+
+        ldr             w,    [sp, #36]
+        subs            h,    h,    #16
+        add             yuv,  yuv,  dw, lsl #4
+        sub             yuv,  yuv,  w,  lsl #1
+        add             y,    y,    yw, lsl #4
+        sub             y,    y,    w
+        add             u,    u,    cw, lsl #3
+        sub             u,    u,    w,  asr #1
+        add             v,    v,    cw, lsl #3
+        sub             v,    v,    w,  asr #1
+        bgt             1b
+
+        pop             {r4-r11,pc}
+        .endfunc
+
index b0f1250..4ab8d79 100644 (file)
@@ -2,7 +2,7 @@ DESCRIPTION = "Open Source multimedia player."
 SECTION = "multimedia"
 PRIORITY = "optional"
 HOMEPAGE = "http://www.mplayerhq.hu/"
-DEPENDS = "virtual/libsdl ffmpeg xsp zlib libpng jpeg freetype fontconfig alsa-lib lzo ncurses libxv virtual/libx11 \
+DEPENDS = "virtual/libsdl ffmpeg xsp zlib libpng jpeg liba52 freetype fontconfig alsa-lib lzo ncurses lame libxv virtual/libx11 virtual/kernel \
            ${@base_conditional('ENTERPRISE_DISTRO', '1', '', 'libmad liba52 lame', d)}"
 
 RDEPENDS = "mplayer-common"
@@ -24,6 +24,9 @@ SRC_URI = "svn://svn.mplayerhq.hu/mplayer;module=trunk \
           file://mru-neon-vector-fmul.diff;patch=1 \
           file://configh \
            file://configmak \
+           file://omapfb.patch;patch=1 \
+           file://vo_omapfb.c \
+           file://yuv.S \
           "
 
 # This is required for the collie machine only as all stacks in that
@@ -42,7 +45,7 @@ RCONFLICTS_${PN} = "mplayer-atty"
 RREPLACES_${PN} = "mplayer-atty"
 
 PV = "0.0+1.0rc2+svnr${SRCREV}"
-PR = "r7"
+PR = "r8"
 DEFAULT_PREFERENCE = "-1"
 DEFAULT_PREFERENCE_armv7a = "1"
 
@@ -57,6 +60,9 @@ FILES_mencoder = "${bindir}/mencoder"
 
 inherit autotools pkgconfig
 
+# We want a kernel header for armv7a, but we don't want to make mplayer machine specific for that
+STAGING_KERNEL_DIR = "${STAGING_DIR}/${MACHINE_ARCH}${TARGET_VENDOR}-${TARGET_OS}/kernel"
+
 EXTRA_OECONF = " \
         --prefix=/usr \
        --mandir=${mandir} \
@@ -176,8 +182,8 @@ EXTRA_OECONF = " \
 EXTRA_OECONF_append_arm = " --disable-decoder=vorbis_decoder \
                            --disable-encoder=vorbis_encoder"
 
-EXTRA_OECONF_append_armv6 = " --enable-armv6 "
-EXTRA_OECONF_append_armv7a = "--enable-armv6 "
+EXTRA_OECONF_append_armv6 = " --enable-armv6"
+EXTRA_OECONF_append_armv7a = " --enable-armv6"
 
 
 #build with support for the iwmmxt instruction and pxa270fb overlay support (pxa270 and up)
@@ -201,6 +207,11 @@ do_configure() {
        sed -i 's|/usr/\S*include[\w/]*||g' ${S}/configure
        sed -i 's|/usr/\S*lib[\w/]*||g' ${S}/configure
 
+       cp ${WORKDIR}/yuv.S ${S}/libvo
+       cp ${WORKDIR}/vo_omapfb.c ${S}/libvo
+       cp ${STAGING_KERNEL_DIR}/arch/arm/plat-omap/include/mach/omapfb.h ${S}/libvo/omapfb.h || true
+       cp ${STAGING_KERNEL_DIR}/include/asm-arm/arch-omap/omapfb.h ${S}/libvo/omapfb.h || true
+
         ./configure ${EXTRA_OECONF}
         
        cat ${WORKDIR}/configh >> ${S}/config.h