summaryrefslogtreecommitdiffstats
path: root/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0001-add-omapdmaifbsink.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-ti/gstreamer-ti/gstreamer-ti/0001-add-omapdmaifbsink.patch')
-rw-r--r--extras/recipes-ti/gstreamer-ti/gstreamer-ti/0001-add-omapdmaifbsink.patch1336
1 files changed, 1336 insertions, 0 deletions
diff --git a/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0001-add-omapdmaifbsink.patch b/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0001-add-omapdmaifbsink.patch
new file mode 100644
index 00000000..bcf0d904
--- /dev/null
+++ b/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0001-add-omapdmaifbsink.patch
@@ -0,0 +1,1336 @@
1diff -uNr ticodecplugin/configure.ac ticodecplugin.new/configure.ac
2--- ticodecplugin/configure.ac 2010-08-24 15:08:58.609410984 -0500
3+++ ticodecplugin.new/configure.ac 2010-09-03 13:54:11.909410298 -0500
4@@ -25,6 +25,7 @@
5 AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
6
7 AM_CONFIG_HEADER(config.h)
8+AM_PROG_AS
9
10 dnl check for tools
11 AC_PROG_CC
12diff -uNr ticodecplugin/src/gstticodecplugin.c ticodecplugin.new/src/gstticodecplugin.c
13--- ticodecplugin/src/gstticodecplugin.c 2010-08-24 15:08:58.609410984 -0500
14+++ ticodecplugin.new/src/gstticodecplugin.c 2010-09-03 13:54:11.929409696 -0500
15@@ -42,6 +42,7 @@
16 #include "gsttiaudenc1.h"
17 #include "gsttividresize.h"
18 #include "gsttidmaiperf.h"
19+#include "omapfb.h"
20
21 #ifdef HAVE_C6ACCEL
22 #include "gsttic6xcolorspace.h"
23@@ -134,6 +135,13 @@
24 return FALSE;
25 #endif
26
27+ env_value = getenv("GST_omapdmaifbsink_DISABLE");
28+
29+ if ((!env_value || strcmp(env_value,"1")) && !gst_element_register(
30+ TICodecPlugin, "omapdmaifbsink", GST_RANK_PRIMARY,
31+ GST_OMAPFB_SINK_TYPE))
32+ return FALSE;
33+
34 return TRUE;
35 }
36
37diff -uNr ticodecplugin/src/Makefile.am ticodecplugin.new/src/Makefile.am
38--- ticodecplugin/src/Makefile.am 2010-08-24 22:01:30.989165985 -0500
39+++ ticodecplugin.new/src/Makefile.am 2010-09-03 13:53:41.037663172 -0500
40@@ -12,16 +12,16 @@
41
42
43 # sources used to compile this plug-in
44-libgstticodecplugin_la_SOURCES = gstticodecplugin.c gsttiauddec1.c gsttividdec2.c gsttiimgenc1.c gsttiimgdec1.c gsttidmaibuffertransport.c gsttidmaibuftab.c gstticircbuffer.c gsttidmaivideosink.c gstticodecs.c gstticodecs_platform.c gsttiquicktime_aac.c gsttiquicktime_h264.c gsttividenc1.c gsttiaudenc1.c gstticommonutils.c gsttividresize.c gsttidmaiperf.c gsttiquicktime_mpeg4.c $(C6ACCEL_SRC)
45+libgstticodecplugin_la_SOURCES = gstticodecplugin.c gsttiauddec1.c gsttividdec2.c gsttiimgenc1.c gsttiimgdec1.c gsttidmaibuffertransport.c gsttidmaibuftab.c gstticircbuffer.c gsttidmaivideosink.c gstticodecs.c gstticodecs_platform.c gsttiquicktime_aac.c gsttiquicktime_h264.c gsttividenc1.c gsttiaudenc1.c gstticommonutils.c gsttividresize.c gsttidmaiperf.c gsttiquicktime_mpeg4.c $(C6ACCEL_SRC) omapfb.c yuv.S
46
47 # flags used to compile this plugin
48 # add other _CFLAGS and _LIBS as needed
49-libgstticodecplugin_la_CFLAGS = $(GST_CFLAGS) $(shell cat $(XDC_CONFIG_BASENAME)/compiler.opt)
50-libgstticodecplugin_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-0.10 -lgstaudio-0.10 -lm
51+libgstticodecplugin_la_CFLAGS = $(GST_CFLAGS) $(shell cat $(XDC_CONFIG_BASENAME)/compiler.opt) -I$(LINUXKERNEL_INSTALL_DIR)/include
52+libgstticodecplugin_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-0.10 -lgstaudio-0.10 -lm -lX11
53 libgstticodecplugin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,$(XDC_CONFIG_BASENAME)/linker.cmd -Wl,$(C6ACCEL_LIB)
54
55 # headers we need but don't want installed
56-noinst_HEADERS = gsttiauddec1.h gsttividdec2.h gsttiimgenc1.h gsttiimgdec1.h gsttidmaibuffertransport.h gsttidmaibuftab.h gstticircbuffer.h gsttidmaivideosink.h gsttithreadprops.h gstticodecs.h gsttiquicktime_aac.h gsttiquicktime_h264.h gsttividenc1.h gsttiaudenc1.h gstticommonutils.h gsttividresize.h gsttiquicktime_mpeg4.h $(C6ACCEL_HEAD)
57+noinst_HEADERS = gsttiauddec1.h gsttividdec2.h gsttiimgenc1.h gsttiimgdec1.h gsttidmaibuffertransport.h gsttidmaibuftab.h gstticircbuffer.h gsttidmaivideosink.h gsttithreadprops.h gstticodecs.h gsttiquicktime_aac.h gsttiquicktime_h264.h gsttividenc1.h gsttiaudenc1.h gstticommonutils.h gsttividresize.h gsttiquicktime_mpeg4.h $(C6ACCEL_HEAD) omapfb.h
58
59 # XDC Configuration
60 CONFIGURO = $(XDC_INSTALL_DIR)/xs xdc.tools.configuro
61diff -uNr ticodecplugin/src/omapfb.c ticodecplugin.new/src/omapfb.c
62--- ticodecplugin/src/omapfb.c 1969-12-31 18:00:00.000000000 -0600
63+++ ticodecplugin.new/src/omapfb.c 2010-09-03 13:54:11.929409696 -0500
64@@ -0,0 +1,1005 @@
65+/*
66+ * Copyright (C) 2008 Felipe Contreras <felipe.contreras@gmail.com>
67+ * Copyright (C) 2009 Tim Yamin <plasm@roo.me.uk>
68+ * Copyright (C) 2009 Brijesh Singh <brijesh.ksingh@gmail.com>
69+ *
70+ * X code largely copied from ximagesink by Julien Moutte and
71+ * vo_omapfb.c by Gregoire Gentil.
72+ *
73+ * Use DMAI hw framecopy module to copy the dmai transport buffers.
74+ *
75+ * This library is free software; you can redistribute it and/or
76+ * modify it under the terms of the GNU Lesser General Public
77+ * License as published by the Free Software Foundation
78+ * version 2.1 of the License.
79+ *
80+ * This library is distributed in the hope that it will be useful,
81+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
82+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
83+ * Lesser General Public License for more details.
84+ *
85+ * You should have received a copy of the GNU General Public License
86+ * along with this program; if not, write to the Free Software
87+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
88+ */
89+
90+#include <fcntl.h>
91+#include <sys/ioctl.h>
92+#include <sys/mman.h>
93+#include <unistd.h>
94+#include <string.h>
95+#include <sys/types.h>
96+#include <malloc.h>
97+#include <stdlib.h>
98+
99+#include "omapfb.h"
100+#include <gst/interfaces/xoverlay.h>
101+
102+static GstVideoSinkClass *parent_class = NULL;
103+
104+extern void yuv420_to_yuv422(__uint8_t *yuv, __uint8_t *y, __uint8_t *u, __uint8_t *v,
105+ int w, int h, int yw, int cw, int dw);
106+
107+static void x11_get_window_abs_position(Display *display, Window window,
108+ int *wx, int *wy, int *ww, int *wh)
109+{
110+ Window root, parent;
111+ Window *child;
112+ unsigned int n_children;
113+ XWindowAttributes attribs;
114+
115+ /* Get window attributes */
116+ XGetWindowAttributes(display, window, &attribs);
117+
118+ /* Get relative position of given window */
119+ *wx = attribs.x;
120+ *wy = attribs.y;
121+ if (ww)
122+ *ww = attribs.width;
123+ if (wh)
124+ *wh = attribs.height;
125+
126+ /* Query window tree information */
127+ XQueryTree(display, window, &root, &parent, &child, &n_children);
128+ if (parent)
129+ {
130+ int x, y;
131+
132+ /* If we have a parent we must go there and discover his position */
133+ x11_get_window_abs_position(display, parent, &x, &y, NULL, NULL);
134+ *wx += x;
135+ *wy += y;
136+ }
137+
138+ /* If we had children, free them */
139+ if(n_children)
140+ XFree(child);
141+}
142+
143+static GstXWindow *
144+gst_omapfbsink_xwindow_new (GstOmapFbSink * omapfbsink, gint width, gint height)
145+{
146+ GstXWindow *xwindow = NULL;
147+ XGCValues values;
148+
149+ if(!omapfbsink->xcontext)
150+ return NULL;
151+
152+ xwindow = g_new0 (GstXWindow, 1);
153+ xwindow->width = width;
154+ xwindow->height = height;
155+ xwindow->internal = TRUE;
156+
157+ g_mutex_lock (omapfbsink->x_lock);
158+ xwindow->win = XCreateSimpleWindow (omapfbsink->xcontext->disp,
159+ omapfbsink->xcontext->root,
160+ 0, 0, xwindow->width, xwindow->height,
161+ 0, 0, omapfbsink->colorKey);
162+
163+ /* We have to do that to prevent X from redrawing the background on
164+ ConfigureNotify. This takes away flickering of video when resizing. */
165+ XSetWindowBackgroundPixmap (omapfbsink->xcontext->disp, xwindow->win, None);
166+
167+ if (omapfbsink->handle_events) {
168+ Atom wm_delete;
169+
170+ XSelectInput (omapfbsink->xcontext->disp, xwindow->win, ExposureMask |
171+ StructureNotifyMask | PointerMotionMask | KeyPressMask |
172+ KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
173+
174+ /* Tell the window manager we'd like delete client messages instead of
175+ * being killed */
176+ wm_delete = XInternAtom (omapfbsink->xcontext->disp,
177+ "WM_DELETE_WINDOW", False);
178+ (void) XSetWMProtocols (omapfbsink->xcontext->disp, xwindow->win,
179+ &wm_delete, 1);
180+ }
181+
182+ xwindow->gc = XCreateGC (omapfbsink->xcontext->disp, xwindow->win,
183+ 0, &values);
184+
185+ XMapRaised (omapfbsink->xcontext->disp, xwindow->win);
186+ XSync (omapfbsink->xcontext->disp, FALSE);
187+
188+ g_mutex_unlock (omapfbsink->x_lock);
189+ gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (omapfbsink), xwindow->win);
190+
191+ return xwindow;
192+}
193+
194+static gboolean gst_omapfbsink_update_plane (GstOmapFbSink *omapfbsink)
195+{
196+ int wx, wy, ww, wh;
197+ if (!omapfbsink->xcontext)
198+ {
199+ if (ioctl (omapfbsink->overlay_fd, OMAPFB_SETUP_PLANE, &omapfbsink->plane_info))
200+ return FALSE;
201+ return TRUE;
202+ }
203+
204+ if (omapfbsink->plane_info.enabled != 1)
205+ return FALSE;
206+
207+ x11_get_window_abs_position(omapfbsink->xcontext->disp,
208+ omapfbsink->xwindow->win, &wx, &wy, &ww, &wh);
209+
210+ if (wx != omapfbsink->xwindow->wx || wy != omapfbsink->xwindow->wy ||
211+ wh != omapfbsink->xwindow->height || ww != omapfbsink->xwindow->width) {
212+ omapfbsink->plane_info.out_width = omapfbsink->xwindow->width = ww;
213+ omapfbsink->plane_info.out_height = omapfbsink->xwindow->height = wh;
214+ omapfbsink->plane_info.pos_x = omapfbsink->xwindow->wx = wx;
215+ omapfbsink->plane_info.pos_y = omapfbsink->xwindow->wy = wy;
216+
217+ GST_DEBUG_OBJECT(omapfbsink, "updating geometry to: (%d,%d) %dx%d", wx, wy, ww, wh);
218+
219+ XSetForeground (omapfbsink->xcontext->disp, omapfbsink->xwindow->gc, omapfbsink->colorKey);
220+ XFillRectangle (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, omapfbsink->xwindow->gc, 0, 0, ww, wh);
221+
222+ if (ioctl (omapfbsink->overlay_fd, OMAPFB_SETUP_PLANE, &omapfbsink->plane_info))
223+ return FALSE;
224+ }
225+
226+ return TRUE;
227+}
228+
229+static void
230+gst_omapfbsink_expose (GstXOverlay * overlay)
231+{
232+ gst_omapfbsink_update_plane(GST_OMAPFB_SINK (overlay));
233+}
234+
235+static void
236+gst_omapfbsink_xwindow_destroy (GstOmapFbSink * omapfbsink,
237+ GstXWindow * xwindow)
238+{
239+ g_return_if_fail (xwindow != NULL);
240+ g_mutex_lock (omapfbsink->x_lock);
241+
242+ /* If we did not create that window we just free the GC and let it live */
243+ if (xwindow->internal)
244+ XDestroyWindow (omapfbsink->xcontext->disp, xwindow->win);
245+ else
246+ XSelectInput (omapfbsink->xcontext->disp, xwindow->win, 0);
247+
248+ XFreeGC (omapfbsink->xcontext->disp, xwindow->gc);
249+ XSync (omapfbsink->xcontext->disp, FALSE);
250+ g_mutex_unlock (omapfbsink->x_lock);
251+ g_free (xwindow);
252+}
253+
254+/* This function handles XEvents that might be in the queue. It generates
255+ GstEvent that will be sent upstream in the pipeline to handle interactivity
256+ and navigation.*/
257+static void
258+gst_omapfbsink_handle_xevents (GstOmapFbSink * omapfbsink)
259+{
260+ XEvent e;
261+ g_mutex_lock (omapfbsink->flow_lock);
262+ g_mutex_lock (omapfbsink->x_lock);
263+
264+ while (XCheckWindowEvent (omapfbsink->xcontext->disp,
265+ omapfbsink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) {
266+ switch (e.type) {
267+ case Expose:
268+ case ConfigureNotify:
269+ gst_omapfbsink_update_plane (omapfbsink);
270+ break;
271+ default:
272+ break;
273+ }
274+ }
275+
276+ /* Handle Display events */
277+ while (XPending (omapfbsink->xcontext->disp)) {
278+ XNextEvent (omapfbsink->xcontext->disp, &e);
279+
280+ switch (e.type) {
281+ case ClientMessage:{
282+ Atom wm_delete;
283+
284+ wm_delete = XInternAtom (omapfbsink->xcontext->disp,
285+ "WM_DELETE_WINDOW", False);
286+ if (wm_delete == (Atom) e.xclient.data.l[0]) {
287+ /* Handle window deletion by posting an error on the bus */
288+ GST_ELEMENT_ERROR (omapfbsink, RESOURCE, NOT_FOUND,
289+ ("Output window was closed"), (NULL));
290+
291+ g_mutex_unlock (omapfbsink->x_lock);
292+ gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow);
293+ omapfbsink->xwindow = NULL;
294+ g_mutex_lock (omapfbsink->x_lock);
295+ }
296+ break;
297+ }
298+ default:
299+ break;
300+ }
301+ }
302+
303+ g_mutex_unlock (omapfbsink->x_lock);
304+ g_mutex_unlock (omapfbsink->flow_lock);
305+}
306+
307+static gpointer
308+gst_omapfbsink_event_thread (GstOmapFbSink * omapfbsink)
309+{
310+ GST_OBJECT_LOCK (omapfbsink);
311+ while (omapfbsink->running) {
312+ GST_OBJECT_UNLOCK (omapfbsink);
313+
314+ if (omapfbsink->xwindow)
315+ gst_omapfbsink_handle_xevents (omapfbsink);
316+ g_usleep (100000);
317+
318+ GST_OBJECT_LOCK (omapfbsink);
319+ }
320+ GST_OBJECT_UNLOCK (omapfbsink);
321+
322+ return NULL;
323+}
324+
325+/* This function gets the X Display and global info about it. Everything is
326+ stored in our object and will be cleaned when the object is disposed. */
327+static GstXContext *
328+gst_omapfbsink_xcontext_get (GstOmapFbSink * omapfbsink)
329+{
330+ GstXContext *xcontext = g_new0 (GstXContext, 1);
331+ g_mutex_lock (omapfbsink->x_lock);
332+
333+ xcontext->disp = XOpenDisplay (omapfbsink->display_name);
334+
335+ if (!xcontext->disp) {
336+ g_mutex_unlock (omapfbsink->x_lock);
337+ g_free (xcontext);
338+ GST_ELEMENT_WARNING (omapfbsink, RESOURCE, WRITE,
339+ ("Could not initialise X output"),
340+ ("Could not open display"));
341+ return NULL;
342+ }
343+
344+ xcontext->screen = DefaultScreenOfDisplay (xcontext->disp);
345+ xcontext->screen_num = DefaultScreen (xcontext->disp);
346+ xcontext->visual = DefaultVisual (xcontext->disp, xcontext->screen_num);
347+ xcontext->root = DefaultRootWindow (xcontext->disp);
348+
349+ xcontext->width = DisplayWidth (xcontext->disp, xcontext->screen_num);
350+ xcontext->height = DisplayHeight (xcontext->disp, xcontext->screen_num);
351+
352+ g_mutex_unlock (omapfbsink->x_lock);
353+
354+ /* Setup our event listening thread */
355+ GST_OBJECT_LOCK (omapfbsink);
356+ omapfbsink->running = TRUE;
357+ omapfbsink->event_thread = g_thread_create (
358+ (GThreadFunc) gst_omapfbsink_event_thread, omapfbsink, TRUE, NULL);
359+ GST_OBJECT_UNLOCK (omapfbsink);
360+
361+ return xcontext;
362+}
363+
364+static void
365+gst_omapfbsink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
366+{
367+ GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK (overlay);
368+ GstXWindow *xwindow = NULL;
369+ XWindowAttributes attr;
370+
371+ /* If we already use that window, return */
372+ if (omapfbsink->xwindow && (xwindow_id == omapfbsink->xwindow->win))
373+ return;
374+
375+ /* If the element has not initialized the X11 context try to do so */
376+ if (!omapfbsink->xcontext &&
377+ !(omapfbsink->xcontext = gst_omapfbsink_xcontext_get (omapfbsink))) {
378+ g_mutex_unlock (omapfbsink->flow_lock);
379+ return;
380+ }
381+
382+ /* If a window is there already we destroy it */
383+ if (omapfbsink->xwindow) {
384+ gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow);
385+ omapfbsink->xwindow = NULL;
386+ }
387+
388+ /* If the xid is 0 we go back to an internal window */
389+ if (xwindow_id == 0) {
390+ /* If no width/height caps nego did not happen window will be created
391+ during caps nego then */
392+ if (GST_VIDEO_SINK_WIDTH (omapfbsink) && GST_VIDEO_SINK_HEIGHT (omapfbsink)) {
393+ xwindow = gst_omapfbsink_xwindow_new (omapfbsink,
394+ GST_VIDEO_SINK_WIDTH (omapfbsink),
395+ GST_VIDEO_SINK_HEIGHT (omapfbsink));
396+ }
397+ } else {
398+ xwindow = g_new0 (GstXWindow, 1);
399+ xwindow->wx = xwindow->wy = -1;
400+ xwindow->win = xwindow_id;
401+
402+ /* We get window geometry, set the event we want to receive,
403+ and create a GC */
404+ g_mutex_lock (omapfbsink->x_lock);
405+ XGetWindowAttributes (omapfbsink->xcontext->disp, xwindow->win, &attr);
406+ xwindow->width = attr.width;
407+ xwindow->height = attr.height;
408+ xwindow->internal = FALSE;
409+ if (omapfbsink->handle_events) {
410+ XSelectInput (omapfbsink->xcontext->disp, xwindow->win, ExposureMask |
411+ StructureNotifyMask | PointerMotionMask | KeyPressMask |
412+ KeyReleaseMask);
413+ }
414+
415+ xwindow->gc = XCreateGC (omapfbsink->xcontext->disp, xwindow->win, 0, NULL);
416+ g_mutex_unlock (omapfbsink->x_lock);
417+ }
418+
419+ if (xwindow) {
420+ omapfbsink->xwindow = xwindow;
421+
422+ g_mutex_lock (omapfbsink->x_lock);
423+ gst_omapfbsink_update_plane(omapfbsink);
424+ g_mutex_unlock (omapfbsink->x_lock);
425+ }
426+}
427+
428+static void
429+gst_omapfbsink_xwindow_clear (GstOmapFbSink * omapfbsink,
430+ GstXWindow * xwindow)
431+{
432+ g_return_if_fail (xwindow != NULL);
433+ g_mutex_lock (omapfbsink->x_lock);
434+
435+ XSetForeground (omapfbsink->xcontext->disp, xwindow->gc,
436+ XBlackPixel (omapfbsink->xcontext->disp,
437+ omapfbsink->xcontext->screen_num));
438+
439+ XFillRectangle (omapfbsink->xcontext->disp, xwindow->win, xwindow->gc,
440+ 0, 0, xwindow->width, xwindow->height);
441+
442+ XSync (omapfbsink->xcontext->disp, FALSE);
443+ g_mutex_unlock (omapfbsink->x_lock);
444+}
445+
446+static void
447+gst_omapfbsink_set_event_handling (GstXOverlay * overlay,
448+ gboolean handle_events)
449+{
450+ GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK (overlay);
451+ omapfbsink->handle_events = handle_events;
452+
453+ g_mutex_lock (omapfbsink->flow_lock);
454+
455+ if (G_UNLIKELY (!omapfbsink->xwindow)) {
456+ g_mutex_unlock (omapfbsink->flow_lock);
457+ return;
458+ }
459+
460+ g_mutex_lock (omapfbsink->x_lock);
461+
462+ if (handle_events) {
463+ if (omapfbsink->xwindow->internal) {
464+ XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win,
465+ ExposureMask | StructureNotifyMask | PointerMotionMask |
466+ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
467+ } else {
468+ XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win,
469+ ExposureMask | StructureNotifyMask | PointerMotionMask |
470+ KeyPressMask | KeyReleaseMask);
471+ }
472+ } else {
473+ XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, 0);
474+ }
475+
476+ g_mutex_unlock (omapfbsink->x_lock);
477+ g_mutex_unlock (omapfbsink->flow_lock);
478+}
479+
480+static void
481+gst_omapfbsink_xoverlay_init (GstXOverlayClass * iface)
482+{
483+ iface->set_xwindow_id = gst_omapfbsink_set_xwindow_id;
484+ iface->expose = gst_omapfbsink_expose;
485+ iface->handle_events = gst_omapfbsink_set_event_handling;
486+}
487+
488+static GstCaps *
489+generate_sink_template (void)
490+{
491+ GstCaps *caps;
492+ GstStructure *struc;
493+
494+ caps = gst_caps_new_empty ();
495+
496+ struc = gst_structure_new ("video/x-raw-yuv",
497+ "width", GST_TYPE_INT_RANGE, 16, 4096,
498+ "height", GST_TYPE_INT_RANGE, 16, 4096,
499+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30, 1,
500+ NULL);
501+
502+ {
503+ GValue list;
504+ GValue val;
505+
506+ list.g_type = val.g_type = 0;
507+
508+ g_value_init (&list, GST_TYPE_LIST);
509+ g_value_init (&val, GST_TYPE_FOURCC);
510+
511+#if 0
512+ gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'));
513+ gst_value_list_append_value (&list, &val);
514+#else
515+ gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('I', '4', '2', '0'));
516+ gst_value_list_append_value (&list, &val);
517+
518+ gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'));
519+ gst_value_list_append_value (&list, &val);
520+#endif
521+
522+ gst_structure_set_value (struc, "format", &list);
523+
524+ g_value_unset (&val);
525+ g_value_unset (&list);
526+ }
527+
528+ gst_caps_append_structure (caps, struc);
529+
530+ return caps;
531+}
532+
533+static GstFlowReturn
534+buffer_alloc (GstBaseSink *bsink,
535+ guint64 offset,
536+ guint size,
537+ GstCaps *caps,
538+ GstBuffer **buf)
539+{
540+ GstOmapFbSink *self;
541+ GstBuffer *buffer = NULL;
542+ GstFlowReturn ret = GST_FLOW_OK;
543+ self = GST_OMAPFB_SINK (bsink);
544+
545+ if(self->row_skip) {
546+ buffer = gst_buffer_new ();
547+ GST_BUFFER_DATA (buffer) = self->buffer = self->framebuffer;
548+ GST_BUFFER_SIZE (buffer) = self->buffer_size = size;
549+ gst_buffer_set_caps (buffer, caps);
550+ } else {
551+ if(self->buffer && size == self->buffer_size) {
552+ buffer = gst_buffer_new ();
553+ GST_BUFFER_DATA (buffer) = self->buffer;
554+ GST_BUFFER_SIZE (buffer) = size;
555+ gst_buffer_set_caps (buffer, caps);
556+ } else {
557+ if(self->buffer)
558+ free(self->buffer);
559+ if(posix_memalign(&self->buffer, 16, (size_t) size) == 0) {
560+ buffer = gst_buffer_new ();
561+ GST_BUFFER_DATA (buffer) = self->buffer;
562+ GST_BUFFER_SIZE (buffer) = self->buffer_size = size;
563+ gst_buffer_set_caps (buffer, caps);
564+ } else {
565+ GST_ELEMENT_ERROR (self, RESOURCE, WRITE, ("Could not allocate aligned buf!"),
566+ ("Could not alloc aligned buf!"));
567+ }
568+ }
569+ }
570+
571+ *buf = buffer;
572+ return ret;
573+}
574+
575+static void
576+x_memcpy (GstOmapFbSink *omapfbsink, __uint8_t *outBuf, __uint8_t *inBuf)
577+{
578+ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;
579+ Buffer_Handle hInBuf = NULL, hOutBuf = NULL;
580+ Framecopy_Attrs fcAttrs = Framecopy_Attrs_DEFAULT;
581+ int size;
582+
583+ if (omapfbsink->hFc == NULL) {
584+ fcAttrs.accel = TRUE;
585+ omapfbsink->hFc = Framecopy_create(&fcAttrs);
586+ if (omapfbsink->hFc == NULL) {
587+ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to create dmai framecopy handle"), ("failed to create dmai framecopy handle"));
588+ goto cleanup;
589+ }
590+ }
591+
592+ gfxAttrs.bAttrs.reference = TRUE;
593+ gfxAttrs.dim.width = GST_VIDEO_SINK_WIDTH (omapfbsink);
594+ gfxAttrs.dim.height = GST_VIDEO_SINK_HEIGHT (omapfbsink);
595+ gfxAttrs.colorSpace = ColorSpace_UYVY;
596+ gfxAttrs.dim.lineLength = omapfbsink->fixinfo.line_length;
597+ size = gfxAttrs.dim.height * gfxAttrs.dim.width * 2;
598+
599+ hInBuf = Buffer_create(size, BufferGfx_getBufferAttrs(&gfxAttrs));
600+ if (hInBuf == NULL) {
601+ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("Could not allocate refer dmai buffer"), ("Could not allocate refer dmai buffer"));
602+ goto cleanup;
603+ }
604+ Buffer_setUserPtr(hInBuf, (Int8*) inBuf);
605+ Buffer_setNumBytesUsed(hInBuf,Buffer_getSize(hInBuf));
606+
607+ hOutBuf = Buffer_create(size, BufferGfx_getBufferAttrs(&gfxAttrs));
608+ if (hOutBuf == NULL) {
609+ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("Could not allocate refer dmai buffer"), ("Could not allocate refer dmai buffer"));
610+ goto cleanup;
611+ }
612+ Buffer_setUserPtr(hOutBuf, (Int8*) outBuf);
613+ Buffer_setNumBytesUsed(hOutBuf,Buffer_getSize(hOutBuf));
614+
615+
616+ if (Framecopy_config(omapfbsink->hFc, hInBuf, hOutBuf) < 0) {
617+ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to configure dmai framecopy handle"), ("failed to configure dmai framecopy handle"));
618+ goto cleanup;
619+ }
620+
621+ if (Framecopy_execute(omapfbsink->hFc, hInBuf, hOutBuf) < 0) {
622+ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to execute dmai framecopy handle"), ("failed to configure dmai framecopy handle"));
623+ goto cleanup;
624+ }
625+ cleanup:
626+
627+ if (hInBuf)
628+ Buffer_delete(hInBuf);
629+ if (hOutBuf)
630+ Buffer_delete(hOutBuf);
631+}
632+
633+static GstFlowReturn
634+render (GstBaseSink * bsink, GstBuffer * buf)
635+{
636+ int i, w, h;
637+ GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK(bsink);
638+ __uint8_t *fb = omapfbsink->framebuffer, *data = GST_BUFFER_DATA(buf);
639+ gboolean useXcopy = FALSE;
640+
641+ if (GST_IS_TIDMAIBUFFERTRANSPORT(buf)) {
642+ GST_LOG("found dmai transport buffer, enabling hw framecopy.\n");
643+ useXcopy = TRUE;
644+ }
645+
646+ if(omapfbsink->plane_info.enabled == 2)
647+ {
648+ omapfbsink->plane_info.enabled = 1;
649+
650+ g_mutex_lock (omapfbsink->x_lock);
651+ gst_omapfbsink_update_plane(omapfbsink);
652+ g_mutex_unlock (omapfbsink->x_lock);
653+ }
654+
655+ /* If a buffer which wasn't supplied by us is given to us to render with,
656+ we need to copy to our buffer first so that memory alignment constraints
657+ are met. */
658+ if((data != omapfbsink->buffer && GST_BUFFER_SIZE(buf) <= omapfbsink->buffer_size) && !useXcopy)
659+ {
660+ memcpy(omapfbsink->buffer, data, GST_BUFFER_SIZE(buf));
661+ data = omapfbsink->buffer;
662+ }
663+
664+ /* buffer_alloc gave a direct buffer, so we have nothing to
665+ do here... */
666+ if(omapfbsink->row_skip)
667+ return GST_FLOW_OK;
668+
669+ switch(omapfbsink->image_format) {
670+ case GST_MAKE_FOURCC('I', '4', '2', '0'):
671+ /* Convert to YUV422 and send to FB */
672+
673+ h = GST_VIDEO_SINK_HEIGHT (omapfbsink);
674+ w = GST_VIDEO_SINK_WIDTH (omapfbsink);
675+
676+ __uint8_t *y, *u, *v;
677+ y = data;
678+ u = y + w * h;
679+ v = u + w / 2 * h / 2;
680+ yuv420_to_yuv422(fb, y, u, v, w & ~15, h, w, w / 2, omapfbsink->fixinfo.line_length);
681+ break;
682+
683+ case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
684+ /* Send to FB, taking into account line_length */
685+ if (useXcopy) {
686+ x_memcpy(omapfbsink, fb, data);
687+ }
688+ else {
689+
690+ w = 2 * GST_VIDEO_SINK_WIDTH (omapfbsink);
691+ for(i = 0; i < GST_VIDEO_SINK_HEIGHT (omapfbsink); i++)
692+ {
693+ memcpy(fb, data, w);
694+
695+ fb += omapfbsink->fixinfo.line_length;
696+ data += w;
697+ }
698+ }
699+ break;
700+ }
701+
702+ return GST_FLOW_OK;
703+}
704+
705+static gboolean
706+setcaps (GstBaseSink *bsink,
707+ GstCaps *vscapslist)
708+{
709+ GstOmapFbSink *self;
710+ GstStructure *structure;
711+
712+ gint width, height;
713+ struct omapfb_color_key color_key;
714+
715+ self = GST_OMAPFB_SINK (bsink);
716+
717+ structure = gst_caps_get_structure (vscapslist, 0);
718+
719+ gst_structure_get_int (structure, "width", &width);
720+ gst_structure_get_int (structure, "height", &height);
721+
722+ self->overlay_info.xres = MIN (self->varinfo.xres, width) & ~15;
723+ self->overlay_info.yres = MIN (self->varinfo.yres, height) & ~15;
724+ self->overlay_info.xres_virtual = self->overlay_info.xres;
725+ self->overlay_info.yres_virtual = self->overlay_info.yres;
726+
727+ self->overlay_info.xoffset = 0;
728+ self->overlay_info.yoffset = 0;
729+
730+ gst_structure_get_fourcc (structure, "format", &self->image_format);
731+ switch(self->image_format) {
732+ case GST_MAKE_FOURCC('I', '4', '2', '0'):
733+ self->row_skip = FALSE; /* Colorspace conversion required */
734+ self->overlay_info.nonstd = OMAPFB_COLOR_YUY422;
735+ break;
736+ case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
737+ /* Can data be pushed straight to the FB or do we need to interleave? */
738+ if (self->fixinfo.line_length != 2 * width)
739+ self->row_skip = FALSE;
740+ else
741+ self->row_skip = TRUE;
742+ self->overlay_info.nonstd = OMAPFB_COLOR_YUV422;
743+ break;
744+ }
745+
746+ if (ioctl (self->overlay_fd, FBIOPUT_VSCREENINFO, &self->overlay_info))
747+ return FALSE;
748+
749+ GST_VIDEO_SINK_WIDTH (self) = width;
750+ GST_VIDEO_SINK_HEIGHT (self) = height;
751+ if (!self->xwindow) {
752+ self->xwindow = gst_omapfbsink_xwindow_new (self,
753+ GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self));
754+ }
755+
756+ color_key.channel_out = OMAPFB_CHANNEL_OUT_LCD;
757+ color_key.background = 0x0;
758+ color_key.trans_key = self->colorKey;
759+ if (self->xwindow)
760+ color_key.key_type = OMAPFB_COLOR_KEY_GFX_DST;
761+ else
762+ color_key.key_type = OMAPFB_COLOR_KEY_DISABLED;
763+
764+ if (ioctl (self->overlay_fd, OMAPFB_SET_COLOR_KEY, &color_key))
765+ return FALSE;
766+
767+ self->plane_info.pos_x = 0;
768+ self->plane_info.pos_y = 0;
769+ self->plane_info.out_width = self->overlay_info.xres;
770+ self->plane_info.out_height = self->overlay_info.yres;
771+ self->plane_info.enabled = 2;
772+
773+ if (ioctl (self->overlay_fd, FBIOGET_FSCREENINFO, &self->fixinfo))
774+ return FALSE;
775+
776+ self->enabled = TRUE;
777+ return TRUE;
778+}
779+
780+static gboolean
781+start (GstBaseSink *bsink)
782+{
783+ GstOmapFbSink *self;
784+ int fd;
785+
786+ self = GST_OMAPFB_SINK (bsink);
787+
788+ fd = open ("/dev/fb0", O_RDWR);
789+
790+ if (fd == -1)
791+ return FALSE;
792+
793+ if (ioctl (fd, FBIOGET_VSCREENINFO, &self->varinfo))
794+ {
795+ close (fd);
796+ return FALSE;
797+ }
798+
799+ if (close (fd))
800+ return FALSE;
801+
802+ self->overlay_fd = open ("/dev/fb1", O_RDWR);
803+
804+ if (self->overlay_fd == -1)
805+ return FALSE;
806+
807+ if (ioctl (self->overlay_fd, FBIOGET_VSCREENINFO, &self->overlay_info))
808+ return FALSE;
809+
810+ if (ioctl (self->overlay_fd, OMAPFB_QUERY_PLANE, &self->plane_info))
811+ return FALSE;
812+
813+ if (ioctl (self->overlay_fd, OMAPFB_QUERY_MEM, &self->mem_info))
814+ return FALSE;
815+
816+ self->framebuffer = mmap (NULL, self->mem_info.size, PROT_WRITE, MAP_SHARED, self->overlay_fd, 0);
817+ if (self->framebuffer == MAP_FAILED)
818+ return FALSE;
819+
820+ return TRUE;
821+}
822+
823+static gboolean
824+stop (GstBaseSink *bsink)
825+{
826+ GstOmapFbSink *self;
827+
828+ self = GST_OMAPFB_SINK (bsink);
829+
830+ if (self->enabled)
831+ {
832+ self->plane_info.enabled = 0;
833+
834+ if (ioctl (self->overlay_fd, OMAPFB_SETUP_PLANE, &self->plane_info))
835+ return FALSE;
836+ }
837+
838+ if (munmap (self->framebuffer, self->mem_info.size))
839+ return FALSE;
840+
841+ if (close (self->overlay_fd))
842+ return FALSE;
843+
844+ if (self->hFc)
845+ Framecopy_delete(self->hFc);
846+
847+ return TRUE;
848+}
849+
850+/* This function cleans the X context. Closing the Display and unrefing the
851+ caps for supported formats. */
852+static void
853+gst_omapfbsink_xcontext_clear (GstOmapFbSink * omapfbsink)
854+{
855+ GstXContext *xcontext;
856+ GST_OBJECT_LOCK (omapfbsink);
857+ if (omapfbsink->xcontext == NULL) {
858+ GST_OBJECT_UNLOCK (omapfbsink);
859+ return;
860+ }
861+
862+ xcontext = omapfbsink->xcontext;
863+ omapfbsink->xcontext = NULL;
864+
865+ GST_OBJECT_UNLOCK (omapfbsink);
866+ g_mutex_lock (omapfbsink->x_lock);
867+
868+ XCloseDisplay (xcontext->disp);
869+ g_mutex_unlock (omapfbsink->x_lock);
870+ g_free (xcontext);
871+}
872+
873+static void
874+gst_omapfbsink_reset (GstOmapFbSink *omapfbsink)
875+{
876+ GThread *thread;
877+
878+ GST_OBJECT_LOCK (omapfbsink);
879+ omapfbsink->running = FALSE;
880+ /* grab thread and mark it as NULL */
881+ thread = omapfbsink->event_thread;
882+ omapfbsink->event_thread = NULL;
883+ GST_OBJECT_UNLOCK (omapfbsink);
884+
885+ /* Wait for our event thread to finish before we clean up our stuff. */
886+ if (thread)
887+ g_thread_join (thread);
888+
889+ g_mutex_lock (omapfbsink->flow_lock);
890+ if (omapfbsink->xwindow) {
891+ gst_omapfbsink_xwindow_clear (omapfbsink, omapfbsink->xwindow);
892+ gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow);
893+ omapfbsink->xwindow = NULL;
894+ }
895+ g_mutex_unlock (omapfbsink->flow_lock);
896+ gst_omapfbsink_xcontext_clear (omapfbsink);
897+}
898+
899+static GstStateChangeReturn
900+gst_omapfbsink_change_state (GstElement * element, GstStateChange transition)
901+{
902+ GstOmapFbSink *omapfbsink;
903+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
904+ GstXContext *xcontext = NULL;
905+
906+ omapfbsink = GST_OMAPFB_SINK (element);
907+
908+ switch (transition) {
909+ case GST_STATE_CHANGE_NULL_TO_READY:
910+
911+ /* Initializing the XContext */
912+ if (omapfbsink->xcontext == NULL) {
913+ xcontext = gst_omapfbsink_xcontext_get (omapfbsink);
914+
915+ GST_OBJECT_LOCK (omapfbsink);
916+ omapfbsink->xcontext = xcontext;
917+ GST_OBJECT_UNLOCK (omapfbsink);
918+ }
919+ break;
920+ case GST_STATE_CHANGE_READY_TO_PAUSED:
921+ g_mutex_lock (omapfbsink->flow_lock);
922+ if (omapfbsink->xwindow)
923+ gst_omapfbsink_xwindow_clear (omapfbsink, omapfbsink->xwindow);
924+ g_mutex_unlock (omapfbsink->flow_lock);
925+ break;
926+ case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
927+ break;
928+ default:
929+ break;
930+ }
931+
932+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
933+
934+ switch (transition) {
935+ case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
936+ break;
937+ case GST_STATE_CHANGE_PAUSED_TO_READY:
938+ GST_VIDEO_SINK_WIDTH (omapfbsink) = 0;
939+ GST_VIDEO_SINK_HEIGHT (omapfbsink) = 0;
940+ break;
941+ case GST_STATE_CHANGE_READY_TO_NULL:
942+ gst_omapfbsink_reset (omapfbsink);
943+ break;
944+ default:
945+ break;
946+ }
947+
948+ return ret;
949+}
950+
951+static void
952+type_class_init (gpointer g_class,
953+ gpointer class_data)
954+{
955+ GstElementClass *element_class;
956+ GstBaseSinkClass *base_sink_class;
957+
958+ element_class = (GstElementClass *) g_class;
959+ base_sink_class = (GstBaseSinkClass *) g_class;
960+
961+ parent_class = g_type_class_peek_parent (g_class);
962+
963+ base_sink_class->set_caps = GST_DEBUG_FUNCPTR (setcaps);
964+ base_sink_class->buffer_alloc = GST_DEBUG_FUNCPTR (buffer_alloc);
965+ base_sink_class->render = GST_DEBUG_FUNCPTR (render);
966+ base_sink_class->start = GST_DEBUG_FUNCPTR (start);
967+ base_sink_class->stop = GST_DEBUG_FUNCPTR (stop);
968+
969+ element_class->change_state = gst_omapfbsink_change_state;
970+}
971+
972+static void
973+type_base_init (gpointer g_class)
974+{
975+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
976+
977+ {
978+ GstElementDetails details;
979+
980+ details.longname = "Linux OMAP framebuffer sink";
981+ details.klass = "Sink/Video";
982+ details.description = "Renders video with omapfb";
983+ details.author = "Felipe Contreras";
984+
985+ gst_element_class_set_details (element_class, &details);
986+ }
987+
988+ {
989+ GstPadTemplate *template;
990+
991+ template = gst_pad_template_new ("sink", GST_PAD_SINK,
992+ GST_PAD_ALWAYS,
993+ generate_sink_template ());
994+
995+ gst_element_class_add_pad_template (element_class, template);
996+ }
997+}
998+
999+static gboolean
1000+gst_omapfbsink_interface_supported (GstImplementsInterface * iface, GType type)
1001+{
1002+ g_assert (type == GST_TYPE_X_OVERLAY);
1003+ return TRUE;
1004+}
1005+
1006+static void
1007+gst_omapfbsink_interface_init (GstImplementsInterfaceClass * klass)
1008+{
1009+ klass->supported = gst_omapfbsink_interface_supported;
1010+}
1011+
1012+static void
1013+gst_omapfbsink_init (GstOmapFbSink * omapfbsink)
1014+{
1015+ omapfbsink->display_name = NULL;
1016+ omapfbsink->xcontext = NULL;
1017+ omapfbsink->xwindow = NULL;
1018+
1019+ omapfbsink->event_thread = NULL;
1020+ omapfbsink->running = FALSE;
1021+
1022+ omapfbsink->x_lock = g_mutex_new ();
1023+ omapfbsink->flow_lock = g_mutex_new ();
1024+
1025+ omapfbsink->handle_events = TRUE;
1026+ omapfbsink->colorKey = 0xff0;
1027+
1028+ omapfbsink->plane_info.enabled = 0;
1029+ omapfbsink->row_skip = FALSE;
1030+
1031+ omapfbsink->buffer = NULL;
1032+ omapfbsink->buffer_size = 0;
1033+ omapfbsink->hFc = NULL;
1034+}
1035+
1036+GType
1037+gst_omapfbsink_get_type (void)
1038+{
1039+ static GType type = 0;
1040+
1041+ if (G_UNLIKELY (type == 0))
1042+ {
1043+ GTypeInfo *type_info;
1044+ static const GInterfaceInfo iface_info = {
1045+ (GInterfaceInitFunc) gst_omapfbsink_interface_init,
1046+ NULL,
1047+ NULL,
1048+ };
1049+ static const GInterfaceInfo overlay_info = {
1050+ (GInterfaceInitFunc) gst_omapfbsink_xoverlay_init,
1051+ NULL,
1052+ NULL,
1053+ };
1054+ type_info = g_new0 (GTypeInfo, 1);
1055+ type_info->class_size = sizeof (GstOmapFbSinkClass);
1056+ type_info->base_init = type_base_init;
1057+ type_info->class_init = type_class_init;
1058+ type_info->instance_size = sizeof (GstOmapFbSink);
1059+ type_info->instance_init = (GInstanceInitFunc) gst_omapfbsink_init;
1060+
1061+ type = g_type_register_static (GST_TYPE_BASE_SINK, "GstOmapFbSink", type_info, 0);
1062+ g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info);
1063+ g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &overlay_info);
1064+
1065+ g_free (type_info);
1066+ }
1067+
1068+ return type;
1069+}
1070diff -uNr ticodecplugin/src/omapfb.h ticodecplugin.new/src/omapfb.h
1071--- ticodecplugin/src/omapfb.h 1969-12-31 18:00:00.000000000 -0600
1072+++ ticodecplugin.new/src/omapfb.h 2010-09-03 13:54:11.929409696 -0500
1073@@ -0,0 +1,142 @@
1074+/*
1075+ * Copyright (C) 2008 Felipe Contreras <felipe.contreras@gmail.com>
1076+ *
1077+ * This library is free software; you can redistribute it and/or
1078+ * modify it under the terms of the GNU Lesser General Public
1079+ * License as published by the Free Software Foundation
1080+ * version 2.1 of the License.
1081+ *
1082+ * This library is distributed in the hope that it will be useful,
1083+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1084+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1085+ * Lesser General Public License for more details.
1086+ *
1087+ * You should have received a copy of the GNU General Public License
1088+ * along with this program; if not, write to the Free Software
1089+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
1090+ */
1091+
1092+#ifndef GST_OMAPFB_H
1093+#define GST_OMAPFB_H
1094+
1095+#include <ti/sdo/dmai/BufferGfx.h>
1096+#include <ti/sdo/dmai/Framecopy.h>
1097+
1098+#include "gsttidmaibuffertransport.h"
1099+#include <gst/gst.h>
1100+#include <gst/video/gstvideosink.h>
1101+#include <gst/video/video.h>
1102+
1103+#include <X11/Xlib.h>
1104+#include <X11/Xutil.h>
1105+
1106+#include <linux/fb.h>
1107+#include <linux/omapfb.h>
1108+
1109+
1110+G_BEGIN_DECLS
1111+
1112+#define GST_OMAPFB_SINK_TYPE (gst_omapfbsink_get_type ())
1113+#define GST_OMAPFB_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_OMAPFB_SINK_TYPE, GstOmapFbSink))
1114+
1115+typedef struct GstXContext GstXContext;
1116+typedef struct GstXWindow GstXWindow;
1117+typedef struct GstOmapFbSink GstOmapFbSink;
1118+typedef struct GstOmapFbSinkClass GstOmapFbSinkClass;
1119+
1120+/**
1121+ * GstXWindow:
1122+ * @win: the Window ID of this X11 window
1123+ * @width: the width in pixels of Window @win
1124+ * @height: the height in pixels of Window @win
1125+ * @internal: used to remember if Window @win was created internally or passed
1126+ * through the #GstXOverlay interface
1127+ * @gc: the Graphical Context of Window @win
1128+ *
1129+ * Structure used to store informations about a Window.
1130+ */
1131+struct GstXWindow {
1132+ Window win;
1133+ gint width, height;
1134+ gboolean internal;
1135+ GC gc;
1136+
1137+ gint wx, wy;
1138+};
1139+
1140+/**
1141+ * GstXContext:
1142+ * @disp: the X11 Display of this context
1143+ * @screen: the default Screen of Display @disp
1144+ * @screen_num: the Screen number of @screen
1145+ * @visual: the default Visual of Screen @screen
1146+ * @root: the root Window of Display @disp
1147+ * @white: the value of a white pixel on Screen @screen
1148+ * @black: the value of a black pixel on Screen @screen
1149+ * @depth: the color depth of Display @disp
1150+ * @bpp: the number of bits per pixel on Display @disp
1151+ * @endianness: the endianness of image bytes on Display @disp
1152+ * @width: the width in pixels of Display @disp
1153+ * @height: the height in pixels of Display @disp
1154+ *
1155+ * Structure used to store various informations collected/calculated for a
1156+ * Display.
1157+ */
1158+struct GstXContext {
1159+ Display *disp;
1160+ Screen *screen;
1161+ gint screen_num;
1162+
1163+ Visual *visual;
1164+ Window root;
1165+
1166+ gint depth;
1167+ gint bpp;
1168+
1169+ gint width, height;
1170+};
1171+
1172+struct GstOmapFbSink
1173+{
1174+ GstVideoSink videosink;
1175+
1176+ struct fb_fix_screeninfo fixinfo;
1177+ struct fb_var_screeninfo varinfo;
1178+ struct fb_var_screeninfo overlay_info;
1179+ struct omapfb_mem_info mem_info;
1180+ struct omapfb_plane_info plane_info;
1181+
1182+ int overlay_fd;
1183+ unsigned char *framebuffer;
1184+ gboolean enabled;
1185+
1186+ GMutex *x_lock;
1187+ GMutex *flow_lock;
1188+
1189+ GstXContext *xcontext;
1190+ GstXWindow *xwindow;
1191+
1192+ gulong colorKey;
1193+ char *display_name;
1194+ GThread *event_thread;
1195+
1196+ void *buffer;
1197+ guint buffer_size;
1198+ guint image_format;
1199+
1200+ gboolean row_skip;
1201+ gboolean handle_events;
1202+ gboolean running;
1203+ Framecopy_Handle hFc;
1204+};
1205+
1206+struct GstOmapFbSinkClass
1207+{
1208+ GstBaseSinkClass parent_class;
1209+};
1210+
1211+GType gst_omapfbsink_get_type (void);
1212+
1213+G_END_DECLS
1214+
1215+#endif /* GST_OMAPFB_H */
1216diff -uNr ticodecplugin/src/yuv.S ticodecplugin.new/src/yuv.S
1217--- ticodecplugin/src/yuv.S 1969-12-31 18:00:00.000000000 -0600
1218+++ ticodecplugin.new/src/yuv.S 2010-09-03 13:54:11.929409696 -0500
1219@@ -0,0 +1,117 @@
1220+/*
1221+ Copyright (C) 2008 Mans Rullgard
1222+
1223+ Permission is hereby granted, free of charge, to any person
1224+ obtaining a copy of this software and associated documentation
1225+ files (the "Software"), to deal in the Software without
1226+ restriction, including without limitation the rights to use, copy,
1227+ modify, merge, publish, distribute, sublicense, and/or sell copies
1228+ of the Software, and to permit persons to whom the Software is
1229+ furnished to do so, subject to the following conditions:
1230+
1231+ The above copyright notice and this permission notice shall be
1232+ included in all copies or substantial portions of the Software.
1233+
1234+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1235+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1236+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1237+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1238+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1239+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1240+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1241+ DEALINGS IN THE SOFTWARE.
1242+*/
1243+
1244+ .fpu neon
1245+ .text
1246+
1247+@ yuv420_to_yuv422(uint8_t *yuv, uint8_t *y, uint8_t *u, uint8_t *v,
1248+@ int w, int h, int yw, int cw, int dw)
1249+
1250+#define yuv r0
1251+#define y r1
1252+#define u r2
1253+#define v r3
1254+#define w r4
1255+#define h r5
1256+#define yw r6
1257+#define cw r7
1258+#define dw r8
1259+
1260+#define tyuv r9
1261+#define ty r10
1262+#define tu r11
1263+#define tv r12
1264+#define i lr
1265+
1266+ .global yuv420_to_yuv422
1267+ .func yuv420_to_yuv422
1268+yuv420_to_yuv422:
1269+ push {r4-r11,lr}
1270+ add r4, sp, #36
1271+ ldm r4, {r4-r8}
1272+1:
1273+ mov tu, u
1274+ mov tv, v
1275+ vld1.64 {d2}, [u,:64], cw @ u0
1276+ vld1.64 {d3}, [v,:64], cw @ v0
1277+ mov tyuv, yuv
1278+ mov ty, y
1279+ vzip.8 d2, d3 @ u0v0
1280+ mov i, #16
1281+2:
1282+ pld [y, #64]
1283+ vld1.64 {d0, d1}, [y,:128], yw @ y0
1284+ pld [u, #64]
1285+ subs i, i, #4
1286+ vld1.64 {d6}, [u,:64], cw @ u2
1287+ pld [y, #64]
1288+ vld1.64 {d4, d5}, [y,:128], yw @ y1
1289+ pld [v, #64]
1290+ vld1.64 {d7}, [v,:64], cw @ v2
1291+ pld [y, #64]
1292+ vld1.64 {d16,d17}, [y,:128], yw @ y2
1293+ vzip.8 d6, d7 @ u2v2
1294+ pld [u, #64]
1295+ vld1.64 {d22}, [u,:64], cw @ u4
1296+ pld [v, #64]
1297+ vld1.64 {d23}, [v,:64], cw @ v4
1298+ pld [y, #64]
1299+ vld1.64 {d20,d21}, [y,:128], yw @ y3
1300+ vmov q9, q3 @ u2v2
1301+ vzip.8 d22, d23 @ u4v4
1302+ vrhadd.u8 q3, q1, q3 @ u1v1
1303+ vzip.8 q0, q1 @ y0u0y0v0
1304+ vmov q12, q11 @ u4v4
1305+ vzip.8 q2, q3 @ y1u1y1v1
1306+ vrhadd.u8 q11, q9, q11 @ u3v3
1307+ vst1.64 {d0-d3}, [yuv,:128], dw @ y0u0y0v0
1308+ vzip.8 q8, q9 @ y2u2y2v2
1309+ vst1.64 {d4-d7}, [yuv,:128], dw @ y1u1y1v1
1310+ vzip.8 q10, q11 @ y3u3y3v3
1311+ vst1.64 {d16-d19}, [yuv,:128], dw @ y2u2y2v2
1312+ vmov q1, q12
1313+ vst1.64 {d20-d23}, [yuv,:128], dw @ y3u3y3v3
1314+ bgt 2b
1315+ subs w, w, #16
1316+ add yuv, tyuv, #32
1317+ add y, ty, #16
1318+ add u, tu, #8
1319+ add v, tv, #8
1320+ bgt 1b
1321+
1322+ ldr w, [sp, #36]
1323+ subs h, h, #16
1324+ add yuv, yuv, dw, lsl #4
1325+ sub yuv, yuv, w, lsl #1
1326+ add y, y, yw, lsl #4
1327+ sub y, y, w
1328+ add u, u, cw, lsl #3
1329+ sub u, u, w, asr #1
1330+ add v, v, cw, lsl #3
1331+ sub v, v, w, asr #1
1332+ bgt 1b
1333+
1334+ pop {r4-r11,pc}
1335+ .endfunc
1336+