Merge ~alfonsosanchezbeato/ubuntu/+source/gst-plugins-bad1.0:mirsink into ~ubuntu-desktop/ubuntu/+source/gst-plugins-bad1.0:master

Proposed by Alfonso Sanchez-Beato
Status: Merged
Merged at revision: b5c14a9645f8d2360140a4e8be1aa732a4a00489
Proposed branch: ~alfonsosanchezbeato/ubuntu/+source/gst-plugins-bad1.0:mirsink
Merge into: ~ubuntu-desktop/ubuntu/+source/gst-plugins-bad1.0:master
Diff against target: 2788 lines (+1658/-252)
11 files modified
debian/build-deps (+5/-5)
debian/build-deps.in (+5/-5)
debian/changelog (+28/-0)
debian/control (+7/-7)
debian/control.in (+2/-2)
debian/gstreamer-hybris.install (+1/-1)
debian/gstreamer-plugins-bad.install (+1/-0)
debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch (+244/-229)
debian/patches/desktop-mirsink.patch (+1355/-0)
debian/patches/series (+1/-0)
debian/rules (+9/-3)
Reviewer Review Type Date Requested Status
Iain Lane Approve
Jim Hodapp (community) code Approve
Review via email: mp+317315@code.launchpad.net

Commit message

New desktop mirsink and rename of the old one to hybrissink

Description of the change

New desktop mirsink and rename of the old one to hybrissink

To post a comment you must log in.
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Several comments, questions and things to change inline below.

review: Needs Fixing (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Comments addressed and branch refreshed.

Revision history for this message
Jim Hodapp (jhodapp) :
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks very good, thanks!

review: Approve (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

@jhodapp thanks for the review! Re: how mir_display_config_get_output works I will try to find out in the mir channel.

Revision history for this message
Iain Lane (laney) wrote :

Cheers.

I made some trivial tweaks and uploaded. Thanks for forwarding upstream; please do keep on working with them to get it merged there.

review: Approve
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Thanks Iain. I'm pretty confident that they'll take our changes. They provided two quality code reviews of the new mirsink just a few hours after Alfonso proposed it as a patch upstream.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/build-deps b/debian/build-deps
2index 13195ec..6725eb0 100644
3--- a/debian/build-deps
4+++ b/debian/build-deps
5@@ -36,10 +36,10 @@ libexif-dev (>= 0.6.16)
6 libfaad-dev (>= 2.7)
7 libfluidsynth-dev (>= 1.0)
8 libgirepository1.0-dev (>= 0.9.12-4~)
9-libgl1-mesa-dev [!armhf]
10+libgl1-mesa-dev [!armhf !arm64]
11 libgles2-mesa-dev
12 libglib2.0-dev (>= 2.40)
13-libglu1-mesa-dev [!armhf]
14+libglu1-mesa-dev [!armhf !arm64]
15 libgme-dev
16 libgnutls28-dev (>= 2.11.3)
17 libgsm1-dev
18@@ -49,8 +49,8 @@ libgtk-3-dev (>= 3.15.0)
19 libiptcdata0-dev (>= 1.0.2)
20 libkate-dev (>= 0.1.7)
21 liblilv-dev (>= 0.16)
22-libmedia-dev (>= 0.1.0+git20131207+e452e83-0ubuntu3) [i386 armhf]
23-libmirclient-dev [i386 armhf]
24+libmedia-dev (>= 0.1.0+git20151016+6d424c9-0ubuntu23) [i386 armhf arm64]
25+libmirclient-dev [i386 amd64 armhf arm64]
26 libmjpegtools-dev
27 libmms-dev (>= 0.4)
28 libmodplug-dev
29@@ -62,7 +62,7 @@ libopenexr-dev
30 libopenjp2-7-dev
31 libopus-dev (>= 0.9.4)
32 liborc-0.4-dev (>= 1:0.4.17)
33-libplatform-api1-dev [i386 armhf]
34+libplatform-api1-dev [i386 armhf arm64]
35 libpng-dev
36 librsvg2-dev (>= 2.36.2)
37 librtmp-dev
38diff --git a/debian/build-deps.in b/debian/build-deps.in
39index 4a558b6..1556e31 100644
40--- a/debian/build-deps.in
41+++ b/debian/build-deps.in
42@@ -38,9 +38,9 @@ libx11-dev
43 libass-dev (>= 0.10.4)
44 libmodplug-dev
45 libkate-dev (>= 0.1.7)
46-libmedia-dev (>= 0.1.0+git20131207+e452e83-0ubuntu3) [i386 armhf]
47-libplatform-api1-dev [i386 armhf]
48-libmirclient-dev [i386 armhf]
49+libmedia-dev (>= 0.1.0+git20131207+e452e83-0ubuntu3) [i386 armhf arm64]
50+libplatform-api1-dev [i386 armhf arm64]
51+libmirclient-dev [i386 amd64 armhf arm64]
52 libgme-dev
53 librsvg2-dev (>= 2.36.2)
54 libcairo2-dev
55@@ -59,10 +59,10 @@ libopenal-dev (>= 1:1.14)
56 libzvbi-dev
57 libspandsp-dev
58 libopus-dev (>= 0.9.4)
59-libgl1-mesa-dev [!armhf]
60+libgl1-mesa-dev [!armhf !arm64]
61 libegl1-mesa-dev
62 libgles2-mesa-dev
63-libglu1-mesa-dev [!armhf]
64+libglu1-mesa-dev [!armhf !arm64]
65 libxml2-dev (>= 2.8)
66 libfluidsynth-dev (>= 1.0)
67 libsrtp0-dev
68diff --git a/debian/changelog b/debian/changelog
69index 3673062..5deeba9 100644
70--- a/debian/changelog
71+++ b/debian/changelog
72@@ -1,3 +1,31 @@
73+gst-plugins-bad1.0 (1.10.3-1ubuntu4) zesty; urgency=medium
74+
75+ * [ Ɓukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> ]
76+ * debian/control*, debian/rules, debian/build-deps*:
77+ - Build gstreamer1.0-hybris for arm64, bump the required version of
78+ libmedia-dev to a one that has a working arm64 linker in hybris.
79+ * debian/rules:
80+ - For arm64 force using HYBRIS_ANDROID_SDK_VERSION=23 as there is no jb
81+ linker built in hybris for this architecture.
82+
83+ [ Alfonso Sanchez-Beato (email Canonical) ]
84+ * Rename old mirsink to hybrissink to better reflect its nature
85+ * Create new mirsink for desktop
86+
87+ -- Alfonso Sanchez-Beato (email Canonical) <alfonso.sanchez-beato@canonical.com> Wed, 22 Feb 2017 17:02:05 +0100
88+
89+gst-plugins-bad1.0 (1.10.3-1ubuntu3) zesty; urgency=medium
90+
91+ * No-change rebuild against libx265-110.
92+
93+ -- Mattia Rizzolo <mapreri@ubuntu.com> Sun, 19 Feb 2017 16:58:32 +0100
94+
95+gst-plugins-bad1.0 (1.10.3-1ubuntu2) zesty; urgency=medium
96+
97+ * No-change rebuild against libx265-102.
98+
99+ -- Mattia Rizzolo <mapreri@ubuntu.com> Tue, 31 Jan 2017 22:45:53 +0100
100+
101 gst-plugins-bad1.0 (1.10.3-1ubuntu1) zesty; urgency=medium
102
103 * Merge with Debian unstable; remaining changes:
104diff --git a/debian/control b/debian/control
105index 6a85000..fe00eb4 100644
106--- a/debian/control
107+++ b/debian/control
108@@ -51,10 +51,10 @@ Build-Depends: autoconf (>= 2.69),
109 libfaad-dev (>= 2.7),
110 libfluidsynth-dev (>= 1.0),
111 libgirepository1.0-dev (>= 0.9.12-4~),
112- libgl1-mesa-dev [!armhf],
113+ libgl1-mesa-dev [!armhf !arm64],
114 libgles2-mesa-dev,
115 libglib2.0-dev (>= 2.40),
116- libglu1-mesa-dev [!armhf],
117+ libglu1-mesa-dev [!armhf !arm64],
118 libgme-dev,
119 libgnutls28-dev (>= 2.11.3),
120 libgsm1-dev,
121@@ -64,8 +64,8 @@ Build-Depends: autoconf (>= 2.69),
122 libiptcdata0-dev (>= 1.0.2),
123 libkate-dev (>= 0.1.7),
124 liblilv-dev (>= 0.16),
125- libmedia-dev (>= 0.1.0+git20131207+e452e83-0ubuntu3) [i386 armhf],
126- libmirclient-dev [i386 armhf],
127+ libmedia-dev (>= 0.1.0+git20151016+6d424c9-0ubuntu23) [i386 armhf arm64],
128+ libmirclient-dev [i386 amd64 armhf arm64],
129 libmjpegtools-dev,
130 libmms-dev (>= 0.4),
131 libmodplug-dev,
132@@ -77,7 +77,7 @@ Build-Depends: autoconf (>= 2.69),
133 libopenjp2-7-dev,
134 libopus-dev (>= 0.9.4),
135 liborc-0.4-dev (>= 1:0.4.17),
136- libplatform-api1-dev [i386 armhf],
137+ libplatform-api1-dev [i386 armhf arm64],
138 libpng-dev,
139 librsvg2-dev (>= 2.36.2),
140 librtmp-dev,
141@@ -130,7 +130,7 @@ Description: GStreamer documentation for plugins from the "bad" set
142 This package contains the documentation for plugins from the "bad" set.
143
144 Package: gstreamer1.0-hybris
145-Architecture: i386 armhf
146+Architecture: i386 armhf arm64
147 Multi-Arch: same
148 Depends: ${misc:Depends},
149 ${shlibs:Depends}
150@@ -255,7 +255,7 @@ Architecture: any
151 Multi-Arch: same
152 Section: debug
153 Priority: extra
154-Depends: gstreamer1.0-hybris (= ${binary:Version}) [i386 armhf],
155+Depends: gstreamer1.0-hybris (= ${binary:Version}) [i386 armhf arm64],
156 gstreamer1.0-plugins-bad (= ${binary:Version}),
157 ${misc:Depends}
158 Replaces: gstreamer1.0-plugins-base-dbg (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2)
159diff --git a/debian/control.in b/debian/control.in
160index 2c3ce0b..aae5c96 100644
161--- a/debian/control.in
162+++ b/debian/control.in
163@@ -36,7 +36,7 @@ Description: GStreamer documentation for plugins from the "bad" set
164 This package contains the documentation for plugins from the "bad" set.
165
166 Package: @GST_PKGNAME@-hybris
167-Architecture: i386 armhf
168+Architecture: i386 armhf arm64
169 Multi-Arch: same
170 Depends: ${misc:Depends},
171 ${shlibs:Depends}
172@@ -161,7 +161,7 @@ Architecture: any
173 Multi-Arch: same
174 Section: debug
175 Priority: extra
176-Depends: @GST_PKGNAME@-hybris (= ${binary:Version}) [i386 armhf],
177+Depends: @GST_PKGNAME@-hybris (= ${binary:Version}) [i386 armhf arm64],
178 @GST_PKGNAME@-plugins-bad (= ${binary:Version}),
179 ${misc:Depends}
180 Replaces: gstreamer1.0-plugins-base-dbg (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2)
181diff --git a/debian/gstreamer-hybris.install b/debian/gstreamer-hybris.install
182index ce83264..7b78f5d 100644
183--- a/debian/gstreamer-hybris.install
184+++ b/debian/gstreamer-hybris.install
185@@ -1,2 +1,2 @@
186 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstandroidmedia.so
187-debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmirsink.so
188+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgsthybrissink.so
189diff --git a/debian/gstreamer-plugins-bad.install b/debian/gstreamer-plugins-bad.install
190index 13730a1..e1aea24 100644
191--- a/debian/gstreamer-plugins-bad.install
192+++ b/debian/gstreamer-plugins-bad.install
193@@ -48,6 +48,7 @@ debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstladspa.so
194 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstlibde265.so
195 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstlv2.so
196 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmidi.so
197+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmirsink.so
198 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmms.so
199 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmodplug.so
200 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpeg2enc.so
201diff --git a/debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch b/debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch
202index c54121e..05e0b37 100644
203--- a/debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch
204+++ b/debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch
205@@ -1,10 +1,11 @@
206-From: Jim Hodapp <jim.hodapp@canonical.com>
207+From: Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>
208 Date: Tue, 14 Jul 2015 10:41:17 +0000
209 Subject: Add mirsink and androidmedia-hybris support
210
211 Add mirsink and androidmedia over hybris for hardware accelerated
212 decoding using libstagefright and the hybris compat layer.
213
214+From: Jim Hodapp <jim.hodapp@canonical.com>
215 From: Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>
216 From: Ratchanan Srirattanamet <ratchananster@gmail.com> (LP: #1452386, LP: #1653373)
217 Origin: vendor
218@@ -12,11 +13,11 @@ Forwarded: no
219 ---
220 configure.ac | 15 +
221 ext/Makefile.am | 8 +
222- ext/mir/Makefile.am | 17 +
223- ext/mir/gstmirsink.c | 854 ++++++++++
224- ext/mir/gstmirsink.h | 134 ++
225- ext/mir/mirpool.c | 434 +++++
226- ext/mir/mirpool.h | 91 ++
227+ ext/hybris/Makefile.am | 17 +
228+ ext/hybris/gsthybrissink.c | 854 ++++++++++
229+ ext/hybris/gsthybrissink.h | 134 ++
230+ ext/hybris/mirpool.c | 434 +++++
231+ ext/hybris/mirpool.h | 91 ++
232 gst-libs/gst/Makefile.am | 8 +-
233 gst-libs/gst/mir/Makefile.am | 26 +
234 gst-libs/gst/mir/gstmircontext.c | 155 ++
235@@ -36,11 +37,11 @@ Forwarded: no
236 tests/check/pipelines/gstamcvideodec.c | 538 +++++++
237 tests/check/pipelines/gstamcvideodec_egl.c | 56 +
238 25 files changed, 8791 insertions(+), 7 deletions(-)
239- create mode 100644 ext/mir/Makefile.am
240- create mode 100644 ext/mir/gstmirsink.c
241- create mode 100644 ext/mir/gstmirsink.h
242- create mode 100644 ext/mir/mirpool.c
243- create mode 100644 ext/mir/mirpool.h
244+ create mode 100644 ext/hybris/Makefile.am
245+ create mode 100644 ext/hybris/gsthybrissink.c
246+ create mode 100644 ext/hybris/gsthybrissink.h
247+ create mode 100644 ext/hybris/mirpool.c
248+ create mode 100644 ext/hybris/mirpool.h
249 create mode 100644 gst-libs/gst/mir/Makefile.am
250 create mode 100644 gst-libs/gst/mir/gstmircontext.c
251 create mode 100644 gst-libs/gst/mir/gstmircontext.h
252@@ -52,11 +53,11 @@ Forwarded: no
253 create mode 100644 tests/check/pipelines/gstamcvideodec.c
254 create mode 100644 tests/check/pipelines/gstamcvideodec_egl.c
255
256-Index: b/configure.ac
257-===================================================================
258+diff --git a/configure.ac b/configure.ac
259+index f2c63a1..7444429 100644
260 --- a/configure.ac
261 +++ b/configure.ac
262-@@ -1784,6 +1784,18 @@
263+@@ -1784,6 +1784,18 @@ AG_GST_CHECK_FEATURE(ANDROID_MEDIA, [Android Media], androidmedia, [
264 esac
265 ])
266
267@@ -75,7 +76,7 @@ Index: b/configure.ac
268 dnl *** AppleMedia (OS X and iOS) ***
269 translit(dnm, m, l) AM_CONDITIONAL(USE_APPLE_MEDIA, true)
270 HAVE_APPLE_MEDIA="no"
271-@@ -3464,6 +3476,7 @@
272+@@ -3464,6 +3476,7 @@ AM_CONDITIONAL(DECKLINK_OSX, false)
273 AM_CONDITIONAL(USE_DIRECTFB, false)
274 AM_CONDITIONAL(USE_WAYLAND, false)
275 AM_CONDITIONAL(USE_DAALA, false)
276@@ -83,7 +84,7 @@ Index: b/configure.ac
277 AM_CONDITIONAL(USE_DTS, false)
278 AM_CONDITIONAL(USE_EXIF, false)
279 AM_CONDITIONAL(USE_RESINDVD, false)
280-@@ -3703,6 +3716,7 @@
281+@@ -3703,6 +3716,7 @@ gst-libs/gst/gl/egl/Makefile
282 gst-libs/gst/gl/wayland/Makefile
283 gst-libs/gst/gl/win32/Makefile
284 gst-libs/gst/gl/x11/Makefile
285@@ -91,76 +92,78 @@ Index: b/configure.ac
286 gst-libs/gst/insertbin/Makefile
287 gst-libs/gst/interfaces/Makefile
288 gst-libs/gst/codecparsers/Makefile
289-@@ -3786,6 +3800,7 @@
290+@@ -3786,6 +3800,7 @@ ext/dc1394/Makefile
291 ext/directfb/Makefile
292 ext/wayland/Makefile
293 ext/daala/Makefile
294-+ext/mir/Makefile
295++ext/hybris/Makefile
296 ext/dts/Makefile
297 ext/gl/Makefile
298 ext/gtk/Makefile
299-Index: b/ext/Makefile.am
300-===================================================================
301+diff --git a/ext/Makefile.am b/ext/Makefile.am
302+index bae25c2..709bdb2 100644
303 --- a/ext/Makefile.am
304 +++ b/ext/Makefile.am
305-@@ -70,6 +70,12 @@
306+@@ -70,6 +70,12 @@ else
307 DAALA_DIR=
308 endif
309
310 +if USE_ANDROID_MEDIA_HYBRIS
311-+MIR_DIR=mir
312++HYBRIS_DIR=hybris
313 +else
314-+MIR_DIR=
315++HYBRIS_DIR=
316 +endif
317 +
318 if USE_DTS
319 DTS_DIR=dts
320 else
321-@@ -457,6 +463,7 @@
322+@@ -457,6 +463,7 @@ SUBDIRS=\
323 $(LIBDE265_DIR) \
324 $(LIBMMS_DIR) \
325 $(LIBVISUAL_DIR) \
326-+ $(MIR_DIR) \
327++ $(HYBRIS_DIR) \
328 $(MODPLUG_DIR) \
329 $(MPEG2ENC_DIR) \
330 $(MIMIC_DIR) \
331-@@ -508,6 +515,7 @@
332+@@ -508,6 +515,7 @@ DIST_SUBDIRS = \
333 dc1394 \
334 directfb \
335 wayland \
336-+ mir \
337++ hybris \
338 faac \
339 faad \
340 fdkaac \
341-Index: b/ext/mir/Makefile.am
342-===================================================================
343+diff --git a/ext/hybris/Makefile.am b/ext/hybris/Makefile.am
344+new file mode 100644
345+index 0000000..31c2576
346 --- /dev/null
347-+++ b/ext/mir/Makefile.am
348++++ b/ext/hybris/Makefile.am
349 @@ -0,0 +1,17 @@
350-+plugin_LTLIBRARIES = libgstmirsink.la
351++plugin_LTLIBRARIES = libgsthybrissink.la
352 +
353-+libgstmirsink_la_SOURCES = gstmirsink.c mirpool.c
354-+libgstmirsink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
355++libgsthybrissink_la_SOURCES = gsthybrissink.c mirpool.c
356++libgsthybrissink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
357 + $(UBUNTU_PLATFORM_CFLAGS) \
358 + $(MIR_CFLAGS) \
359 + -I../../gst-libs/
360-+libgstmirsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS) \
361++libgsthybrissink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS) \
362 + -lgstvideo-$(GST_API_VERSION) \
363 + $(top_builddir)/gst-libs/gst/mir/libgstmiralloc-$(GST_API_VERSION).la \
364 + -lmedia \
365 + $(EGL_LIBS) $(EGLGLES_LIBS) \
366 + $(MIR_LIBS)
367-+libgstmirsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
368-+libgstmirsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
369-+include_HEADERS = mirpool.h gstmirsink.h
370++libgsthybrissink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
371++libgsthybrissink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
372++include_HEADERS = mirpool.h gsthybrissink.h
373 +noinst_HEADERS =
374-Index: b/ext/mir/gstmirsink.c
375-===================================================================
376+diff --git a/ext/hybris/gsthybrissink.c b/ext/hybris/gsthybrissink.c
377+new file mode 100644
378+index 0000000..d64eee0
379 --- /dev/null
380-+++ b/ext/mir/gstmirsink.c
381++++ b/ext/hybris/gsthybrissink.c
382 @@ -0,0 +1,854 @@
383 +/*
384-+ * GStreamer Mir video sink
385++ * GStreamer Hybris/Mir video sink
386 + * Copyright (C) 2013 Canonical Ltd
387 + *
388 + * This library is free software; you can redistribute it and/or
389@@ -180,17 +183,17 @@ Index: b/ext/mir/gstmirsink.c
390 + */
391 +
392 +/**
393-+ * SECTION:element-mirsink
394++ * SECTION:element-hybrissink
395 + *
396-+ * The mirsink creates its own window and renders the decoded video frames there.
397++ * The hybrissink creates its own window and renders the decoded video frames there.
398 + * Setup the Mir environment as described in
399 + * <ulink url="http://mir.freedesktop.org/building.html">Mir</ulink> home page.
400 + *
401 + * <refsect2>
402 + * <title>Example pipeline</title>
403 + * |[
404-+ * gst-launch -v filesrc ! qtdemux ! h264parse ! queue ! amcviddec-omxtiducati1videodecoder ! mirsink
405-+ * ]| test the video rendering with mirsink
406++ * gst-launch -v filesrc ! qtdemux ! h264parse ! queue ! amcviddec-omxtiducati1videodecoder ! hybrissink
407++ * ]| test the video rendering with hybrissink
408 + * </refsect2>
409 + */
410 +
411@@ -198,7 +201,7 @@ Index: b/ext/mir/gstmirsink.c
412 +#include <config.h>
413 +#endif
414 +
415-+#include "gstmirsink.h"
416++#include "gsthybrissink.h"
417 +#include "mirpool.h"
418 +
419 +#include <gst/mir/mirallocator.h>
420@@ -227,24 +230,24 @@ Index: b/ext/mir/gstmirsink.c
421 + PROP_MIR_VIDEO_WIDTH
422 +};
423 +
424-+GST_DEBUG_CATEGORY (gstmir_debug);
425-+#define GST_CAT_DEFAULT gstmir_debug
426++GST_DEBUG_CATEGORY (gsthybris_debug);
427++#define GST_CAT_DEFAULT gsthybris_debug
428 +
429 +#if 0
430-+static const char gst_mirsink_sink_caps_str[] =
431++static const char gst_hybrissink_sink_caps_str[] =
432 +GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_MIR_IMAGE,
433 + GST_VIDEO_FORMATS_ALL) ";"
434 + GST_VIDEO_CAPS_MAKE_WITH_FEATURES
435 + (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
436 + GST_VIDEO_FORMATS_ALL);
437 +
438-+ static GstStaticPadTemplate gst_mirsink_sink_caps_template =
439++ static GstStaticPadTemplate gst_hybrissink_sink_caps_template =
440 + GST_STATIC_PAD_TEMPLATE ("sink",
441 + GST_PAD_SINK,
442 + GST_PAD_ALWAYS,
443-+ GST_STATIC_CAPS (gst_mirsink_sink_caps_str));
444++ GST_STATIC_CAPS (gst_hybrissink_sink_caps_str));
445 +#else
446-+static GstStaticPadTemplate gst_mirsink_sink_caps_template =
447++static GstStaticPadTemplate gst_hybrissink_sink_caps_template =
448 +GST_STATIC_PAD_TEMPLATE ("sink",
449 + GST_PAD_SINK,
450 + GST_PAD_ALWAYS,
451@@ -260,28 +263,28 @@ Index: b/ext/mir/gstmirsink.c
452 +static guint surface_texture_client_set_signal = 0;
453 +
454 +/* Fixme: Add more interfaces */
455-+#define gst_mir_sink_parent_class parent_class
456-+G_DEFINE_TYPE (GstMirSink, gst_mir_sink, GST_TYPE_VIDEO_SINK);
457++#define gst_hybris_sink_parent_class parent_class
458++G_DEFINE_TYPE (GstHybrisSink, gst_hybris_sink, GST_TYPE_VIDEO_SINK);
459 +
460-+static void gst_mir_sink_get_property (GObject * object,
461++static void gst_hybris_sink_get_property (GObject * object,
462 + guint prop_id, GValue * value, GParamSpec * pspec);
463-+static void gst_mir_sink_set_property (GObject * object,
464++static void gst_hybris_sink_set_property (GObject * object,
465 + guint prop_id, const GValue * value, GParamSpec * pspec);
466-+static void gst_mir_sink_finalize (GObject * object);
467-+static void gst_mir_sink_set_context (GstElement * element,
468++static void gst_hybris_sink_finalize (GObject * object);
469++static void gst_hybris_sink_set_context (GstElement * element,
470 + GstContext * context);
471-+static GstCaps *gst_mir_sink_get_caps (GstBaseSink * bsink, GstCaps * filter);
472-+static gboolean gst_mir_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
473-+static gboolean gst_mir_sink_start (GstBaseSink * bsink);
474-+static gboolean gst_mir_sink_stop (GstBaseSink * bsink);
475-+static gboolean gst_mir_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer);
476++static GstCaps *gst_hybris_sink_get_caps (GstBaseSink * bsink, GstCaps * filter);
477++static gboolean gst_hybris_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
478++static gboolean gst_hybris_sink_start (GstBaseSink * bsink);
479++static gboolean gst_hybris_sink_stop (GstBaseSink * bsink);
480++static gboolean gst_hybris_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer);
481 +static gboolean
482-+gst_mir_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query);
483-+static gboolean gst_mir_sink_render (GstBaseSink * bsink, GstBuffer * buffer);
484-+static gboolean gst_mir_sink_query (GstBaseSink * bsink, GstQuery * query);
485++gst_hybris_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query);
486++static gboolean gst_hybris_sink_render (GstBaseSink * bsink, GstBuffer * buffer);
487++static gboolean gst_hybris_sink_query (GstBaseSink * bsink, GstQuery * query);
488 +
489 +static void
490-+gst_mir_sink_class_init (GstMirSinkClass * klass)
491++gst_hybris_sink_class_init (GstHybrisSinkClass * klass)
492 +{
493 + GObjectClass *gobject_class;
494 + GstElementClass *gstelement_class;
495@@ -291,27 +294,27 @@ Index: b/ext/mir/gstmirsink.c
496 + gstelement_class = (GstElementClass *) klass;
497 + gstbasesink_class = (GstBaseSinkClass *) klass;
498 +
499-+ gobject_class->set_property = gst_mir_sink_set_property;
500-+ gobject_class->get_property = gst_mir_sink_get_property;
501-+ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_mir_sink_finalize);
502-+ gstelement_class->set_context = gst_mir_sink_set_context;
503++ gobject_class->set_property = gst_hybris_sink_set_property;
504++ gobject_class->get_property = gst_hybris_sink_get_property;
505++ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_hybris_sink_finalize);
506++ gstelement_class->set_context = gst_hybris_sink_set_context;
507 +
508 + gst_element_class_add_pad_template (gstelement_class,
509-+ gst_static_pad_template_get (&gst_mirsink_sink_caps_template));
510++ gst_static_pad_template_get (&gst_hybrissink_sink_caps_template));
511 +
512 + gst_element_class_set_static_metadata (gstelement_class,
513-+ "Mir video sink", "Sink/Video",
514-+ "Output to Mir surface", "Jim Hodapp <jim.hodapp@canonical.com>");
515-+
516-+ gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_mir_sink_get_caps);
517-+ gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_mir_sink_set_caps);
518-+ gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_mir_sink_start);
519-+ gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_mir_sink_stop);
520-+ gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_mir_sink_preroll);
521++ "Hybris/Mir video sink", "Sink/Video",
522++ "Output to hybris/Mir surface", "Jim Hodapp <jim.hodapp@canonical.com>");
523++
524++ gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_hybris_sink_get_caps);
525++ gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_hybris_sink_set_caps);
526++ gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_hybris_sink_start);
527++ gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_hybris_sink_stop);
528++ gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_hybris_sink_preroll);
529 + gstbasesink_class->propose_allocation =
530-+ GST_DEBUG_FUNCPTR (gst_mir_sink_propose_allocation);
531-+ gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_mir_sink_render);
532-+ gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_mir_sink_query);
533++ GST_DEBUG_FUNCPTR (gst_hybris_sink_propose_allocation);
534++ gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_hybris_sink_render);
535++ gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_hybris_sink_query);
536 +
537 + /* This signal is for being notified when a frame is ready to be rendered. This
538 + * is useful for anything outside of the sink that needs to know when each frame
539@@ -319,13 +322,13 @@ Index: b/ext/mir/gstmirsink.c
540 + frame_ready_signal =
541 + g_signal_new ("frame-ready", G_TYPE_FROM_CLASS (klass),
542 + G_SIGNAL_RUN_LAST,
543-+ G_STRUCT_OFFSET (GstMirSinkClass, frame_ready_changed), NULL, NULL,
544++ G_STRUCT_OFFSET (GstHybrisSinkClass, frame_ready_changed), NULL, NULL,
545 + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 0);
546 +
547 + surface_texture_client_set_signal =
548 + g_signal_new ("surface-texture-client", G_TYPE_FROM_CLASS (klass),
549 + G_SIGNAL_RUN_LAST,
550-+ G_STRUCT_OFFSET (GstMirSinkClass, surface_texture_client_changed), NULL,
551++ G_STRUCT_OFFSET (GstHybrisSinkClass, surface_texture_client_changed), NULL,
552 + NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
553 +
554 + g_object_class_install_property (gobject_class, PROP_MIR_TEXTURE_ID,
555@@ -345,19 +348,19 @@ Index: b/ext/mir/gstmirsink.c
556 +}
557 +
558 +static void
559-+gst_mir_sink_init (GstMirSink * sink)
560++gst_hybris_sink_init (GstHybrisSink * sink)
561 +{
562-+ GST_DEBUG_OBJECT (sink, "Initializing mirsink");
563++ GST_DEBUG_OBJECT (sink, "Initializing hybrissink");
564 + sink->pool = NULL;
565 +
566 + g_mutex_init (&sink->mir_lock);
567 +}
568 +
569 +static void
570-+gst_mir_sink_get_property (GObject * object,
571++gst_hybris_sink_get_property (GObject * object,
572 + guint prop_id, GValue * value, GParamSpec * pspec)
573 +{
574-+ GstMirSink *sink = GST_MIR_SINK (object);
575++ GstHybrisSink *sink = GST_HYBRIS_SINK (object);
576 +
577 + switch (prop_id) {
578 + case PROP_MIR_TEXTURE_ID:
579@@ -376,16 +379,16 @@ Index: b/ext/mir/gstmirsink.c
580 +}
581 +
582 +static void
583-+gst_mir_sink_create_surface_texture (GObject * object)
584++gst_hybris_sink_create_surface_texture (GObject * object)
585 +{
586-+ GstMirSink *sink = GST_MIR_SINK (object);
587++ GstHybrisSink *sink = GST_HYBRIS_SINK (object);
588 +
589 + /* Create a new SurfaceTextureClientHybris instance from a texture ID */
590 + sink->surface_texture_client =
591 + surface_texture_client_create_by_id (sink->texture_id);
592 + GST_DEBUG_OBJECT (sink, "Created new SurfaceTextureClientHybris instance: %p",
593 + sink->surface_texture_client);
594-+ /* Because mirsink is being loaded, we are definitely doing
595++ /* Because hybrissink is being loaded, we are definitely doing
596 + * hardware rendering.
597 + */
598 + surface_texture_client_set_hardware_rendering (sink->surface_texture_client,
599@@ -397,16 +400,16 @@ Index: b/ext/mir/gstmirsink.c
600 +}
601 +
602 +static void
603-+gst_mir_sink_set_property (GObject * object,
604++gst_hybris_sink_set_property (GObject * object,
605 + guint prop_id, const GValue * value, GParamSpec * pspec)
606 +{
607-+ GstMirSink *sink = GST_MIR_SINK (object);
608++ GstHybrisSink *sink = GST_HYBRIS_SINK (object);
609 +
610 + switch (prop_id) {
611 + case PROP_MIR_TEXTURE_ID:
612 + sink->texture_id = g_value_get_uint (value);
613 + GST_WARNING_OBJECT (object, "texture_id: %d", sink->texture_id);
614-+ gst_mir_sink_create_surface_texture (object);
615++ gst_hybris_sink_create_surface_texture (object);
616 + break;
617 + default:
618 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
619@@ -447,9 +450,9 @@ Index: b/ext/mir/gstmirsink.c
620 +#endif
621 +
622 +static void
623-+gst_mir_sink_finalize (GObject * object)
624++gst_hybris_sink_finalize (GObject * object)
625 +{
626-+ GstMirSink *sink = GST_MIR_SINK (object);
627++ GstHybrisSink *sink = GST_HYBRIS_SINK (object);
628 +
629 + GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
630 +
631@@ -474,9 +477,9 @@ Index: b/ext/mir/gstmirsink.c
632 +}
633 +
634 +static void
635-+gst_mir_sink_set_context (GstElement * element, GstContext * context)
636++gst_hybris_sink_set_context (GstElement * element, GstContext * context)
637 +{
638-+ GstMirSink *sink = GST_MIR_SINK (element);
639++ GstHybrisSink *sink = GST_HYBRIS_SINK (element);
640 + SurfaceTextureClientHybris stc;
641 +
642 + GST_DEBUG_OBJECT (element, "%s", __PRETTY_FUNCTION__);
643@@ -490,9 +493,9 @@ Index: b/ext/mir/gstmirsink.c
644 +}
645 +
646 +static gboolean
647-+gst_mir_sink_query (GstBaseSink * bsink, GstQuery * query)
648++gst_hybris_sink_query (GstBaseSink * bsink, GstQuery * query)
649 +{
650-+ GstMirSink *sink = GST_MIR_SINK (bsink);
651++ GstHybrisSink *sink = GST_HYBRIS_SINK (bsink);
652 +
653 + GST_INFO_OBJECT (sink, "query type %s", GST_QUERY_TYPE_NAME (query));
654 +
655@@ -581,7 +584,7 @@ Index: b/ext/mir/gstmirsink.c
656 +}
657 +
658 +static void
659-+create_window (GstMirSink * sink, struct display *display, int width,
660++create_window (GstHybrisSink * sink, struct display *display, int width,
661 + int height)
662 +{
663 + struct window *window;
664@@ -598,7 +601,7 @@ Index: b/ext/mir/gstmirsink.c
665 + window->height = height;
666 +
667 + window->properties = ua_ui_window_properties_new_for_normal_window ();
668-+ ua_ui_window_properties_set_titlen (window->properties, "MirSinkWindow", 13);
669++ ua_ui_window_properties_set_titlen (window->properties, "HybrisSinkWindow", 13);
670 +
671 + ua_ui_window_properties_set_role (window->properties, 1);
672 + ua_ui_window_properties_set_input_cb_and_ctx (window->properties, NULL, NULL);
673@@ -624,12 +627,12 @@ Index: b/ext/mir/gstmirsink.c
674 +#endif
675 +
676 +static GstCaps *
677-+gst_mir_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
678++gst_hybris_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
679 +{
680-+ GstMirSink *sink;
681++ GstHybrisSink *sink;
682 + GstCaps *caps;
683 +
684-+ sink = GST_MIR_SINK (bsink);
685++ sink = GST_HYBRIS_SINK (bsink);
686 +
687 + GST_DEBUG_OBJECT (sink, "%s", __PRETTY_FUNCTION__);
688 +
689@@ -646,9 +649,9 @@ Index: b/ext/mir/gstmirsink.c
690 +}
691 +
692 +static gboolean
693-+gst_mir_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
694++gst_hybris_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
695 +{
696-+ GstMirSink *sink = GST_MIR_SINK (bsink);
697++ GstHybrisSink *sink = GST_HYBRIS_SINK (bsink);
698 + GstBufferPool *newpool, *oldpool;
699 + GstMirBufferPool *m_pool;
700 + GstVideoInfo info;
701@@ -658,7 +661,7 @@ Index: b/ext/mir/gstmirsink.c
702 + };
703 + guint size;
704 +
705-+ sink = GST_MIR_SINK (bsink);
706++ sink = GST_HYBRIS_SINK (bsink);
707 +
708 + GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
709 +
710@@ -727,9 +730,9 @@ Index: b/ext/mir/gstmirsink.c
711 +}
712 +
713 +static gboolean
714-+gst_mir_sink_start (GstBaseSink * bsink)
715++gst_hybris_sink_start (GstBaseSink * bsink)
716 +{
717-+ GstMirSink *sink = (GstMirSink *) bsink;
718++ GstHybrisSink *sink = (GstHybrisSink *) bsink;
719 +
720 + GST_DEBUG_OBJECT (sink, "start");
721 +
722@@ -738,7 +741,7 @@ Index: b/ext/mir/gstmirsink.c
723 + */
724 + if (!sink->surface_texture_client && sink->texture_id > 0) {
725 + GST_DEBUG_OBJECT (sink, "Creating new SurfaceTextureClientHybris instance");
726-+ gst_mir_sink_create_surface_texture (G_OBJECT (bsink));
727++ gst_hybris_sink_create_surface_texture (G_OBJECT (bsink));
728 + }
729 +#if 0
730 + /* If we are using a texture_id, there's no need to use the Ubuntu
731@@ -784,9 +787,9 @@ Index: b/ext/mir/gstmirsink.c
732 +}
733 +
734 +static gboolean
735-+gst_mir_sink_stop (GstBaseSink * bsink)
736++gst_hybris_sink_stop (GstBaseSink * bsink)
737 +{
738-+ GstMirSink *sink = (GstMirSink *) bsink;
739++ GstHybrisSink *sink = (GstHybrisSink *) bsink;
740 +
741 + GST_DEBUG_OBJECT (sink, "stop");
742 +
743@@ -806,9 +809,9 @@ Index: b/ext/mir/gstmirsink.c
744 +}
745 +
746 +static gboolean
747-+gst_mir_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
748++gst_hybris_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
749 +{
750-+ GstMirSink *sink = GST_MIR_SINK (bsink);
751++ GstHybrisSink *sink = GST_HYBRIS_SINK (bsink);
752 + GstBufferPool *pool;
753 + GstStructure *config;
754 + GstCaps *caps;
755@@ -916,16 +919,16 @@ Index: b/ext/mir/gstmirsink.c
756 +}
757 +
758 +static GstFlowReturn
759-+gst_mir_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
760++gst_hybris_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
761 +{
762 + GST_DEBUG_OBJECT (bsink, "preroll buffer %p", buffer);
763-+ return gst_mir_sink_render (bsink, buffer);
764++ return gst_hybris_sink_render (bsink, buffer);
765 +}
766 +
767 +static GstFlowReturn
768-+gst_mir_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
769++gst_hybris_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
770 +{
771-+ GstMirSink *sink = GST_MIR_SINK (bsink);
772++ GstHybrisSink *sink = GST_HYBRIS_SINK (bsink);
773 + //GstVideoRectangle src, dst, res;
774 + GstBuffer *to_render;
775 + GstMirMeta *meta;
776@@ -1002,21 +1005,22 @@ Index: b/ext/mir/gstmirsink.c
777 +static gboolean
778 +plugin_init (GstPlugin * plugin)
779 +{
780-+ GST_DEBUG_CATEGORY_INIT (gstmir_debug, "mirsink", 0, " mir video sink");
781++ GST_DEBUG_CATEGORY_INIT (gsthybris_debug, "hybrissink", 0, " hybris video sink");
782 +
783-+ return gst_element_register (plugin, "mirsink", GST_RANK_MARGINAL,
784-+ GST_TYPE_MIR_SINK);
785++ return gst_element_register (plugin, "hybrissink", GST_RANK_MARGINAL,
786++ GST_TYPE_HYBRIS_SINK);
787 +}
788 +
789 +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
790 + GST_VERSION_MINOR,
791-+ mirsink,
792-+ "Mir Video Sink", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
793++ hybrissink,
794++ "Hybris Video Sink", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
795 + GST_PACKAGE_ORIGIN)
796-Index: b/ext/mir/gstmirsink.h
797-===================================================================
798+diff --git a/ext/hybris/gsthybrissink.h b/ext/hybris/gsthybrissink.h
799+new file mode 100644
800+index 0000000..c5e5353
801 --- /dev/null
802-+++ b/ext/mir/gstmirsink.h
803++++ b/ext/hybris/gsthybrissink.h
804 @@ -0,0 +1,134 @@
805 +/*
806 + * GStreamer Mir video sink
807@@ -1038,8 +1042,8 @@ Index: b/ext/mir/gstmirsink.h
808 + * Boston, MA 02110-1301 USA.
809 + */
810 +
811-+#ifndef __GST_MIR_VIDEO_SINK_H__
812-+#define __GST_MIR_VIDEO_SINK_H__
813++#ifndef __GST_HYBRIS_VIDEO_SINK_H__
814++#define __GST_HYBRIS_VIDEO_SINK_H__
815 +
816 +#include <stdio.h>
817 +#include <stdlib.h>
818@@ -1067,21 +1071,21 @@ Index: b/ext/mir/gstmirsink.h
819 +#include <hybris/media/surface_texture_client_hybris.h>
820 +//#include <gst/mir/gstmircontext.h>
821 +
822-+#define GST_TYPE_MIR_SINK \
823-+ (gst_mir_sink_get_type())
824-+#define GST_MIR_SINK(obj) \
825-+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MIR_SINK,GstMirSink))
826-+#define GST_MIR_SINK_CLASS(klass) \
827-+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MIR_SINK,GstMirSinkClass))
828-+#define GST_IS_MIR_SINK(obj) \
829-+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MIR_SINK))
830-+#define GST_IS_MIR_SINK_CLASS(klass) \
831-+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MIR_SINK))
832-+#define GST_MIR_SINK_GET_CLASS(inst) \
833-+ (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_MIR_SINK, GstMirSinkClass))
834-+
835-+typedef struct _GstMirSink GstMirSink;
836-+typedef struct _GstMirSinkClass GstMirSinkClass;
837++#define GST_TYPE_HYBRIS_SINK \
838++ (gst_hybris_sink_get_type())
839++#define GST_HYBRIS_SINK(obj) \
840++ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_HYBRIS_SINK,GstHybrisSink))
841++#define GST_HYBRIS_SINK_CLASS(klass) \
842++ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_HYBRIS_SINK,GstHybrisSinkClass))
843++#define GST_IS_HYBRIS_SINK(obj) \
844++ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_HYBRIS_SINK))
845++#define GST_IS_HYBRIS_SINK_CLASS(klass) \
846++ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_HYBRIS_SINK))
847++#define GST_HYBRIS_SINK_GET_CLASS(inst) \
848++ (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_HYBRIS_SINK, GstHybrisSinkClass))
849++
850++typedef struct _GstHybrisSink GstHybrisSink;
851++typedef struct _GstHybrisSinkClass GstHybrisSinkClass;
852 +
853 +#include "mirpool.h"
854 +
855@@ -1119,7 +1123,7 @@ Index: b/ext/mir/gstmirsink.h
856 + EGLNativeWindowType egl_native_window;
857 +};
858 +
859-+struct _GstMirSink
860++struct _GstHybrisSink
861 +{
862 + GstVideoSink parent;
863 +
864@@ -1139,23 +1143,24 @@ Index: b/ext/mir/gstmirsink.h
865 + gint video_height;
866 +};
867 +
868-+struct _GstMirSinkClass
869++struct _GstHybrisSinkClass
870 +{
871 + GstVideoSinkClass parent;
872 +
873-+ void (*frame_ready_changed) (GstMirSink *sink, gpointer renderer);
874-+ void (*surface_texture_client_changed) (GstMirSink *sink, gpointer surface_texture_client, gpointer renderer);
875++ void (*frame_ready_changed) (GstHybrisSink *sink, gpointer renderer);
876++ void (*surface_texture_client_changed) (GstHybrisSink *sink, gpointer surface_texture_client, gpointer renderer);
877 +};
878 +
879-+GType gst_mir_sink_get_type (void) G_GNUC_CONST;
880++GType gst_hybris_sink_get_type (void) G_GNUC_CONST;
881 +
882 +G_END_DECLS
883 +
884-+#endif /* __GST_MIR_VIDEO_SINK_H__ */
885-Index: b/ext/mir/mirpool.c
886-===================================================================
887++#endif /* __GST_HYBRIS_VIDEO_SINK_H__ */
888+diff --git a/ext/hybris/mirpool.c b/ext/hybris/mirpool.c
889+new file mode 100644
890+index 0000000..77c5368
891 --- /dev/null
892-+++ b/ext/mir/mirpool.c
893++++ b/ext/hybris/mirpool.c
894 @@ -0,0 +1,434 @@
895 +/*
896 + * GStreamer Mir buffer pool
897@@ -1182,7 +1187,7 @@ Index: b/ext/mir/mirpool.c
898 +#endif
899 +
900 +/* Object header */
901-+#include "gstmirsink.h"
902++#include "gsthybrissink.h"
903 +#include "mirpool.h"
904 +
905 +#include <gst/mir/mirallocator.h>
906@@ -1305,7 +1310,7 @@ Index: b/ext/mir/mirpool.c
907 +gst_buffer_add_mir_meta (GstBuffer * buffer, GstMirBufferPool * mpool)
908 +{
909 + GstMirMeta *mmeta;
910-+ GstMirSink *sink;
911++ GstHybrisSink *sink;
912 + guint stride = 0;
913 + guint size = 0;
914 +
915@@ -1501,15 +1506,15 @@ Index: b/ext/mir/mirpool.c
916 +}
917 +
918 +GstBufferPool *
919-+gst_mir_buffer_pool_new (GstMirSink * mirsink)
920++gst_mir_buffer_pool_new (GstHybrisSink * hybrissink)
921 +{
922 + GstMirBufferPool *m_pool;
923 +
924 + GST_WARNING ("%s", __PRETTY_FUNCTION__);
925 +
926-+ g_return_val_if_fail (GST_IS_MIR_SINK (mirsink), NULL);
927++ g_return_val_if_fail (GST_IS_HYBRIS_SINK (hybrissink), NULL);
928 + m_pool = g_object_new (GST_TYPE_MIR_BUFFER_POOL, NULL);
929-+ m_pool->sink = gst_object_ref (mirsink);
930++ m_pool->sink = gst_object_ref (hybrissink);
931 +
932 + return GST_BUFFER_POOL_CAST (m_pool);
933 +}
934@@ -1591,10 +1596,11 @@ Index: b/ext/mir/mirpool.c
935 +
936 + G_OBJECT_CLASS (gst_mir_buffer_pool_parent_class)->finalize (object);
937 +}
938-Index: b/ext/mir/mirpool.h
939-===================================================================
940+diff --git a/ext/hybris/mirpool.h b/ext/hybris/mirpool.h
941+new file mode 100644
942+index 0000000..d18844e
943 --- /dev/null
944-+++ b/ext/mir/mirpool.h
945++++ b/ext/hybris/mirpool.h
946 @@ -0,0 +1,91 @@
947 +/*
948 + * GStreamer Mir buffer pool
949@@ -1621,7 +1627,7 @@ Index: b/ext/mir/mirpool.h
950 +
951 +G_BEGIN_DECLS
952 +
953-+#include "gstmirsink.h"
954++#include "gsthybrissink.h"
955 +#include <hybris/media/media_codec_layer.h>
956 +#include <hybris/media/surface_texture_client_hybris.h>
957 +typedef struct _GstMirMeta GstMirMeta;
958@@ -1639,7 +1645,7 @@ Index: b/ext/mir/mirpool.h
959 +struct _GstMirMeta {
960 + GstMeta meta;
961 +
962-+ GstMirSink *sink;
963++ GstHybrisSink *sink;
964 +
965 + size_t size;
966 + /* Are we doing hardware rendering? */
967@@ -1656,7 +1662,7 @@ Index: b/ext/mir/mirpool.h
968 +{
969 + GstBufferPool bufferpool;
970 +
971-+ GstMirSink *sink;
972++ GstHybrisSink *sink;
973 +
974 + /*Fixme: keep all these in GstMirBufferPoolPrivate*/
975 + GstCaps *caps;
976@@ -1678,7 +1684,7 @@ Index: b/ext/mir/mirpool.h
977 +
978 +GType gst_mir_buffer_pool_get_type (void);
979 +
980-+GstBufferPool *gst_mir_buffer_pool_new (GstMirSink * mirsink);
981++GstBufferPool *gst_mir_buffer_pool_new (GstHybrisSink * hybrissink);
982 +void gst_mir_buffer_pool_set_surface_texture_client (GstBufferPool * pool, SurfaceTextureClientHybris sfc);
983 +void gst_mir_buffer_pool_set_hardware_rendering (GstBufferPool * pool, gboolean do_hardware_rendering);
984 +gboolean gst_mir_buffer_pool_get_hardware_rendering (GstMirBufferPool * mpool);
985@@ -1687,11 +1693,11 @@ Index: b/ext/mir/mirpool.h
986 +G_END_DECLS
987 +
988 +#endif /*__GST_MIR_BUFFER_POOL_H__*/
989-Index: b/gst-libs/gst/Makefile.am
990-===================================================================
991+diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am
992+index 7d0b309..81bfeb3 100644
993 --- a/gst-libs/gst/Makefile.am
994 +++ b/gst-libs/gst/Makefile.am
995-@@ -6,12 +6,16 @@
996+@@ -6,12 +6,16 @@ if USE_GLES2
997 GL_DIR = gl
998 endif
999
1000@@ -1709,7 +1715,7 @@ Index: b/gst-libs/gst/Makefile.am
1001
1002 noinst_HEADERS = gst-i18n-plugin.h gettext.h glib-compat-private.h
1003 DIST_SUBDIRS = uridownloader adaptivedemux interfaces gl basecamerabinsrc \
1004-@@ -24,7 +28,7 @@
1005+@@ -24,7 +28,7 @@ adaptivedemux: uridownloader
1006
1007 INDEPENDENT_SUBDIRS = \
1008 interfaces basecamerabinsrc codecparsers insertbin uridownloader \
1009@@ -1718,8 +1724,9 @@ Index: b/gst-libs/gst/Makefile.am
1010
1011 .PHONY: independent-subdirs $(INDEPENDENT_SUBDIRS)
1012
1013-Index: b/gst-libs/gst/mir/Makefile.am
1014-===================================================================
1015+diff --git a/gst-libs/gst/mir/Makefile.am b/gst-libs/gst/mir/Makefile.am
1016+new file mode 100644
1017+index 0000000..a2bfe9b
1018 --- /dev/null
1019 +++ b/gst-libs/gst/mir/Makefile.am
1020 @@ -0,0 +1,26 @@
1021@@ -1749,8 +1756,9 @@ Index: b/gst-libs/gst/mir/Makefile.am
1022 + $(GST_LIB_LDFLAGS) \
1023 + $(GST_ALL_LDFLAGS) \
1024 + $(GST_LT_LDFLAGS)
1025-Index: b/gst-libs/gst/mir/gstmircontext.c
1026-===================================================================
1027+diff --git a/gst-libs/gst/mir/gstmircontext.c b/gst-libs/gst/mir/gstmircontext.c
1028+new file mode 100644
1029+index 0000000..c4ba833
1030 --- /dev/null
1031 +++ b/gst-libs/gst/mir/gstmircontext.c
1032 @@ -0,0 +1,155 @@
1033@@ -1909,8 +1917,9 @@ Index: b/gst-libs/gst/mir/gstmircontext.c
1034 +
1035 + return NULL;
1036 +}
1037-Index: b/gst-libs/gst/mir/gstmircontext.h
1038-===================================================================
1039+diff --git a/gst-libs/gst/mir/gstmircontext.h b/gst-libs/gst/mir/gstmircontext.h
1040+new file mode 100644
1041+index 0000000..2226684
1042 --- /dev/null
1043 +++ b/gst-libs/gst/mir/gstmircontext.h
1044 @@ -0,0 +1,43 @@
1045@@ -1957,8 +1966,9 @@ Index: b/gst-libs/gst/mir/gstmircontext.h
1046 +G_END_DECLS
1047 +
1048 +#endif /* __GST_MIR_COMMON_H__ */
1049-Index: b/gst-libs/gst/mir/mirallocator.c
1050-===================================================================
1051+diff --git a/gst-libs/gst/mir/mirallocator.c b/gst-libs/gst/mir/mirallocator.c
1052+new file mode 100644
1053+index 0000000..ac6e766
1054 --- /dev/null
1055 +++ b/gst-libs/gst/mir/mirallocator.c
1056 @@ -0,0 +1,272 @@
1057@@ -2234,8 +2244,9 @@ Index: b/gst-libs/gst/mir/mirallocator.c
1058 +
1059 + return GST_MEMORY_CAST (mem);
1060 +}
1061-Index: b/gst-libs/gst/mir/mirallocator.h
1062-===================================================================
1063+diff --git a/gst-libs/gst/mir/mirallocator.h b/gst-libs/gst/mir/mirallocator.h
1064+new file mode 100644
1065+index 0000000..efe3fe0
1066 --- /dev/null
1067 +++ b/gst-libs/gst/mir/mirallocator.h
1068 @@ -0,0 +1,69 @@
1069@@ -2308,11 +2319,11 @@ Index: b/gst-libs/gst/mir/mirallocator.h
1070 + gpointer user_data, GDestroyNotify user_data_destroy);
1071 +
1072 +#endif /* __GST_MIR_ALLOCATOR_H__ */
1073-Index: b/sys/Makefile.am
1074-===================================================================
1075+diff --git a/sys/Makefile.am b/sys/Makefile.am
1076+index 5365316..23215eb 100644
1077 --- a/sys/Makefile.am
1078 +++ b/sys/Makefile.am
1079-@@ -10,6 +10,12 @@
1080+@@ -10,6 +10,12 @@ else
1081 ANDROID_MEDIA_DIR=
1082 endif
1083
1084@@ -2325,8 +2336,8 @@ Index: b/sys/Makefile.am
1085 if USE_APPLE_MEDIA
1086 APPLE_MEDIA_DIR=applemedia
1087 else
1088-Index: b/sys/androidmedia/Makefile.am
1089-===================================================================
1090+diff --git a/sys/androidmedia/Makefile.am b/sys/androidmedia/Makefile.am
1091+index cb194f1..6507e85 100644
1092 --- a/sys/androidmedia/Makefile.am
1093 +++ b/sys/androidmedia/Makefile.am
1094 @@ -1,6 +1,12 @@
1095@@ -2343,7 +2354,7 @@ Index: b/sys/androidmedia/Makefile.am
1096 gstahcsrc.c \
1097 gstahssrc.c \
1098 gstamcaudiodec.c \
1099-@@ -13,6 +19,7 @@
1100+@@ -13,6 +19,7 @@ libgstandroidmedia_la_SOURCES = \
1101 gst-android-hardware-camera.c \
1102 gst-android-hardware-sensor.c \
1103 gstjniutils.c
1104@@ -2351,7 +2362,7 @@ Index: b/sys/androidmedia/Makefile.am
1105
1106 noinst_HEADERS = \
1107 gstahcsrc.h \
1108-@@ -33,9 +40,11 @@
1109+@@ -33,9 +40,11 @@ noinst_HEADERS = \
1110 libgstandroidmedia_la_CFLAGS = \
1111 -I$(top_srcdir)/gst-libs \
1112 -I$(top_builddir)/gst-libs \
1113@@ -2363,7 +2374,7 @@ Index: b/sys/androidmedia/Makefile.am
1114 $(ORC_CFLAGS) \
1115 -DGST_USE_UNSTABLE_API
1116
1117-@@ -43,20 +52,24 @@
1118+@@ -43,15 +52,19 @@ libgstandroidmedia_la_LIBADD = \
1119 $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-$(GST_API_VERSION).la \
1120 $(top_builddir)/gst-libs/gst/gl/libgstgl-$(GST_API_VERSION).la \
1121 $(GST_PLUGINS_BASE_LIBS) \
1122@@ -2373,7 +2384,7 @@ Index: b/sys/androidmedia/Makefile.am
1123 -lgstvideo-@GST_API_VERSION@ \
1124 + -lmedia \
1125 $(GST_BASE_LIBS) \
1126-- $(GST_LIBS) \
1127+ $(GST_LIBS) \
1128 - $(ORC_LIBS)
1129 + $(ORC_LIBS) \
1130 + $(top_builddir)/gst-libs/gst/mir/libgstmiralloc-@GST_API_VERSION@.la
1131@@ -2384,17 +2395,16 @@ Index: b/sys/androidmedia/Makefile.am
1132 androidmedia_java_classesdir = $(datadir)/gst-android/ndk-build/androidmedia/
1133 androidmedia_java_classes_DATA = \
1134 org/freedesktop/gstreamer/androidmedia/GstAhcCallback.java \
1135- org/freedesktop/gstreamer/androidmedia/GstAhsCallback.java \
1136- org/freedesktop/gstreamer/androidmedia/GstAmcOnFrameAvailableListener.java
1137-+endif
1138+@@ -60,3 +73,4 @@ androidmedia_java_classes_DATA = \
1139
1140 # Make sure the .java files end up in the tarball
1141 EXTRA_DIST = $(androidmedia_java_classes_DATA)
1142-Index: b/sys/androidmedia/gstamc-constants.h
1143-===================================================================
1144++endif
1145+diff --git a/sys/androidmedia/gstamc-constants.h b/sys/androidmedia/gstamc-constants.h
1146+index cc43f61..8ef701f 100644
1147 --- a/sys/androidmedia/gstamc-constants.h
1148 +++ b/sys/androidmedia/gstamc-constants.h
1149-@@ -92,7 +92,10 @@
1150+@@ -92,7 +92,10 @@ enum
1151 COLOR_Format18BitBGR666 = 41,
1152 COLOR_Format24BitARGB6666 = 42,
1153 COLOR_Format24BitABGR6666 = 43,
1154@@ -2405,7 +2415,7 @@ Index: b/sys/androidmedia/gstamc-constants.h
1155 COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100,
1156 COLOR_INTEL_FormatYUV420PackedSemiPlanar = 0x7fa00e00,
1157 COLOR_INTEL_FormatYUV420PackedSemiPlanar_Tiled = 0x7fa00f00,
1158-@@ -112,8 +115,15 @@
1159+@@ -112,8 +115,15 @@ enum
1160 * FIXME: Not actually implemented in the video decoder, it will just error out
1161 * The format seems to be equiv to V4L2_PIX_FMT_NV12MT_16X16 */
1162 COLOR_OMX_SEC_FormatNV12Tiled = 0x7fc00002,
1163@@ -2421,8 +2431,8 @@ Index: b/sys/androidmedia/gstamc-constants.h
1164 };
1165
1166 enum
1167-Index: b/sys/androidmedia/gstamc.h
1168-===================================================================
1169+diff --git a/sys/androidmedia/gstamc.h b/sys/androidmedia/gstamc.h
1170+index 383eb42..dc5f459 100644
1171 --- a/sys/androidmedia/gstamc.h
1172 +++ b/sys/androidmedia/gstamc.h
1173 @@ -24,12 +24,67 @@
1174@@ -2494,7 +2504,7 @@ Index: b/sys/androidmedia/gstamc.h
1175 typedef struct _GstAmcCodecInfo GstAmcCodecInfo;
1176 typedef struct _GstAmcCodecType GstAmcCodecType;
1177 typedef struct _GstAmcCodec GstAmcCodec;
1178-@@ -59,16 +114,29 @@
1179+@@ -59,16 +114,29 @@ struct _GstAmcCodecInfo {
1180 };
1181
1182 struct _GstAmcFormat {
1183@@ -2524,7 +2534,7 @@ Index: b/sys/androidmedia/gstamc.h
1184 };
1185
1186 struct _GstAmcBufferInfo {
1187-@@ -83,7 +151,15 @@
1188+@@ -83,7 +151,15 @@ extern GQuark gst_amc_codec_info_quark;
1189 GstAmcCodec * gst_amc_codec_new (const gchar *name, GError **err);
1190 void gst_amc_codec_free (GstAmcCodec * codec);
1191
1192@@ -2540,7 +2550,7 @@ Index: b/sys/androidmedia/gstamc.h
1193 GstAmcFormat * gst_amc_codec_get_output_format (GstAmcCodec * codec, GError **err);
1194
1195 gboolean gst_amc_codec_start (GstAmcCodec * codec, GError **err);
1196-@@ -91,18 +167,33 @@
1197+@@ -91,18 +167,33 @@ gboolean gst_amc_codec_stop (GstAmcCodec * codec, GError **err);
1198 gboolean gst_amc_codec_flush (GstAmcCodec * codec, GError **err);
1199 gboolean gst_amc_codec_release (GstAmcCodec * codec, GError **err);
1200
1201@@ -2559,9 +2569,9 @@ Index: b/sys/androidmedia/gstamc.h
1202
1203 gboolean gst_amc_codec_queue_input_buffer (GstAmcCodec * codec, gint index, const GstAmcBufferInfo *info, GError **err);
1204 +#ifdef HAVE_ANDROID_MEDIA_HYBRIS
1205-+gboolean gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index, gboolean render, GError **err);
1206-+#else
1207 gboolean gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index, gboolean render, GError **err);
1208++#else
1209++gboolean gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index, gboolean render, GError **err);
1210 +#endif
1211
1212
1213@@ -2574,7 +2584,7 @@ Index: b/sys/androidmedia/gstamc.h
1214 void gst_amc_format_free (GstAmcFormat * format);
1215
1216 gchar * gst_amc_format_to_string (GstAmcFormat * format, GError **err);
1217-@@ -118,6 +209,10 @@
1218+@@ -118,6 +209,10 @@ gboolean gst_amc_format_set_string (GstAmcFormat *format, const gchar *key, cons
1219 gboolean gst_amc_format_get_buffer (GstAmcFormat *format, const gchar *key, guint8 **data, gsize *size, GError **err);
1220 gboolean gst_amc_format_set_buffer (GstAmcFormat *format, const gchar *key, guint8 *data, gsize size, GError **err);
1221
1222@@ -2585,11 +2595,11 @@ Index: b/sys/androidmedia/gstamc.h
1223 GstVideoFormat gst_amc_color_format_to_video_format (const GstAmcCodecInfo * codec_info, const gchar * mime, gint color_format);
1224 gint gst_amc_video_format_to_color_format (const GstAmcCodecInfo * codec_info, const gchar * mime, GstVideoFormat video_format);
1225
1226-Index: b/sys/androidmedia/gstamcaudiodec.h
1227-===================================================================
1228+diff --git a/sys/androidmedia/gstamcaudiodec.h b/sys/androidmedia/gstamcaudiodec.h
1229+index 04e9734..72d68fc 100644
1230 --- a/sys/androidmedia/gstamcaudiodec.h
1231 +++ b/sys/androidmedia/gstamcaudiodec.h
1232-@@ -51,6 +51,10 @@
1233+@@ -51,6 +51,10 @@ struct _GstAmcAudioDec
1234
1235 /* < private > */
1236 GstAmcCodec *codec;
1237@@ -2600,7 +2610,7 @@ Index: b/sys/androidmedia/gstamcaudiodec.h
1238
1239 GstCaps *input_caps;
1240 GList *codec_datas;
1241-@@ -81,6 +85,10 @@
1242+@@ -81,6 +85,10 @@ struct _GstAmcAudioDec
1243 gboolean draining;
1244 /* TRUE if the component is drained currently */
1245 gboolean drained;
1246@@ -2611,8 +2621,9 @@ Index: b/sys/androidmedia/gstamcaudiodec.h
1247
1248 GstFlowReturn downstream_flow_ret;
1249 };
1250-Index: b/sys/androidmedia/gstamcaudiodechybris.c
1251-===================================================================
1252+diff --git a/sys/androidmedia/gstamcaudiodechybris.c b/sys/androidmedia/gstamcaudiodechybris.c
1253+new file mode 100644
1254+index 0000000..f361418
1255 --- /dev/null
1256 +++ b/sys/androidmedia/gstamcaudiodechybris.c
1257 @@ -0,0 +1,1291 @@
1258@@ -3907,8 +3918,9 @@ Index: b/sys/androidmedia/gstamcaudiodechybris.c
1259 +
1260 + return ret;
1261 +}
1262-Index: b/sys/androidmedia/gstamchybris.c
1263-===================================================================
1264+diff --git a/sys/androidmedia/gstamchybris.c b/sys/androidmedia/gstamchybris.c
1265+new file mode 100644
1266+index 0000000..f01a873
1267 --- /dev/null
1268 +++ b/sys/androidmedia/gstamchybris.c
1269 @@ -0,0 +1,2189 @@
1270@@ -6101,8 +6113,8 @@ Index: b/sys/androidmedia/gstamchybris.c
1271 + "Android Media Hybris plugin",
1272 + plugin_init,
1273 + PACKAGE_VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
1274-Index: b/sys/androidmedia/gstamcvideodec.h
1275-===================================================================
1276+diff --git a/sys/androidmedia/gstamcvideodec.h b/sys/androidmedia/gstamcvideodec.h
1277+index 039a785..9dd60f5 100644
1278 --- a/sys/androidmedia/gstamcvideodec.h
1279 +++ b/sys/androidmedia/gstamcvideodec.h
1280 @@ -22,12 +22,20 @@
1281@@ -6128,7 +6140,7 @@ Index: b/sys/androidmedia/gstamcvideodec.h
1282
1283 G_BEGIN_DECLS
1284
1285-@@ -62,10 +70,19 @@
1286+@@ -62,10 +70,19 @@ struct _GstAmcVideoDec
1287 /* < private > */
1288 GstAmcCodec *codec;
1289 GstAmcCodecConfig codec_config;
1290@@ -6148,7 +6160,7 @@ Index: b/sys/androidmedia/gstamcvideodec.h
1291 /* Output format of the codec */
1292 GstVideoFormat format;
1293 GstAmcColorFormatInfo color_format_info;
1294-@@ -81,6 +98,10 @@
1295+@@ -81,6 +98,10 @@ struct _GstAmcVideoDec
1296 gboolean started;
1297 gboolean flushing;
1298
1299@@ -6159,7 +6171,7 @@ Index: b/sys/androidmedia/gstamcvideodec.h
1300 GstClockTime last_upstream_ts;
1301
1302 /* Draining state */
1303-@@ -90,21 +111,30 @@
1304+@@ -90,21 +111,30 @@ struct _GstAmcVideoDec
1305 gboolean draining;
1306 /* TRUE if the component is drained currently */
1307 gboolean drained;
1308@@ -6190,7 +6202,7 @@ Index: b/sys/androidmedia/gstamcvideodec.h
1309 GError *gl_error;
1310 GMutex gl_lock;
1311 GCond gl_cond;
1312-@@ -113,6 +143,16 @@
1313+@@ -113,6 +143,16 @@ struct _GstAmcVideoDec
1314 guint gl_ready_frame_count; /* n buffers ready for GL access */
1315 guint gl_released_frame_count; /* n buffers released */
1316 GQueue *gl_queue;
1317@@ -6207,8 +6219,9 @@ Index: b/sys/androidmedia/gstamcvideodec.h
1318 };
1319
1320 struct _GstAmcVideoDecClass
1321-Index: b/sys/androidmedia/gstamcvideodechybris.c
1322-===================================================================
1323+diff --git a/sys/androidmedia/gstamcvideodechybris.c b/sys/androidmedia/gstamcvideodechybris.c
1324+new file mode 100644
1325+index 0000000..5a97e88
1326 --- /dev/null
1327 +++ b/sys/androidmedia/gstamcvideodechybris.c
1328 @@ -0,0 +1,2408 @@
1329@@ -6252,7 +6265,7 @@ Index: b/sys/androidmedia/gstamcvideodechybris.c
1330 +#include <string.h>
1331 +
1332 +#include <gst/mir/mirallocator.h>
1333-+#include <ext/mir/mirpool.h>
1334++#include <ext/hybris/mirpool.h>
1335 +
1336 +#ifdef HAVE_ORC
1337 +#include <orc/orc.h>
1338@@ -8620,11 +8633,11 @@ Index: b/sys/androidmedia/gstamcvideodechybris.c
1339 +
1340 + return TRUE;
1341 +}
1342-Index: b/tests/check/Makefile.am
1343-===================================================================
1344+diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
1345+index 39f5aba..24051d8 100644
1346 --- a/tests/check/Makefile.am
1347 +++ b/tests/check/Makefile.am
1348-@@ -217,6 +217,12 @@
1349+@@ -217,6 +217,12 @@ else
1350 check_gl=
1351 endif
1352
1353@@ -8637,7 +8650,7 @@ Index: b/tests/check/Makefile.am
1354 VALGRIND_TO_FIX = \
1355 elements/mpeg2enc \
1356 elements/mplex \
1357-@@ -282,6 +288,7 @@
1358+@@ -282,6 +288,7 @@ check_PROGRAMS = \
1359 elements/rtponviftimestamp \
1360 elements/id3mux \
1361 pipelines/mxf \
1362@@ -8645,8 +8658,9 @@ Index: b/tests/check/Makefile.am
1363 $(check_mimic) \
1364 libs/mpegvideoparser \
1365 libs/mpegts \
1366-Index: b/tests/check/pipelines/gstamcvideodec.c
1367-===================================================================
1368+diff --git a/tests/check/pipelines/gstamcvideodec.c b/tests/check/pipelines/gstamcvideodec.c
1369+new file mode 100644
1370+index 0000000..eb6d9e9
1371 --- /dev/null
1372 +++ b/tests/check/pipelines/gstamcvideodec.c
1373 @@ -0,0 +1,538 @@
1374@@ -9188,8 +9202,9 @@ Index: b/tests/check/pipelines/gstamcvideodec.c
1375 +}
1376 +
1377 +GST_CHECK_MAIN (gstamcvideodec);
1378-Index: b/tests/check/pipelines/gstamcvideodec_egl.c
1379-===================================================================
1380+diff --git a/tests/check/pipelines/gstamcvideodec_egl.c b/tests/check/pipelines/gstamcvideodec_egl.c
1381+new file mode 100644
1382+index 0000000..56b70ed
1383 --- /dev/null
1384 +++ b/tests/check/pipelines/gstamcvideodec_egl.c
1385 @@ -0,0 +1,56 @@
1386diff --git a/debian/patches/desktop-mirsink.patch b/debian/patches/desktop-mirsink.patch
1387new file mode 100644
1388index 0000000..c1ff0c7
1389--- /dev/null
1390+++ b/debian/patches/desktop-mirsink.patch
1391@@ -0,0 +1,1355 @@
1392+From: =?utf-8?q?Alfonso_S=C3=A1nchez-Beato?= <alfonsosanchezbeato@yahoo.es>
1393+Date: Tue, 14 Feb 2017 16:39:12 +0100
1394+Subject: New mirsink for desktop usage
1395+
1396+The mirsink works in two modes: if "export-buffers" property is set, it
1397+exports dma buffers that are sent to the client by posting a GstMessage.
1398+If not, it creates its own rendering Mir window.
1399+
1400+From: Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>
1401+Origin: vendor
1402+Forwarded: no
1403+---
1404+ configure.ac | 13 +
1405+ ext/Makefile.am | 8 +
1406+ ext/mir/Makefile.am | 14 +
1407+ ext/mir/gstmirsink.c | 1113 ++++++++++++++++++++++++++++++++++++++++++++++++++
1408+ ext/mir/gstmirsink.h | 117 ++++++
1409+ 5 files changed, 1265 insertions(+)
1410+ create mode 100644 ext/mir/Makefile.am
1411+ create mode 100644 ext/mir/gstmirsink.c
1412+ create mode 100644 ext/mir/gstmirsink.h
1413+
1414+diff --git a/configure.ac b/configure.ac
1415+index 7444429..54b1891 100644
1416+--- a/configure.ac
1417++++ b/configure.ac
1418+@@ -1796,6 +1796,17 @@ AG_GST_CHECK_FEATURE(ANDROID_MEDIA_HYBRIS, [Android Media Hybris], androidmediah
1419+ )], HAVE_ANDROID_MEDIA_HYBRIS="no")
1420+ ])
1421+
1422++dnl *** A mir-based Platform ***
1423++translit(dnm, m, l) AM_CONDITIONAL(USE_MIR, true)
1424++HAVE_MIR="no"
1425++dnl Check for the presence of Mir client library
1426++AG_GST_CHECK_FEATURE(MIR, [Mir Server], mir, [
1427++ PKG_CHECK_MODULES(MIR, mirclient,
1428++ [HAVE_MIR="yes"],
1429++ [HAVE_MIR="no"]
1430++ )
1431++])
1432++
1433+ dnl *** AppleMedia (OS X and iOS) ***
1434+ translit(dnm, m, l) AM_CONDITIONAL(USE_APPLE_MEDIA, true)
1435+ HAVE_APPLE_MEDIA="no"
1436+@@ -3477,6 +3488,7 @@ AM_CONDITIONAL(USE_DIRECTFB, false)
1437+ AM_CONDITIONAL(USE_WAYLAND, false)
1438+ AM_CONDITIONAL(USE_DAALA, false)
1439+ AM_CONDITIONAL(USE_ANDROID_MEDIA_HYBRIS, false)
1440++AM_CONDITIONAL(USE_MIR, false)
1441+ AM_CONDITIONAL(USE_DTS, false)
1442+ AM_CONDITIONAL(USE_EXIF, false)
1443+ AM_CONDITIONAL(USE_RESINDVD, false)
1444+@@ -3818,6 +3830,7 @@ ext/libde265/Makefile
1445+ ext/libmms/Makefile
1446+ ext/libvisual/Makefile
1447+ ext/Makefile
1448++ext/mir/Makefile
1449+ ext/modplug/Makefile
1450+ ext/mpeg2enc/Makefile
1451+ ext/mimic/Makefile
1452+diff --git a/ext/Makefile.am b/ext/Makefile.am
1453+index 709bdb2..3ff2fc9 100644
1454+--- a/ext/Makefile.am
1455++++ b/ext/Makefile.am
1456+@@ -76,6 +76,12 @@ else
1457+ HYBRIS_DIR=
1458+ endif
1459+
1460++if USE_MIR
1461++MIR_DIR=mir
1462++else
1463++MIR_DIR=
1464++endif
1465++
1466+ if USE_DTS
1467+ DTS_DIR=dts
1468+ else
1469+@@ -464,6 +470,7 @@ SUBDIRS=\
1470+ $(LIBMMS_DIR) \
1471+ $(LIBVISUAL_DIR) \
1472+ $(HYBRIS_DIR) \
1473++ $(MIR_DIR) \
1474+ $(MODPLUG_DIR) \
1475+ $(MPEG2ENC_DIR) \
1476+ $(MIMIC_DIR) \
1477+@@ -516,6 +523,7 @@ DIST_SUBDIRS = \
1478+ directfb \
1479+ wayland \
1480+ hybris \
1481++ mir \
1482+ faac \
1483+ faad \
1484+ fdkaac \
1485+diff --git a/ext/mir/Makefile.am b/ext/mir/Makefile.am
1486+new file mode 100644
1487+index 0000000..c691e7a
1488+--- /dev/null
1489++++ b/ext/mir/Makefile.am
1490+@@ -0,0 +1,14 @@
1491++plugin_LTLIBRARIES = libgstmirsink.la
1492++
1493++libgstmirsink_la_SOURCES = gstmirsink.c
1494++libgstmirsink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
1495++ $(MIR_CFLAGS) \
1496++ -I../../gst-libs/
1497++libgstmirsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS) \
1498++ -lgstvideo-$(GST_API_VERSION) \
1499++ $(GL_LIBS) $(EGL_LIBS) $(EGLGLES_LIBS) \
1500++ $(MIR_LIBS)
1501++libgstmirsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
1502++libgstmirsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
1503++include_HEADERS = gstmirsink.h
1504++noinst_HEADERS =
1505+diff --git a/ext/mir/gstmirsink.c b/ext/mir/gstmirsink.c
1506+new file mode 100644
1507+index 0000000..533ae67
1508+--- /dev/null
1509++++ b/ext/mir/gstmirsink.c
1510+@@ -0,0 +1,1113 @@
1511++/*
1512++ * GStreamer Mir video sink
1513++ * Copyright (C) 2017 Canonical Ltd
1514++ *
1515++ * This library is free software; you can redistribute it and/or
1516++ * modify it under the terms of the GNU Library General Public
1517++ * License as published by the Free Software Foundation; either
1518++ * version 3 of the License, or (at your option) any later version.
1519++ *
1520++ * This library is distributed in the hope that it will be useful,
1521++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1522++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1523++ * Library General Public License for more details.
1524++ *
1525++ * You should have received a copy of the GNU Library General Public
1526++ * License along with this library; if not, write to the Free
1527++ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1528++ * Boston, MA 02110-1301 USA.
1529++ */
1530++
1531++/**
1532++ * SECTION:element-mirsink
1533++ *
1534++ * The mirsink works in two modes: if "export-buffers" property is set, it
1535++ * exports dma buffers that are sent to the client by posting a GstMessage.
1536++ * If not, it creates its own rendering window.
1537++ * TODO: a third mode where the rendering surface is provided by the client.
1538++ *
1539++ * <refsect2>
1540++ * <title>Example pipeline</title>
1541++ * |[
1542++ * gst-launch-1.0 filesrc location=<video_file> ! qtdemux ! queue ! \
1543++ * h264parse ! avdec_h264 ! mirsink
1544++ * ]| test the video rendering with mirsink
1545++ * </refsect2>
1546++ */
1547++
1548++#ifdef HAVE_CONFIG_H
1549++#include <config.h>
1550++#endif
1551++
1552++#include "gstmirsink.h"
1553++
1554++/* signals */
1555++enum
1556++{
1557++ SIGNAL_0,
1558++ LAST_SIGNAL
1559++};
1560++
1561++/* Properties */
1562++enum
1563++{
1564++ PROP_0,
1565++ PROP_MIR_EXPORT_BUFFERS,
1566++ PROP_MIR_VIDEO_HEIGHT,
1567++ PROP_MIR_VIDEO_WIDTH
1568++};
1569++
1570++GST_DEBUG_CATEGORY (gstmir_debug);
1571++#define GST_CAT_DEFAULT gstmir_debug
1572++
1573++static GstStaticPadTemplate gst_mirsink_sink_caps_template =
1574++ GST_STATIC_PAD_TEMPLATE ("sink",
1575++ GST_PAD_SINK,
1576++ GST_PAD_ALWAYS,
1577++ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
1578++ ("{ BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, "
1579++ "RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, "
1580++ "YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }"))
1581++ );
1582++
1583++#define gst_mir_sink_parent_class parent_class
1584++G_DEFINE_TYPE (GstMirSink, gst_mir_sink, GST_TYPE_VIDEO_SINK);
1585++
1586++static void gst_mir_sink_get_property (GObject * object,
1587++ guint prop_id, GValue * value, GParamSpec * pspec);
1588++static void gst_mir_sink_set_property (GObject * object,
1589++ guint prop_id, const GValue * value, GParamSpec * pspec);
1590++static void gst_mir_sink_finalize (GObject * object);
1591++static void gst_mir_sink_set_context (GstElement * element,
1592++ GstContext * context);
1593++static GstCaps *gst_mir_sink_get_caps (GstBaseSink * bsink, GstCaps * filter);
1594++static gboolean gst_mir_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
1595++static gboolean gst_mir_sink_start (GstBaseSink * bsink);
1596++static gboolean gst_mir_sink_stop (GstBaseSink * bsink);
1597++static gboolean gst_mir_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer);
1598++static gboolean
1599++gst_mir_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query);
1600++static gboolean gst_mir_sink_render (GstBaseSink * bsink, GstBuffer * buffer);
1601++static gboolean gst_mir_sink_query (GstBaseSink * bsink, GstQuery * query);
1602++
1603++static void
1604++gst_mir_sink_class_init (GstMirSinkClass * klass)
1605++{
1606++ GObjectClass *gobject_class;
1607++ GstElementClass *gstelement_class;
1608++ GstBaseSinkClass *gstbasesink_class;
1609++
1610++ gobject_class = (GObjectClass *) klass;
1611++ gstelement_class = (GstElementClass *) klass;
1612++ gstbasesink_class = (GstBaseSinkClass *) klass;
1613++
1614++ gobject_class->set_property = gst_mir_sink_set_property;
1615++ gobject_class->get_property = gst_mir_sink_get_property;
1616++ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_mir_sink_finalize);
1617++
1618++ gst_element_class_add_pad_template (gstelement_class,
1619++ gst_static_pad_template_get (&gst_mirsink_sink_caps_template));
1620++
1621++ gst_element_class_set_static_metadata (gstelement_class,
1622++ "Mir video sink", "Sink/Video",
1623++ "Output to Mir surface",
1624++ "Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>");
1625++
1626++ //gstelement_class->change_state =
1627++ // GST_DEBUG_FUNCPTR (gst_mir_sink_change_state);
1628++ gstelement_class->set_context = GST_DEBUG_FUNCPTR (gst_mir_sink_set_context);
1629++
1630++ gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_mir_sink_get_caps);
1631++ gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_mir_sink_set_caps);
1632++ gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_mir_sink_start);
1633++ gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_mir_sink_stop);
1634++ gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_mir_sink_preroll);
1635++ gstbasesink_class->propose_allocation =
1636++ GST_DEBUG_FUNCPTR (gst_mir_sink_propose_allocation);
1637++ gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_mir_sink_render);
1638++ gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_mir_sink_query);
1639++
1640++ g_object_class_install_property (gobject_class, PROP_MIR_EXPORT_BUFFERS,
1641++ g_param_spec_boolean ("export-buffers", "Export buffers flag",
1642++ "If set, dma_buf fds with decoded video are exported", FALSE,
1643++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1644++
1645++ g_object_class_install_property (gobject_class, PROP_MIR_VIDEO_HEIGHT,
1646++ g_param_spec_uint ("height", "Video Height",
1647++ "Height of each video frame", 0,
1648++ UINT_MAX, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
1649++
1650++ g_object_class_install_property (gobject_class, PROP_MIR_VIDEO_WIDTH,
1651++ g_param_spec_uint ("width", "Video Width",
1652++ "Width of each video frame", 0,
1653++ UINT_MAX, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
1654++}
1655++
1656++static void
1657++gst_mir_sink_init (GstMirSink * sink)
1658++{
1659++ GST_DEBUG_OBJECT (sink, "Initializing mirsink");
1660++ sink->pool = NULL;
1661++
1662++ sink->export_buffers = FALSE;
1663++
1664++ g_mutex_init (&sink->mir_lock);
1665++}
1666++
1667++static void
1668++gst_mir_sink_get_property (GObject * object,
1669++ guint prop_id, GValue * value, GParamSpec * pspec)
1670++{
1671++ GstMirSink *sink = GST_MIR_SINK (object);
1672++
1673++ switch (prop_id) {
1674++ case PROP_MIR_EXPORT_BUFFERS:
1675++ g_value_set_boolean (value, sink->export_buffers);
1676++ break;
1677++ case PROP_MIR_VIDEO_HEIGHT:
1678++ g_value_set_uint (value, sink->video_height);
1679++ break;
1680++ case PROP_MIR_VIDEO_WIDTH:
1681++ g_value_set_uint (value, sink->video_width);
1682++ break;
1683++ default:
1684++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1685++ break;
1686++ }
1687++}
1688++
1689++static void
1690++gst_mir_sink_set_property (GObject * object,
1691++ guint prop_id, const GValue * value, GParamSpec * pspec)
1692++{
1693++ GstMirSink *sink = GST_MIR_SINK (object);
1694++
1695++ switch (prop_id) {
1696++ case PROP_MIR_EXPORT_BUFFERS:
1697++ sink->export_buffers = g_value_get_boolean (value);
1698++ GST_INFO_OBJECT (object, "export_buffers set: %d", sink->export_buffers);
1699++ break;
1700++ default:
1701++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1702++ break;
1703++ }
1704++}
1705++
1706++static void
1707++gst_mir_sink_finalize (GObject * object)
1708++{
1709++ GstMirSink *sink = GST_MIR_SINK (object);
1710++
1711++ GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
1712++
1713++ g_mutex_clear (&sink->mir_lock);
1714++
1715++ G_OBJECT_CLASS (parent_class)->finalize (object);
1716++}
1717++
1718++static void
1719++gst_mir_sink_set_context (GstElement * element, GstContext * context)
1720++{
1721++ /* TODO Will handle reception of mir rendering window */
1722++ GST_INFO_OBJECT (element, "%s", __PRETTY_FUNCTION__);
1723++}
1724++
1725++static gboolean
1726++gst_mir_sink_query (GstBaseSink * bsink, GstQuery * query)
1727++{
1728++ GstMirSink *sink = GST_MIR_SINK (bsink);
1729++
1730++ GST_INFO_OBJECT (sink, "query type %s", GST_QUERY_TYPE_NAME (query));
1731++
1732++ switch (GST_QUERY_TYPE (query)) {
1733++ case GST_QUERY_CONTEXT:
1734++ default:
1735++ goto base_class;
1736++ break;
1737++ }
1738++
1739++base_class:
1740++ return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
1741++}
1742++
1743++static GstCaps *
1744++gst_mir_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
1745++{
1746++ GstMirSink *sink;
1747++ GstCaps *caps;
1748++
1749++ sink = GST_MIR_SINK (bsink);
1750++
1751++ GST_DEBUG_OBJECT (sink, "%s", __PRETTY_FUNCTION__);
1752++
1753++ caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink));
1754++ if (filter) {
1755++ GstCaps *intersection;
1756++
1757++ intersection =
1758++ gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
1759++ gst_caps_unref (caps);
1760++ caps = intersection;
1761++ }
1762++ return caps;
1763++}
1764++
1765++static gboolean
1766++gst_mir_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
1767++{
1768++ GstMirSink *sink = GST_MIR_SINK (bsink);
1769++ GstVideoInfo info;
1770++ GstStructure *structure;
1771++ GstBufferPool *newpool;
1772++
1773++ sink = GST_MIR_SINK (bsink);
1774++
1775++ GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
1776++
1777++ if (!gst_video_info_from_caps (&info, caps))
1778++ goto invalid_format;
1779++
1780++ sink->video_width = info.width;
1781++ sink->video_height = info.height;
1782++ sink->video_format = (info.finfo)->format;
1783++
1784++ GST_DEBUG_OBJECT (sink, "sink->video_width: %u", sink->video_width);
1785++ GST_DEBUG_OBJECT (sink, "sink->video_height: %u", sink->video_height);
1786++ GST_DEBUG_OBJECT (sink, "Format %s (%s, %d)", (info.finfo)->description,
1787++ (info.finfo)->name, sink->video_format);
1788++ GST_DEBUG_OBJECT (sink, "Default allocator at 0x%p",
1789++ gst_allocator_find (NULL));
1790++
1791++ /* Create a new pool for the new configuration */
1792++ GST_DEBUG_OBJECT (sink, "Creating new GstBufferPool");
1793++ newpool = gst_video_buffer_pool_new ();
1794++ if (!newpool)
1795++ goto pool_failed;
1796++
1797++ structure = gst_buffer_pool_get_config (newpool);
1798++ /* Allocate a minimum of 2 buffers and an unlimited maximum (max=0) */
1799++ gst_buffer_pool_config_set_params (structure, caps, info.size, 2, 0);
1800++ /* Using default allocator for decoded buffers */
1801++ gst_buffer_pool_config_set_allocator (structure, gst_allocator_find (NULL),
1802++ NULL);
1803++ if (!gst_buffer_pool_set_config (newpool, structure))
1804++ goto config_failed;
1805++
1806++ gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool);
1807++ gst_object_unref (newpool);
1808++
1809++ GST_DEBUG_OBJECT (sink, "Finishing up set_caps");
1810++
1811++ return TRUE;
1812++
1813++invalid_format:
1814++ {
1815++ GST_DEBUG_OBJECT (sink,
1816++ "Could not locate image format from caps %" GST_PTR_FORMAT, caps);
1817++ return FALSE;
1818++ }
1819++pool_failed:
1820++ {
1821++ GST_DEBUG_OBJECT (sink, "Failed to create new pool");
1822++ return FALSE;
1823++ }
1824++config_failed:
1825++ {
1826++ GST_DEBUG_OBJECT (bsink, "failed setting config");
1827++ gst_object_unref (newpool);
1828++ return FALSE;
1829++ }
1830++}
1831++
1832++/* vertex shader */
1833++static const char vshadersrc[] =
1834++ "attribute vec4 attrpos;\n"
1835++ "attribute vec2 attrcordY;\n"
1836++ "attribute vec2 attrcordU;\n"
1837++ "attribute vec2 attrcordV;\n"
1838++ "varying vec2 cordY;\n"
1839++ "varying vec2 cordU;\n"
1840++ "varying vec2 cordV;\n"
1841++ "\n"
1842++ "void main ()\n"
1843++ "{\n"
1844++ " cordY = attrcordY;\n"
1845++ " cordU = attrcordU;\n"
1846++ " cordV = attrcordV;\n"
1847++ " gl_Position = attrpos;\n"
1848++ "}\n";
1849++
1850++/* fragment shader */
1851++static const char fshadersrc[] =
1852++ "precision mediump float;\n"
1853++ "uniform sampler2D sampY;\n"
1854++ "uniform sampler2D sampU;\n"
1855++ "uniform sampler2D sampV;\n"
1856++ "uniform mat4 yuvmat;\n"
1857++ "varying vec2 cordY;\n"
1858++ "varying vec2 cordU;\n"
1859++ "varying vec2 cordV;\n"
1860++ "\n"
1861++ "/* Convert YV12 to RGB */\n"
1862++ "void main()\n"
1863++ "{\n"
1864++ " vec4 yuv, rgb;\n"
1865++ "\n"
1866++ " yuv.rgba = vec4(texture2D(sampY, cordY).r,\n"
1867++ " texture2D(sampU, cordU).r - 0.5,\n"
1868++ " texture2D(sampV, cordV).r - 0.5,\n"
1869++ " 1.0);\n"
1870++ "\n"
1871++ " rgb = yuvmat * yuv;\n"
1872++ " gl_FragColor = rgb;\n"
1873++ "}\n";
1874++
1875++/* YUV to RGB conversion matrix */
1876++static GLfloat yuv_coef_bt601[4][4] =
1877++{
1878++ { 1.0f, 1.0f, 1.0f, 0.0f },
1879++ { 0.0f, -0.344f, 1.773f, 0.0f },
1880++ { 1.403f, -0.714f, 0.0f, 0.0f },
1881++ { 0.0f, 0.0f, 0.0f, 1.0f }
1882++};
1883++
1884++/* Set vertex coordinates to (-1,1), (1,1), (1,-1), (-1,-1), so we fill all
1885++ * the virtual device surface.
1886++ */
1887++static GLfloat dest_vert[4][2] =
1888++{ { -1.f, 1.f }, { 1.f, 1.f }, { 1.f, -1.f }, { -1.f, -1.f } };
1889++
1890++/* Set texture coordinates to (0,0), (1,0), (1,1), (0,1) so we cover fully the
1891++ * drawn surface. Note that texture coordinates have a [0,1] range.
1892++ */
1893++static GLfloat tex_vert[3][4][2] =
1894++{
1895++ { { 0.f, 0.f }, { 1.f, 0.f }, { 1.f, 1.f }, { 0.f, 1.f } },
1896++ { { 0.f, 0.f }, { 1.f, 0.f }, { 1.f, 1.f }, { 0.f, 1.f } },
1897++ { { 0.f, 0.f }, { 1.f, 0.f }, { 1.f, 1.f }, { 0.f, 1.f } },
1898++};
1899++
1900++static gboolean
1901++gl_error(GstMirSink *sink)
1902++{
1903++ GLenum err;
1904++ gboolean is_gl_err = FALSE;
1905++
1906++ while((err = glGetError()) != GL_NO_ERROR) {
1907++ GST_ERROR_OBJECT (sink, "OpenGL error %d (0x%X)", err, err);
1908++ is_gl_err = TRUE;
1909++ }
1910++
1911++ return is_gl_err;
1912++}
1913++
1914++static GLuint
1915++load_shader (GstMirSink *sink, const char *src, GLenum type)
1916++{
1917++ GLuint shader = glCreateShader (type);
1918++ GLint compiled;
1919++
1920++ if (!shader)
1921++ goto exit;
1922++
1923++ glShaderSource (shader, 1, &src, NULL);
1924++ glCompileShader (shader);
1925++ glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled);
1926++
1927++ if (!compiled) {
1928++ GLchar log[1024];
1929++
1930++ glGetShaderInfoLog (shader, sizeof log - 1, NULL, log);
1931++ log[sizeof log - 1] = '\0';
1932++ GST_ERROR_OBJECT (sink, "load_shader compile failed: %s", log);
1933++ glDeleteShader (shader);
1934++ shader = 0;
1935++ }
1936++
1937++exit:
1938++ return shader;
1939++}
1940++
1941++static gboolean
1942++create_shaders (GstMirSink *sink)
1943++{
1944++ GLint linked;
1945++ int i;
1946++
1947++ sink->vshader = load_shader (sink, vshadersrc, GL_VERTEX_SHADER);
1948++ if (!sink->vshader) {
1949++ GST_ERROR_OBJECT (sink, "Cannot create vertex shader for mirsink");
1950++ goto error;
1951++ }
1952++ sink->fshader = load_shader (sink, fshadersrc, GL_FRAGMENT_SHADER);
1953++ if (!sink->fshader) {
1954++ GST_ERROR_OBJECT (sink, "Cannot create fragment shader for mirsink");
1955++ goto error;
1956++ }
1957++ sink->prog = glCreateProgram ();
1958++ if (!sink->prog) {
1959++ GST_ERROR_OBJECT (sink, "Cannot create GLSL program");
1960++ goto error;
1961++ }
1962++ glAttachShader (sink->prog, sink->vshader);
1963++ glAttachShader (sink->prog, sink->fshader);
1964++ glLinkProgram (sink->prog);
1965++
1966++ glGetProgramiv (sink->prog, GL_LINK_STATUS, &linked);
1967++ if (!linked) {
1968++ GLchar log[1024];
1969++ glGetProgramInfoLog (sink->prog, sizeof log - 1, NULL, log);
1970++ log[sizeof log - 1] = '\0';
1971++ GST_ERROR_OBJECT (sink, "Link failed: %s", log);
1972++ goto error;
1973++ }
1974++
1975++ glUseProgram (sink->prog);
1976++
1977++ sink->attrpos = glGetAttribLocation (sink->prog, "attrpos");
1978++ sink->attrcordYUV[0] = glGetAttribLocation (sink->prog, "attrcordY");
1979++ sink->attrcordYUV[1] = glGetAttribLocation (sink->prog, "attrcordU");
1980++ sink->attrcordYUV[2] = glGetAttribLocation (sink->prog, "attrcordV");
1981++ sink->sampYUV[0] = glGetUniformLocation (sink->prog, "sampY");
1982++ sink->sampYUV[1] = glGetUniformLocation (sink->prog, "sampU");
1983++ sink->sampYUV[2] = glGetUniformLocation (sink->prog, "sampV");
1984++ sink->yuvmat = glGetUniformLocation (sink->prog, "yuvmat");
1985++
1986++ /* Set shader variables */
1987++
1988++ glUniformMatrix4fv (sink->yuvmat, 1, GL_FALSE, &yuv_coef_bt601[0][0]);
1989++
1990++ /* Missing components filled by specification with (0,0,0,1) */
1991++ glVertexAttribPointer (sink->attrpos, 2, GL_FLOAT, GL_FALSE, 0, dest_vert);
1992++ glEnableVertexAttribArray (sink->attrpos);
1993++
1994++ for (i = 0; i < G_N_ELEMENTS (sink->attrcordYUV); ++i) {
1995++ glVertexAttribPointer (sink->attrcordYUV[i], 2, GL_FLOAT,
1996++ GL_FALSE, 0, tex_vert[i]);
1997++ glEnableVertexAttribArray (sink->attrcordYUV[i]);
1998++ }
1999++
2000++ /* Create textures for YUV planes */
2001++ glGenTextures (G_N_ELEMENTS (sink->text_id), sink->text_id);
2002++
2003++ for (i = 0; i < G_N_ELEMENTS (sink->attrcordYUV); ++i) {
2004++ /* GL_TEXTUREi = GL_TEXTURE0 + i is guaranteed */
2005++ /* Looks like OGLES selects the first free texture anyway, so calling
2006++ * glActiveTexture here is not a must. But it is needed when rendering. */
2007++ glActiveTexture (GL_TEXTURE0 + i);
2008++ glBindTexture (GL_TEXTURE_2D, sink->text_id[i]);
2009++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2010++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2011++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2012++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2013++ glUniform1i (sink->sampYUV[i], i);
2014++ }
2015++
2016++ if (gl_error (sink))
2017++ goto error;
2018++
2019++ return TRUE;
2020++
2021++error:
2022++ glDeleteTextures (G_N_ELEMENTS (sink->text_id), sink->text_id);
2023++ /* So we know they do not exist anymore */
2024++ memset (sink->text_id, 0, sizeof sink->text_id);
2025++
2026++ glDisableVertexAttribArray (sink->attrpos);
2027++ sink->attrpos = 0;
2028++ for (i = 0; i < G_N_ELEMENTS (sink->attrcordYUV); ++i)
2029++ glDisableVertexAttribArray (sink->attrcordYUV[i]);
2030++ /* So we know they do not exist anymore */
2031++ memset (sink->attrcordYUV, 0, sizeof sink->attrcordYUV);
2032++
2033++ glDeleteShader (sink->vshader);
2034++ glDeleteShader (sink->fshader);
2035++ glDeleteProgram (sink->prog);
2036++ sink->vshader = 0;
2037++ sink->fshader = 0;
2038++ sink->prog = 0;
2039++
2040++ return FALSE;
2041++}
2042++
2043++static void
2044++mir_eglapp_handle_event (MirWindow *surface, MirEvent const *ev, void *ctx)
2045++{
2046++ GstMirSink *sink = ctx;
2047++
2048++ switch (mir_event_get_type (ev)) {
2049++ case mir_event_type_input:
2050++ case mir_event_type_surface:
2051++ case mir_event_type_resize:
2052++ break;
2053++ case mir_event_type_close_surface:
2054++ /* TODO Stop streaming if this happens. Handle locking. */
2055++ GST_DEBUG_OBJECT (sink, "Received close event from server");
2056++ break;
2057++ default:
2058++ break;
2059++ }
2060++}
2061++
2062++static const MirOutput *
2063++find_active_output (const MirDisplayConfig *conf)
2064++{
2065++ int num_outputs = mir_display_config_get_num_outputs (conf);
2066++ int i;
2067++
2068++ for (i = 0; i < num_outputs; ++i) {
2069++ MirOutput const *output = mir_display_config_get_output (conf, i);
2070++ MirOutputConnectionState state = mir_output_get_connection_state (output);
2071++
2072++ if (state == mir_output_connection_state_connected &&
2073++ mir_output_is_enabled (output))
2074++ return output;
2075++ }
2076++
2077++ return NULL;
2078++}
2079++
2080++static EGLSurface
2081++create_window (GstMirSink *sink, EGLConfig eglconfig)
2082++{
2083++ MirEGLNativeWindowType mir_window;
2084++ MirDisplayConfig *display_config = NULL;
2085++ const MirOutput *display_output;
2086++ const MirOutputMode *display_mode;
2087++ int pos_x, pos_y;
2088++ MirWindowSpec *spec = NULL;
2089++ MirPixelFormat pixel_format;
2090++ int width, height;
2091++ MirBufferStream *buff_stream;
2092++
2093++ pixel_format = mir_connection_get_egl_pixel_format (sink->conn,
2094++ sink->egldisplay, eglconfig);
2095++
2096++ GST_DEBUG_OBJECT (sink, "Mir chose format %d", pixel_format);
2097++ /* As we are opaque then it's OK to switch pixel format slightly,
2098++ * to enable bypass/overlays to work. Otherwise the presence of an
2099++ * alpha channel would prevent them from being used.
2100++ * It would be really nice if Mesa just gave us the right answer in
2101++ * the first place though. (LP: #1480755)
2102++ */
2103++ if (pixel_format == mir_pixel_format_abgr_8888)
2104++ pixel_format = mir_pixel_format_xbgr_8888;
2105++ else if (pixel_format == mir_pixel_format_argb_8888)
2106++ pixel_format = mir_pixel_format_xrgb_8888;
2107++ GST_DEBUG_OBJECT (sink, "Selected format is %d", pixel_format);
2108++
2109++ display_config = mir_connection_create_display_configuration (sink->conn);
2110++ display_output = find_active_output (display_config);
2111++ if (!display_output) {
2112++ GST_ERROR_OBJECT (sink, "There is no active output");
2113++ goto error;
2114++ }
2115++
2116++ display_mode = mir_output_get_current_mode (display_output);
2117++ if (!display_mode) {
2118++ GST_ERROR_OBJECT (sink, "No default mode for output");
2119++ goto error;
2120++ }
2121++
2122++ pos_x = mir_output_get_position_x (display_output);
2123++ pos_y = mir_output_get_position_y (display_output);
2124++
2125++ width = mir_output_mode_get_width (display_mode);
2126++ height = mir_output_mode_get_height (display_mode);
2127++
2128++ GST_DEBUG_OBJECT (sink, "Current active output is %dx%d %+d%+d\n",
2129++ width, height, pos_x, pos_y);
2130++
2131++ mir_display_config_release (display_config);
2132++
2133++ spec = mir_create_normal_window_spec (sink->conn, width, height);
2134++ mir_window_spec_set_pixel_format (spec, pixel_format);
2135++ mir_window_spec_set_name (spec, "mirsink");
2136++
2137++ sink->window = mir_create_window_sync (spec);
2138++ mir_window_spec_release (spec);
2139++
2140++ if (!mir_window_is_valid (sink->window)) {
2141++ GST_ERROR_OBJECT (sink, "Cannot create valid window");
2142++ goto error;
2143++ }
2144++
2145++ mir_window_set_event_handler (sink->window, mir_eglapp_handle_event, sink);
2146++
2147++ buff_stream = mir_window_get_buffer_stream (sink->window);
2148++ mir_window = mir_buffer_stream_get_egl_native_window (buff_stream);
2149++
2150++ return eglCreateWindowSurface (sink->egldisplay, eglconfig,
2151++ (EGLNativeWindowType) mir_window, NULL);
2152++
2153++error:
2154++ if (sink->window) {
2155++ mir_window_release_sync (sink->window);
2156++ sink->window = NULL;
2157++ }
2158++ if (display_config)
2159++ mir_display_config_release (display_config);
2160++
2161++ return EGL_NO_SURFACE;
2162++}
2163++
2164++static gboolean
2165++gst_mir_sink_start (GstBaseSink * bsink)
2166++{
2167++ GstMirSink *sink = (GstMirSink *) bsink;
2168++
2169++ GST_DEBUG_OBJECT (sink, "start");
2170++
2171++ return TRUE;
2172++}
2173++
2174++static gboolean
2175++gst_mir_sink_stop (GstBaseSink * bsink)
2176++{
2177++ GstMirSink *sink = (GstMirSink *) bsink;
2178++ int i;
2179++
2180++ GST_DEBUG_OBJECT (sink, "stop");
2181++
2182++ /* Clean up GL stuff */
2183++
2184++ if (sink->buf_fd) {
2185++ close (sink->buf_fd);
2186++ sink->buf_fd = 0;
2187++ }
2188++
2189++ glDeleteFramebuffers(1, &sink->fbo);
2190++ sink->fbo = 0;
2191++ glDeleteTextures (1, &sink->render_tex);
2192++ sink->render_tex = 0;
2193++
2194++ glDeleteTextures (G_N_ELEMENTS (sink->text_id), sink->text_id);
2195++ memset (sink->text_id, 0, sizeof sink->text_id);
2196++
2197++ glDisableVertexAttribArray (sink->attrpos);
2198++ sink->attrpos = 0;
2199++ for (i = 0; i < G_N_ELEMENTS (sink->attrcordYUV); ++i)
2200++ glDisableVertexAttribArray (sink->attrcordYUV[i]);
2201++ memset (sink->attrcordYUV, 0, sizeof sink->attrcordYUV);
2202++
2203++ glDeleteShader (sink->vshader);
2204++ glDeleteShader (sink->fshader);
2205++ glDeleteProgram (sink->prog);
2206++ sink->vshader = 0;
2207++ sink->fshader = 0;
2208++ sink->prog = 0;
2209++
2210++ /* Clean up EGL stuff */
2211++
2212++ if (sink->egldisplay != EGL_NO_DISPLAY) {
2213++ if (sink->eglsurface != EGL_NO_SURFACE) {
2214++ eglDestroySurface (sink->egldisplay, sink->eglsurface);
2215++ sink->eglsurface = EGL_NO_SURFACE;
2216++ }
2217++ if (sink->eglctx != EGL_NO_CONTEXT) {
2218++ eglDestroyContext (sink->egldisplay, sink->eglctx);
2219++ sink->eglctx = EGL_NO_CONTEXT;
2220++ }
2221++ eglTerminate (sink->egldisplay);
2222++ sink->egldisplay = EGL_NO_DISPLAY;
2223++ }
2224++
2225++ /* Clean up Mir stuff */
2226++
2227++ if (sink->window) {
2228++ mir_window_release_sync (sink->window);
2229++ sink->window = NULL;
2230++ }
2231++ if (sink->conn) {
2232++ mir_connection_release (sink->conn);
2233++ sink->conn = NULL;
2234++ }
2235++
2236++ /* The pool is not re-used so must be destroyed here */
2237++ if (sink->pool) {
2238++ gst_object_unref (sink->pool);
2239++ sink->pool = NULL;
2240++ }
2241++
2242++ return TRUE;
2243++}
2244++
2245++static gboolean
2246++gst_mir_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
2247++{
2248++ GstMirSink *sink = GST_MIR_SINK (bsink);
2249++ GstStructure *config;
2250++ guint size, min_bufs, max_bufs;
2251++
2252++ GST_DEBUG_OBJECT (sink, "Proposing ALLOCATION params");
2253++
2254++ config = gst_buffer_pool_get_config (sink->pool);
2255++ gst_buffer_pool_config_get_params (config, NULL, &size, &min_bufs, &max_bufs);
2256++
2257++ /* we do have a pool for sure (created in set_caps),
2258++ * so let's propose it anyway, but also propose the allocator on its own
2259++ */
2260++ gst_query_add_allocation_pool (query, sink->pool, size, min_bufs, max_bufs);
2261++ gst_query_add_allocation_param (query, gst_allocator_find (NULL), NULL);
2262++
2263++ gst_structure_free (config);
2264++
2265++ return TRUE;
2266++}
2267++
2268++static GstFlowReturn
2269++gst_mir_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
2270++{
2271++ GST_DEBUG_OBJECT (bsink, "preroll buffer %p", buffer);
2272++ return gst_mir_sink_render (bsink, buffer);
2273++}
2274++
2275++static PFNEGLCREATEIMAGEKHRPROC _eglCreateImageKHR;
2276++static PFNEGLDESTROYIMAGEKHRPROC _eglDestroyImageKHR;
2277++static PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC _eglExportDMABUFImageQueryMESA;
2278++static PFNEGLEXPORTDMABUFIMAGEMESAPROC _eglExportDMABUFImageMESA;
2279++
2280++static gboolean
2281++find_extension (const char *extensions, const char *ext)
2282++{
2283++ const char *found = strstr (extensions, ext);
2284++ int name_len = strlen (ext);
2285++
2286++ for (; found; found = strstr (found + name_len, ext)) {
2287++ if (found[name_len] == ' ' || found[name_len] == '\0')
2288++ return TRUE;
2289++ }
2290++
2291++ return FALSE;
2292++}
2293++
2294++static gboolean
2295++import_egl_extensions (GstMirSink *sink)
2296++{
2297++ /* EGL_KHR_image_base: for eglCreateImageKHR/eglDestroyImageKHR
2298++ * EGL_MESA_image_dma_buf_export: for eglExportDMABUFImage*MESA
2299++ * EGL_KHR_surfaceless_context: to render without a surface
2300++ */
2301++ static const char *ext_str[] = { "EGL_KHR_image_base",
2302++ "EGL_MESA_image_dma_buf_export",
2303++ "EGL_KHR_surfaceless_context"};
2304++ const char *extensions;
2305++ int i;
2306++
2307++ extensions = eglQueryString (sink->egldisplay, EGL_EXTENSIONS);
2308++ if (!extensions)
2309++ return FALSE;
2310++
2311++ for (i = 0; i < G_N_ELEMENTS (ext_str); ++i) {
2312++ if (!find_extension (extensions, ext_str[i])) {
2313++ GST_ERROR_OBJECT (sink, "EGL extension %s not found", ext_str[i]);
2314++ return FALSE;
2315++ }
2316++ }
2317++
2318++ _eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)
2319++ eglGetProcAddress("eglCreateImageKHR");
2320++ _eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)
2321++ eglGetProcAddress("eglDestroyImageKHR");
2322++ _eglExportDMABUFImageQueryMESA = (PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC)
2323++ eglGetProcAddress("eglExportDMABUFImageQueryMESA");
2324++ _eglExportDMABUFImageMESA = (PFNEGLEXPORTDMABUFIMAGEMESAPROC)
2325++ eglGetProcAddress("eglExportDMABUFImageMESA");
2326++
2327++ if (!_eglCreateImageKHR || !_eglDestroyImageKHR ||
2328++ !_eglExportDMABUFImageQueryMESA || !_eglExportDMABUFImageMESA) {
2329++ GST_ERROR_OBJECT (sink, "Cannot load EGL extensions");
2330++ return FALSE;
2331++ }
2332++
2333++ return TRUE;
2334++}
2335++
2336++static gboolean
2337++export_buffers (GstMirSink *sink)
2338++{
2339++ EGLImageKHR egl_image = EGL_NO_IMAGE_KHR;
2340++ EGLint image_attrs[] = {
2341++ EGL_GL_TEXTURE_LEVEL_KHR, 0, /* mip map level to reference */
2342++ EGL_IMAGE_PRESERVED_KHR, EGL_FALSE,
2343++ EGL_NONE
2344++ };
2345++ EGLBoolean ok;
2346++ int fourcc, num_planes;
2347++ EGLuint64KHR modifiers;
2348++ EGLint stride, offset;
2349++
2350++ if (!import_egl_extensions (sink))
2351++ goto error;
2352++
2353++ /* Create and configure rendering texture */
2354++ glGenTextures (1, &sink->render_tex);
2355++ glActiveTexture (GL_TEXTURE3);
2356++ glBindTexture (GL_TEXTURE_2D, sink->render_tex);
2357++ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
2358++ sink->video_width, sink->video_height, 0,
2359++ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2360++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2361++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2362++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2363++ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2364++ /* Generate framebuffer object */
2365++ glGenFramebuffers (1, &sink->fbo);
2366++ /* Set as target for rendering */
2367++ glBindFramebuffer (GL_FRAMEBUFFER, sink->fbo);
2368++ glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
2369++ sink->render_tex, 0);
2370++
2371++ if (gl_error (sink))
2372++ goto error;
2373++
2374++ /* Create EGL image from rendering texture */
2375++
2376++ egl_image = _eglCreateImageKHR(sink->egldisplay, sink->eglctx,
2377++ EGL_GL_TEXTURE_2D_KHR,
2378++ (EGLClientBuffer) (long) sink->render_tex, image_attrs);
2379++ if (egl_image == EGL_NO_IMAGE_KHR) {
2380++ GST_ERROR_OBJECT (sink, "eglCreateImageKHR error 0x%x", eglGetError());
2381++ goto error;
2382++ }
2383++
2384++ /* Now get dma_buf file descriptor and related data */
2385++
2386++ ok = _eglExportDMABUFImageQueryMESA (sink->egldisplay, egl_image,
2387++ &fourcc, &num_planes, &modifiers);
2388++ if (!ok) {
2389++ GST_ERROR_OBJECT (sink, "eglExportDMABUFImageQueryMESA error 0x%x",
2390++ eglGetError());
2391++ goto error;
2392++ }
2393++
2394++ ok = _eglExportDMABUFImageMESA (sink->egldisplay, egl_image,
2395++ &sink->buf_fd, &stride, &offset);
2396++ if (!ok) {
2397++ GST_ERROR_OBJECT (sink, "eglExportDMABUFImageMESA error 0x%x",
2398++ eglGetError());
2399++ goto error;
2400++ }
2401++
2402++ ok = _eglDestroyImageKHR (sink->egldisplay, egl_image);
2403++ if (!ok)
2404++ GST_ERROR_OBJECT (sink, "eglDestroyImageKHR error 0x%x",
2405++ eglGetError());
2406++
2407++ /* Post message with export data to application */
2408++ gst_element_post_message (GST_ELEMENT (sink),
2409++ gst_message_new_custom (GST_MESSAGE_ELEMENT, GST_OBJECT (sink),
2410++ gst_structure_new ("buffer-export-data",
2411++ "fd", G_TYPE_INT, sink->buf_fd,
2412++ "width", G_TYPE_INT, sink->video_width,
2413++ "height", G_TYPE_INT, sink->video_height,
2414++ "fourcc", G_TYPE_INT, fourcc,
2415++ "stride", G_TYPE_INT, stride,
2416++ "offset", G_TYPE_INT, offset,
2417++ NULL)));
2418++
2419++ return TRUE;
2420++
2421++error:
2422++ if (sink->buf_fd) {
2423++ close (sink->buf_fd);
2424++ sink->buf_fd = 0;
2425++ }
2426++
2427++ if (egl_image != EGL_NO_IMAGE_KHR)
2428++ _eglDestroyImageKHR (sink->egldisplay, egl_image);
2429++
2430++ glDeleteFramebuffers(1, &sink->fbo);
2431++ sink->fbo = 0;
2432++ glDeleteTextures (1, &sink->render_tex);
2433++ sink->render_tex = 0;
2434++
2435++ return FALSE;
2436++}
2437++
2438++static gboolean
2439++init_renderer (GstMirSink *sink)
2440++{
2441++ EGLBoolean ok;
2442++ EGLConfig eglconfig;
2443++ EGLint neglconfigs;
2444++ const EGLint attribs[] = {
2445++ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
2446++ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
2447++ EGL_RED_SIZE, 8,
2448++ EGL_GREEN_SIZE, 8,
2449++ EGL_BLUE_SIZE, 8,
2450++ EGL_ALPHA_SIZE, 0,
2451++ EGL_NONE
2452++ };
2453++ EGLint ctxattribs[] = {
2454++ EGL_CONTEXT_CLIENT_VERSION, 2,
2455++ EGL_NONE
2456++ };
2457++
2458++ /* Use default server */
2459++ sink->conn = mir_connect_sync (NULL, "mirsink");
2460++ if (!mir_connection_is_valid (sink->conn)) {
2461++ GST_ERROR_OBJECT (sink, "Cannot create Mir connection");
2462++ goto error;
2463++ }
2464++
2465++ sink->egldisplay = eglGetDisplay (
2466++ mir_connection_get_egl_native_display (sink->conn));
2467++ if (sink->egldisplay == EGL_NO_DISPLAY) {
2468++ GST_ERROR_OBJECT (sink, "Cannot create egl display");
2469++ goto error;
2470++ }
2471++
2472++ ok = eglInitialize (sink->egldisplay, NULL, NULL);
2473++ if (!ok) {
2474++ GST_ERROR_OBJECT (sink, "Cannot initialize egl");
2475++ goto error;
2476++ }
2477++
2478++ ok = eglChooseConfig (sink->egldisplay, attribs, &eglconfig, 1, &neglconfigs);
2479++ if (!ok) {
2480++ GST_ERROR_OBJECT (sink, "Cannot configure egl");
2481++ goto error;
2482++ }
2483++ if (neglconfigs < 1) {
2484++ GST_ERROR_OBJECT (sink, "no egl config available");
2485++ goto error;
2486++ }
2487++
2488++ /* If exporting, use EGL_KHR_surfaceless_context so we can render offscreen.
2489++ * Otherwise, create a Mir window.
2490++ */
2491++ if (sink->export_buffers) {
2492++ sink->eglsurface = EGL_NO_SURFACE;
2493++ } else {
2494++ sink->eglsurface = create_window (sink, eglconfig);
2495++ if (sink->eglsurface == EGL_NO_SURFACE)
2496++ goto error;
2497++ }
2498++
2499++ sink->eglctx =
2500++ eglCreateContext (sink->egldisplay, eglconfig, EGL_NO_CONTEXT, ctxattribs);
2501++ if (sink->eglctx == EGL_NO_CONTEXT) {
2502++ GST_ERROR_OBJECT (sink, "eglCreateContext failed");
2503++ goto error;
2504++ }
2505++ ok =
2506++ eglMakeCurrent (sink->egldisplay, sink->eglsurface, sink->eglsurface,
2507++ sink->eglctx);
2508++ if (!ok) {
2509++ GST_ERROR_OBJECT (sink, "eglMakeCurrent failed");
2510++ goto error;
2511++ }
2512++
2513++ /* Configure shaders */
2514++ if (!create_shaders (sink))
2515++ goto error;
2516++
2517++ /* Proceed to export buffers*/
2518++ if (sink->export_buffers)
2519++ if (!export_buffers (sink))
2520++ goto error;
2521++
2522++ return TRUE;
2523++
2524++error:
2525++ if (sink->egldisplay != EGL_NO_DISPLAY) {
2526++ if (sink->eglsurface != EGL_NO_SURFACE) {
2527++ eglDestroySurface (sink->egldisplay, sink->eglsurface);
2528++ sink->eglsurface = EGL_NO_SURFACE;
2529++ }
2530++ if (sink->eglctx != EGL_NO_CONTEXT) {
2531++ eglDestroyContext (sink->egldisplay, sink->eglctx);
2532++ sink->eglctx = EGL_NO_CONTEXT;
2533++ }
2534++ eglTerminate (sink->egldisplay);
2535++ sink->egldisplay = EGL_NO_DISPLAY;
2536++ }
2537++ if (sink->conn) {
2538++ mir_connection_release (sink->conn);
2539++ sink->conn = NULL;
2540++ }
2541++ return FALSE;
2542++}
2543++
2544++static GstFlowReturn
2545++gst_mir_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
2546++{
2547++ GstMirSink *sink = GST_MIR_SINK (bsink);
2548++ GstMapInfo src;
2549++ guint8 *next_plane;
2550++ int i;
2551++ /* Determines order of triangle strip */
2552++ GLubyte idx[4] = { 0, 1, 3, 2 };
2553++ EGLint width, height;
2554++ EGLBoolean ok;
2555++
2556++ GST_DEBUG_OBJECT (sink, "render buffer 0x%p", buffer);
2557++
2558++ /* Surface *must* be created in the rendering thread */
2559++ if (!sink->conn)
2560++ if (!init_renderer (sink))
2561++ return GST_FLOW_ERROR;
2562++
2563++ gst_buffer_map (buffer, &src, GST_MAP_READ);
2564++
2565++ /* Associate YUV planes to our textures */
2566++ /* TODO Can we have stride in the input buffers? how to know? */
2567++ for (i = 0, next_plane = src.data; i < 3; ++i) {
2568++ /* GL_TEXTUREi = GL_TEXTURE0 + i is guaranteed */
2569++ glActiveTexture (GL_TEXTURE0 + i);
2570++ glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE,
2571++ i == 0 ? sink->video_width : sink->video_width / 2,
2572++ i == 0 ? sink->video_height : sink->video_height / 2,
2573++ 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
2574++ next_plane);
2575++ next_plane += (sink->video_width * sink->video_height) / (i == 0 ? 1 : 4);
2576++ }
2577++
2578++ if (sink->export_buffers) {
2579++ glViewport (0, 0, sink->video_width, sink->video_height);
2580++ } else {
2581++ if (eglQuerySurface (sink->egldisplay, sink->eglsurface, EGL_WIDTH, &width) &&
2582++ eglQuerySurface (sink->egldisplay, sink->eglsurface, EGL_HEIGHT, &height)) {
2583++ GST_DEBUG_OBJECT (sink, "Output size is %d x %d", width, height);
2584++ glViewport (0, 0, width, height);
2585++ }
2586++ }
2587++
2588++ /* Perform YUV -> RGB conversion by using GLSL shaders, and draw */
2589++ glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
2590++
2591++ /* Just print the errors */
2592++ gl_error (sink);
2593++
2594++ if (sink->export_buffers) {
2595++ /* Notify texture ready (TODO: use explicit fences when widely available) */
2596++ gst_element_post_message (GST_ELEMENT (sink),
2597++ gst_message_new_custom (GST_MESSAGE_ELEMENT, GST_OBJECT (sink),
2598++ gst_structure_new_empty ("frame-ready")));
2599++ } else {
2600++ ok = eglSwapBuffers (sink->egldisplay, sink->eglsurface);
2601++ if (!ok)
2602++ GST_ERROR_OBJECT (sink, "eglSwapBuffers failed: %d", eglGetError());
2603++ }
2604++
2605++ gst_buffer_unmap (buffer, &src);
2606++
2607++ return GST_FLOW_OK;
2608++}
2609++
2610++static gboolean
2611++plugin_init (GstPlugin * plugin)
2612++{
2613++ GST_DEBUG_CATEGORY_INIT (gstmir_debug, "mirsink", 0, " mir video sink");
2614++
2615++ return gst_element_register (plugin, "mirsink", GST_RANK_MARGINAL,
2616++ GST_TYPE_MIR_SINK);
2617++}
2618++
2619++GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
2620++ GST_VERSION_MINOR,
2621++ mirsink,
2622++ "Mir Video Sink", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
2623++ GST_PACKAGE_ORIGIN)
2624+diff --git a/ext/mir/gstmirsink.h b/ext/mir/gstmirsink.h
2625+new file mode 100644
2626+index 0000000..6e3edb5
2627+--- /dev/null
2628++++ b/ext/mir/gstmirsink.h
2629+@@ -0,0 +1,117 @@
2630++/*
2631++ * GStreamer Mir video sink
2632++ * Copyright (C) 2017 Canonical Ltd
2633++ *
2634++ * This library is free software; you can redistribute it and/or
2635++ * modify it under the terms of the GNU Library General Public
2636++ * License as published by the Free Software Foundation; either
2637++ * version 3 of the License, or (at your option) any later version.
2638++ *
2639++ * This library is distributed in the hope that it will be useful,
2640++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2641++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2642++ * Library General Public License for more details.
2643++ *
2644++ * You should have received a copy of the GNU Library General Public
2645++ * License along with this library; if not, write to the Free
2646++ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2647++ * Boston, MA 02110-1301 USA.
2648++ */
2649++
2650++#ifndef __GST_MIR_VIDEO_SINK_H__
2651++#define __GST_MIR_VIDEO_SINK_H__
2652++
2653++#include <stdio.h>
2654++#include <stdlib.h>
2655++#include <string.h>
2656++#include <math.h>
2657++#include <sys/types.h>
2658++#include <sys/stat.h>
2659++#include <sys/time.h>
2660++#include <sys/ioctl.h>
2661++#include <sys/mman.h>
2662++#include <fcntl.h>
2663++#include <assert.h>
2664++#include <unistd.h>
2665++#include <stdint.h>
2666++
2667++#define GL_GLEXT_PROTOTYPES
2668++#define EGL_EGLEXT_PROTOTYPES
2669++
2670++#include <mir_toolkit/mir_client_library.h>
2671++#include <EGL/egl.h>
2672++#include <EGL/eglext.h>
2673++#include <GLES2/gl2.h>
2674++#include <GLES2/gl2ext.h>
2675++
2676++#include <gst/gst.h>
2677++#include <gst/video/video.h>
2678++#include <gst/video/gstvideosink.h>
2679++#include <gst/video/gstvideometa.h>
2680++
2681++#define GST_TYPE_MIR_SINK \
2682++ (gst_mir_sink_get_type())
2683++#define GST_MIR_SINK(obj) \
2684++ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MIR_SINK,GstMirSink))
2685++#define GST_MIR_SINK_CLASS(klass) \
2686++ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MIR_SINK,GstMirSinkClass))
2687++#define GST_IS_MIR_SINK(obj) \
2688++ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MIR_SINK))
2689++#define GST_IS_MIR_SINK_CLASS(klass) \
2690++ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MIR_SINK))
2691++#define GST_MIR_SINK_GET_CLASS(inst) \
2692++ (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_MIR_SINK, GstMirSinkClass))
2693++
2694++typedef struct _GstMirSink GstMirSink;
2695++typedef struct _GstMirSinkClass GstMirSinkClass;
2696++
2697++struct _GstMirSink
2698++{
2699++ GstVideoSink parent;
2700++
2701++ GstBufferPool *pool;
2702++
2703++ GMutex mir_lock;
2704++
2705++ /* Whether to export buffers or render them in a local window */
2706++ gboolean export_buffers;
2707++ gint video_width;
2708++ gint video_height;
2709++ GstVideoFormat video_format;
2710++
2711++ MirConnection *conn;
2712++ MirWindow *window;
2713++
2714++ EGLDisplay egldisplay;
2715++ EGLSurface eglsurface;
2716++ EGLContext eglctx;
2717++
2718++ GLuint vshader, fshader;
2719++
2720++ /* Indexes to shader variables */
2721++ GLint attrpos;
2722++ GLint attrcordYUV[3];
2723++ GLint sampYUV[3];
2724++ GLint yuvmat;
2725++
2726++ GLuint text_id[3];
2727++
2728++ GLuint prog;
2729++
2730++ /* Framebuffer object */
2731++ GLuint fbo;
2732++ GLuint render_tex;
2733++
2734++ int buf_fd;
2735++};
2736++
2737++struct _GstMirSinkClass
2738++{
2739++ GstVideoSinkClass parent;
2740++};
2741++
2742++GType gst_mir_sink_get_type (void) G_GNUC_CONST;
2743++
2744++G_END_DECLS
2745++
2746++#endif /* __GST_MIR_VIDEO_SINK_H__ */
2747diff --git a/debian/patches/series b/debian/patches/series
2748index 08e77ca..451778e 100644
2749--- a/debian/patches/series
2750+++ b/debian/patches/series
2751@@ -3,3 +3,4 @@
2752 0001-Make-sure-to-link-gme-plugin-with-lz.patch
2753 pcfile-requires-plugins-good
2754 adding-mirsink-and-android-media-over-hybris-support.patch
2755+desktop-mirsink.patch
2756diff --git a/debian/rules b/debian/rules
2757index 939e685..46d6771 100755
2758--- a/debian/rules
2759+++ b/debian/rules
2760@@ -80,8 +80,8 @@ VERSIONIZE= \
2761 #debug package
2762 DEB_DH_STRIP_ARGS := --dbg-package=$(gst_pkgname)-plugins-bad-dbg
2763
2764-# miralloc is just enabled for i386 and armhf (need android for the other archs)
2765-android_hybris_archs := i386 armhf
2766+# miralloc is just enabled for some archs (need android for the other archs)
2767+android_hybris_archs := i386 armhf arm64
2768 ifeq ($(DEB_HOST_ARCH_CPU), $(findstring $(DEB_HOST_ARCH_CPU), $(android_hybris_archs)))
2769 miralloc = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/libgstmiralloc-$(gst_abi).so.*
2770 mirallocdev = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/libgstmiralloc-$(gst_abi).so
2771@@ -219,10 +219,16 @@ ifeq (,$(findstring $(DEB_HOST_ARCH),m68k arm))
2772 DEB_CONFIGURE_EXTRA_FLAGS += --enable-gtk-doc
2773 endif
2774
2775-ifneq (,$(findstring $(DEB_HOST_ARCH),armhf))
2776+ifneq (,$(findstring $(DEB_HOST_ARCH),armhf arm64))
2777 DEB_CONFIGURE_EXTRA_FLAGS += --disable-opengl --disable-glx
2778 endif
2779
2780+# for arm64 we need to use hybris android sdk version 23 as there is no
2781+# jb linker for it
2782+ifneq (,$(findstring $(DEB_HOST_ARCH),arm64))
2783+export HYBRIS_ANDROID_SDK_VERSION=23
2784+endif
2785+
2786 common-binary-fixup-arch::
2787 rm -r $(CURDIR)/debian/libgstreamer-plugins-bad$(gst_abi)-dev/usr/include/*/*/basecamerabinsrc \
2788 $(CURDIR)/debian/libgstreamer-plugins-bad$(gst_abi)-dev/usr/include/*/*/interfaces/photography* \

Subscribers

People subscribed via source and target branches