Merge ~alfonsosanchezbeato/ubuntu/+source/gst-plugins-bad1.0:mirsink into ~ubuntu-desktop/ubuntu/+source/gst-plugins-bad1.0:master
- Git
- lp:~alfonsosanchezbeato/ubuntu/+source/gst-plugins-bad1.0
- mirsink
- Merge into 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) |
Related bugs: |
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
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_
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
1 | diff --git a/debian/build-deps b/debian/build-deps |
2 | index 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 |
38 | diff --git a/debian/build-deps.in b/debian/build-deps.in |
39 | index 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 |
68 | diff --git a/debian/changelog b/debian/changelog |
69 | index 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: |
104 | diff --git a/debian/control b/debian/control |
105 | index 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) |
159 | diff --git a/debian/control.in b/debian/control.in |
160 | index 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) |
181 | diff --git a/debian/gstreamer-hybris.install b/debian/gstreamer-hybris.install |
182 | index 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 |
189 | diff --git a/debian/gstreamer-plugins-bad.install b/debian/gstreamer-plugins-bad.install |
190 | index 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 |
201 | diff --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 |
202 | index 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 @@ |
1386 | diff --git a/debian/patches/desktop-mirsink.patch b/debian/patches/desktop-mirsink.patch |
1387 | new file mode 100644 |
1388 | index 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__ */ |
2747 | diff --git a/debian/patches/series b/debian/patches/series |
2748 | index 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 |
2756 | diff --git a/debian/rules b/debian/rules |
2757 | index 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* \ |
Several comments, questions and things to change inline below.