[oe] [PATCH] gstreamer-ti-ddompe: add recipe

Tim Harvey harvey.tim at gmail.com
Tue Nov 16 23:23:02 UTC 2010


The gstreamer-ti-ddompe branch contains some additional features that have not
made it upstream yet.

See http://processors.wiki.ti.com/index.php/GStreamer_Plug-in_2.x_Design

Signed-off-by: Tim Harvey <harvey.tim at gmail.com>
---
 .../gstreamer-ti-ddompe-add-omapfb.patch           | 1354 ++++++++++++++++++++
 recipes/ti/gstreamer-ti-ddompe_svn.bb              |   48 +
 2 files changed, 1402 insertions(+), 0 deletions(-)
 create mode 100644 recipes/ti/gstreamer-ti-ddompe/gstreamer-ti-ddompe-add-omapfb.patch
 create mode 100644 recipes/ti/gstreamer-ti-ddompe_svn.bb

diff --git a/recipes/ti/gstreamer-ti-ddompe/gstreamer-ti-ddompe-add-omapfb.patch b/recipes/ti/gstreamer-ti-ddompe/gstreamer-ti-ddompe-add-omapfb.patch
new file mode 100644
index 0000000..2e38708
--- /dev/null
+++ b/recipes/ti/gstreamer-ti-ddompe/gstreamer-ti-ddompe-add-omapfb.patch
@@ -0,0 +1,1354 @@
+Index: ticodecplugin/configure.ac
+===================================================================
+--- ticodecplugin.orig/configure.ac	2010-05-25 21:19:03.826848988 -0600
++++ ticodecplugin/configure.ac	2010-05-25 21:19:04.007159812 -0600
+@@ -23,6 +23,7 @@
+ AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
+ 
+ AM_CONFIG_HEADER(config.h)
++AM_PROG_AS
+ 
+ dnl check for tools
+ AC_PROG_CC
+Index: ticodecplugin/src/gstticodecplugin.c
+===================================================================
+--- ticodecplugin.orig/src/gstticodecplugin.c	2010-05-25 21:19:03.826848988 -0600
++++ ticodecplugin/src/gstticodecplugin.c	2010-05-26 05:57:39.703158338 -0600
+@@ -56,6 +56,7 @@
+ #include "gsttipriority.h"
+ #include "ti_encoders.h"
+ #include "ittiam_encoders.h"
++#include "omapfb.h"
+ 
+ /* Audio caps */
+ static GstStaticCaps gstti_pcm_caps = GST_STATIC_CAPS(
+@@ -472,6 +473,10 @@
+         GST_RANK_PRIMARY,GST_TYPE_DMAI_RESIZER))
+         return FALSE;
+ 
++    if (!gst_element_register(TICodecPlugin, "omapdmaifbsink", 
++        GST_RANK_PRIMARY,GST_OMAPFB_SINK_TYPE))
++        return FALSE;
++
+     return TRUE;
+ }
+ 
+Index: ticodecplugin/src/omapfb.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ ticodecplugin/src/omapfb.c	2010-05-25 21:19:04.010846015 -0600
+@@ -0,0 +1,1005 @@
++/*
++ * Copyright (C) 2008 Felipe Contreras <felipe.contreras at gmail.com>
++ * Copyright (C) 2009 Tim Yamin <plasm at roo.me.uk>
++ * Copyright (C) 2009 Brijesh Singh <brijesh.ksingh at gmail.com>
++ *  
++ * X code largely copied from ximagesink by Julien Moutte and
++ * vo_omapfb.c by Gregoire Gentil.
++ *
++ * Use DMAI hw framecopy module to copy the dmai transport buffers.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
++ */
++
++#include <fcntl.h>
++#include <sys/ioctl.h>
++#include <sys/mman.h>
++#include <unistd.h>
++#include <string.h>
++#include <sys/types.h>
++#include <malloc.h>
++#include <stdlib.h>
++
++#include "omapfb.h"
++#include <gst/interfaces/xoverlay.h>
++
++static GstVideoSinkClass *parent_class = NULL;
++
++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 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 them */
++    if(n_children)
++        XFree(child);
++}
++
++static GstXWindow *
++gst_omapfbsink_xwindow_new (GstOmapFbSink * omapfbsink, gint width, gint height)
++{
++    GstXWindow *xwindow = NULL;
++    XGCValues values;
++
++    if(!omapfbsink->xcontext)
++        return NULL;
++
++    xwindow = g_new0 (GstXWindow, 1);
++    xwindow->width = width;
++    xwindow->height = height;
++    xwindow->internal = TRUE;
++
++    g_mutex_lock (omapfbsink->x_lock);
++    xwindow->win = XCreateSimpleWindow (omapfbsink->xcontext->disp,
++                    omapfbsink->xcontext->root,
++                    0, 0, xwindow->width, xwindow->height,
++                    0, 0, omapfbsink->colorKey);
++
++    /* We have to do that to prevent X from redrawing the background on
++       ConfigureNotify. This takes away flickering of video when resizing. */
++    XSetWindowBackgroundPixmap (omapfbsink->xcontext->disp, xwindow->win, None);
++
++    if (omapfbsink->handle_events) {
++        Atom wm_delete;
++
++    XSelectInput (omapfbsink->xcontext->disp, xwindow->win, ExposureMask |
++              StructureNotifyMask | PointerMotionMask | KeyPressMask |
++              KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
++
++    /* Tell the window manager we'd like delete client messages instead of
++     * being killed */
++    wm_delete = XInternAtom (omapfbsink->xcontext->disp,
++                 "WM_DELETE_WINDOW", False);
++    (void) XSetWMProtocols (omapfbsink->xcontext->disp, xwindow->win,
++                &wm_delete, 1);
++    }
++
++    xwindow->gc = XCreateGC (omapfbsink->xcontext->disp, xwindow->win,
++                 0, &values);
++
++    XMapRaised (omapfbsink->xcontext->disp, xwindow->win);
++    XSync (omapfbsink->xcontext->disp, FALSE);
++
++    g_mutex_unlock (omapfbsink->x_lock);
++    gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (omapfbsink), xwindow->win);
++
++    return xwindow;
++}
++
++static gboolean gst_omapfbsink_update_plane (GstOmapFbSink *omapfbsink)
++{
++    int wx, wy, ww, wh;
++    if (!omapfbsink->xcontext)
++    {
++        if (ioctl (omapfbsink->overlay_fd, OMAPFB_SETUP_PLANE, &omapfbsink->plane_info))
++            return FALSE;
++        return TRUE;
++    }
++
++    if (omapfbsink->plane_info.enabled != 1)
++        return FALSE;
++
++    x11_get_window_abs_position(omapfbsink->xcontext->disp,
++                omapfbsink->xwindow->win, &wx, &wy, &ww, &wh);
++
++    if (wx != omapfbsink->xwindow->wx || wy != omapfbsink->xwindow->wy ||
++    wh != omapfbsink->xwindow->height || ww != omapfbsink->xwindow->width) {
++        omapfbsink->plane_info.out_width = omapfbsink->xwindow->width = ww;
++    omapfbsink->plane_info.out_height = omapfbsink->xwindow->height = wh;
++        omapfbsink->plane_info.pos_x = omapfbsink->xwindow->wx = wx;
++        omapfbsink->plane_info.pos_y = omapfbsink->xwindow->wy = wy;
++
++        GST_DEBUG_OBJECT(omapfbsink, "updating geometry to: (%d,%d) %dx%d", wx, wy, ww, wh);
++
++        XSetForeground (omapfbsink->xcontext->disp, omapfbsink->xwindow->gc, omapfbsink->colorKey);
++        XFillRectangle (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, omapfbsink->xwindow->gc, 0, 0, ww, wh);
++
++        if (ioctl (omapfbsink->overlay_fd, OMAPFB_SETUP_PLANE, &omapfbsink->plane_info))
++      return FALSE;
++    }
++
++    return TRUE;
++}
++
++static void
++gst_omapfbsink_expose (GstXOverlay * overlay)
++{
++    gst_omapfbsink_update_plane(GST_OMAPFB_SINK (overlay));
++}
++
++static void
++gst_omapfbsink_xwindow_destroy (GstOmapFbSink * omapfbsink,
++    GstXWindow * xwindow)
++{
++    g_return_if_fail (xwindow != NULL);
++    g_mutex_lock (omapfbsink->x_lock);
++
++    /* If we did not create that window we just free the GC and let it live */
++    if (xwindow->internal)
++        XDestroyWindow (omapfbsink->xcontext->disp, xwindow->win);
++    else
++        XSelectInput (omapfbsink->xcontext->disp, xwindow->win, 0);
++
++    XFreeGC (omapfbsink->xcontext->disp, xwindow->gc);
++    XSync (omapfbsink->xcontext->disp, FALSE);
++    g_mutex_unlock (omapfbsink->x_lock);
++    g_free (xwindow);
++}
++
++/* This function handles XEvents that might be in the queue. It generates
++   GstEvent that will be sent upstream in the pipeline to handle interactivity
++   and navigation.*/
++static void
++gst_omapfbsink_handle_xevents (GstOmapFbSink * omapfbsink)
++{
++    XEvent e;
++    g_mutex_lock (omapfbsink->flow_lock);
++    g_mutex_lock (omapfbsink->x_lock);
++
++    while (XCheckWindowEvent (omapfbsink->xcontext->disp,
++           omapfbsink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) {
++        switch (e.type) {
++            case Expose:
++            case ConfigureNotify:
++                gst_omapfbsink_update_plane (omapfbsink);
++                break;
++            default:
++                break;
++        }
++    }
++
++    /* Handle Display events */
++    while (XPending (omapfbsink->xcontext->disp)) {
++        XNextEvent (omapfbsink->xcontext->disp, &e);
++
++        switch (e.type) {
++            case ClientMessage:{
++                Atom wm_delete;
++
++                wm_delete = XInternAtom (omapfbsink->xcontext->disp,
++                        "WM_DELETE_WINDOW", False);
++                if (wm_delete == (Atom) e.xclient.data.l[0]) {
++                    /* Handle window deletion by posting an error on the bus */
++                    GST_ELEMENT_ERROR (omapfbsink, RESOURCE, NOT_FOUND,
++                            ("Output window was closed"), (NULL));
++
++                    g_mutex_unlock (omapfbsink->x_lock);
++                    gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow);
++                    omapfbsink->xwindow = NULL;
++                    g_mutex_lock (omapfbsink->x_lock);
++                }
++                break;
++            }
++            default:
++                break;
++        }
++    }
++
++    g_mutex_unlock (omapfbsink->x_lock);
++    g_mutex_unlock (omapfbsink->flow_lock);
++}
++
++static gpointer
++gst_omapfbsink_event_thread (GstOmapFbSink * omapfbsink)
++{
++    GST_OBJECT_LOCK (omapfbsink);
++    while (omapfbsink->running) {
++        GST_OBJECT_UNLOCK (omapfbsink);
++
++    if (omapfbsink->xwindow)
++      gst_omapfbsink_handle_xevents (omapfbsink);
++    g_usleep (100000);
++
++    GST_OBJECT_LOCK (omapfbsink);
++    }
++    GST_OBJECT_UNLOCK (omapfbsink);
++
++    return NULL;
++}
++
++/* This function gets the X Display and global info about it. Everything is
++   stored in our object and will be cleaned when the object is disposed. */
++static GstXContext *
++gst_omapfbsink_xcontext_get (GstOmapFbSink * omapfbsink)
++{
++    GstXContext *xcontext = g_new0 (GstXContext, 1);
++    g_mutex_lock (omapfbsink->x_lock);
++
++    xcontext->disp = XOpenDisplay (omapfbsink->display_name);
++
++    if (!xcontext->disp) {
++        g_mutex_unlock (omapfbsink->x_lock);
++    g_free (xcontext);
++    GST_ELEMENT_WARNING (omapfbsink, RESOURCE, WRITE,
++                 ("Could not initialise X output"),
++                 ("Could not open display"));
++    return NULL;
++    }
++
++    xcontext->screen = DefaultScreenOfDisplay (xcontext->disp);
++    xcontext->screen_num = DefaultScreen (xcontext->disp);
++    xcontext->visual = DefaultVisual (xcontext->disp, xcontext->screen_num);
++    xcontext->root = DefaultRootWindow (xcontext->disp);
++
++    xcontext->width = DisplayWidth (xcontext->disp, xcontext->screen_num);
++    xcontext->height = DisplayHeight (xcontext->disp, xcontext->screen_num);
++
++    g_mutex_unlock (omapfbsink->x_lock);
++
++    /* Setup our event listening thread */
++    GST_OBJECT_LOCK (omapfbsink);
++    omapfbsink->running = TRUE;
++    omapfbsink->event_thread = g_thread_create (
++      (GThreadFunc) gst_omapfbsink_event_thread, omapfbsink, TRUE, NULL);
++    GST_OBJECT_UNLOCK (omapfbsink);
++
++    return xcontext;
++}
++
++static void
++gst_omapfbsink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
++{
++    GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK (overlay);
++    GstXWindow *xwindow = NULL;
++    XWindowAttributes attr;
++
++    /* If we already use that window, return */
++    if (omapfbsink->xwindow && (xwindow_id == omapfbsink->xwindow->win))
++        return;
++
++    /* If the element has not initialized the X11 context try to do so */
++    if (!omapfbsink->xcontext &&
++    !(omapfbsink->xcontext = gst_omapfbsink_xcontext_get (omapfbsink))) {
++      g_mutex_unlock (omapfbsink->flow_lock);
++      return;
++    }
++
++    /* If a window is there already we destroy it */
++    if (omapfbsink->xwindow) {
++      gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow);
++      omapfbsink->xwindow = NULL;
++    }
++
++    /* If the xid is 0 we go back to an internal window */
++    if (xwindow_id == 0) {
++      /* If no width/height caps nego did not happen window will be created
++     during caps nego then */
++      if (GST_VIDEO_SINK_WIDTH (omapfbsink) && GST_VIDEO_SINK_HEIGHT (omapfbsink)) {
++    xwindow = gst_omapfbsink_xwindow_new (omapfbsink,
++          GST_VIDEO_SINK_WIDTH (omapfbsink),
++          GST_VIDEO_SINK_HEIGHT (omapfbsink));
++      }
++    } else {
++        xwindow = g_new0 (GstXWindow, 1);
++    xwindow->wx = xwindow->wy = -1;
++    xwindow->win = xwindow_id;
++
++    /* We get window geometry, set the event we want to receive,
++       and create a GC */
++    g_mutex_lock (omapfbsink->x_lock);
++    XGetWindowAttributes (omapfbsink->xcontext->disp, xwindow->win, &attr);
++    xwindow->width = attr.width;
++    xwindow->height = attr.height;
++    xwindow->internal = FALSE;
++    if (omapfbsink->handle_events) {
++        XSelectInput (omapfbsink->xcontext->disp, xwindow->win, ExposureMask |
++              StructureNotifyMask | PointerMotionMask | KeyPressMask |
++              KeyReleaseMask);
++    }
++
++        xwindow->gc = XCreateGC (omapfbsink->xcontext->disp, xwindow->win, 0, NULL);
++    g_mutex_unlock (omapfbsink->x_lock);
++    }
++
++    if (xwindow) {
++        omapfbsink->xwindow = xwindow;
++
++    g_mutex_lock (omapfbsink->x_lock);
++    gst_omapfbsink_update_plane(omapfbsink);
++    g_mutex_unlock (omapfbsink->x_lock);
++    }
++}
++
++static void
++gst_omapfbsink_xwindow_clear (GstOmapFbSink * omapfbsink,
++                  GstXWindow * xwindow)
++{
++    g_return_if_fail (xwindow != NULL);
++    g_mutex_lock (omapfbsink->x_lock);
++
++    XSetForeground (omapfbsink->xcontext->disp, xwindow->gc,
++            XBlackPixel (omapfbsink->xcontext->disp,
++                 omapfbsink->xcontext->screen_num));
++
++    XFillRectangle (omapfbsink->xcontext->disp, xwindow->win, xwindow->gc,
++            0, 0, xwindow->width, xwindow->height);
++
++    XSync (omapfbsink->xcontext->disp, FALSE);
++    g_mutex_unlock (omapfbsink->x_lock);
++}
++
++static void
++gst_omapfbsink_set_event_handling (GstXOverlay * overlay,
++    gboolean handle_events)
++{
++    GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK (overlay);
++    omapfbsink->handle_events = handle_events;
++
++    g_mutex_lock (omapfbsink->flow_lock);
++
++    if (G_UNLIKELY (!omapfbsink->xwindow)) {
++        g_mutex_unlock (omapfbsink->flow_lock);
++    return;
++    }
++
++    g_mutex_lock (omapfbsink->x_lock);
++
++    if (handle_events) {
++        if (omapfbsink->xwindow->internal) {
++      XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win,
++            ExposureMask | StructureNotifyMask | PointerMotionMask |
++            KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
++    } else {
++      XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win,
++            ExposureMask | StructureNotifyMask | PointerMotionMask |
++            KeyPressMask | KeyReleaseMask);
++    }
++    } else {
++        XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, 0);
++    }
++
++    g_mutex_unlock (omapfbsink->x_lock);
++    g_mutex_unlock (omapfbsink->flow_lock);
++}
++
++static void
++gst_omapfbsink_xoverlay_init (GstXOverlayClass * iface)
++{
++    iface->set_xwindow_id = gst_omapfbsink_set_xwindow_id;
++    iface->expose = gst_omapfbsink_expose;
++    iface->handle_events = gst_omapfbsink_set_event_handling;
++}
++
++static GstCaps *
++generate_sink_template (void)
++{
++    GstCaps *caps;
++    GstStructure *struc;
++
++    caps = gst_caps_new_empty ();
++
++    struc = gst_structure_new ("video/x-raw-yuv",
++                               "width", GST_TYPE_INT_RANGE, 16, 4096,
++                               "height", GST_TYPE_INT_RANGE, 16, 4096,
++                               "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30, 1,
++                               NULL);
++
++    {
++        GValue list;
++        GValue val;
++
++        list.g_type = val.g_type = 0;
++
++        g_value_init (&list, GST_TYPE_LIST);
++        g_value_init (&val, GST_TYPE_FOURCC);
++
++#if 0
++        gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'));
++        gst_value_list_append_value (&list, &val);
++#else
++    gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('I', '4', '2', '0'));
++    gst_value_list_append_value (&list, &val);
++
++        gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'));
++        gst_value_list_append_value (&list, &val);
++#endif
++
++        gst_structure_set_value (struc, "format", &list);
++
++        g_value_unset (&val);
++        g_value_unset (&list);
++    }
++
++    gst_caps_append_structure (caps, struc);
++
++    return caps;
++}
++
++static GstFlowReturn
++buffer_alloc (GstBaseSink *bsink,
++              guint64 offset,
++              guint size,
++              GstCaps *caps,
++              GstBuffer **buf)
++{
++    GstOmapFbSink *self;
++    GstBuffer *buffer = NULL;
++    GstFlowReturn ret = GST_FLOW_OK;
++    self = GST_OMAPFB_SINK (bsink);
++
++    if(self->row_skip) {
++        buffer = gst_buffer_new ();
++        GST_BUFFER_DATA (buffer) = self->buffer = self->framebuffer;
++        GST_BUFFER_SIZE (buffer) = self->buffer_size = size;
++        gst_buffer_set_caps (buffer, caps);
++    } else {
++        if(self->buffer && size == self->buffer_size) {
++            buffer = gst_buffer_new ();
++            GST_BUFFER_DATA (buffer) = self->buffer;
++            GST_BUFFER_SIZE (buffer) = size;
++            gst_buffer_set_caps (buffer, caps);
++        } else {
++            if(self->buffer)
++                free(self->buffer);
++            if(posix_memalign(&self->buffer, 16, (size_t) size) == 0) {
++                buffer = gst_buffer_new ();
++                GST_BUFFER_DATA (buffer) = self->buffer;
++                GST_BUFFER_SIZE (buffer) = self->buffer_size = size;
++                gst_buffer_set_caps (buffer, caps);
++            } else {
++                GST_ELEMENT_ERROR (self, RESOURCE, WRITE, ("Could not allocate aligned buf!"),
++                                  ("Could not alloc aligned buf!"));
++            }
++        }
++    }
++
++    *buf = buffer;
++    return ret;
++}
++
++static void
++x_memcpy (GstOmapFbSink *omapfbsink, __uint8_t *outBuf, __uint8_t *inBuf)
++{
++    BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;
++    Buffer_Handle hInBuf = NULL, hOutBuf = NULL;
++    Framecopy_Attrs fcAttrs = Framecopy_Attrs_DEFAULT;
++    int size;
++
++    if (omapfbsink->hFc == NULL) {
++        fcAttrs.accel = TRUE;
++        omapfbsink->hFc = Framecopy_create(&fcAttrs);
++        if (omapfbsink->hFc == NULL) {
++            GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to create dmai framecopy handle"), ("failed to create dmai framecopy handle"));
++            goto cleanup;
++        }
++    }
++
++    gfxAttrs.bAttrs.reference   = TRUE;
++    gfxAttrs.dim.width          = GST_VIDEO_SINK_WIDTH (omapfbsink);
++    gfxAttrs.dim.height         = GST_VIDEO_SINK_HEIGHT (omapfbsink);
++    gfxAttrs.colorSpace         = ColorSpace_UYVY;
++    gfxAttrs.dim.lineLength     = omapfbsink->fixinfo.line_length;
++    size = gfxAttrs.dim.height * gfxAttrs.dim.width * 2;
++
++    hInBuf = Buffer_create(size, BufferGfx_getBufferAttrs(&gfxAttrs));
++    if (hInBuf == NULL) {
++        GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("Could not allocate refer dmai buffer"), ("Could not allocate refer dmai buffer"));
++        goto cleanup;
++    }
++    Buffer_setUserPtr(hInBuf, (Int8*) inBuf);
++    Buffer_setNumBytesUsed(hInBuf,Buffer_getSize(hInBuf));
++
++    hOutBuf = Buffer_create(size, BufferGfx_getBufferAttrs(&gfxAttrs));
++    if (hOutBuf == NULL) {
++        GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("Could not allocate refer dmai buffer"), ("Could not allocate refer dmai buffer"));
++        goto cleanup;
++    }
++    Buffer_setUserPtr(hOutBuf, (Int8*) outBuf);
++    Buffer_setNumBytesUsed(hOutBuf,Buffer_getSize(hOutBuf));
++
++
++    if (Framecopy_config(omapfbsink->hFc, hInBuf, hOutBuf) < 0) {
++        GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to configure dmai framecopy handle"), ("failed to configure dmai framecopy handle"));
++        goto cleanup;
++    }
++
++    if (Framecopy_execute(omapfbsink->hFc, hInBuf, hOutBuf) < 0) {
++        GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to execute dmai framecopy handle"), ("failed to configure dmai framecopy handle"));
++        goto cleanup;
++    }
++    cleanup:
++
++    if (hInBuf)
++        Buffer_delete(hInBuf);
++    if (hOutBuf)
++        Buffer_delete(hOutBuf);
++}
++
++static GstFlowReturn
++render (GstBaseSink * bsink, GstBuffer * buf)
++{
++    int i, w, h;
++    GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK(bsink);
++    __uint8_t *fb = omapfbsink->framebuffer, *data = GST_BUFFER_DATA(buf);
++    gboolean useXcopy = FALSE;
++
++    if (GST_IS_TIDMAIBUFFERTRANSPORT(buf)) {
++        GST_LOG("found dmai transport buffer, enabling hw framecopy.\n");
++        useXcopy = TRUE;
++    }
++
++    if(omapfbsink->plane_info.enabled == 2)
++    {
++        omapfbsink->plane_info.enabled = 1;
++
++        g_mutex_lock (omapfbsink->x_lock);
++        gst_omapfbsink_update_plane(omapfbsink);
++        g_mutex_unlock (omapfbsink->x_lock);
++    }
++
++    /* If a buffer which wasn't supplied by us is given to us to render with,
++       we need to copy to our buffer first so that memory alignment constraints
++       are met. */
++    if((data != omapfbsink->buffer && GST_BUFFER_SIZE(buf) <= omapfbsink->buffer_size) && !useXcopy)
++    {
++        memcpy(omapfbsink->buffer, data, GST_BUFFER_SIZE(buf));
++        data = omapfbsink->buffer;
++    }
++
++    /* buffer_alloc gave a direct buffer, so we have nothing to
++       do here... */
++    if(omapfbsink->row_skip)
++        return GST_FLOW_OK;
++
++    switch(omapfbsink->image_format) {
++        case GST_MAKE_FOURCC('I', '4', '2', '0'):
++            /* Convert to YUV422 and send to FB */
++
++            h = GST_VIDEO_SINK_HEIGHT (omapfbsink);
++            w = GST_VIDEO_SINK_WIDTH (omapfbsink);
++
++            __uint8_t *y, *u, *v;
++            y = data;
++            u = y + w * h;
++            v = u + w / 2 * h / 2;
++            yuv420_to_yuv422(fb, y, u, v, w & ~15, h, w, w / 2, omapfbsink->fixinfo.line_length);
++            break;
++
++        case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
++            /* Send to FB, taking into account line_length */
++            if (useXcopy) {
++                x_memcpy(omapfbsink, fb, data);
++            }
++            else {
++
++            w = 2 * GST_VIDEO_SINK_WIDTH (omapfbsink);
++            for(i = 0; i < GST_VIDEO_SINK_HEIGHT (omapfbsink); i++)
++            {
++                memcpy(fb, data, w);
++
++                fb += omapfbsink->fixinfo.line_length;
++                data += w;
++            }
++            }
++            break;
++    }
++
++    return GST_FLOW_OK;
++}
++
++static gboolean
++setcaps (GstBaseSink *bsink,
++         GstCaps *vscapslist)
++{
++    GstOmapFbSink *self;
++    GstStructure *structure;
++
++    gint width, height;
++    struct omapfb_color_key color_key;
++
++    self = GST_OMAPFB_SINK (bsink);
++
++    structure = gst_caps_get_structure (vscapslist, 0);
++
++    gst_structure_get_int (structure, "width", &width);
++    gst_structure_get_int (structure, "height", &height);
++
++    self->overlay_info.xres = MIN (self->varinfo.xres, width) & ~15;
++    self->overlay_info.yres = MIN (self->varinfo.yres, height) & ~15;
++    self->overlay_info.xres_virtual = self->overlay_info.xres;
++    self->overlay_info.yres_virtual = self->overlay_info.yres;
++
++    self->overlay_info.xoffset = 0;
++    self->overlay_info.yoffset = 0;
++
++    gst_structure_get_fourcc (structure, "format", &self->image_format);
++    switch(self->image_format) {
++        case GST_MAKE_FOURCC('I', '4', '2', '0'):
++            self->row_skip = FALSE; /* Colorspace conversion required */
++            self->overlay_info.nonstd = OMAPFB_COLOR_YUY422;
++            break;
++        case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
++            /* Can data be pushed straight to the FB or do we need to interleave? */
++            if (self->fixinfo.line_length != 2 * width)
++                self->row_skip = FALSE;
++            else
++                self->row_skip = TRUE;
++            self->overlay_info.nonstd = OMAPFB_COLOR_YUV422;
++            break;
++    }
++
++    if (ioctl (self->overlay_fd, FBIOPUT_VSCREENINFO, &self->overlay_info))
++        return FALSE;
++
++    GST_VIDEO_SINK_WIDTH (self) = width;
++    GST_VIDEO_SINK_HEIGHT (self) = height;
++    if (!self->xwindow) {
++        self->xwindow = gst_omapfbsink_xwindow_new (self,
++            GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self));
++    }
++
++    color_key.channel_out = OMAPFB_CHANNEL_OUT_LCD;
++    color_key.background = 0x0;
++    color_key.trans_key = self->colorKey;
++    if (self->xwindow)
++        color_key.key_type = OMAPFB_COLOR_KEY_GFX_DST;
++    else
++        color_key.key_type = OMAPFB_COLOR_KEY_DISABLED;
++
++    if (ioctl (self->overlay_fd, OMAPFB_SET_COLOR_KEY, &color_key))
++        return FALSE;
++
++    self->plane_info.pos_x = 0;
++    self->plane_info.pos_y = 0;
++    self->plane_info.out_width = self->overlay_info.xres;
++    self->plane_info.out_height = self->overlay_info.yres;
++    self->plane_info.enabled = 2;
++
++    if (ioctl (self->overlay_fd, FBIOGET_FSCREENINFO, &self->fixinfo))
++        return FALSE;
++
++    self->enabled = TRUE;
++    return TRUE;
++}
++
++static gboolean
++start (GstBaseSink *bsink)
++{
++    GstOmapFbSink *self;
++    int fd;
++
++    self = GST_OMAPFB_SINK (bsink);
++
++    fd = open ("/dev/fb0", O_RDWR);
++
++    if (fd == -1)
++        return FALSE;
++
++    if (ioctl (fd, FBIOGET_VSCREENINFO, &self->varinfo))
++    {
++        close (fd);
++        return FALSE;
++    }
++
++    if (close (fd))
++        return FALSE;
++
++    self->overlay_fd = open ("/dev/fb1", O_RDWR);
++
++    if (self->overlay_fd == -1)
++        return FALSE;
++
++    if (ioctl (self->overlay_fd, FBIOGET_VSCREENINFO, &self->overlay_info))
++        return FALSE;
++
++    if (ioctl (self->overlay_fd, OMAPFB_QUERY_PLANE, &self->plane_info))
++        return FALSE;
++
++    if (ioctl (self->overlay_fd, OMAPFB_QUERY_MEM, &self->mem_info))
++        return FALSE;
++
++    self->framebuffer = mmap (NULL, self->mem_info.size, PROT_WRITE, MAP_SHARED, self->overlay_fd, 0);
++    if (self->framebuffer == MAP_FAILED)
++        return FALSE;
++
++    return TRUE;
++}
++
++static gboolean
++stop (GstBaseSink *bsink)
++{
++    GstOmapFbSink *self;
++
++    self = GST_OMAPFB_SINK (bsink);
++
++    if (self->enabled)
++    {
++        self->plane_info.enabled = 0;
++
++        if (ioctl (self->overlay_fd, OMAPFB_SETUP_PLANE, &self->plane_info))
++            return FALSE;
++    }
++
++    if (munmap (self->framebuffer, self->mem_info.size))
++        return FALSE;
++
++    if (close (self->overlay_fd))
++        return FALSE;
++
++    if (self->hFc) 
++        Framecopy_delete(self->hFc);
++
++    return TRUE;
++}
++
++/* This function cleans the X context. Closing the Display and unrefing the
++   caps for supported formats. */
++static void
++gst_omapfbsink_xcontext_clear (GstOmapFbSink * omapfbsink)
++{
++    GstXContext *xcontext;
++    GST_OBJECT_LOCK (omapfbsink);
++    if (omapfbsink->xcontext == NULL) {
++      GST_OBJECT_UNLOCK (omapfbsink);
++      return;
++    }
++
++    xcontext = omapfbsink->xcontext;
++    omapfbsink->xcontext = NULL;
++
++    GST_OBJECT_UNLOCK (omapfbsink);
++    g_mutex_lock (omapfbsink->x_lock);
++
++    XCloseDisplay (xcontext->disp);
++    g_mutex_unlock (omapfbsink->x_lock);
++    g_free (xcontext);
++}
++
++static void
++gst_omapfbsink_reset (GstOmapFbSink *omapfbsink)
++{
++    GThread *thread;
++
++    GST_OBJECT_LOCK (omapfbsink);
++    omapfbsink->running = FALSE;
++    /* grab thread and mark it as NULL */
++    thread = omapfbsink->event_thread;
++    omapfbsink->event_thread = NULL;
++    GST_OBJECT_UNLOCK (omapfbsink);
++
++    /* Wait for our event thread to finish before we clean up our stuff. */
++    if (thread)
++      g_thread_join (thread);
++
++    g_mutex_lock (omapfbsink->flow_lock);
++    if (omapfbsink->xwindow) {
++        gst_omapfbsink_xwindow_clear (omapfbsink, omapfbsink->xwindow);
++        gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow);
++        omapfbsink->xwindow = NULL;
++    }
++    g_mutex_unlock (omapfbsink->flow_lock);
++    gst_omapfbsink_xcontext_clear (omapfbsink);
++}
++
++static GstStateChangeReturn
++gst_omapfbsink_change_state (GstElement * element, GstStateChange transition)
++{
++    GstOmapFbSink *omapfbsink;
++    GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
++    GstXContext *xcontext = NULL;
++
++    omapfbsink = GST_OMAPFB_SINK (element);
++
++    switch (transition) {
++    case GST_STATE_CHANGE_NULL_TO_READY:
++
++        /* Initializing the XContext */
++        if (omapfbsink->xcontext == NULL) {
++            xcontext = gst_omapfbsink_xcontext_get (omapfbsink);
++
++            GST_OBJECT_LOCK (omapfbsink);
++            omapfbsink->xcontext = xcontext;
++            GST_OBJECT_UNLOCK (omapfbsink);
++        }
++        break;
++    case GST_STATE_CHANGE_READY_TO_PAUSED:
++        g_mutex_lock (omapfbsink->flow_lock);
++        if (omapfbsink->xwindow)
++            gst_omapfbsink_xwindow_clear (omapfbsink, omapfbsink->xwindow);
++        g_mutex_unlock (omapfbsink->flow_lock);
++        break;
++    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
++        break;
++    default:
++        break;
++    }
++
++    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
++
++    switch (transition) {
++    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
++        break;
++    case GST_STATE_CHANGE_PAUSED_TO_READY:
++        GST_VIDEO_SINK_WIDTH (omapfbsink) = 0;
++        GST_VIDEO_SINK_HEIGHT (omapfbsink) = 0;
++        break;
++    case GST_STATE_CHANGE_READY_TO_NULL:
++        gst_omapfbsink_reset (omapfbsink);
++        break;
++    default:
++        break;
++    }
++
++    return ret;
++}
++
++static void
++type_class_init (gpointer g_class,
++                 gpointer class_data)
++{
++    GstElementClass *element_class;
++    GstBaseSinkClass *base_sink_class;
++
++    element_class = (GstElementClass *) g_class;
++    base_sink_class = (GstBaseSinkClass *) g_class;
++
++    parent_class = g_type_class_peek_parent (g_class);
++
++    base_sink_class->set_caps = GST_DEBUG_FUNCPTR (setcaps);
++    base_sink_class->buffer_alloc = GST_DEBUG_FUNCPTR (buffer_alloc);
++    base_sink_class->render = GST_DEBUG_FUNCPTR (render);
++    base_sink_class->start = GST_DEBUG_FUNCPTR (start);
++    base_sink_class->stop = GST_DEBUG_FUNCPTR (stop);
++
++    element_class->change_state = gst_omapfbsink_change_state;
++}
++
++static void
++type_base_init (gpointer g_class)
++{
++    GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
++
++    {
++        GstElementDetails details;
++
++        details.longname = "Linux OMAP framebuffer sink";
++        details.klass = "Sink/Video";
++        details.description = "Renders video with omapfb";
++        details.author = "Felipe Contreras";
++
++        gst_element_class_set_details (element_class, &details);
++    }
++
++    {
++        GstPadTemplate *template;
++
++        template = gst_pad_template_new ("sink", GST_PAD_SINK,
++                                         GST_PAD_ALWAYS,
++                                         generate_sink_template ());
++
++        gst_element_class_add_pad_template (element_class, template);
++    }
++}
++
++static gboolean
++gst_omapfbsink_interface_supported (GstImplementsInterface * iface, GType type)
++{
++    g_assert (type == GST_TYPE_X_OVERLAY);
++    return TRUE;
++}
++
++static void
++gst_omapfbsink_interface_init (GstImplementsInterfaceClass * klass)
++{
++    klass->supported = gst_omapfbsink_interface_supported;
++}
++
++static void
++gst_omapfbsink_init (GstOmapFbSink * omapfbsink)
++{
++    omapfbsink->display_name = NULL;
++    omapfbsink->xcontext = NULL;
++    omapfbsink->xwindow = NULL;
++
++    omapfbsink->event_thread = NULL;
++    omapfbsink->running = FALSE;
++
++    omapfbsink->x_lock = g_mutex_new ();
++    omapfbsink->flow_lock = g_mutex_new ();
++
++    omapfbsink->handle_events = TRUE;
++    omapfbsink->colorKey = 0xff0;
++
++    omapfbsink->plane_info.enabled = 0;
++    omapfbsink->row_skip = FALSE;
++
++    omapfbsink->buffer = NULL;
++    omapfbsink->buffer_size = 0;
++    omapfbsink->hFc = NULL;
++}
++
++GType
++gst_omapfbsink_get_type (void)
++{
++    static GType type = 0;
++
++    if (G_UNLIKELY (type == 0))
++    {  
++        GTypeInfo *type_info;
++        static const GInterfaceInfo iface_info = {
++            (GInterfaceInitFunc) gst_omapfbsink_interface_init,
++            NULL,
++            NULL,
++        };
++        static const GInterfaceInfo overlay_info = {
++            (GInterfaceInitFunc) gst_omapfbsink_xoverlay_init,
++            NULL,
++            NULL,
++        };
++        type_info = g_new0 (GTypeInfo, 1);
++        type_info->class_size = sizeof (GstOmapFbSinkClass);
++        type_info->base_init = type_base_init;
++        type_info->class_init = type_class_init;
++        type_info->instance_size = sizeof (GstOmapFbSink);
++        type_info->instance_init = (GInstanceInitFunc) gst_omapfbsink_init;
++
++        type = g_type_register_static (GST_TYPE_BASE_SINK, "GstOmapFbSink", type_info, 0);
++        g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info);
++        g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &overlay_info);
++
++        g_free (type_info);
++    }
++
++    return type;
++}
+Index: ticodecplugin/src/omapfb.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ ticodecplugin/src/omapfb.h	2010-05-25 21:19:04.010846015 -0600
+@@ -0,0 +1,142 @@
++/*
++ * Copyright (C) 2008 Felipe Contreras <felipe.contreras at gmail.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
++ */
++
++#ifndef GST_OMAPFB_H
++#define GST_OMAPFB_H
++
++#include <ti/sdo/dmai/BufferGfx.h>
++#include <ti/sdo/dmai/Framecopy.h>
++
++#include "gsttidmaibuffertransport.h"
++#include <gst/gst.h>
++#include <gst/video/gstvideosink.h>
++#include <gst/video/video.h>
++
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++
++#include <linux/fb.h>
++#include <linux/omapfb.h>
++
++
++G_BEGIN_DECLS
++
++#define GST_OMAPFB_SINK_TYPE (gst_omapfbsink_get_type ())
++#define GST_OMAPFB_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_OMAPFB_SINK_TYPE, GstOmapFbSink))
++
++typedef struct GstXContext GstXContext;
++typedef struct GstXWindow GstXWindow;
++typedef struct GstOmapFbSink GstOmapFbSink;
++typedef struct GstOmapFbSinkClass GstOmapFbSinkClass;
++
++/**
++ * GstXWindow:
++ * @win: the Window ID of this X11 window
++ * @width: the width in pixels of Window @win
++ * @height: the height in pixels of Window @win
++ * @internal: used to remember if Window @win was created internally or passed
++ * through the #GstXOverlay interface
++ * @gc: the Graphical Context of Window @win
++ *
++ * Structure used to store informations about a Window.
++ */
++struct GstXWindow {
++    Window win;
++    gint width, height;
++    gboolean internal;
++    GC gc;
++
++    gint wx, wy;
++};
++
++/**
++ * GstXContext:
++ * @disp: the X11 Display of this context
++ * @screen: the default Screen of Display @disp
++ * @screen_num: the Screen number of @screen
++ * @visual: the default Visual of Screen @screen
++ * @root: the root Window of Display @disp
++ * @white: the value of a white pixel on Screen @screen
++ * @black: the value of a black pixel on Screen @screen
++ * @depth: the color depth of Display @disp
++ * @bpp: the number of bits per pixel on Display @disp
++ * @endianness: the endianness of image bytes on Display @disp
++ * @width: the width in pixels of Display @disp
++ * @height: the height in pixels of Display @disp
++ *
++ * Structure used to store various informations collected/calculated for a
++ * Display.
++ */
++struct GstXContext {
++    Display *disp;
++    Screen *screen;
++    gint screen_num;
++
++    Visual *visual;
++    Window root;
++
++    gint depth;
++    gint bpp;
++
++    gint width, height;
++};
++
++struct GstOmapFbSink
++{
++    GstVideoSink videosink;
++
++    struct fb_fix_screeninfo fixinfo;
++    struct fb_var_screeninfo varinfo;
++    struct fb_var_screeninfo overlay_info;
++    struct omapfb_mem_info mem_info;
++    struct omapfb_plane_info plane_info;
++
++    int overlay_fd;
++    unsigned char *framebuffer;
++    gboolean enabled;
++
++    GMutex *x_lock;
++    GMutex *flow_lock;
++
++    GstXContext *xcontext;
++    GstXWindow *xwindow;
++
++    gulong colorKey;
++    char *display_name;
++    GThread *event_thread;
++
++    void *buffer;
++    guint buffer_size;
++    guint image_format;
++
++    gboolean row_skip;
++    gboolean handle_events;
++    gboolean running;
++    Framecopy_Handle hFc;
++};
++
++struct GstOmapFbSinkClass
++{
++    GstBaseSinkClass parent_class;
++};
++
++GType gst_omapfbsink_get_type (void);
++
++G_END_DECLS
++
++#endif /* GST_OMAPFB_H */
+Index: ticodecplugin/src/yuv.S
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ ticodecplugin/src/yuv.S	2010-05-25 21:19:04.010846015 -0600
+@@ -0,0 +1,117 @@
++/*
++    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}
++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: ticodecplugin/src/Makefile.am
+===================================================================
+--- ticodecplugin.orig/src/Makefile.am	2010-05-25 21:19:03.826848988 -0600
++++ ticodecplugin/src/Makefile.am	2010-05-26 07:31:11.870787253 -0600
+@@ -8,15 +8,16 @@
+ gsttisupport_generic.c gsttisupport_mpeg4.c gsttisupport_h264.c gsttisupport_jpeg.c \
+ gsttiauddec1.c gsttiauddec.c gsttiaudenc1.c gsttiaudenc.c gsttiimgenc1.c gsttiimgenc.c \
+ gsttisupport_aac.c gsttisupport_mp3.c gsttisupport_wma.c gsttidmaiperf.c\
+-gstticommonutils.c ti_encoders.c ittiam_encoders.c ittiam_caps.c caps.c
++gstticommonutils.c ti_encoders.c ittiam_encoders.c ittiam_caps.c caps.c \
++omapfb.c yuv.S
+ 
+ # flags used to compile this plugin
+ # add other _CFLAGS and _LIBS as needed
+-libgstticodecplugin_la_CFLAGS  = $(GST_CFLAGS) \
++libgstticodecplugin_la_CFLAGS  = $(GST_CFLAGS) -I$(LINUXKERNEL_INSTALL_DIR)/include \
+ $(shell cat @XDC_CONFIG_BASENAME@/compiler.opt) -DPLATFORM=$(PLATFORM)
+ 
+ libgstticodecplugin_la_LIBADD  = $(GST_LIBS) $(GST_BASE_LIBS) \
+-$(GST_PLUGINS_BASE_LIBS) -lgstvideo-0.10 -lm
++$(GST_PLUGINS_BASE_LIBS) -lgstvideo-0.10 -lgstinterfaces-0.10 -lm -lX11
+ 
+ libgstticodecplugin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) \
+ -Wl, at XDC_CONFIG_BASENAME@/linker.cmd
+@@ -26,12 +27,13 @@
+ gsttiparsers.h gsttisupport_generic.h gsttisupport_h264.h \
+ gsttisupport_mpeg4.h gsttisupport_aac.h gsttisupport_mp3.h \
+ gsttisupport_wma.h gsttisupport_jpeg.h ti_encoders.h caps.h gsttidmaidec.h \
+-gsttidmaienc.h gsttidmaiaccel.h gsttipriority.h ittiam_encoders.h ittiam_caps.h
++gsttidmaienc.h gsttidmaiaccel.h gsttipriority.h ittiam_encoders.h ittiam_caps.h \
++omapfb.h
+ 
+ # XDC Configuration
+ CONFIGURO     = $(XDC_INSTALL_DIR)/xs xdc.tools.configuro
+ BUILT_SOURCES = @XDC_CONFIG_BASENAME@/compiler.opt @XDC_CONFIG_BASENAME@/linker.cmd
+-XDC_PATH      = .;$(XDC_INSTALL_DIR)/packages;$(LINK_INSTALL_DIR)/packages;$(FC_INSTALL_DIR)/packages;$(CE_INSTALL_DIR)/packages;$(XDAIS_INSTALL_DIR)/packages;$(CODEC_INSTALL_DIR)/packages;$(CMEM_INSTALL_DIR)/packages;$(DMAI_INSTALL_DIR)/packages;$(LPM_INSTALL_DIR)/packages;$(XDC_USER_PATH);
++XDC_PATH      = .;$(XDC_INSTALL_DIR)/packages;$(LINK_INSTALL_DIR);$(FC_INSTALL_DIR)/packages;$(CE_INSTALL_DIR)/packages;$(XDAIS_INSTALL_DIR)/packages;$(CODEC_INSTALL_DIR)/packages;$(CMEM_INSTALL_DIR)/packages;$(DMAI_INSTALL_DIR)/packages;$(LPM_INSTALL_DIR)/packages;$(XDC_USER_PATH);
+ 
+ %/compiler.opt %/linker.cmd : %.cfg
+ 	XDCPATH="$(XDC_PATH)" $(CONFIGURO) -c $(MVTOOL_DIR) -o  @XDC_CONFIG_BASENAME@ -t $(XDC_TARGET) -p $(XDC_PLATFORM) -b $(DMAI_INSTALL_DIR)/packages/config.bld $<
diff --git a/recipes/ti/gstreamer-ti-ddompe_svn.bb b/recipes/ti/gstreamer-ti-ddompe_svn.bb
new file mode 100644
index 0000000..67be4c6
--- /dev/null
+++ b/recipes/ti/gstreamer-ti-ddompe_svn.bb
@@ -0,0 +1,48 @@
+require recipes/ti/gstreamer-ti.inc
+
+DESCRIPTION = "GSTREAMER Plugin (gstreamer-ti) for TI ARM/DSP processors, DDOMPE branch"
+DEPENDS = "ti-dmai gstreamer gst-plugins-base gst-plugins-good gst-plugins-ugly"
+PROVIDES = "gstreamer-ti"
+PV = "svnr${SRCREV}"
+FILESPATHPKG =. "gstreamer-ti:"
+
+SRC_URI = "\
+  svn://gforge.ti.com/svn/gstreamer_ti/branches/BRANCH_DDOMPE/gstreamer_ti/ti_build;module=ticodecplugin;proto=https;user=anonymous;pswd='' \
+  file://gstreamer-ti-rc.sh \
+"
+SRC_URI_append_omap3 = " \
+  file://gstreamer-ti-ddompe-add-omapfb.patch \
+"
+# use local loadmodules.sh for these platform
+# TODO: must be removed onces these loadmodules goes in gstreamer.ti.com
+SRC_URI_append_dm365 = " file://loadmodules.sh"
+SRC_URI_append_omapl137 = " file://loadmodules.sh"
+SRC_URI_append_omapl138 = " file://loadmodules.sh "
+SRC_URI_append_omap3 = " file://loadmodules.sh "
+
+S = "${WORKDIR}/ticodecplugin"
+SRCREV = "851"
+
+EXTRA_OECONF_dm6446 = "--with-preset=dm6446"
+EXTRA_OECONF_dm6467 = "--with-preset=dm6447"
+EXTRA_OECONF_omap3_append = " --with-preset=omap35x"
+EXTRA_OECONF_dm365 = "--with-preset=dm365"
+EXTRA_OECONF_dm355 = "--with-preset=dm355"
+EXTRA_OECONF_omapl138_append = " --with-preset=omapl138"
+
+do_configure_prepend() {
+    # XDCPATH fixups
+    sed -i -e 's:(LINK_INSTALL_DIR)/packages:(LINK_XDC_ROOT):g' ${S}/src/Makefile.am
+    sed -i -e 's:(XDC_USER_PATH);:(XDC_USER_PATH);$(EDMA3_LLD_INSTALL_DIR)/packages;$(C6ACCEL_INSTALL_DIR)/soc/c6accelw;$(C6ACCEL_INSTALL_DIR)/soc/packages:g' ${S}/src/Makefile.am
+}
+do_install_prepend() {
+    # keep gstreamer-ti.inc's do_install_prepend happy
+    mkdir -p ${WORKDIR}/gstreamer_ti/gstreamer_demo/shared
+}
+
+pkg_postinst_gstreamer-ti-demo-script () {
+        ln -sf ${installdir}/ti-codecs-server/* ${installdir}/gst/${PLATFORM}/
+}
+
+# ti-dspbios-tree needs to be in includes - not clear where the other INCLUDES are setup
+CPPFLAGS_append = " -I${BIOS_INSTALL_DIR}/packages"
-- 
1.7.0.4





More information about the Openembedded-devel mailing list