diff options
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.patch | 1336 |
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 @@ | |||
1 | diff -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 | ||
12 | diff -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 | |||
37 | diff -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 | ||
61 | diff -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 | +} | ||
1070 | diff -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 */ | ||
1216 | diff -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 | + | ||