From: Ricardo Salveti de Araujo Date: Thu, 20 Mar 2014 01:23:43 +0000 (-0300) Subject: Imported Debian patch 0.1.0+git20131207+e452e83-0ubuntu12 X-Git-Tag: debian/0.1.0+git20131207+e452e83-0ubuntu12^0 X-Git-Url: https://git.piment-noir.org/?p=deb_libhybris.git;a=commitdiff_plain Imported Debian patch 0.1.0+git20131207+e452e83-0ubuntu12 --- diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..f19cbbf --- /dev/null +++ b/debian/changelog @@ -0,0 +1,424 @@ +libhybris (0.1.0+git20131207+e452e83-0ubuntu12) trusty; urgency=medium + + * input: add method to check if compat side is available + + -- Ricardo Salveti de Araujo Wed, 19 Mar 2014 22:23:43 -0300 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu11) trusty; urgency=medium + + * hardware.c: hw_get_module should return an error if module not found, + instead of crashing with SIGSEGV (LP: #1208862) + + -- Ricardo Salveti de Araujo Wed, 19 Mar 2014 19:07:57 -0300 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu10) trusty; urgency=medium + + [ Iain Lane ] + * Turn on wayland support to provide libwayland-egl, which mesa in Ubuntu + relies on. This makes libhybris a viable provider of the + _egl_conf alternate. (LP: #1206371) + + [ Ricardo Salveti de Araujo ] + * debian/rules: changing default alternatives priority to be lower than + the one provided by mesa (EGL/GLES), avoid breaking normal desktop + (LP: #1232962) + + -- Ricardo Salveti de Araujo Tue, 18 Mar 2014 21:47:34 -0300 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu9) trusty; urgency=medium + + * camera_compatibility_layer.cpp: in our case the texture is controlled by + the app (avoid locks in gl consumer) LP: #1282701 + + -- Ricardo Salveti de Araujo Mon, 03 Mar 2014 14:24:20 -0300 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu8) trusty; urgency=medium + + * common: also protecting the bionic system property calls + + -- Ricardo Salveti de Araujo Wed, 26 Feb 2014 01:34:19 -0300 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu7) trusty; urgency=medium + + * media: fixing code for 4.4 and improving the release_output_buffer logic + + -- Ricardo Salveti de Araujo Fri, 21 Feb 2014 00:57:19 -0300 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu6) trusty; urgency=medium + + * Making compat code compatible with Android 4.4.2 + + -- Ricardo Salveti de Araujo Thu, 23 Jan 2014 02:38:35 -0200 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu5) trusty; urgency=medium + + * Allowing grouper to share the shm block between users for usc + + -- Ricardo Salveti de Araujo Tue, 14 Jan 2014 20:01:25 -0200 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu4) trusty; urgency=low + + * debian/control: fix typo in descriptions (LP: #1255726, LP: #1259341) + + -- Benjamin Kerensa Sun, 05 Jan 2014 13:37:00 -0800 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu3) trusty; urgency=low + + * compat/media, hybris/media: removing singleton and simplifying the code now + that most of the sync logic is happening in gstreamer + + -- Ricardo Salveti de Araujo Mon, 23 Dec 2013 15:04:51 -0200 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu2) trusty; urgency=low + + * hybris/media: adding missing surface_texture_client_hardware_rendering + function in surface_texture_client_hybris.h, that got removed during a + rebase conflict. + + -- Ricardo Salveti de Araujo Thu, 19 Dec 2013 13:20:26 -0200 + +libhybris (0.1.0+git20131207+e452e83-0ubuntu1) trusty; urgency=low + + * New upstream snapshot: + - Rebasing patches and removing the ones that are already available in + upstream + - Performance improvements for the glesv2 hybris driver + - android-platform-headers renamed and migrated to a different source + package (android-headers) + - Most libraries can now be used via a pkg-config file + + -- Ricardo Salveti de Araujo Wed, 11 Dec 2013 01:31:48 -0200 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu37) trusty; urgency=low + + * Mark android-platform-headers Multi-Arch: foreign, so that libhardware-dev + is cross-installable. + * Use the right compiler if set up for cross-compiling. + Cross-build-dependencies won't work right due to the dep on + gcc-4.7/g++-4.7, but this will work better than anything else and you can + satisfy the build-deps by hand for now. + + -- Steve Langasek Sat, 23 Nov 2013 05:41:05 +0000 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu36) trusty; urgency=low + + * 0035-hooks.c-adding-hooks-for-asprintf-and-vasprintf-both.patch: + - Missing hooks needed by the emulator EGL/GLES driver + + -- Ricardo Salveti de Araujo Thu, 14 Nov 2013 17:34:51 -0200 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu35) saucy; urgency=low + + * 0034-Support-for-software-rendering-and-buffer-management.patch: + - Add a getter function that allows a client app to check to see if we + are doing hardware rendering. + + -- Ricardo Salveti de Araujo Mon, 14 Oct 2013 17:04:02 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu34) saucy; urgency=low + + * 0034-Support-for-software-rendering-and-buffer-management.patch: + - Enable support for software rendering and improving buffer management + when decoding/rendering a video + + -- Ricardo Salveti de Araujo Wed, 09 Oct 2013 18:46:48 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu33) saucy; urgency=low + + * 0033-hardware-adding-missing-power.h.patch: + - Adding missing libhardware power.h header + + -- Ricardo Salveti de Araujo Wed, 09 Oct 2013 11:48:44 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu32) saucy; urgency=low + + * 0032-Make-the-decoding-rendering-loop-much-more-robust.-F.patch: + - Making the decoding/rendering loop more robust by releasing + the output buffers in case the hal call fails (LP: #1234207) + + -- Ricardo Salveti de Araujo Wed, 02 Oct 2013 22:48:24 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu31) saucy; urgency=low + + * 0031-Fixes-bug-lp-1234007-out-of-index-crash-for-handling.patch: + - Fixing an out of index crash when handling media_codec_layer output + buffers list (LP: #1234007) + + -- Ricardo Salveti de Araujo Wed, 02 Oct 2013 11:35:46 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu30) saucy; urgency=low + + * 0030-compat-media-also-support-decoding-with-playbin.patch: + - Refreshing patch adding another method to ask when the client is ready + for rendering + + -- Ricardo Salveti de Araujo Mon, 30 Sep 2013 16:08:45 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu29) saucy; urgency=low + + * 0030-compat-media-also-support-decoding-with-playbin.patch: + - Improving rendering/decoding handling to also work with playbin + + -- Ricardo Salveti de Araujo Fri, 27 Sep 2013 13:54:55 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu28) saucy; urgency=low + + * 0029-compat-input-take-full-geometry-by-default-in-input-.patch: + - Removing surfaceflinger dependency of the input stack by allowing the + consumer to pass the screen width and height + + -- Ricardo Salveti de Araujo Wed, 25 Sep 2013 23:21:51 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu27) saucy; urgency=low + + * 0028-surface_texture_client_hybris-using-float-instead-of.patch: + - Using float directly instead of GLfloat to avoid conflicts with Qt + + -- Ricardo Salveti de Araujo Fri, 13 Sep 2013 10:30:57 -0400 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu26) saucy; urgency=low + + * 0027-media-provide-a-method-to-check-the-compat-availabil.patch: + - Provide a runtime method to check if the media compat layer is available + in the system (/system from Android) + + -- Ricardo Salveti de Araujo Thu, 12 Sep 2013 11:13:39 -0400 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu25) saucy; urgency=low + + * 0026-Added-a-function-to-get-the-transformation-matrix-an.patch: + - Adding extra surface texture calls for media playback + + -- Ricardo Salveti de Araujo Wed, 11 Sep 2013 10:33:17 -0400 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu24) saucy; urgency=low + + * Moving the media HAL into a separated package (libmedia), so we can have + the proper package dependencies in the gst-plugins-bad package (otherwise + it ends up depending on libhybris, which breaks EGL for desktop). + + -- Ricardo Salveti de Araujo Tue, 10 Sep 2013 10:40:32 -0400 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu23) saucy; urgency=low + + * 0025-audio.h-handling-the-float-based-function-calls-with.patch: + - Using proper aapcs attribute to the float based function calls in the + audio HAL + + -- Ricardo Salveti de Araujo Tue, 10 Sep 2013 09:48:48 -0400 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu22) saucy; urgency=low + + * 0024-compat-input-block-poll-avoid-waking-up-at-every-500.patch: + - Block poll when retrieving the input events via HAL, to avoid waking up + at every 500 ms + + -- Ricardo Salveti de Araujo Wed, 04 Sep 2013 21:21:34 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu21) saucy; urgency=low + + * 0010-hardware-include-adding-audio-hal-related-headers-fr.patch: + - Updating patch to really reflect headers from android-4.2.2_r1.2 + + -- Ricardo Salveti de Araujo Thu, 29 Aug 2013 00:05:31 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu20) saucy; urgency=low + + * 0023-compat-media-make-use-of-NativeBufferAllocator-inste.patch: + - Make media use a native buffer allocator so we don't need to depend on + surface flinger + + -- Ricardo Salveti de Araujo Wed, 28 Aug 2013 17:37:10 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu19) saucy; urgency=low + + * 0022-compat-camera-make-use-of-native-buffer-allocator-in.patch: + - Make camera use a native buffer allocator so we don't need to depend on + surface flinger + + -- Ricardo Salveti de Araujo Tue, 27 Aug 2013 17:08:03 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu18) saucy; urgency=low + + * 0021-hooks.c-also-add-a-matching-sysconf-for-_SC_NPROCESS.patch: + - Add a matching sysconf for _SC_NPROCESSORS_ONLN, used by libstagefright + + -- Ricardo Salveti de Araujo Mon, 26 Aug 2013 18:22:29 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu17) saucy; urgency=low + + * 0020-Change-the-SurfaceTextureClientUbuntu-API-to-be-sing.patch: + - Change API to be singleton-based to work around Gstreamer playbin + weirdness. + + -- Ricardo Salveti de Araujo Mon, 26 Aug 2013 11:10:11 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu16) saucy; urgency=low + + * 0019-Fix-last-argument-to-pthread_cond_timedwait.patch: + - Fixing last argument of pthread_cond_timedwait so it can work as + expected. + + -- Ricardo Salveti de Araujo Fri, 09 Aug 2013 10:51:32 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu15) saucy; urgency=low + + * 0018-properties.c-better-handling-for-name-and-value-size.patch: + - Better handling key and size names, avoid overflow issue with a blob + used by nexus 4 (libqmi_cci.so) - bug found by diwic + + -- Ricardo Salveti de Araujo Fri, 09 Aug 2013 07:51:28 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu14) saucy; urgency=low + + * debian/control: doing proper replaces/breaks for the new packages + + -- Ricardo Salveti de Araujo Tue, 06 Aug 2013 19:12:43 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu13) saucy; urgency=low + + * debian/control: + - Creating android-platform-headers that contains the original Android + headers. This will later come from a different src package once we + rebase libhybris with current upstream. + - Moving libhardware2 and libhybris-common into separated packages, + so we don't have libmirclient depending on the egl/gles libraries. + - Split for other packages should happen once the library is renamed + with upstream, so we can use libhybris/android-foo instead + * 0017-common-hooks.c-handle-null-attr-in-pthread_rwlock_in.patch: + - Handle null attr in pthread_rwlock_init, as it's a valid use case + + -- Ricardo Salveti de Araujo Tue, 06 Aug 2013 15:44:07 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu12) saucy; urgency=low + + * 0016-media-adding-files-for-media-codec-support-with-stag.patch: + - Adding media codec support to allow video decode using libstagefright + directly + + -- Ricardo Salveti de Araujo Wed, 31 Jul 2013 23:31:32 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu11) saucy; urgency=low + + * 0015-camera_compatibility_layer.cpp-don-t-explicitly-rele.patch: + - Don't explicitly release frames, avoid crash on manta + + -- Ricardo Salveti de Araujo Thu, 18 Jul 2013 04:14:07 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu10) saucy; urgency=low + + * debian/control: including missing ui headers into libhybris-dev + (LP: #1199953) + * 0014-input_compatibility_layer.cpp-avoid-blocking-on-exit.patch: avoid + blocking on exit and shutdown (LP: #1199897) + + -- Ricardo Salveti de Araujo Wed, 10 Jul 2013 19:36:09 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu9) saucy; urgency=low + + * debian/control: build only for armhf, i386 and amd64 + + -- Ricardo Salveti de Araujo Mon, 01 Jul 2013 19:27:07 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu8) saucy; urgency=low + + * 0013-implement-getset-property-via-property-service.patch: + - Adding support for get/set property using the Android property service + * libandroid-properties1: new library to export the property_get, + property_set and property_list android calls + * libhybris-utils: new package providing the getprop and setprop utilities + + -- Ricardo Salveti de Araujo Mon, 01 Jul 2013 18:50:12 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu7) saucy; urgency=low + + * Forcing GCC 4.7, to avoid issues with 4.8 ABI changes (temporarily until + the android side can be built with 4.8 as well) + + -- Ricardo Salveti de Araujo Wed, 26 Jun 2013 18:19:13 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu6) saucy; urgency=low + + * Adding 0012-hooks.c-handle-invalid-mutex-in-pthread_mutex_destro.patch: + - Handling invalid mutex in pthread_mutex_destroy + + -- Ricardo Salveti de Araujo Tue, 25 Jun 2013 00:45:56 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu5) saucy; urgency=low + + * 0010-hardware-include-adding-audio-hal-related-headers-fr.patch: + - Updating based on the version set upstream + * Adding 0011-hooks.c-no-need-to-map-strcasestr.patch: + - Remove hook for strcasesrt, glibc verision behaves differently + + -- Ricardo Salveti de Araujo Mon, 24 Jun 2013 23:03:45 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu4) saucy; urgency=low + + * Adding 0010-hardware-include-adding-audio-hal-related-headers-fr.patch: + - Exporting headers needed to access the Android Audio HAL + + -- Ricardo Salveti de Araujo Mon, 24 Jun 2013 01:28:22 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu3) saucy; urgency=low + + * Adding 0009-jb-linker.c-reduce-debugging-output-for-prelinked-li.patch: + - Reducing debugging output for the prelinked library detection logic + + -- Ricardo Salveti de Araujo Wed, 19 Jun 2013 22:28:28 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu2) saucy; urgency=low + + * Adding 0008-hooks-shm-fixing-logic-with-cond-is-negative-error.patch: + - Fixing int -> unsigned int conversion when handling android shared cond + + -- Ricardo Salveti de Araujo Fri, 14 Jun 2013 05:57:51 -0300 + +libhybris (0.1.0+git20130606+c5d897a-0ubuntu1) saucy; urgency=low + + * New upstream snapshot + * Updating patches against latest upstream, dropping (already merged): + - 0005-egl-platform-common-implement-conversion-to-base-buf.patch + - 0006-hooks-using-shm-hybris-pshared.patch + * Fixing logging support, adding: + - 0006-jb-linker.c-allow-debug-of-the-linker-and-hooked-sym.patch + - 0007-jb-linker.c-ubuntu-touch-uses-dev-alog-instead-of-de.patch + + -- Ricardo Salveti de Araujo Fri, 07 Jun 2013 02:54:18 -0300 + +libhybris (0.1.0+git20130606+6f67260-0ubuntu1) saucy; urgency=low + + * New upstream snapshot + * Updating patches against latest upstream + * debian/rules: moving get-orig-source to get-packaged-orig-source + * debian/patches/0005-egl-platform-common-implement-conversion-to-base-buf.patch: + Implement native conversion to base buffer class + * debian/patches/0006-hooks-using-shm-hybris-pshared.patch: use SHM between + hybris instances for pshared mutex and condition (needed by MIR) + + -- Ricardo Salveti de Araujo Wed, 05 Jun 2013 22:22:02 -0300 + +libhybris (0.1.0+git20130604+1b671a8-0ubuntu1) saucy; urgency=low + + * New upstream snapshot + * Removed patches that are now available in upstream: + - 0001-hybris-include-separating-include-files-per-director.patch + - 0002-Input-adding-initial-compat-files-for-input.patch + - 0005-common-hooks.c-adding-hooks-used-by-the-ubuntu-media.patch + - 0007-common-properties.c-also-probe-property-from-kernel-.patch + - 0008-common-linkers-removing-Android.mk-files-are-they-ar.patch + + -- Ricardo Salveti de Araujo Tue, 04 Jun 2013 14:25:42 -0300 + +libhybris (0.1.0+git20130601+dfb2e26-0ubuntu2) saucy; urgency=low + + * debian/copyright: fixing license and copyright entries based on a review + done by Sebastien Bacher + + -- Ricardo Salveti de Araujo Tue, 04 Jun 2013 07:33:11 -0300 + +libhybris (0.1.0+git20130601+dfb2e26-0ubuntu1) saucy; urgency=low + + * Initial release for Ubuntu + + -- Ricardo Salveti de Araujo Tue, 04 Jun 2013 02:58:01 -0300 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..88605f3 --- /dev/null +++ b/debian/control @@ -0,0 +1,176 @@ +Source: libhybris +Priority: extra +Maintainer: Ubuntu Developers +Build-Depends: debhelper (>= 9.0.0), + autotools-dev, + dh-autoreconf, + android-headers (>= 4.2.2), + gcc-4.7, + g++-4.7, + quilt, + pkg-config, + libgles2-mesa-dev, + libwayland-dev +Standards-Version: 3.9.4 +Section: libs +Vcs-Git: git://phablet.ubuntu.com/ubuntu/libhybris.git +Vcs-Browser: http://phablet.ubuntu.com/gitweb?p=ubuntu/libhybris.git;a=summary + +Package: libandroid-properties1 +Architecture: armhf i386 amd64 +Depends: ${shlibs:Depends}, + ${misc:Depends} +Description: Library to provide access to get, set and list Android properties + Contains a library that provides access to get, set and list Android + properties, which can be used by any Ubuntu app that needs to probe + for properties (gps, modem, device specifics). + +Package: libandroid-properties-dev +Section: libdevel +Architecture: armhf i386 amd64 +Depends: libandroid-properties1 (= ${binary:Version}), + ${misc:Depends} +Description: Development headers files for libandroid-properties + Contains the development files for use in applications that wants to get, + set or list the Android properties. + +Package: libmedia1 +Architecture: armhf i386 amd64 +Depends: ${shlibs:Depends}, + ${misc:Depends} +Replaces: libhybris (<< 0.1.0+git20130606+c5d897a-0ubuntu24) +Breaks: libhybris (<< 0.1.0+git20130606+c5d897a-0ubuntu24) +Description: Library to provide access to the Android Media HAL + Contains a library that provides access to the Android Media HAL, + which abstract the access to the Android libstagefright based + decoders. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libmedia-dev +Section: libdevel +Architecture: armhf i386 amd64 +Depends: libmedia1 (= ${binary:Version}), + android-headers (>= 4.2.2), + ${misc:Depends} +Replaces: libhybris-dev (<< 0.1.0+git20130606+c5d897a-0ubuntu24) +Breaks: libhybris-dev (<< 0.1.0+git20130606+c5d897a-0ubuntu24) +Description: Development files for libmedia + Contains the development files for the Android Media HAL, which + abstract the access to the Android libstagefright based decoders. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhardware2 +Architecture: armhf i386 amd64 +Depends: ${shlibs:Depends}, + ${misc:Depends} +Replaces: libhybris (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Breaks: libhybris (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Description: Library to provide access to the Android libhardware HAL + Contains a library that provides access to the Android libhardware HAL, + which can be used to access a wide range of other HALs, such as audio, + power, gralloc, etc. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhardware-dev +Section: libdevel +Architecture: armhf i386 amd64 +Depends: libhardware2 (= ${binary:Version}), + android-headers (>= 4.2.2), + ${misc:Depends} +Replaces: libhybris-dev (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Breaks: libhybris-dev (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Description: Development files for libhardware + Contains the development files the Android libhardware HAL, which can be + used to access a wide range of other HALs, such as audio, power, gralloc, + etc. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhybris-common1 +Architecture: armhf i386 amd64 +Depends: ${shlibs:Depends}, + ${misc:Depends} +Replaces: libhybris (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Breaks: libhybris (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Description: Common library that contains the Android linker and custom hooks + Contains a common library that contains the Android linker, used to + dynamically load and use symbols from Android based libraries. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhybris-common-dev +Section: libdevel +Architecture: armhf i386 amd64 +Depends: libhybris-common1 (= ${binary:Version}), + ${misc:Depends} +Replaces: libhybris-dev (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Breaks: libhybris-dev (<< 0.1.0+git20130606+c5d897a-0ubuntu13) +Description: Development files for libhybris-common + Contains the development files for the common library that contains the + Android linker, used to dynamically load and use symbols from Android + based libraries. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhybris +Architecture: armhf i386 amd64 +Depends: libandroid-properties1 (= ${binary:Version}), + libhardware2, + libmedia1, + ${shlibs:Depends}, + ${misc:Depends} +Description: Allows to run bionic-based HW adaptations in glibc systems - libs + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhybris-dev +Section: libdevel +Architecture: armhf i386 amd64 +Depends: libhybris (= ${binary:Version}), + android-headers (>= 4.2.2), + libandroid-properties-dev (= ${binary:Version}), + libhardware-dev (= ${binary:Version}), + libmedia-dev (= ${binary:Version}), + libhybris-common-dev (= ${binary:Version}), + ${misc:Depends}, + libgles2-mesa-dev, +Description: Development headers and libraries for libhybris + Contains the header files for use in developing applications that use + the libhybris library. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhybris-utils +Section: utils +Architecture: armhf i386 amd64 +Depends: libhybris (= ${binary:Version}), + ${shlibs:Depends}, + ${misc:Depends} +Description: Utilities to help working with the Android HW abstraction layer + Contains utilities used to help working with Android HW abstraction layer. + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. + +Package: libhybris-test +Section: devel +Architecture: armhf i386 amd64 +Depends: libhybris (= ${binary:Version}), + ${shlibs:Depends}, + ${misc:Depends} +Description: Allows to run bionic-based HW adaptations in glibc systems - tests + Contains the test applications used to validate libhybris (needs Android + libraries or container). + . + Hybris is a solution that allows the use of bionic-based HW adaptations in + glibc systems. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..23dd030 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,255 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: libhybris +Source: https://github.com/libhybris/libhybris + +Files: compat/surface_flinger/* hybris/include/hybris/internal/surface_flinger_compatibility_layer_internal.h hybris/include/hybris/surface_flinger/surface_flinger_compatibility_layer.h hybris/sf/sf.c hybris/tests/test_sf.c +Copyright: 2013 Canonical Ltd +License: Apache 2.0 + +Files: compat/ui/* hybris/egl/eglhybris.h hybris/hardware/hardware.c hybris/include/hybris/ui/ui_compatibility_layer.h hybris/ui/ui.c hybris/tests/test_lights.c hybris/tests/test_sensors.c hybris/tests/test_ui.c +Copyright: 2012-2013 Simon Busch +License: Apache 2.0 + +Files: hybris/include/hybris/internal/binding.h +Copyright: 2013 Simon Busch + 2012 Canonical Ltd +License: Apache 2.0 + +Files: hybris/egl/platforms/common/native_handle.c +Copyright: 2007 The Android Open Source Project +License: Apache 2.0 + +Files: hybris/common/hooks.c +Copyright: 2012 Carsten Munk + 2012 Canonical Ltd +License: Apache 2.0 + +Files: hybris/tests/test_gps.c +Copyright: 2013 Jolla Mobile +License: Apache 2.0 + +Files: hybris/common/logging.* +Copyright: 2013 Thomas Perl +License: Apache 2.0 + +Files: hybris/egl/platforms/fbdev/fbdev_window.* +Copyright: 2013 libhybris +License: Apache 2.0 + +Files: hybris/egl/platforms/wayland/eglplatform_wayland.cpp hybris/egl/platforms/wayland/wayland_window.h hybris/egl/platforms/wayland/wayland_window.cpp +Copyright: 2013 Jolla Ltd +License: LGPL-2.1 + +Files: hybris/common/properties.* hybris/egl/egl.c hybris/glesv2/glesv2.c hybris/tests/test_glesv2.c hybris/tests/test_egl.c +Copyright: 2012 Carsten Munk +License: Apache 2.0 + +Files: hybris/include/CL/* hybris/include/KHR/* hybris/include/EGL/* hybris/include/VG/* hybris/include/GL/glxext.h hybris/include/GL/glext.h hybris/include/GL/wglext.h +Copyright: 2007-2012 The Khronos Group Inc +License: X11/MIT + +Files: hybris/include/GL/glx.h hybris/include/GL/glx_mangle.h hybris/include/GL/osmesa.h +Copyright: 1999-2006 Brian Paul +License: X11/MIT + +Files: hybris/include/GL/gl.h +Copyright: 1999-2006 Brian Paul + 2009 VMware, Inc. +License: X11/MIT + +Files: hybris/include/GL/wmesa.h +Copyright: 1995-1998 Brian Paul +License: LGPL-2+ + +Files: hybris/include/GL/internal/sarea.h +Copyright: 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + 2000 VA Linux Systems, Inc. +License: X11/MIT + +Files: hybris/include/GL/internal/dri_interface.h +Copyright: 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + 2007-2008 Red Hat, Inc. + 2004 IBM Corporation +License: X11/MIT + +Files: hybris/include/GLES2/gl2.h hybris/include/GLES2/gl2ext.h hybris/include/GLES2/gl2platform.h hybris/include/GLES/gl.h hybris/include/GLES/glext.h hybris/include/GLES/glplatform.h +Copyright: 2010-2012 Silicon Graphics, Inc +License: SGI-2.0 + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + . + The above copyright notice including the dates of first publication and either + this permission notice or a reference to http://oss.sgi.com/projects/FreeB/ + shall be included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC. BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + . + Except as contained in this notice, the name of Silicon Graphics, Inc. shall + not be used in advertising or otherwise to promote the sale, use or other + dealings in this Software without prior written authorization from Silicon + Graphics, Inc. + +Files: utils/load_sym_files.py +Copyright: 2013 Adrian Negreanu +License: GPL-3+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + On Debian systems, the full text of the GNU Lesser General Public + License version 3 can be found in the file + `/usr/share/common-licenses/GPL-3'. + +Files: hybris/common/gingerbread/* hybris/common/ics/* hybris/common/jb/* +Copyright: 2007-2010 The Android Open Source Project +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +Files: hybris/egl/platforms/common/wayland-android-client-protocol.h hybris/egl/platforms/common/wayland-android-protocol.c hybris/egl/platforms/common/server_wlegl_buffer.h hybris/egl/platforms/common/server_wlegl_buffer.cpp hybris/egl/platforms/common/server_wlegl.h hybris/egl/platforms/common/wayland-android.xml hybris/egl/platforms/common/server_wlegl_handle.cpp hybris/egl/platforms/common/wayland-android-server-protocol.h hybris/egl/platforms/common/server_wlegl.cpp hybris/egl/platforms/common/server_wlegl_private.h +Copyright: 2012 Collabora, Ltd. +License: MIT2 + Permission to use, copy, modify, distribute, and sell this software and + its documentation for any purpose is hereby granted without fee, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the copyright holders not be used in + advertising or publicity pertaining to distribution of the software + without specific, written prior permission. The copyright holders make + no representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied warranty. + . + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Files: hybris/common/strlcpy.c +Copyright: 1998 Todd C. Miller +License: ICS + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +License: Apache 2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +License: LGPL-2.1 + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation, version 2.1 + of the License. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA + . + On Debian systems, the full text of the GNU Lesser General Public + License version 2.1 can be found in the file + `/usr/share/common-licenses/LGPL-2.1'. + +License: LGPL-2+ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA + . + On Debian systems, the full text of the GNU Lesser General Public + License version 2 can be found in the file + `/usr/share/common-licenses/LGPL-2'. + +License: X11/MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/debian/getprop.1 b/debian/getprop.1 new file mode 100644 index 0000000..851fe9d --- /dev/null +++ b/debian/getprop.1 @@ -0,0 +1,24 @@ +.TH GETPROP 1 "July 1, 2013" +.SH NAME +getprop \- get property via the android property service +.SH SYNOPSIS +.B getprop +.RI "[property] [default]" +.SH DESCRIPTION +.PP +\fBgetprop\fP is an android utility to retrive a property via the android property service. + +All properties and values are retrieved when there's no argument. + +.SH OPTIONS +.TP +.B property +Name of the property to be retrieved +.TP +.B default +Default property value in case it's not available in the android property service +.SH AUTHOR +getprop is originally available in the Android AOSP project. +.PP +This manual page was written by Ricardo Salveti de Araujo , +for the Debian project (and may be used by others). diff --git a/debian/libandroid-properties-dev.install b/debian/libandroid-properties-dev.install new file mode 100644 index 0000000..25ed677 --- /dev/null +++ b/debian/libandroid-properties-dev.install @@ -0,0 +1,3 @@ +usr/lib/*/libandroid-properties.so +usr/lib/*/pkgconfig/libandroid-properties.pc +usr/include/hybris/properties diff --git a/debian/libandroid-properties1.install b/debian/libandroid-properties1.install new file mode 100644 index 0000000..5640d04 --- /dev/null +++ b/debian/libandroid-properties1.install @@ -0,0 +1 @@ +usr/lib/*/libandroid-properties.so.* diff --git a/debian/libhardware-dev.install b/debian/libhardware-dev.install new file mode 100644 index 0000000..cfbd33f --- /dev/null +++ b/debian/libhardware-dev.install @@ -0,0 +1,2 @@ +usr/lib/*/libhardware.so +usr/lib/*/pkgconfig/libhardware.pc diff --git a/debian/libhardware2.install b/debian/libhardware2.install new file mode 100644 index 0000000..44f5dca --- /dev/null +++ b/debian/libhardware2.install @@ -0,0 +1 @@ +usr/lib/*/libhardware.so.* diff --git a/debian/libhybris-common-dev.install b/debian/libhybris-common-dev.install new file mode 100644 index 0000000..612e3e7 --- /dev/null +++ b/debian/libhybris-common-dev.install @@ -0,0 +1 @@ +usr/lib/*/libhybris-common.so diff --git a/debian/libhybris-common1.install b/debian/libhybris-common1.install new file mode 100644 index 0000000..148cf34 --- /dev/null +++ b/debian/libhybris-common1.install @@ -0,0 +1 @@ +usr/lib/*/libhybris-common.so.* diff --git a/debian/libhybris-dev.install b/debian/libhybris-dev.install new file mode 100644 index 0000000..6c428c8 --- /dev/null +++ b/debian/libhybris-dev.install @@ -0,0 +1,21 @@ +usr/lib/*/libhybris-eglplatformcommon.so +usr/lib/*/libhybris-hwcomposerwindow.so +usr/lib/*/libsync.so +usr/lib/*/libui.so +usr/lib/*/libsf.so +usr/lib/*/libis.so +usr/lib/*/libcamera.so +usr/lib/*/pkgconfig/hwcomposer-egl.pc +usr/lib/*/pkgconfig/hybris-egl-platform.pc +usr/lib/*/pkgconfig/libis.pc +usr/lib/*/pkgconfig/libcamera.pc +usr/lib/*/pkgconfig/libsf.pc +usr/lib/*/pkgconfig/libsync.pc +usr/include/hybris/input +usr/include/hybris/camera +usr/include/hybris/eglplatformcommon +usr/include/hybris/surface_flinger +usr/include/hybris/ui +usr/include/hybris/eglplatformcommon +usr/include/hybris/hwcomposerwindow +usr/include/hybris/dlfcn diff --git a/debian/libhybris-test.install b/debian/libhybris-test.install new file mode 100644 index 0000000..04baf6a --- /dev/null +++ b/debian/libhybris-test.install @@ -0,0 +1 @@ +usr/bin/test_* diff --git a/debian/libhybris-utils.install b/debian/libhybris-utils.install new file mode 100644 index 0000000..552d1c9 --- /dev/null +++ b/debian/libhybris-utils.install @@ -0,0 +1,2 @@ +usr/bin/getprop +usr/bin/setprop diff --git a/debian/libhybris-utils.manpages b/debian/libhybris-utils.manpages new file mode 100644 index 0000000..6cb23c0 --- /dev/null +++ b/debian/libhybris-utils.manpages @@ -0,0 +1,2 @@ +debian/getprop.1 +debian/setprop.1 diff --git a/debian/libhybris.dirs.in b/debian/libhybris.dirs.in new file mode 100644 index 0000000..1d78224 --- /dev/null +++ b/debian/libhybris.dirs.in @@ -0,0 +1,2 @@ +usr/lib/arm-linux-gnueabihf/libhybris +#PKGLIBDIR# diff --git a/debian/libhybris.install.in b/debian/libhybris.install.in new file mode 100644 index 0000000..d20f0bc --- /dev/null +++ b/debian/libhybris.install.in @@ -0,0 +1,11 @@ +usr/lib/*/libhybris-eglplatformcommon.so.* +usr/lib/*/libhybris-hwcomposerwindow.so.* +usr/lib/*/libsync.so.* +usr/lib/*/libui.so.* +usr/lib/*/libsf.so.* +usr/lib/*/libis.so.* +usr/lib/*/libcamera.so.* +usr/lib/*/libhybris/*.so +usr/lib/*/libwayland-egl.so.* #PKGLIBDIR# +usr/lib/*/libEGL.so.* #PKGLIBDIR# +usr/lib/*/libGLESv2.so.* #PKGLIBDIR# diff --git a/debian/libhybris.links.in b/debian/libhybris.links.in new file mode 100644 index 0000000..12590e7 --- /dev/null +++ b/debian/libhybris.links.in @@ -0,0 +1 @@ +#LIBDIR#/libhybris-common.so.1 #LIBDIR#/libhybris_ics.so diff --git a/debian/libhybris.postinst.in b/debian/libhybris.postinst.in new file mode 100644 index 0000000..da45afb --- /dev/null +++ b/debian/libhybris.postinst.in @@ -0,0 +1,21 @@ +#!/bin/sh +# Copyright (C) 2007 Mario Limonciello +# Copyright (C) 2009-2011 Canonical Ltd. + +set -e + +PACKAGE_NAME=#DRIVERNAME# +ARCH=`dpkg --print-architecture` + +if [ "$1" = "configure" ]; then + + update-alternatives --force \ + --install /#SYSCONFDIR#/ld.so.conf.d/#DEB_HOST_MULTIARCH#_EGL.conf #DEB_HOST_MULTIARCH#_egl_conf /#LDSOCONF# #ALTPRIORITY# + + # ldconfig needs to be run immediately as we're changing /etc/ld.so.conf.d/ with + # alternatives. + LDCONFIG_NOTRIGGER=y ldconfig + +fi + +#DEBHELPER# diff --git a/debian/libhybris.postrm.in b/debian/libhybris.postrm.in new file mode 100644 index 0000000..f975b6f --- /dev/null +++ b/debian/libhybris.postrm.in @@ -0,0 +1,47 @@ +#! /bin/sh +# +# see: dh_installdeb(1) +# +# Copyright (C) 2007 Mario Limonciello +# Copyright (C) 2009-2011 Canonical Ltd. + +set -e + +# summary of how this script can be called: +# * `remove' +# * `purge' +# * `upgrade' +# * `failed-upgrade' +# * `abort-install' +# * `abort-install' +# * `abort-upgrade' +# * `disappear' overwrit>r> +# for details, see /usr/share/doc/packaging-manual/ + +PKGNAME=#DRIVERNAME# + +case "$1" in + remove|purge) + + if [ "$1" = "purge" ]; then + rm -Rf /#PKGLIBDIR# + else + # This will preserve the etc directory + rm -f /#PKGLIBDIR#/* 2>/dev/null || true + fi + + ;; + + upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 0 + +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# diff --git a/debian/libhybris.prerm.in b/debian/libhybris.prerm.in new file mode 100644 index 0000000..16d94e5 --- /dev/null +++ b/debian/libhybris.prerm.in @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Copyright (C) 2007 Mario Limonciello +# Copyright (C) 2009-2011 Canonical Ltd. + +set -e + +PACKAGE_NAME=#DRIVERNAME# + +case "$1" in + remove) + update-alternatives --remove #DEB_HOST_MULTIARCH#_egl_conf /#LDSOCONF# + + # explicit ldconfig due to alternatives + LDCONFIG_NOTRIGGER=y ldconfig + ;; +esac + +#DEBHELPER# diff --git a/debian/libmedia-dev.install b/debian/libmedia-dev.install new file mode 100644 index 0000000..d75bd81 --- /dev/null +++ b/debian/libmedia-dev.install @@ -0,0 +1,3 @@ +usr/lib/*/libmedia.so +usr/lib/*/pkgconfig/libmedia.pc +usr/include/hybris/media diff --git a/debian/libmedia1.install b/debian/libmedia1.install new file mode 100644 index 0000000..a1562da --- /dev/null +++ b/debian/libmedia1.install @@ -0,0 +1 @@ +usr/lib/*/libmedia.so.* diff --git a/debian/patches/debian-changes b/debian/patches/debian-changes new file mode 100644 index 0000000..96cd18e --- /dev/null +++ b/debian/patches/debian-changes @@ -0,0 +1,7670 @@ +Subject: Collected Debian patches for libhybris +Author: Ricardo Salveti de Araujo + +The libhybris package is maintained in Git rather than maintaining +patches as separate files, and separating the patches doesn't seem to +be worth the effort. They are therefore all included in this single +Debian patch. + +For full commit history and separated commits, see the packaging Git +repository. +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/Android.common.mk +@@ -0,0 +1,10 @@ ++# define ANDROID_VERSION MAJOR, MINOR and PATCH ++ ++ANDROID_VERSION_MAJOR := $(word 1, $(subst ., , $(PLATFORM_VERSION))) ++ANDROID_VERSION_MINOR := $(word 2, $(subst ., , $(PLATFORM_VERSION))) ++ANDROID_VERSION_PATCH := $(word 3, $(subst ., , $(PLATFORM_VERSION))) ++ ++LOCAL_CFLAGS += \ ++ -DANDROID_VERSION_MAJOR=$(ANDROID_VERSION_MAJOR) \ ++ -DANDROID_VERSION_MINOR=$(ANDROID_VERSION_MINOR) \ ++ -DANDROID_VERSION_PATCH=$(ANDROID_VERSION_PATCH) +--- libhybris-0.1.0+git20131207+e452e83.orig/compat/camera/Android.mk ++++ libhybris-0.1.0+git20131207+e452e83/compat/camera/Android.mk +@@ -1,5 +1,6 @@ + LOCAL_PATH:= $(call my-dir) + include $(CLEAR_VARS) ++include $(LOCAL_PATH)/../Android.common.mk + + HYBRIS_PATH := $(LOCAL_PATH)/../../hybris + +--- libhybris-0.1.0+git20131207+e452e83.orig/compat/camera/camera_compatibility_layer.cpp ++++ libhybris-0.1.0+git20131207+e452e83/compat/camera/camera_compatibility_layer.cpp +@@ -27,17 +27,25 @@ + #include + #include + #include ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 + #include ++#else ++#include ++#endif + #include + ++#include ++#include ++ + #undef LOG_TAG + #define LOG_TAG "CameraCompatibilityLayer" + #include + #include ++#include + + #define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__) + +-// From android::SurfaceTexture::FrameAvailableListener ++// From android::GLConsumer::FrameAvailableListener + void CameraControl::onFrameAvailable() + { + REPORT_FUNCTION(); +@@ -170,7 +178,11 @@ CameraControl* android_camera_connect_to + + CameraControl* cc = new CameraControl(); + cc->listener = listener; ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3 ++ cc->camera = android::Camera::connect(camera_id, android::String16("hybris"), android::Camera::USE_CALLING_UID); ++#else + cc->camera = android::Camera::connect(camera_id); ++#endif + + if (cc->camera == NULL) + return NULL; +@@ -511,30 +523,57 @@ void android_camera_set_preview_texture( + assert(control); + + static const bool allow_synchronous_mode = false; ++ static const bool is_controlled_by_app = true; + + android::sp native_alloc( + new android::NativeBufferAlloc() + ); + + android::sp buffer_queue( ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 + new android::BufferQueue(false, NULL, native_alloc) ++#else ++ new android::BufferQueue(NULL, native_alloc) ++#endif + ); + + if (control->preview_texture == NULL) { ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 + control->preview_texture = android::sp( + new android::SurfaceTexture( ++#else ++ control->preview_texture = android::sp( ++ new android::GLConsumer( ++#endif ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 + texture_id, + allow_synchronous_mode, + GL_TEXTURE_EXTERNAL_OES, + true, + buffer_queue)); ++#else ++ buffer_queue, ++ texture_id, ++ GL_TEXTURE_EXTERNAL_OES, ++ true, ++ is_controlled_by_app)); ++#endif + } + + control->preview_texture->setFrameAvailableListener( ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 + android::sp(control)); ++#else ++ android::sp(control)); ++#endif ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 + control->camera->setPreviewTexture(control->preview_texture->getBufferQueue()); ++#else ++ control->camera->setPreviewTarget(buffer_queue); ++#endif + } + ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 + void android_camera_set_preview_surface(CameraControl* control, SfSurface* surface) + { + REPORT_FUNCTION(); +@@ -544,6 +583,7 @@ void android_camera_set_preview_surface( + android::Mutex::Autolock al(control->guard); + control->camera->setPreviewDisplay(surface->surface); + } ++#endif + + void android_camera_start_preview(CameraControl* control) + { +--- libhybris-0.1.0+git20131207+e452e83.orig/compat/input/Android.mk ++++ libhybris-0.1.0+git20131207+e452e83/compat/input/Android.mk +@@ -18,6 +18,11 @@ LOCAL_SHARED_LIBRARIES := \ + libgui \ + libandroidfw + ++HAS_LIBINPUTSERVICE := $(shell test $(ANDROID_VERSION_MAJOR) -eq 4 -a $(ANDROID_VERSION_MINOR) -gt 2 && echo true) ++ifeq ($(HAS_LIBINPUTSERVICE),true) ++LOCAL_SHARED_LIBRARIES += libinputservice ++endif ++ + LOCAL_C_INCLUDES := \ + $(HYBRIS_PATH)/include \ + external/skia/include/core \ +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/Android.mk +@@ -0,0 +1,109 @@ ++LOCAL_PATH:= $(call my-dir) ++include $(CLEAR_VARS) ++include $(LOCAL_PATH)/../Android.common.mk ++ ++HYBRIS_PATH := $(LOCAL_PATH)/../../hybris ++ ++LOCAL_CFLAGS += -std=gnu++0x ++ ++LOCAL_SRC_FILES:= \ ++ media_compatibility_layer.cpp \ ++ media_codec_layer.cpp \ ++ media_codec_list.cpp \ ++ media_format_layer.cpp \ ++ surface_texture_client_hybris.cpp \ ++ recorder_compatibility_layer.cpp ++ ++LOCAL_MODULE:= libmedia_compat_layer ++LOCAL_MODULE_TAGS := optional ++ ++LOCAL_SHARED_LIBRARIES := \ ++ libcutils \ ++ libcamera_client \ ++ libutils \ ++ libbinder \ ++ libhardware \ ++ libui \ ++ libgui \ ++ libstagefright \ ++ libstagefright_foundation \ ++ libEGL \ ++ libGLESv2 \ ++ libmedia ++ ++LOCAL_C_INCLUDES := \ ++ $(HYBRIS_PATH)/include \ ++ frameworks/base/media/libstagefright/include \ ++ frameworks/base/include/media/stagefright \ ++ frameworks/base/include/media ++ ++include $(BUILD_SHARED_LIBRARY) ++ ++include $(CLEAR_VARS) ++include $(LOCAL_PATH)/../Android.common.mk ++ ++LOCAL_SRC_FILES:= \ ++ direct_media_test.cpp ++ ++LOCAL_MODULE:= direct_media_test ++LOCAL_MODULE_TAGS := optional ++ ++LOCAL_C_INCLUDES := \ ++ $(HYBRIS_PATH)/include \ ++ bionic \ ++ bionic/libstdc++/include \ ++ external/gtest/include \ ++ external/stlport/stlport \ ++ external/skia/include/core \ ++ frameworks/base/include ++ ++LOCAL_SHARED_LIBRARIES := \ ++ libis_compat_layer \ ++ libsf_compat_layer \ ++ libmedia_compat_layer \ ++ libcutils \ ++ libutils \ ++ libbinder \ ++ libhardware \ ++ libui \ ++ libgui \ ++ libEGL \ ++ libGLESv2 ++ ++include $(BUILD_EXECUTABLE) ++ ++include $(CLEAR_VARS) ++include $(LOCAL_PATH)/../Android.common.mk ++ ++LOCAL_CFLAGS += -Wno-multichar -D SIMPLE_PLAYER -std=gnu++0x ++ ++LOCAL_SRC_FILES:= \ ++ media_codec_layer.cpp \ ++ media_codec_list.cpp \ ++ media_format_layer.cpp \ ++ codec.cpp \ ++ SimplePlayer.cpp ++ ++LOCAL_SHARED_LIBRARIES := \ ++ libstagefright \ ++ libstagefright_foundation \ ++ liblog \ ++ libutils \ ++ libbinder \ ++ libmedia \ ++ libgui \ ++ libcutils \ ++ libui ++ ++LOCAL_C_INCLUDES:= \ ++ $(HYBRIS_PATH)/include \ ++ frameworks/av/media/libstagefright \ ++ frameworks/native/include/media/openmax \ ++ frameworks/base/media/libstagefright/include \ ++ frameworks/base/include/media/stagefright \ ++ frameworks/base/include/media ++ ++LOCAL_MODULE:= codec ++LOCAL_MODULE_TAGS := optional ++ ++include $(BUILD_EXECUTABLE) +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/SimplePlayer.cpp +@@ -0,0 +1,777 @@ ++/* ++ * Copyright (C) 2012 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++//#define LOG_NDEBUG 0 ++#define LOG_TAG "SimplePlayer" ++#include ++ ++#include "SimplePlayer.h" ++ ++#include ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define USE_MEDIA_CODEC_LAYER ++ ++namespace android { ++ ++SimplePlayer::SimplePlayer() ++ : mState(UNINITIALIZED), ++ mDoMoreStuffGeneration(0), ++ mStartTimeRealUs(-1ll) { ++} ++ ++SimplePlayer::~SimplePlayer() { ++} ++ ++// static ++status_t PostAndAwaitResponse( ++ const sp &msg, sp *response) { ++ status_t err = msg->postAndAwaitResponse(response); ++ printf("%s\n", __PRETTY_FUNCTION__); ++ ++ if (err != OK) { ++ return err; ++ } ++ ++ if (!(*response)->findInt32("err", &err)) { ++ err = OK; ++ } ++ ++ return err; ++} ++status_t SimplePlayer::setDataSource(const char *path) { ++ sp msg = new AMessage(kWhatSetDataSource, id()); ++ msg->setString("path", path); ++ sp response; ++ return PostAndAwaitResponse(msg, &response); ++} ++ ++status_t SimplePlayer::setSurface(const sp &surfaceTexture) { ++ sp msg = new AMessage(kWhatSetSurface, id()); ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ sp surfaceTextureClient; ++ if (surfaceTexture != NULL) { ++ surfaceTextureClient = new SurfaceTextureClient(surfaceTexture); ++ } ++#else ++ sp surfaceTextureClient; ++ if (surfaceTexture != NULL) { ++ surfaceTextureClient = new Surface(surfaceTexture); ++ } ++#endif ++ ++ msg->setObject( ++ "native-window", new NativeWindowWrapper(surfaceTextureClient)); ++ ++ sp response; ++ return PostAndAwaitResponse(msg, &response); ++} ++ ++status_t SimplePlayer::prepare() { ++ sp msg = new AMessage(kWhatPrepare, id()); ++ sp response; ++ return PostAndAwaitResponse(msg, &response); ++} ++ ++status_t SimplePlayer::start() { ++ printf("%s\n", __PRETTY_FUNCTION__); ++ sp msg = new AMessage(kWhatStart, id()); ++ sp response; ++ return PostAndAwaitResponse(msg, &response); ++} ++ ++status_t SimplePlayer::stop() { ++ sp msg = new AMessage(kWhatStop, id()); ++ sp response; ++ return PostAndAwaitResponse(msg, &response); ++} ++ ++status_t SimplePlayer::reset() { ++ sp msg = new AMessage(kWhatReset, id()); ++ sp response; ++ return PostAndAwaitResponse(msg, &response); ++} ++ ++void SimplePlayer::onMessageReceived(const sp &msg) { ++ switch (msg->what()) { ++ case kWhatSetDataSource: ++ { ++ status_t err; ++ if (mState != UNINITIALIZED) { ++ err = INVALID_OPERATION; ++ } else { ++ CHECK(msg->findString("path", &mPath)); ++ mState = UNPREPARED; ++ } ++ ++ uint32_t replyID; ++ CHECK(msg->senderAwaitsResponse(&replyID)); ++ ++ sp response = new AMessage; ++ response->setInt32("err", err); ++ response->postReply(replyID); ++ break; ++ } ++ ++ case kWhatSetSurface: ++ { ++ status_t err; ++ if (mState != UNPREPARED) { ++ err = INVALID_OPERATION; ++ } else { ++ sp obj; ++ CHECK(msg->findObject("native-window", &obj)); ++ ++ mNativeWindow = static_cast(obj.get()); ++ ++ err = OK; ++ } ++ ++ uint32_t replyID; ++ CHECK(msg->senderAwaitsResponse(&replyID)); ++ ++ sp response = new AMessage; ++ response->setInt32("err", err); ++ response->postReply(replyID); ++ break; ++ } ++ ++ case kWhatPrepare: ++ { ++ status_t err; ++ if (mState != UNPREPARED) { ++ err = INVALID_OPERATION; ++ } else { ++ err = onPrepare(); ++ ++ if (err == OK) { ++ mState = STOPPED; ++ } ++ } ++ ++ uint32_t replyID; ++ CHECK(msg->senderAwaitsResponse(&replyID)); ++ ++ sp response = new AMessage; ++ response->setInt32("err", err); ++ response->postReply(replyID); ++ break; ++ } ++ ++ case kWhatStart: ++ { ++ status_t err = OK; ++ ++ if (mState == UNPREPARED) { ++ err = onPrepare(); ++ ++ if (err == OK) { ++ mState = STOPPED; ++ } ++ } ++ ++ if (err == OK) { ++ if (mState != STOPPED) { ++ err = INVALID_OPERATION; ++ } else { ++ err = onStart(); ++ ++ if (err == OK) { ++ mState = STARTED; ++ } ++ } ++ } ++ ++ uint32_t replyID; ++ CHECK(msg->senderAwaitsResponse(&replyID)); ++ ++ sp response = new AMessage; ++ response->setInt32("err", err); ++ response->postReply(replyID); ++ break; ++ } ++ ++ case kWhatStop: ++ { ++ status_t err; ++ ++ if (mState != STARTED) { ++ err = INVALID_OPERATION; ++ } else { ++ err = onStop(); ++ ++ if (err == OK) { ++ mState = STOPPED; ++ } ++ } ++ ++ uint32_t replyID; ++ CHECK(msg->senderAwaitsResponse(&replyID)); ++ ++ sp response = new AMessage; ++ response->setInt32("err", err); ++ response->postReply(replyID); ++ break; ++ } ++ ++ case kWhatReset: ++ { ++ status_t err = OK; ++ ++ if (mState == STARTED) { ++ CHECK_EQ(onStop(), (status_t)OK); ++ mState = STOPPED; ++ } ++ ++ if (mState == STOPPED) { ++ err = onReset(); ++ mState = UNINITIALIZED; ++ } ++ ++ uint32_t replyID; ++ CHECK(msg->senderAwaitsResponse(&replyID)); ++ ++ sp response = new AMessage; ++ response->setInt32("err", err); ++ response->postReply(replyID); ++ break; ++ } ++ ++ case kWhatDoMoreStuff: ++ { ++ int32_t generation; ++ CHECK(msg->findInt32("generation", &generation)); ++ ++ if (generation != mDoMoreStuffGeneration) { ++ break; ++ } ++ ++ status_t err = onDoMoreStuff(); ++ ++ if (err == OK) { ++ msg->post(10000ll); ++ } ++ break; ++ } ++ ++ default: ++ TRESPASS(); ++ } ++} ++ ++status_t SimplePlayer::onPrepare() { ++ CHECK_EQ(mState, UNPREPARED); ++ printf("%s\n", __PRETTY_FUNCTION__); ++ ++ mExtractor = new NuMediaExtractor; ++ ++ status_t err = mExtractor->setDataSource(mPath.c_str()); ++ ++ if (err != OK) { ++ mExtractor.clear(); ++ return err; ++ } ++ ++ if (mCodecLooper == NULL) { ++ mCodecLooper = new ALooper; ++ mCodecLooper->start(); ++ } ++ ++ bool haveAudio = false; ++ bool haveVideo = false; ++ for (size_t i = 0; i < mExtractor->countTracks(); ++i) { ++ sp format; ++ status_t err = mExtractor->getTrackFormat(i, &format); ++ CHECK_EQ(err, (status_t)OK); ++ ++ AString mime; ++ int32_t width = 0, height = 0, maxInputSize = 0; ++ int64_t durationUs = 0; ++ sp csd0, csd1; ++#ifdef USE_MEDIA_CODEC_LAYER ++ MediaFormat mformat; ++#endif ++ CHECK(format->findString("mime", &mime)); ++ ++ if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) { ++ //haveAudio = true; ++ printf("*** Have audio but skipping it!\n"); ++ continue; ++ } else if (!haveVideo && !strncasecmp(mime.c_str(), "video/", 6)) { ++ haveVideo = true; ++ CHECK(format->findInt32("width", &width)); ++ CHECK(format->findInt32("height", &height)); ++ CHECK(format->findInt64("durationUs", &durationUs)); ++ CHECK(format->findInt32("max-input-size", &maxInputSize)); ++ CHECK(format->findBuffer("csd-0", &csd0)); ++ CHECK(format->findBuffer("csd-1", &csd1)); ++#ifdef USE_MEDIA_CODEC_LAYER ++ mformat = media_format_create_video_format(mime.c_str(), width, height, durationUs, maxInputSize); ++ media_format_set_byte_buffer(mformat, "csd-0", csd0->data(), csd0->size()); ++ media_format_set_byte_buffer(mformat, "csd-1", csd1->data(), csd1->size()); ++#endif ++ } else { ++ continue; ++ } ++ ++ err = mExtractor->selectTrack(i); ++ CHECK_EQ(err, (status_t)OK); ++ ++ CodecState *state = ++ &mStateByTrackIndex.editValueAt( ++ mStateByTrackIndex.add(i, CodecState())); ++ ++ state->mNumFramesWritten = 0; ++#ifdef USE_MEDIA_CODEC_LAYER ++ state->mCodecDelegate = media_codec_create_by_codec_type(mime.c_str()); ++ state->mCodec = media_codec_get(state->mCodecDelegate); ++ CHECK(state->mCodecDelegate != NULL); ++#else ++ state->mCodec = MediaCodec::CreateByType( ++ mCodecLooper, mime.c_str(), false /* encoder */); ++#endif ++ ++ CHECK(state->mCodec != NULL); ++ ++#ifdef USE_MEDIA_CODEC_LAYER ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ err = media_codec_configure(state->mCodecDelegate, mformat, mNativeWindow->getSurfaceTextureClient().get(), 0); ++#else ++ err = media_codec_configure(state->mCodecDelegate, mformat, mNativeWindow->getSurface().get(), 0); ++#endif ++#else ++ err = state->mCodec->configure( ++ format, ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ mNativeWindow->getSurfaceTextureClient(), ++#else ++ mNativeWindow->getSurface(), ++#endif ++ NULL /* crypto */, ++ 0 /* flags */); ++#endif ++ ++ CHECK_EQ(err, (status_t)OK); ++ ++ size_t j = 0; ++ sp buffer; ++ // Place the CSD data into the source buffer ++ while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) { ++ state->mCSD.push_back(buffer); ++ ++ ++j; ++ } ++ } ++ ++ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { ++ CodecState *state = &mStateByTrackIndex.editValueAt(i); ++ ++#ifdef USE_MEDIA_CODEC_LAYER ++ status_t err = media_codec_start(state->mCodecDelegate); ++#else ++ status_t err = state->mCodec->start(); ++#endif ++ CHECK_EQ(err, (status_t)OK); ++ ++#ifdef USE_MEDIA_CODEC_LAYER ++ size_t nInputBuffers = media_codec_get_input_buffers_size(state->mCodecDelegate); ++ ALOGD("nInputBuffers: %u", nInputBuffers); ++ for (size_t i=0; imCodecDelegate, i); ++ CHECK(data != NULL); ++ size_t size = media_codec_get_nth_input_buffer_capacity(state->mCodecDelegate, i); ++ ALOGD("input buffer[%d] size: %d", i, size); ++ sp buf = new ABuffer(data, size); ++ state->mBuffers[0].insertAt(new ABuffer(data, size), i); ++ } ++#else ++ err = state->mCodec->getInputBuffers(&state->mBuffers[0]); ++ CHECK_EQ(err, (status_t)OK); ++#endif ++ ++ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]); ++ CHECK_EQ(err, (status_t)OK); ++ ++ for (size_t j = 0; j < state->mCSD.size(); ++j) { ++ const sp &srcBuffer = state->mCSD.itemAt(j); ++ ++ size_t index; ++#ifdef USE_MEDIA_CODEC_LAYER ++ err = media_codec_dequeue_input_buffer(state->mCodecDelegate, &index, -1ll); ++#else ++ err = state->mCodec->dequeueInputBuffer(&index, -1ll); ++#endif ++ CHECK_EQ(err, (status_t)OK); ++ ++ const sp &dstBuffer = state->mBuffers[0].itemAt(index); ++ ++ CHECK_LE(srcBuffer->size(), dstBuffer->capacity()); ++ dstBuffer->setRange(0, srcBuffer->size()); ++ memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size()); ++ ++#ifdef USE_MEDIA_CODEC_LAYER ++ MediaCodecBufferInfo bufInfo; ++ bufInfo.index = index; ++ bufInfo.offset = 0; ++ bufInfo.size = dstBuffer->size(); ++ bufInfo.presentation_time_us = 0ll; ++ bufInfo.flags = MediaCodec::BUFFER_FLAG_CODECCONFIG; ++ ++ err = media_codec_queue_input_buffer( ++ state->mCodecDelegate, ++ &bufInfo); ++ ++#else ++ err = state->mCodec->queueInputBuffer( ++ index, ++ 0, ++ dstBuffer->size(), ++ 0ll, ++ MediaCodec::BUFFER_FLAG_CODECCONFIG); ++#endif ++ CHECK_EQ(err, (status_t)OK); ++ } ++ } ++ ++ return OK; ++} ++ ++status_t SimplePlayer::onStart() { ++ CHECK_EQ(mState, STOPPED); ++ ++ mStartTimeRealUs = -1ll; ++ ++ sp msg = new AMessage(kWhatDoMoreStuff, id()); ++ msg->setInt32("generation", ++mDoMoreStuffGeneration); ++ msg->post(); ++ ++ return OK; ++} ++ ++status_t SimplePlayer::onStop() { ++ CHECK_EQ(mState, STARTED); ++ ++ ++mDoMoreStuffGeneration; ++ ++ return OK; ++} ++ ++status_t SimplePlayer::onReset() { ++ CHECK_EQ(mState, STOPPED); ++ ++ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { ++ CodecState *state = &mStateByTrackIndex.editValueAt(i); ++ ++ CHECK_EQ(state->mCodec->release(), (status_t)OK); ++ } ++ ++ mStartTimeRealUs = -1ll; ++ ++ mStateByTrackIndex.clear(); ++ mCodecLooper.clear(); ++ mExtractor.clear(); ++ mNativeWindow.clear(); ++ mPath.clear(); ++ ++ return OK; ++} ++ ++status_t SimplePlayer::onDoMoreStuff() { ++ ALOGV("onDoMoreStuff"); ++ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { ++ CodecState *state = &mStateByTrackIndex.editValueAt(i); ++ ++ status_t err; ++ do { ++ size_t index; ++#ifdef USE_MEDIA_CODEC_LAYER ++ err = media_codec_dequeue_input_buffer(state->mCodecDelegate, &index, 0ll); ++#else ++ err = state->mCodec->dequeueInputBuffer(&index); ++#endif ++ ++ if (err == OK) { ++ ALOGD("dequeued input buffer on track %d", ++ mStateByTrackIndex.keyAt(i)); ++ ++ state->mAvailInputBufferIndices.push_back(index); ++ } else { ++ ALOGD("dequeueInputBuffer on track %d returned %d", ++ mStateByTrackIndex.keyAt(i), err); ++ } ++ } while (err == OK); ++ ++ do { ++#ifdef USE_MEDIA_CODEC_LAYER ++ BufferInfo info; ++ MediaCodecBufferInfo bufInfo; ++ err = media_codec_dequeue_output_buffer( ++ state->mCodecDelegate, ++ &bufInfo, ++ 0ll); ++ ++ info.mIndex = bufInfo.index; ++ info.mOffset = bufInfo.offset; ++ info.mSize = bufInfo.size; ++ info.mPresentationTimeUs = bufInfo.presentation_time_us; ++ info.mFlags = bufInfo.flags; ++ ++#else ++ BufferInfo info; ++ err = state->mCodec->dequeueOutputBuffer( ++ &info.mIndex, ++ &info.mOffset, ++ &info.mSize, ++ &info.mPresentationTimeUs, ++ &info.mFlags); ++#endif ++ ++ if (err == OK) { ++ ALOGV("dequeued output buffer on track %d", ++ mStateByTrackIndex.keyAt(i)); ++ ++ state->mAvailOutputBufferInfos.push_back(info); ++ } else if (err == INFO_FORMAT_CHANGED) { ++ err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state); ++ CHECK_EQ(err, (status_t)OK); ++ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { ++ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]); ++ CHECK_EQ(err, (status_t)OK); ++ } else { ++ ALOGV("dequeueOutputBuffer on track %d returned %d", ++ mStateByTrackIndex.keyAt(i), err); ++ } ++ } while (err == OK ++ || err == INFO_FORMAT_CHANGED ++ || err == INFO_OUTPUT_BUFFERS_CHANGED); ++ } ++ ++ for (;;) { ++ size_t trackIndex; ++ status_t err = mExtractor->getSampleTrackIndex(&trackIndex); ++ ++ if (err != OK) { ++ ALOGI("encountered input EOS."); ++ break; ++ } else { ++ CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex); ++ ++ if (state->mAvailInputBufferIndices.empty()) { ++ break; ++ } ++ ++ size_t index = *state->mAvailInputBufferIndices.begin(); ++ state->mAvailInputBufferIndices.erase( ++ state->mAvailInputBufferIndices.begin()); ++ ++ const sp &dstBuffer = ++ state->mBuffers[0].itemAt(index); ++ ++ err = mExtractor->readSampleData(dstBuffer); ++ CHECK_EQ(err, (status_t)OK); ++ ++ int64_t timeUs; ++ CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK); ++ ++#ifdef USE_MEDIA_CODEC_LAYER ++ MediaCodecBufferInfo bufInfo; ++ bufInfo.index = index; ++ bufInfo.offset = dstBuffer->offset(); ++ bufInfo.size = dstBuffer->size(); ++ bufInfo.presentation_time_us = timeUs; ++ bufInfo.flags = 0; ++ ++ err = media_codec_queue_input_buffer( ++ state->mCodecDelegate, ++ &bufInfo); ++ ++#else ++ err = state->mCodec->queueInputBuffer( ++ index, ++ dstBuffer->offset(), ++ dstBuffer->size(), ++ timeUs, ++ 0); ++#endif ++ CHECK_EQ(err, (status_t)OK); ++ ++ ALOGV("enqueued input data on track %d", trackIndex); ++ ++ err = mExtractor->advance(); ++ CHECK_EQ(err, (status_t)OK); ++ } ++ } ++ ++ int64_t nowUs = ALooper::GetNowUs(); ++ ++ if (mStartTimeRealUs < 0ll) { ++ mStartTimeRealUs = nowUs + 1000000ll; ++ } ++ ++ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { ++ CodecState *state = &mStateByTrackIndex.editValueAt(i); ++ ++ while (!state->mAvailOutputBufferInfos.empty()) { ++ BufferInfo *info = &*state->mAvailOutputBufferInfos.begin(); ++ ++ int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs; ++ int64_t lateByUs = nowUs - whenRealUs; ++ ++ if (lateByUs > -10000ll) { ++ bool release = true; ++ ++ if (lateByUs > 30000ll) { ++ ALOGI("track %d buffer late by %lld us, dropping.", ++ mStateByTrackIndex.keyAt(i), lateByUs); ++ state->mCodec->releaseOutputBuffer(info->mIndex); ++ } else { ++ if (state->mAudioTrack != NULL) { ++ const sp &srcBuffer = ++ state->mBuffers[1].itemAt(info->mIndex); ++ ++ renderAudio(state, info, srcBuffer); ++ ++ if (info->mSize > 0) { ++ release = false; ++ } ++ } ++ ++ if (release) { ++#ifdef USE_MEDIA_CODEC_LAYER ++ ALOGD("Rendering output buffer index %d and releasing", info->mIndex); ++ state->mCodec->renderOutputBufferAndRelease( ++ info->mIndex); ++#else ++ ALOGD("Releasing output buffer index %d", info->mIndex); ++ state->mCodec->releaseOutputBuffer(info->mIndex); ++#endif ++ } ++ } ++ ++ if (release) { ++ state->mAvailOutputBufferInfos.erase( ++ state->mAvailOutputBufferInfos.begin()); ++ ++ info = NULL; ++ } else { ++ break; ++ } ++ } else { ++ ALOGV("track %d buffer early by %lld us.", ++ mStateByTrackIndex.keyAt(i), -lateByUs); ++ break; ++ } ++ } ++ } ++ ++ return OK; ++} ++ ++status_t SimplePlayer::onOutputFormatChanged( ++ size_t trackIndex, CodecState *state) { ++ sp format; ++ status_t err = state->mCodec->getOutputFormat(&format); ++ ++ if (err != OK) { ++ return err; ++ } ++ ++ AString mime; ++ CHECK(format->findString("mime", &mime)); ++ ++ if (!strncasecmp(mime.c_str(), "audio/", 6)) { ++ int32_t channelCount; ++ int32_t sampleRate; ++ CHECK(format->findInt32("channel-count", &channelCount)); ++ CHECK(format->findInt32("sample-rate", &sampleRate)); ++ ++ state->mAudioTrack = new AudioTrack( ++ AUDIO_STREAM_MUSIC, ++ sampleRate, ++ AUDIO_FORMAT_PCM_16_BIT, ++ audio_channel_out_mask_from_count(channelCount), ++ 0); ++ ++ state->mNumFramesWritten = 0; ++ } ++ ++ return OK; ++} ++ ++void SimplePlayer::renderAudio( ++ CodecState *state, BufferInfo *info, const sp &buffer) { ++ CHECK(state->mAudioTrack != NULL); ++ ++ if (state->mAudioTrack->stopped()) { ++ state->mAudioTrack->start(); ++ } ++ ++ uint32_t numFramesPlayed; ++ CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK); ++ ++ uint32_t numFramesAvailableToWrite = ++ state->mAudioTrack->frameCount() ++ - (state->mNumFramesWritten - numFramesPlayed); ++ ++ size_t numBytesAvailableToWrite = ++ numFramesAvailableToWrite * state->mAudioTrack->frameSize(); ++ ++ size_t copy = info->mSize; ++ if (copy > numBytesAvailableToWrite) { ++ copy = numBytesAvailableToWrite; ++ } ++ ++ if (copy == 0) { ++ return; ++ } ++ ++ int64_t startTimeUs = ALooper::GetNowUs(); ++ ++ ssize_t nbytes = state->mAudioTrack->write( ++ buffer->base() + info->mOffset, copy); ++ ++ CHECK_EQ(nbytes, (ssize_t)copy); ++ ++ int64_t delayUs = ALooper::GetNowUs() - startTimeUs; ++ ++ uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize(); ++ ++ if (delayUs > 2000ll) { ++ ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, " ++ "numFramesWritten=%u", ++ delayUs, numFramesAvailableToWrite, numFramesWritten); ++ } ++ ++ info->mOffset += nbytes; ++ info->mSize -= nbytes; ++ ++ state->mNumFramesWritten += numFramesWritten; ++} ++ ++} // namespace android +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/SimplePlayer.h +@@ -0,0 +1,120 @@ ++/* ++ * Copyright (C) 2012 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++namespace android { ++ ++struct ABuffer; ++struct ALooper; ++struct AudioTrack; ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++struct ISurfaceTexture; ++#else ++struct IGraphicBufferProducer; ++#endif ++struct MediaCodec; ++struct NativeWindowWrapper; ++struct NuMediaExtractor; ++ ++struct SimplePlayer : public AHandler { ++ SimplePlayer(); ++ ++ status_t setDataSource(const char *path); ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ status_t setSurface(const sp &surfaceTexture); ++#else ++ status_t setSurface(const sp &surfaceTexture); ++#endif ++ status_t prepare(); ++ status_t start(); ++ status_t stop(); ++ status_t reset(); ++ ++protected: ++ virtual ~SimplePlayer(); ++ ++ virtual void onMessageReceived(const sp &msg); ++ ++private: ++ enum State { ++ UNINITIALIZED, ++ UNPREPARED, ++ STOPPED, ++ STARTED ++ }; ++ ++ enum { ++ kWhatSetDataSource, ++ kWhatSetSurface, ++ kWhatPrepare, ++ kWhatStart, ++ kWhatStop, ++ kWhatReset, ++ kWhatDoMoreStuff, ++ }; ++ ++ struct BufferInfo { ++ size_t mIndex; ++ size_t mOffset; ++ size_t mSize; ++ int64_t mPresentationTimeUs; ++ uint32_t mFlags; ++ }; ++ ++ struct CodecState ++ { ++ sp mCodec; ++ MediaCodecDelegate mCodecDelegate; ++ Vector > mCSD; ++ Vector > mBuffers[2]; ++ ++ List mAvailInputBufferIndices; ++ List mAvailOutputBufferInfos; ++ ++ sp mAudioTrack; ++ uint32_t mNumFramesWritten; ++ }; ++ ++ State mState; ++ AString mPath; ++ sp mNativeWindow; ++ ++ sp mExtractor; ++ sp mCodecLooper; ++ KeyedVector mStateByTrackIndex; ++ int32_t mDoMoreStuffGeneration; ++ ++ int64_t mStartTimeRealUs; ++ ++ status_t onPrepare(); ++ status_t onStart(); ++ status_t onStop(); ++ status_t onReset(); ++ status_t onDoMoreStuff(); ++ status_t onOutputFormatChanged(size_t trackIndex, CodecState *state); ++ ++ void renderAudio( ++ CodecState *state, BufferInfo *info, const sp &buffer); ++ ++ DISALLOW_EVIL_CONSTRUCTORS(SimplePlayer); ++}; ++ ++} // namespace android +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/codec.cpp +@@ -0,0 +1,433 @@ ++/* ++ * Copyright (C) 2012 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#define LOG_NDEBUG 0 ++#define LOG_TAG "codec" ++#include ++ ++#include "SimplePlayer.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void usage(const char *me) { ++ fprintf(stderr, "usage: %s [-a] use audio\n" ++ "\t\t[-v] use video\n" ++ "\t\t[-p] playback\n" ++ "\t\t[-S] allocate buffers from a surface\n", ++ me); ++ ++ exit(1); ++} ++ ++namespace android { ++ ++struct CodecState { ++ sp mCodec; ++ Vector > mInBuffers; ++ Vector > mOutBuffers; ++ bool mSignalledInputEOS; ++ bool mSawOutputEOS; ++ int64_t mNumBuffersDecoded; ++ int64_t mNumBytesDecoded; ++ bool mIsAudio; ++}; ++ ++} // namespace android ++ ++static int decode( ++ const android::sp &looper, ++ const char *path, ++ bool useAudio, ++ bool useVideo, ++ const android::sp &surface) { ++ using namespace android; ++ ++ static int64_t kTimeout = 500ll; ++ ++ sp extractor = new NuMediaExtractor; ++ if (extractor->setDataSource(path) != OK) { ++ fprintf(stderr, "unable to instantiate extractor.\n"); ++ return 1; ++ } ++ ++ KeyedVector stateByTrack; ++ ++ bool haveAudio = false; ++ bool haveVideo = false; ++ for (size_t i = 0; i < extractor->countTracks(); ++i) { ++ sp format; ++ status_t err = extractor->getTrackFormat(i, &format); ++ CHECK_EQ(err, (status_t)OK); ++ ++ AString mime; ++ CHECK(format->findString("mime", &mime)); ++ ++ bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6); ++ bool isVideo = !strncasecmp(mime.c_str(), "video/", 6); ++ ++ if (useAudio && !haveAudio && isAudio) { ++ haveAudio = true; ++ } else if (useVideo && !haveVideo && isVideo) { ++ haveVideo = true; ++ } else { ++ continue; ++ } ++ ++ ALOGV("selecting track %d", i); ++ ++ err = extractor->selectTrack(i); ++ CHECK_EQ(err, (status_t)OK); ++ ++ CodecState *state = ++ &stateByTrack.editValueAt(stateByTrack.add(i, CodecState())); ++ ++ state->mNumBytesDecoded = 0; ++ state->mNumBuffersDecoded = 0; ++ state->mIsAudio = isAudio; ++ ++ state->mCodec = MediaCodec::CreateByType( ++ looper, mime.c_str(), false /* encoder */); ++ ++ CHECK(state->mCodec != NULL); ++ ++ err = state->mCodec->configure( ++ format, isVideo ? surface : NULL, ++ NULL /* crypto */, ++ 0 /* flags */); ++ ++ CHECK_EQ(err, (status_t)OK); ++ ++ state->mSignalledInputEOS = false; ++ state->mSawOutputEOS = false; ++ } ++ ++ CHECK(!stateByTrack.isEmpty()); ++ ++ int64_t startTimeUs = ALooper::GetNowUs(); ++ ++ for (size_t i = 0; i < stateByTrack.size(); ++i) { ++ CodecState *state = &stateByTrack.editValueAt(i); ++ ++ sp codec = state->mCodec; ++ ++ CHECK_EQ((status_t)OK, codec->start()); ++ ++ CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers)); ++ CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers)); ++ ++ ALOGV("got %d input and %d output buffers", ++ state->mInBuffers.size(), state->mOutBuffers.size()); ++ } ++ ++ bool sawInputEOS = false; ++ ++ for (;;) { ++ if (!sawInputEOS) { ++ size_t trackIndex; ++ status_t err = extractor->getSampleTrackIndex(&trackIndex); ++ ++ if (err != OK) { ++ ALOGV("saw input eos"); ++ sawInputEOS = true; ++ } else { ++ CodecState *state = &stateByTrack.editValueFor(trackIndex); ++ ++ size_t index; ++ err = state->mCodec->dequeueInputBuffer(&index, kTimeout); ++ ++ if (err == OK) { ++ ALOGV("filling input buffer %d", index); ++ ++ const sp &buffer = state->mInBuffers.itemAt(index); ++ ++ err = extractor->readSampleData(buffer); ++ CHECK_EQ(err, (status_t)OK); ++ ++ int64_t timeUs; ++ err = extractor->getSampleTime(&timeUs); ++ CHECK_EQ(err, (status_t)OK); ++ ++ uint32_t bufferFlags = 0; ++ ++ err = state->mCodec->queueInputBuffer( ++ index, ++ 0 /* offset */, ++ buffer->size(), ++ timeUs, ++ bufferFlags); ++ ++ CHECK_EQ(err, (status_t)OK); ++ ++ extractor->advance(); ++ } else { ++ CHECK_EQ(err, -EAGAIN); ++ } ++ } ++ } else { ++ for (size_t i = 0; i < stateByTrack.size(); ++i) { ++ CodecState *state = &stateByTrack.editValueAt(i); ++ ++ if (!state->mSignalledInputEOS) { ++ size_t index; ++ status_t err = ++ state->mCodec->dequeueInputBuffer(&index, kTimeout); ++ ++ if (err == OK) { ++ ALOGV("signalling input EOS on track %d", i); ++ ++ err = state->mCodec->queueInputBuffer( ++ index, ++ 0 /* offset */, ++ 0 /* size */, ++ 0ll /* timeUs */, ++ MediaCodec::BUFFER_FLAG_EOS); ++ ++ CHECK_EQ(err, (status_t)OK); ++ ++ state->mSignalledInputEOS = true; ++ } else { ++ CHECK_EQ(err, -EAGAIN); ++ } ++ } ++ } ++ } ++ ++ bool sawOutputEOSOnAllTracks = true; ++ for (size_t i = 0; i < stateByTrack.size(); ++i) { ++ CodecState *state = &stateByTrack.editValueAt(i); ++ if (!state->mSawOutputEOS) { ++ sawOutputEOSOnAllTracks = false; ++ break; ++ } ++ } ++ ++ if (sawOutputEOSOnAllTracks) { ++ break; ++ } ++ ++ for (size_t i = 0; i < stateByTrack.size(); ++i) { ++ CodecState *state = &stateByTrack.editValueAt(i); ++ ++ if (state->mSawOutputEOS) { ++ continue; ++ } ++ ++ size_t index; ++ size_t offset; ++ size_t size; ++ int64_t presentationTimeUs; ++ uint32_t flags; ++ status_t err = state->mCodec->dequeueOutputBuffer( ++ &index, &offset, &size, &presentationTimeUs, &flags, ++ kTimeout); ++ ++ if (err == OK) { ++ ALOGV("draining output buffer %d, time = %lld us", ++ index, presentationTimeUs); ++ ++ ++state->mNumBuffersDecoded; ++ state->mNumBytesDecoded += size; ++ ++ err = state->mCodec->releaseOutputBuffer(index); ++ CHECK_EQ(err, (status_t)OK); ++ ++ if (flags & MediaCodec::BUFFER_FLAG_EOS) { ++ ALOGV("reached EOS on output."); ++ ++ state->mSawOutputEOS = true; ++ } ++ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { ++ ALOGV("INFO_OUTPUT_BUFFERS_CHANGED"); ++ CHECK_EQ((status_t)OK, ++ state->mCodec->getOutputBuffers(&state->mOutBuffers)); ++ ++ ALOGV("got %d output buffers", state->mOutBuffers.size()); ++ } else if (err == INFO_FORMAT_CHANGED) { ++ sp format; ++ CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format)); ++ ++ ALOGV("INFO_FORMAT_CHANGED: %s", format->debugString().c_str()); ++ } else { ++ CHECK_EQ(err, -EAGAIN); ++ } ++ } ++ } ++ ++ int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs; ++ ++ for (size_t i = 0; i < stateByTrack.size(); ++i) { ++ CodecState *state = &stateByTrack.editValueAt(i); ++ ++ CHECK_EQ((status_t)OK, state->mCodec->release()); ++ ++ if (state->mIsAudio) { ++ ALOGD("track %d: %lld bytes received. %.2f KB/sec\n", ++ i, ++ state->mNumBytesDecoded, ++ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs); ++ } else { ++ ALOGD("track %d: %lld frames decoded, %.2f fps. %lld bytes " ++ "received. %.2f KB/sec\n", ++ i, ++ state->mNumBuffersDecoded, ++ state->mNumBuffersDecoded * 1E6 / elapsedTimeUs, ++ state->mNumBytesDecoded, ++ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs); ++ } ++ } ++ ++ return 0; ++} ++ ++int main(int argc, char **argv) { ++ using namespace android; ++ ++ const char *me = argv[0]; ++ ++ bool useAudio = false; ++ bool useVideo = false; ++ bool playback = false; ++ bool useSurface = false; ++ ++ int res; ++ while ((res = getopt(argc, argv, "havpSD")) >= 0) { ++ switch (res) { ++ case 'a': ++ { ++ useAudio = true; ++ break; ++ } ++ ++ case 'v': ++ { ++ useVideo = true; ++ break; ++ } ++ ++ case 'p': ++ { ++ playback = true; ++ break; ++ } ++ ++ case 'S': ++ { ++ useSurface = true; ++ break; ++ } ++ ++ case '?': ++ case 'h': ++ default: ++ { ++ usage(me); ++ } ++ } ++ } ++ ++ argc -= optind; ++ argv += optind; ++ ++ if (argc != 1) { ++ usage(me); ++ } ++ ++ if (!useAudio && !useVideo) { ++ useAudio = useVideo = true; ++ } ++ ++ ProcessState::self()->startThreadPool(); ++ ++ DataSource::RegisterDefaultSniffers(); ++ ++ sp looper = new ALooper; ++ looper->start(); ++ ++ sp composerClient; ++ sp control; ++ sp surface; ++ ++ if (playback || (useSurface && useVideo)) { ++ composerClient = new SurfaceComposerClient; ++ CHECK_EQ(composerClient->initCheck(), (status_t)OK); ++ ++ sp display(SurfaceComposerClient::getBuiltInDisplay( ++ ISurfaceComposer::eDisplayIdMain)); ++ DisplayInfo info; ++ SurfaceComposerClient::getDisplayInfo(display, &info); ++ ssize_t displayWidth = info.w; ++ ssize_t displayHeight = info.h; ++ ++ ALOGV("display is %ld x %ld\n", displayWidth, displayHeight); ++ ++ control = composerClient->createSurface( ++ String8("A Surface"), ++ displayWidth, ++ displayHeight, ++ PIXEL_FORMAT_RGB_565, ++ 0); ++ ++ CHECK(control != NULL); ++ CHECK(control->isValid()); ++ ++ SurfaceComposerClient::openGlobalTransaction(); ++ CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); ++ CHECK_EQ(control->show(), (status_t)OK); ++ SurfaceComposerClient::closeGlobalTransaction(); ++ ++ surface = control->getSurface(); ++ CHECK(surface != NULL); ++ } ++ ++ if (playback) { ++ sp player = new SimplePlayer; ++ looper->registerHandler(player); ++ ++ player->setDataSource(argv[0]); ++ player->setSurface(surface->getSurfaceTexture()); ++ player->start(); ++ ALOGD("Playing for 60 seconds\n"); ++ sleep(60); ++ player->stop(); ++ player->reset(); ++ } else { ++ decode(looper, argv[0], useAudio, useVideo, surface); ++ } ++ ++ if (playback || (useSurface && useVideo)) { ++ composerClient->dispose(); ++ } ++ ++ looper->stop(); ++ ++ return 0; ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/direct_media_test.cpp +@@ -0,0 +1,417 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ * Ricardo Salveti de Araujo ++ */ ++ ++#include ++#include "direct_media_test.h" ++ ++#include ++ ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++using namespace android; ++ ++static float DestWidth = 0.0, DestHeight = 0.0; ++// Actual video dimmensions ++static int Width = 0, Height = 0; ++ ++static GLfloat positionCoordinates[8]; ++ ++MediaPlayerWrapper *player = NULL; ++ ++void calculate_position_coordinates() ++{ ++ // Assuming cropping output for now ++ float x = 1, y = 1; ++ ++ // Black borders ++ x = float(Width / DestWidth); ++ y = float(Height / DestHeight); ++ ++ // Make the larger side be 1 ++ if (x > y) { ++ y /= x; ++ x = 1; ++ } else { ++ x /= y; ++ y = 1; ++ } ++ ++ positionCoordinates[0] = -x; ++ positionCoordinates[1] = y; ++ positionCoordinates[2] = -x; ++ positionCoordinates[3] = -y; ++ positionCoordinates[4] = x; ++ positionCoordinates[5] = -y; ++ positionCoordinates[6] = x; ++ positionCoordinates[7] = y; ++} ++ ++WindowRenderer::WindowRenderer(int width, int height) ++ : mThreadCmd(CMD_IDLE) ++{ ++ createThread(threadStart, this); ++} ++ ++WindowRenderer::~WindowRenderer() ++{ ++} ++ ++int WindowRenderer::threadStart(void* self) ++{ ++ ((WindowRenderer *)self)->glThread(); ++ return 0; ++} ++ ++void WindowRenderer::glThread() ++{ ++ printf("%s\n", __PRETTY_FUNCTION__); ++ ++ Mutex::Autolock autoLock(mLock); ++} ++ ++struct ClientWithSurface ++{ ++ SfClient* client; ++ SfSurface* surface; ++}; ++ ++ClientWithSurface client_with_surface(bool setup_surface_with_egl) ++{ ++ ClientWithSurface cs = ClientWithSurface(); ++ ++ cs.client = sf_client_create(); ++ ++ if (!cs.client) { ++ printf("Problem creating client ... aborting now."); ++ return cs; ++ } ++ ++ static const size_t primary_display = 0; ++ ++ DestWidth = sf_get_display_width(primary_display); ++ DestHeight = sf_get_display_height(primary_display); ++ printf("Primary display width: %f, height: %f\n", DestWidth, DestHeight); ++ ++ SfSurfaceCreationParameters params = { ++ 0, ++ 0, ++ (int) DestWidth, ++ (int) DestHeight, ++ -1, //PIXEL_FORMAT_RGBA_8888, ++ 15000, ++ 0.5f, ++ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL ++ "MediaCompatLayerTestSurface" ++ }; ++ ++ cs.surface = sf_surface_create(cs.client, ¶ms); ++ ++ if (!cs.surface) { ++ printf("Problem creating surface ... aborting now."); ++ return cs; ++ } ++ ++ sf_surface_make_current(cs.surface); ++ ++ return cs; ++} ++ ++struct RenderData ++{ ++ static const char *vertex_shader() ++ { ++ return ++ "attribute vec4 a_position; \n" ++ "attribute vec2 a_texCoord; \n" ++ "uniform mat4 m_texMatrix; \n" ++ "varying vec2 v_texCoord; \n" ++ "varying float topDown; \n" ++ "void main() \n" ++ "{ \n" ++ " gl_Position = a_position; \n" ++ " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n" ++ "} \n"; ++ } ++ ++ static const char *fragment_shader() ++ { ++ return ++ "#extension GL_OES_EGL_image_external : require \n" ++ "precision mediump float; \n" ++ "varying vec2 v_texCoord; \n" ++ "uniform samplerExternalOES s_texture; \n" ++ "void main() \n" ++ "{ \n" ++ " gl_FragColor = texture2D( s_texture, v_texCoord );\n" ++ "} \n"; ++ } ++ ++ static GLuint loadShader(GLenum shaderType, const char* pSource) ++ { ++ GLuint shader = glCreateShader(shaderType); ++ ++ if (shader) { ++ glShaderSource(shader, 1, &pSource, NULL); ++ glCompileShader(shader); ++ GLint compiled = 0; ++ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); ++ ++ if (!compiled) { ++ GLint infoLen = 0; ++ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); ++ if (infoLen) { ++ char* buf = (char*) malloc(infoLen); ++ if (buf) { ++ glGetShaderInfoLog(shader, infoLen, NULL, buf); ++ fprintf(stderr, "Could not compile shader %d:\n%s\n", ++ shaderType, buf); ++ free(buf); ++ } ++ glDeleteShader(shader); ++ shader = 0; ++ } ++ } ++ } else { ++ printf("Error, during shader creation: %i\n", glGetError()); ++ } ++ ++ return shader; ++ } ++ ++ static GLuint create_program(const char* pVertexSource, const char* pFragmentSource) ++ { ++ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); ++ if (!vertexShader) { ++ printf("vertex shader not compiled\n"); ++ return 0; ++ } ++ ++ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); ++ if (!pixelShader) { ++ printf("frag shader not compiled\n"); ++ return 0; ++ } ++ ++ GLuint program = glCreateProgram(); ++ if (program) { ++ glAttachShader(program, vertexShader); ++ glAttachShader(program, pixelShader); ++ glLinkProgram(program); ++ GLint linkStatus = GL_FALSE; ++ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); ++ ++ if (linkStatus != GL_TRUE) { ++ GLint bufLength = 0; ++ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); ++ if (bufLength) { ++ char* buf = (char*) malloc(bufLength); ++ if (buf) { ++ glGetProgramInfoLog(program, bufLength, NULL, buf); ++ fprintf(stderr, "Could not link program:\n%s\n", buf); ++ free(buf); ++ } ++ } ++ glDeleteProgram(program); ++ program = 0; ++ } ++ } ++ ++ return program; ++ } ++ ++ RenderData() : program_object(create_program(vertex_shader(), fragment_shader())) ++ { ++ position_loc = glGetAttribLocation(program_object, "a_position"); ++ tex_coord_loc = glGetAttribLocation(program_object, "a_texCoord"); ++ sampler_loc = glGetUniformLocation(program_object, "s_texture"); ++ matrix_loc = glGetUniformLocation(program_object, "m_texMatrix"); ++ } ++ ++ // Handle to a program object ++ GLuint program_object; ++ // Attribute locations ++ GLint position_loc; ++ GLint tex_coord_loc; ++ // Sampler location ++ GLint sampler_loc; ++ // Matrix location ++ GLint matrix_loc; ++}; ++ ++static int setup_video_texture(ClientWithSurface *cs, GLuint *preview_texture_id) ++{ ++ assert(cs != NULL); ++ assert(preview_texture_id != NULL); ++ ++ sf_surface_make_current(cs->surface); ++ ++ glGenTextures(1, preview_texture_id); ++ glClearColor(0, 0, 0, 0); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ ++ android_media_set_preview_texture(player, *preview_texture_id); ++ ++ return 0; ++} ++ ++static void print_gl_error(unsigned int line) ++{ ++ GLint error = glGetError(); ++ printf("GL error: %#04x (line: %d)\n", error, line); ++} ++ ++static int update_gl_buffer(RenderData *render_data, EGLDisplay *disp, EGLSurface *surface) ++{ ++ assert(disp != NULL); ++ assert(surface != NULL); ++ ++ GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; ++ ++ const GLfloat textureCoordinates[] = { ++ 1.0f, 1.0f, ++ 0.0f, 1.0f, ++ 0.0f, 0.0f, ++ 1.0f, 0.0f ++ }; ++ ++ calculate_position_coordinates(); ++ ++ glClear(GL_COLOR_BUFFER_BIT); ++ // Use the program object ++ glUseProgram(render_data->program_object); ++ // Enable attributes ++ glEnableVertexAttribArray(render_data->position_loc); ++ glEnableVertexAttribArray(render_data->tex_coord_loc); ++ // Load the vertex position ++ glVertexAttribPointer(render_data->position_loc, ++ 2, ++ GL_FLOAT, ++ GL_FALSE, ++ 0, ++ positionCoordinates); ++ // Load the texture coordinate ++ glVertexAttribPointer(render_data->tex_coord_loc, ++ 2, ++ GL_FLOAT, ++ GL_FALSE, ++ 0, ++ textureCoordinates); ++ ++ GLfloat matrix[16]; ++ android_media_surface_texture_get_transformation_matrix(player, matrix); ++ ++ glUniformMatrix4fv(render_data->matrix_loc, 1, GL_FALSE, matrix); ++ ++ glActiveTexture(GL_TEXTURE0); ++ // Set the sampler texture unit to 0 ++ glUniform1i(render_data->sampler_loc, 0); ++ glUniform1i(render_data->matrix_loc, 0); ++ android_media_update_surface_texture(player); ++ glDrawArrays(GL_TRIANGLE_FAN, 0, 4); ++ //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); ++ glDisableVertexAttribArray(render_data->position_loc); ++ glDisableVertexAttribArray(render_data->tex_coord_loc); ++ ++ eglSwapBuffers(*disp, *surface); ++ ++ return 0; ++} ++ ++void set_video_size_cb(int height, int width, void *context) ++{ ++ printf("Video height: %d, width: %d\n", height, width); ++ printf("Video dest height: %f, width: %f\n", DestHeight, DestWidth); ++ ++ Height = height; ++ Width = width; ++} ++ ++int main(int argc, char **argv) ++{ ++ if (argc < 2) { ++ printf("Usage: direct_media_test \n"); ++ return EXIT_FAILURE; ++ } ++ ++ player = android_media_new_player(); ++ if (player == NULL) { ++ printf("Problem creating new media player.\n"); ++ return EXIT_FAILURE; ++ } ++ ++ // Set player event cb for when the video size is known: ++ android_media_set_video_size_cb(player, set_video_size_cb, NULL); ++ ++ printf("Setting data source to: %s.\n", argv[1]); ++ ++ if (android_media_set_data_source(player, argv[1]) != OK) { ++ printf("Failed to set data source: %s\n", argv[1]); ++ return EXIT_FAILURE; ++ } ++ ++ WindowRenderer renderer(DestWidth, DestHeight); ++ ++ printf("Creating EGL surface.\n"); ++ ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */); ++ if (!cs.surface) { ++ printf("Problem acquiring surface for preview"); ++ return EXIT_FAILURE; ++ } ++ ++ printf("Creating GL texture.\n"); ++ GLuint preview_texture_id; ++ EGLDisplay disp = sf_client_get_egl_display(cs.client); ++ EGLSurface surface = sf_surface_get_egl_surface(cs.surface); ++ ++ sf_surface_make_current(cs.surface); ++ if (setup_video_texture(&cs, &preview_texture_id) != OK) { ++ printf("Problem setting up GL texture for video surface.\n"); ++ return EXIT_FAILURE; ++ } ++ ++ RenderData render_data; ++ ++ printf("Starting video playback.\n"); ++ android_media_play(player); ++ ++ printf("Updating gl buffer continuously...\n"); ++ while (android_media_is_playing(player)) { ++ update_gl_buffer(&render_data, &disp, &surface); ++ } ++ ++ android_media_stop(player); ++ ++ return EXIT_SUCCESS; ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/direct_media_test.h +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#ifndef DIRECT_MEDIA_TEST_H_ ++#define DIRECT_MEDIA_TEST_H_ ++ ++#include ++#include ++#include ++ ++namespace android { ++ ++class RenderInput; ++ ++class WindowRenderer ++{ ++public: ++ WindowRenderer(int width, int height); ++ ~WindowRenderer(); ++ ++private: ++ // The GL thread functions ++ static int threadStart(void* self); ++ void glThread(); ++ ++ // These variables are used to communicate between the GL thread and ++ // other threads. ++ Mutex mLock; ++ Condition mCond; ++ enum { ++ CMD_IDLE, ++ CMD_RENDER_INPUT, ++ CMD_RESERVE_TEXTURE, ++ CMD_DELETE_TEXTURE, ++ CMD_QUIT, ++ }; ++ int mThreadCmd; ++ RenderInput* mThreadRenderInput; ++ GLuint mThreadTextureId; ++}; ++} // android ++ ++#endif +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_codec_layer.cpp +@@ -0,0 +1,763 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++// Uncomment to enable verbose debug output ++#define LOG_NDEBUG 0 ++ ++#undef LOG_TAG ++#define LOG_TAG "MediaCodecLayer" ++ ++#include ++#include ++#include ++ ++#include "media_format_layer_priv.h" ++#include "surface_texture_client_hybris_priv.h" ++ ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__); ++ ++using namespace android; ++ ++struct _MediaCodecDelegate : public AHandler ++{ ++public: ++ typedef sp<_MediaCodecDelegate> Ptr; ++ ++ explicit _MediaCodecDelegate(void *context); ++ virtual ~_MediaCodecDelegate(); ++ ++protected: ++ virtual void onMessageReceived(const sp &msg) { } ++ ++public: ++ sp media_codec; ++ sp looper; ++ ++ Vector > input_buffers; ++ Vector > output_buffers; ++ List available_output_buffer_infos; ++ List available_input_buffer_indices; ++ bool output_format_changed; ++ bool hardware_rendering; ++ ++ void *context; ++ unsigned int refcount; ++}; ++ ++_MediaCodecDelegate::_MediaCodecDelegate(void *context) ++ : output_format_changed(false), ++ hardware_rendering(false), ++ context(context), ++ refcount(1) ++{ ++ REPORT_FUNCTION() ++} ++ ++_MediaCodecDelegate::~_MediaCodecDelegate() ++{ ++ REPORT_FUNCTION() ++} ++ ++static inline _MediaCodecDelegate *get_internal_delegate(MediaCodecDelegate delegate) ++{ ++ if (delegate == NULL) ++ { ++ ALOGE("delegate must not be NULL"); ++ return NULL; ++ } ++ ++ _MediaCodecDelegate *d = static_cast<_MediaCodecDelegate*>(delegate); ++ // Some simple sanity checks that must be true for a valid MediaCodecDelegate instance ++ if (d->media_codec == NULL || d->refcount < 1) ++ return NULL; ++ ++ return d; ++} ++ ++MediaCodecDelegate media_codec_create_by_codec_name(const char *name) ++{ ++ REPORT_FUNCTION() ++ ++ if (name == NULL) ++ { ++ ALOGE("name must not be NULL"); ++ return NULL; ++ } ++ ++ ALOGD("Creating codec '%s'", name); ++ ++ ProcessState::self()->startThreadPool(); ++ ++ _MediaCodecDelegate *d(new _MediaCodecDelegate(NULL)); ++ d->looper = new ALooper; ++ d->looper->start(); ++ ++ d->media_codec = android::MediaCodec::CreateByComponentName(d->looper, name); ++ ++ return d; ++} ++ ++#ifdef SIMPLE_PLAYER ++MediaCodec* media_codec_get(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return NULL; ++ ++ return d->media_codec.get(); ++} ++#endif ++ ++MediaCodecDelegate media_codec_create_by_codec_type(const char *type) ++{ ++ REPORT_FUNCTION() ++ ++ if (type == NULL) ++ { ++ ALOGE("type must not be NULL"); ++ return NULL; ++ } ++ ++ ALOGD("Creating codec by type '%s'", type); ++ ++ ProcessState::self()->startThreadPool(); ++ ++ _MediaCodecDelegate *d(new _MediaCodecDelegate(NULL)); ++ d->looper = new ALooper; ++ d->looper->start(); ++ ++ d->media_codec = android::MediaCodec::CreateByType(d->looper, type, false); ++ ++ return d; ++} ++ ++void media_codec_delegate_destroy(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ { ++ ALOGE("d == NULL, cannot destroy MediaCodecDelegate instance"); ++ return; ++ } ++ ++ ALOGI("Releasing media_codec"); ++ d->media_codec->release(); ++ ALOGI("Stopping looper"); ++ d->looper->stop(); ++ ++ ALOGI("Setting refcount = 0"); ++ d->refcount = 0; ++ ++ ALOGI("Deleting the MediaCodecDelegate instance"); ++ delete d; ++} ++ ++void media_codec_delegate_ref(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return; ++ ++ d->refcount++; ++} ++ ++void media_codec_delegate_unref(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ { ++ ALOGE("d == NULL, cannot unref MediaCodecDelegate instance"); ++ return; ++ } ++ ++ if (d->refcount > 1) ++ d->refcount--; ++ else ++ media_codec_delegate_destroy (delegate); ++} ++ ++#ifdef SIMPLE_PLAYER ++int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, void *nativeWindow, uint32_t flags) ++#else ++int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, SurfaceTextureClientHybris stc, uint32_t flags) ++#endif ++{ ++ REPORT_FUNCTION() ++ ++ if (format == NULL) ++ { ++ ALOGE("format must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ _MediaFormat *format_priv = static_cast<_MediaFormat*>(format); ++#ifndef SIMPLE_PLAYER ++ _SurfaceTextureClientHybris *stch = static_cast<_SurfaceTextureClientHybris*>(stc); ++#endif ++ ++ sp aformat = new AMessage; ++ aformat->setString("mime", format_priv->mime.c_str()); ++ if (format_priv->duration_us > 0) ++ aformat->setInt64("durationUs", format_priv->duration_us); ++ aformat->setInt32("width", format_priv->width); ++ aformat->setInt32("height", format_priv->height); ++ if (format_priv->max_input_size > 0) ++ aformat->setInt32("max-input-size", format_priv->max_input_size); ++ ++ ALOGD("Format: %s", aformat->debugString().c_str()); ++ ++#ifdef SIMPLE_PLAYER ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ sp surfaceTextureClient = static_cast(nativeWindow); ++#else ++ sp surfaceTextureClient = static_cast(nativeWindow); ++#endif ++ // TODO: Don't just pass NULL for the security when DRM is needed ++ d->media_codec->configure(aformat, surfaceTextureClient, NULL, flags); ++#else ++ ALOGD("SurfaceTextureClientHybris: %p", stch); ++ ++ // Make sure we're ready to configure the codec and the Surface/SurfaceTextureClient together ++ if (stch != NULL && stch->hardwareRendering() && stch->isReady()) ++ { ++ ALOGD("Doing hardware decoding with hardware rendering"); ++ // TODO: Don't just pass NULL for the security when DRM is needed ++ d->media_codec->configure(aformat, stch, NULL, flags); ++ } ++ else ++ { ++ ALOGD("Doing hardware decoding path with software rendering"); ++ // This scenario is for hardware video decoding, but software rendering, therefore there's ++ // no need to pass a valid Surface/SurfaceTextureClient instance to configure() ++ d->media_codec->configure(aformat, NULL, NULL, flags); ++ } ++ ++#endif ++ ++ return OK; ++} ++ ++int media_codec_set_surface_texture_client(MediaCodecDelegate delegate, SurfaceTextureClientHybris stc) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ if (stc == NULL) ++ { ++ ALOGE("stc must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ _SurfaceTextureClientHybris *stcu = static_cast<_SurfaceTextureClientHybris*>(stc); ++ status_t err = native_window_api_connect(stcu, NATIVE_WINDOW_API_MEDIA); ++ if (err != OK) ++ { ++ ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err); ++ return err; ++ } ++ ++ return OK; ++} ++ ++int media_codec_queue_csd(MediaCodecDelegate delegate, MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ if (format == NULL) ++ { ++ ALOGE("format must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ _MediaFormat *format_priv = static_cast<_MediaFormat*>(format); ++ assert(format_priv->csd != NULL); ++ ++ status_t err = OK; ++ ++ Vector > input_bufs[1]; ++ err = d->media_codec->getInputBuffers(&input_bufs[0]); ++ CHECK_EQ(err, static_cast(OK)); ++ ++ for (size_t i=0; i<2; ++i) ++ { ++ const sp &srcBuffer = format_priv->csd; ++ ++ size_t index = 0; ++ err = d->media_codec->dequeueInputBuffer(&index, -1ll); ++ CHECK_EQ(err, static_cast(OK)); ++ ++ const sp &dstBuffer = input_bufs[0].itemAt(index); ++ ++ CHECK_LE(srcBuffer->size(), dstBuffer->capacity()); ++ dstBuffer->setRange(0, srcBuffer->size()); ++ memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size()); ++ ++ AString err_msg; ++ err = d->media_codec->queueInputBuffer( ++ index, ++ 0, ++ dstBuffer->size(), ++ 0ll, ++ MediaCodec::BUFFER_FLAG_CODECCONFIG); ++ CHECK_EQ(err, static_cast(OK)); ++ } ++ ++ return err; ++} ++ ++int media_codec_start(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ return d->media_codec->start(); ++} ++ ++int media_codec_stop(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ return d->media_codec->stop(); ++} ++ ++int media_codec_release(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ return d->media_codec->release(); ++} ++ ++int media_codec_flush(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ d->available_output_buffer_infos.clear(); ++ ++ return d->media_codec->flush(); ++} ++ ++size_t media_codec_get_input_buffers_size(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ status_t ret = d->media_codec->getInputBuffers(&d->input_buffers); ++ if (ret != OK) ++ { ++ ALOGE("Failed to get input buffers size"); ++ return 0; ++ } ++ ALOGD("Got %d input buffers", d->input_buffers.size()); ++ ++ return d->input_buffers.size(); ++} ++ ++uint8_t *media_codec_get_nth_input_buffer(MediaCodecDelegate delegate, size_t n) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return NULL; ++ ++ if (d->input_buffers.size() == 0) ++ { ++ status_t ret = d->media_codec->getInputBuffers(&d->input_buffers); ++ if (ret != OK) ++ { ++ ALOGE("Failed to get input buffers"); ++ return NULL; ++ } ++ } ++ ++ if (n > d->input_buffers.size()) ++ { ++ ALOGE("Failed to get %uth input buffer, n > total buffer size", n); ++ return NULL; ++ } ++ ++ return d->input_buffers.itemAt(n).get()->data(); ++} ++ ++size_t media_codec_get_nth_input_buffer_capacity(MediaCodecDelegate delegate, size_t n) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ Vector > input_buffers; ++ status_t ret = d->media_codec->getInputBuffers(&input_buffers); ++ if (ret != OK) ++ { ++ ALOGE("Failed to get input buffers"); ++ return 0; ++ } ++ ++ if (n > input_buffers.size()) ++ { ++ ALOGE("Failed to get %uth input buffer capacity, n > total buffer size", n); ++ return 0; ++ } ++ ++ return input_buffers[n].get()->capacity(); ++} ++ ++size_t media_codec_get_output_buffers_size(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ status_t ret = d->media_codec->getOutputBuffers(&d->output_buffers); ++ if (ret != OK) ++ { ++ ALOGE("Failed to get output buffers size"); ++ return 0; ++ } ++ ALOGD("Got %d output buffers", d->output_buffers.size()); ++ ++ return d->output_buffers.size(); ++} ++ ++uint8_t *media_codec_get_nth_output_buffer(MediaCodecDelegate delegate, size_t n) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return NULL; ++ ++ status_t ret = d->media_codec->getOutputBuffers(&d->output_buffers); ++ if (ret != OK) ++ { ++ ALOGE("Failed to get output buffers"); ++ return NULL; ++ } ++ ++ if (n > d->output_buffers.size()) ++ { ++ ALOGE("Failed to get %uth output buffer, n > total buffer size", n); ++ return NULL; ++ } ++ ++ return d->output_buffers.itemAt(n).get()->data(); ++} ++ ++size_t media_codec_get_nth_output_buffer_capacity(MediaCodecDelegate delegate, size_t n) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ status_t ret = d->media_codec->getOutputBuffers(&d->output_buffers); ++ if (ret != OK) ++ { ++ ALOGE("Failed to get output buffers"); ++ return 0; ++ } ++ ++ if (n > d->output_buffers.size()) ++ { ++ ALOGE("Failed to get %uth output buffer capacity, n > total buffer size", n); ++ return 0; ++ } ++ ++ return d->output_buffers[n].get()->capacity(); ++} ++ ++#define INFO_TRY_AGAIN_LATER -1 ++#define INFO_OUTPUT_FORMAT_CHANGED -2 ++#define INFO_OUTPUT_BUFFERS_CHANGED -4 ++ ++int media_codec_dequeue_output_buffer(MediaCodecDelegate delegate, MediaCodecBufferInfo *info, int64_t timeout_us) ++{ ++ REPORT_FUNCTION() ++ ++ if (info == NULL) ++ { ++ ALOGE("info must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ int ret = d->media_codec->dequeueOutputBuffer(&info->index, &info->offset, &info->size, &info->presentation_time_us, &info->flags, timeout_us); ++ ALOGD("dequeueOutputBuffer() ret: %d", ret); ++ info->render_retries = 0; ++ ++ if (ret == -EAGAIN) ++ { ++ ALOGD("dequeueOutputBuffer returned %d", ret); ++ return INFO_TRY_AGAIN_LATER; ++ } ++ else if (ret & ~INFO_OUTPUT_BUFFERS_CHANGED) ++ { ++ ALOGD("Output buffers changed (ret: %d)", ret); ++ return INFO_OUTPUT_BUFFERS_CHANGED + 1; ++ } ++ // FIXME: Get rid of the hardcoded -10 and replace with more elegant solution ++ else if (ret & ~(INFO_FORMAT_CHANGED - 10)) ++ { ++ ALOGD("Output buffer format changed (ret: %d)", ret); ++ d->output_format_changed = true; ++ return -2; ++ } ++ ++ ALOGD("Dequeued output buffer:\n-----------------------"); ++ ALOGD("index: %u", info->index); ++ ALOGD("offset: %d", info->offset); ++ ALOGD("size: %d", info->size); ++ ALOGD("presentation_time_us: %lld", info->presentation_time_us); ++ ALOGD("flags: %d", info->flags); ++ ++ // Keep track of the used output buffer info ++ d->available_output_buffer_infos.push_back(*info); ++ ++ return OK; ++} ++ ++int media_codec_queue_input_buffer(MediaCodecDelegate delegate, const MediaCodecBufferInfo *info) ++{ ++ REPORT_FUNCTION() ++ ++ if (info == NULL) ++ { ++ ALOGE("info must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ // Make sure that there is at least one dequeued input buffer available ++ if (d->available_input_buffer_indices.empty()) ++ { ++ ALOGE("Input buffer index %d has not been dequeued, cannot queue input buffer", info->index); ++ return BAD_VALUE; ++ } ++ ++ const size_t index = *d->available_input_buffer_indices.begin(); ++ d->available_input_buffer_indices.erase(d->available_input_buffer_indices.begin()); ++ ++ ALOGD("info->index: %d", index); ++ ALOGD("info->offset: %d", info->offset); ++ ALOGD("info->size: %d", info->size); ++ ALOGD("info->presentation_time_us: %lld", info->presentation_time_us); ++ ALOGD("info->flags: %d", info->flags); ++ ++ AString err_msg; ++ status_t ret = d->media_codec->queueInputBuffer(index, info->offset, info->size, ++ info->presentation_time_us, info->flags, &err_msg); ++ if (ret != OK) ++ { ++ ALOGE("Failed to queue input buffer (err: %d, index: %d)", ret, index); ++ ALOGE("Detailed error message: %s", err_msg.c_str()); ++ } ++ ++ return ret; ++} ++ ++int media_codec_dequeue_input_buffer(MediaCodecDelegate delegate, size_t *index, int64_t timeout_us) ++{ ++ REPORT_FUNCTION() ++ ++ if (index == NULL) ++ { ++ ALOGE("index must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ status_t ret = d->media_codec->dequeueInputBuffer(index, timeout_us); ++ if (ret == -EAGAIN) ++ { ++ ALOGD("dequeueInputBuffer returned %d, tried timeout: %d", ret, timeout_us); ++ return INFO_TRY_AGAIN_LATER; ++ } ++ else if (ret == OK) ++ { ++ ALOGD("Dequeued input buffer (index: %d)", *index); ++ d->available_input_buffer_indices.push_back(*index); ++ } ++ else ++ ALOGE("Failed to dequeue input buffer (err: %d, index: %d)", ret, *index); ++ ++ return ret; ++} ++ ++int media_codec_release_output_buffer(MediaCodecDelegate delegate, size_t index, uint8_t render) ++{ ++ REPORT_FUNCTION() ++ ALOGV("Requesting to release output buffer index: %d, render: %d", index, render); ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return BAD_VALUE; ++ ++ status_t ret = OK; ++ ++ auto it = d->available_output_buffer_infos.begin(); ++ while (it != d->available_output_buffer_infos.end()) ++ { ++ MediaCodecBufferInfo *info = &*it; ++ ALOGD("info index: %d", info->index); ++ ALOGD("info render_retries: %u", info->render_retries); ++ if (info->render_retries == 1) ++ { ++ ALOGV("Rendering and releasing output buffer %d from the available indices list", info->index); ++ ret = d->media_codec->renderOutputBufferAndRelease(info->index); ++ if (ret != OK) ++ { ++ ALOGE("Failed to release output buffer (ret: %d, index: %d)", ret, info->index); ++ ++info->render_retries; ++ } ++ else ++ { ++ ALOGV("Successfully rendered output buffer %d on a second try.", info->index); ++ d->available_output_buffer_infos.erase(it); ++ } ++ } ++ else if (info->render_retries > 1) ++ { ++ ALOGV("Tried to render output buffer %d twice, dropping.", info->index); ++ ret = d->media_codec->releaseOutputBuffer(info->index); ++ d->available_output_buffer_infos.erase(d->available_output_buffer_infos.begin()); ++ } ++ ++ ++it; ++ } ++ ++ MediaCodecBufferInfo *info = &*d->available_output_buffer_infos.begin(); ++ // Either render and release the output buffer, or just release. ++ if (render) ++ { ++ ALOGV("Rendering and releasing output buffer %d from the available indices list", info->index); ++ ret = d->media_codec->renderOutputBufferAndRelease(info->index); ++ } ++ else ++ { ++ ALOGV("Releasing output buffer %d from the available indices list", info->index); ++ ret = d->media_codec->releaseOutputBuffer(info->index); ++ } ++ if (ret != OK) ++ { ++ ALOGE("Failed to release output buffer (ret: %d, index: %d)", ret, info->index); ++ ++info->render_retries; ++ } else { ++ ALOGV("Released output buffer %d from the available buffer infos list", info->index); ++ d->available_output_buffer_infos.erase(d->available_output_buffer_infos.begin()); ++ } ++ ++ return ret; ++} ++ ++MediaFormat media_codec_get_output_format(MediaCodecDelegate delegate) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaCodecDelegate *d = get_internal_delegate(delegate); ++ if (d == NULL) ++ return NULL; ++ ++ _MediaFormat *f = new _MediaFormat(); ++ ++ sp msg_format; ++ status_t ret = d->media_codec->getOutputFormat(&msg_format); ++ if (ret != OK) ++ { ++ ALOGE("Failed to get the output format"); ++ return NULL; ++ } ++ ++ ALOGD("Output format: %s", msg_format->debugString().c_str()); ++ ++ CHECK(msg_format->findString("mime", &f->mime)); ++ CHECK(msg_format->findInt32("width", &f->width)); ++ CHECK(msg_format->findInt32("height", &f->height)); ++ CHECK(msg_format->findInt32("stride", &f->stride)); ++ CHECK(msg_format->findInt32("slice-height", &f->slice_height)); ++ CHECK(msg_format->findInt32("color-format", &f->color_format)); ++ Rect crop; ++ CHECK(msg_format->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)); ++ ++ return f; ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_codec_list.cpp +@@ -0,0 +1,228 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++// Uncomment to enable verbose debug output ++#define LOG_NDEBUG 0 ++ ++#undef LOG_TAG ++#define LOG_TAG "MediaCodecList" ++ ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__); ++ ++using namespace android; ++ ++ssize_t media_codec_list_find_codec_by_type(const char *type, bool encoder, size_t startIndex) ++{ ++ REPORT_FUNCTION() ++ return MediaCodecList::getInstance()->findCodecByType(type, encoder, startIndex); ++} ++ ++ssize_t media_codec_list_find_codec_by_name(const char *name) ++{ ++ REPORT_FUNCTION() ++ return MediaCodecList::getInstance()->findCodecByName(name); ++} ++ ++size_t media_codec_list_count_codecs() ++{ ++ REPORT_FUNCTION() ++ return MediaCodecList::getInstance()->countCodecs(); ++} ++ ++void media_codec_list_get_codec_info_at_id(size_t index) ++{ ++ REPORT_FUNCTION() ++} ++ ++const char *media_codec_list_get_codec_name(size_t index) ++{ ++ REPORT_FUNCTION() ++ return MediaCodecList::getInstance()->getCodecName(index); ++} ++ ++bool media_codec_list_is_encoder(size_t index) ++{ ++ REPORT_FUNCTION() ++ return MediaCodecList::getInstance()->isEncoder(index); ++} ++ ++size_t media_codec_list_get_num_supported_types(size_t index) ++{ ++ REPORT_FUNCTION() ++ ++ Vector types; ++ status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types); ++ if (err != OK) ++ { ++ ALOGE("Failed to get the number of supported codec types (err: %d)", err); ++ return 0; ++ } ++ ALOGD("Number of supported codec types: %d", types.size()); ++ ++ return types.size(); ++} ++ ++size_t media_codec_list_get_nth_supported_type_len(size_t index, size_t n) ++{ ++ REPORT_FUNCTION() ++ ++ Vector types; ++ status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types); ++ ++ return types[n].size(); ++} ++ ++int media_codec_list_get_nth_supported_type(size_t index, char *type, size_t n) ++{ ++ REPORT_FUNCTION() ++ ++ if (type == NULL) ++ { ++ ALOGE("types must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ Vector types; ++ status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types); ++ for (size_t i=0; i profile_levels; ++ Vector color_formats; ++ ALOGD("index: %d, type: '%s'", index, type); ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 ++ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &color_formats); ++#else ++ uint32_t flags; ++ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &color_formats, &flags); ++#endif ++ if (err != OK) ++ { ++ ALOGE("Failed to get the number of supported codec capabilities (err: %d)", err); ++ return; ++ } ++ ++ if (num_profile_levels != NULL) ++ { ++ ALOGD("Number of codec profile levels: %d", profile_levels.size()); ++ *num_profile_levels = profile_levels.size(); ++ } ++ if (num_color_formats != NULL) ++ { ++ ALOGD("Number of codec color formats: %d", color_formats.size()); ++ *num_color_formats = color_formats.size(); ++ } ++} ++ ++size_t media_codec_list_get_num_profile_levels(size_t index, const char *type) ++{ ++ REPORT_FUNCTION() ++ ++ size_t num = 0; ++ media_codec_list_get_num_codec_capabilities(index, type, &num, NULL); ++ ++ return num; ++} ++ ++size_t media_codec_list_get_num_color_formats(size_t index, const char *type) ++{ ++ REPORT_FUNCTION() ++ ++ size_t num = 0; ++ media_codec_list_get_num_codec_capabilities(index, type, NULL, &num); ++ ++ return num; ++} ++ ++int media_codec_list_get_nth_codec_profile_level(size_t index, const char *type, profile_level *pro_level, size_t n) ++{ ++ REPORT_FUNCTION() ++ ++ if (type == NULL) ++ { ++ ALOGE("types must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ if (pro_level == NULL) ++ { ++ ALOGE("pro_level must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ Vector profile_levels; ++ Vector formats; ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 ++ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats); ++#else ++ uint32_t flags; ++ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats, &flags); ++#endif ++ if (err != OK) ++ { ++ ALOGE("Failed to get the nth codec profile level (err: %d)", err); ++ return 0; ++ } ++ ++ pro_level->profile = profile_levels[n].mProfile; ++ pro_level->level = profile_levels[n].mLevel; ++ ++ return err; ++} ++ ++int media_codec_list_get_codec_color_formats(size_t index, const char *type, uint32_t *color_formats) ++{ ++ REPORT_FUNCTION() ++ ++ Vector profile_levels; ++ Vector formats; ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 ++ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats); ++#else ++ uint32_t flags; ++ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats, &flags); ++#endif ++ if (err != OK) ++ { ++ ALOGE("Failed to get the number of supported codec types (err: %d)", err); ++ return 0; ++ } ++ ++ for (size_t i=0; i ++ * Ricardo Salveti de Araujo ++ */ ++ ++// Uncomment to enable verbose debug output ++#define LOG_NDEBUG 0 ++ ++#undef LOG_TAG ++#define LOG_TAG "MediaCompatibilityLayer" ++ ++#include ++ ++#include ++#include ++ ++#include ++ ++#include ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++#include ++#else ++#include ++#endif ++ ++#include ++#include ++ ++#include ++ ++#include ++ ++#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__) ++ ++namespace android ++{ ++NativeBufferAlloc::NativeBufferAlloc() { ++} ++ ++NativeBufferAlloc::~NativeBufferAlloc() { ++} ++ ++sp NativeBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, ++ PixelFormat format, uint32_t usage, status_t* error) { ++ sp graphicBuffer(new GraphicBuffer(w, h, format, usage)); ++ status_t err = graphicBuffer->initCheck(); ++ *error = err; ++ if (err != 0 || graphicBuffer->handle == 0) { ++ if (err == NO_MEMORY) { ++ GraphicBuffer::dumpAllocationsToSystemLog(); ++ } ++ ALOGI("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " ++ "failed (%s), handle=%p", ++ w, h, strerror(-err), graphicBuffer->handle); ++ return 0; ++ } ++ return graphicBuffer; ++} ++} ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++struct FrameAvailableListener : public android::SurfaceTexture::FrameAvailableListener ++#else ++struct FrameAvailableListener : public android::GLConsumer::FrameAvailableListener ++#endif ++{ ++ public: ++ FrameAvailableListener() ++ : set_video_texture_needs_update_cb(NULL), ++ video_texture_needs_update_context(NULL) ++ { ++ } ++ ++ // From android::GLConsumer/SurfaceTexture::FrameAvailableListener ++ void onFrameAvailable() ++ { ++ if (set_video_texture_needs_update_cb != NULL) ++ set_video_texture_needs_update_cb(video_texture_needs_update_context); ++ } ++ ++ void setVideoTextureNeedsUpdateCb(on_video_texture_needs_update cb, void *context) ++ { ++ set_video_texture_needs_update_cb = cb; ++ video_texture_needs_update_context = context; ++ } ++ ++ private: ++ on_video_texture_needs_update set_video_texture_needs_update_cb; ++ void *video_texture_needs_update_context; ++}; ++ ++class MediaPlayerListenerWrapper : public android::MediaPlayerListener ++{ ++ public: ++ MediaPlayerListenerWrapper() ++ : set_video_size_cb(NULL), ++ video_size_context(NULL), ++ error_cb(NULL), ++ error_context(NULL), ++ playback_complete_cb(NULL), ++ playback_complete_context(NULL), ++ media_prepared_cb(NULL), ++ media_prepared_context(NULL) ++ { ++ } ++ ++ void notify(int msg, int ext1, int ext2, const android::Parcel *obj) ++ { ++ ALOGV("\tmsg: %d, ext1: %d, ext2: %d \n", msg, ext1, ext2); ++ ++ switch (msg) { ++ case android::MEDIA_PREPARED: ++ ALOGV("\tMEDIA_PREPARED msg\n"); ++ if (media_prepared_cb != NULL) ++ media_prepared_cb(media_prepared_context); ++ else ++ ALOGW("Failed to signal media prepared, callback not set."); ++ break; ++ case android::MEDIA_PLAYBACK_COMPLETE: ++ ALOGV("\tMEDIA_PLAYBACK_COMPLETE msg\n"); ++ if (playback_complete_cb != NULL) ++ playback_complete_cb(playback_complete_context); ++ else ++ ALOGW("Failed to signal end of playback, callback not set."); ++ break; ++ case android::MEDIA_BUFFERING_UPDATE: ++ ALOGV("\tMEDIA_BUFFERING_UPDATE msg\n"); ++ break; ++ case android::MEDIA_SEEK_COMPLETE: ++ ALOGV("\tMEDIA_SEEK_COMPLETE msg\n"); ++ break; ++ case android::MEDIA_SET_VIDEO_SIZE: ++ ALOGV("\tMEDIA_SET_VIDEO_SIZE msg\n"); ++ if (set_video_size_cb != NULL) ++ set_video_size_cb(ext2, ext1, video_size_context); ++ else ++ ALOGE("Failed to set video size. set_video_size_cb is NULL."); ++ break; ++ case android::MEDIA_TIMED_TEXT: ++ ALOGV("\tMEDIA_TIMED_TEXT msg\n"); ++ break; ++ case android::MEDIA_ERROR: ++ ALOGV("\tMEDIA_ERROR msg\n"); ++ // TODO: Extend this cb to include the error message ++ if (error_cb != NULL) ++ error_cb(error_context); ++ else ++ ALOGE("Failed to signal error to app layer, callback not set."); ++ break; ++ case android::MEDIA_INFO: ++ ALOGV("\tMEDIA_INFO msg\n"); ++ break; ++ default: ++ ALOGV("\tUnknown media msg\n"); ++ } ++ } ++ ++ void setVideoSizeCb(on_msg_set_video_size cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ set_video_size_cb = cb; ++ video_size_context = context; ++ } ++ ++ void setErrorCb(on_msg_error cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ error_cb = cb; ++ error_context = context; ++ } ++ ++ void setPlaybackCompleteCb(on_playback_complete cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ playback_complete_cb = cb; ++ playback_complete_context = context; ++ } ++ ++ void setMediaPreparedCb(on_media_prepared cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ media_prepared_cb = cb; ++ media_prepared_context = context; ++ } ++ ++ private: ++ on_msg_set_video_size set_video_size_cb; ++ void *video_size_context; ++ on_msg_error error_cb; ++ void *error_context; ++ on_playback_complete playback_complete_cb; ++ void *playback_complete_context; ++ on_media_prepared media_prepared_cb; ++ void *media_prepared_context; ++}; ++ ++// ----- MediaPlayer Wrapper ----- // ++ ++struct MediaPlayerWrapper : public android::MediaPlayer ++{ ++ public: ++ MediaPlayerWrapper() ++ : MediaPlayer(), ++ texture(NULL), ++ media_player_listener(new MediaPlayerListenerWrapper()), ++ frame_listener(new FrameAvailableListener), ++ left_volume(1), // Set vol to 100% for this track by default ++ right_volume(1), ++ source_fd(-1) ++ { ++ setListener(media_player_listener); ++ // Update the live volume with the cached values ++ MediaPlayer::setVolume(left_volume, right_volume); ++ } ++ ++ ~MediaPlayerWrapper() ++ { ++ reset(); ++ source_fd = -1; ++ } ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ android::status_t setVideoSurfaceTexture(const android::sp &surfaceTexture) ++#else ++ android::status_t setVideoSurfaceTexture(android::sp bq, const android::sp &surfaceTexture) ++#endif ++ { ++ REPORT_FUNCTION(); ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ surfaceTexture->getBufferQueue()->setBufferCount(5); ++#else ++ bq->setBufferCount(5); ++#endif ++ texture = surfaceTexture; ++ texture->setFrameAvailableListener(frame_listener); ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ return MediaPlayer::setVideoSurfaceTexture(surfaceTexture->getBufferQueue()); ++#else ++ return MediaPlayer::setVideoSurfaceTexture(bq); ++#endif ++ } ++ ++ void updateGLConsumer() ++ { ++ assert(texture != NULL); ++ texture->updateTexImage(); ++ } ++ ++ void get_transformation_matrix_for_surface_texture(GLfloat* matrix) ++ { ++ assert(texture != NULL); ++ texture->getTransformMatrix(matrix); ++ } ++ ++ void setVideoSizeCb(on_msg_set_video_size cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ assert(media_player_listener != NULL); ++ media_player_listener->setVideoSizeCb(cb, context); ++ } ++ ++ void setVideoTextureNeedsUpdateCb(on_video_texture_needs_update cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ assert(frame_listener != NULL); ++ frame_listener->setVideoTextureNeedsUpdateCb(cb, context); ++ } ++ ++ void setErrorCb(on_msg_error cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ assert(media_player_listener != NULL); ++ media_player_listener->setErrorCb(cb, context); ++ } ++ ++ void setPlaybackCompleteCb(on_playback_complete cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ assert(media_player_listener != NULL); ++ media_player_listener->setPlaybackCompleteCb(cb, context); ++ } ++ ++ void setMediaPreparedCb(on_media_prepared cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ assert(media_player_listener != NULL); ++ media_player_listener->setMediaPreparedCb(cb, context); ++ } ++ ++ void getVolume(float *leftVolume, float *rightVolume) ++ { ++ *leftVolume = left_volume; ++ *rightVolume = right_volume; ++ } ++ ++ android::status_t setVolume(float leftVolume, float rightVolume) ++ { ++ REPORT_FUNCTION(); ++ ++ left_volume = leftVolume; ++ right_volume = rightVolume; ++ return MediaPlayer::setVolume(leftVolume, rightVolume); ++ } ++ ++ int getSourceFd() const { return source_fd; } ++ void setSourceFd(int fd) { source_fd = fd; } ++ ++ private: ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ android::sp texture; ++#else ++ android::sp texture; ++#endif ++ android::sp media_player_listener; ++ android::sp frame_listener; ++ float left_volume; ++ float right_volume; ++ int source_fd; ++}; // MediaPlayerWrapper ++ ++using namespace android; ++ ++// ----- Media Player C API Implementation ----- // ++ ++void android_media_set_video_size_cb(MediaPlayerWrapper *mp, on_msg_set_video_size cb, void *context) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return; ++ } ++ ++ mp->setVideoSizeCb(cb, context); ++} ++ ++void android_media_set_video_texture_needs_update_cb(MediaPlayerWrapper *mp, on_video_texture_needs_update cb, void *context) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return; ++ } ++ ++ mp->setVideoTextureNeedsUpdateCb(cb, context); ++} ++ ++void android_media_set_error_cb(MediaPlayerWrapper *mp, on_msg_error cb, void *context) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return; ++ } ++ ++ mp->setErrorCb(cb, context); ++} ++ ++void android_media_set_playback_complete_cb(MediaPlayerWrapper *mp, on_playback_complete cb, void *context) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return; ++ } ++ ++ mp->setPlaybackCompleteCb(cb, context); ++} ++ ++void android_media_set_media_prepared_cb(MediaPlayerWrapper *mp, on_media_prepared cb, void *context) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return; ++ } ++ ++ mp->setMediaPreparedCb(cb, context); ++} ++ ++MediaPlayerWrapper *android_media_new_player() ++{ ++ REPORT_FUNCTION(); ++ ++ MediaPlayerWrapper *mp = new MediaPlayerWrapper(); ++ if (mp == NULL) { ++ ALOGE("Failed to create new MediaPlayerWrapper instance."); ++ return NULL; ++ } ++ ++ // Required for internal player state processing. Without this, prepare() and start() hang. ++ ProcessState::self()->startThreadPool(); ++ ++ return mp; ++} ++ ++int android_media_set_data_source(MediaPlayerWrapper *mp, const char* url) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ if (url == NULL) { ++ ALOGE("url must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ ALOGD("url: %s", url); ++ ++ String16 src(url); ++ if (src.startsWith(String16("http://")) == true) { ++ ALOGD("HTTP source URL detected"); ++ mp->setDataSource(url, NULL); ++ } else { ++ ALOGD("File source URL detected"); ++ int fd = open(url, O_RDONLY); ++ if (fd < 0) ++ { ++ ALOGE("Failed to open source data at: %s\n", url); ++ return BAD_VALUE; ++ } ++ ++ mp->setSourceFd(fd); ++ ++ struct stat st; ++ stat(url, &st); ++ ++ ALOGD("source file length: %lld\n", st.st_size); ++ ++ mp->setDataSource(fd, 0, st.st_size); ++ } ++ mp->prepare(); ++ ++ return OK; ++} ++ ++int android_media_set_preview_texture(MediaPlayerWrapper *mp, int texture_id) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ android::sp native_alloc( ++ new android::NativeBufferAlloc() ++ ); ++ ++ android::sp buffer_queue( ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 ++ new android::BufferQueue(false, NULL, native_alloc) ++#else ++ new android::BufferQueue(NULL, native_alloc) ++#endif ++ ); ++ ++ static const bool allow_synchronous_mode = true; ++ // Create a new GLConsumer/SurfaceTexture from the texture_id in synchronous mode (don't wait on all data in the buffer) ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ mp->setVideoSurfaceTexture(android::sp( ++ new android::SurfaceTexture( ++#else ++ mp->setVideoSurfaceTexture(buffer_queue, android::sp( ++ new android::GLConsumer( ++#endif ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 ++ texture_id, ++ allow_synchronous_mode, ++ GL_TEXTURE_EXTERNAL_OES, ++ true, ++ buffer_queue))); ++#else ++ buffer_queue, ++ texture_id, ++ GL_TEXTURE_EXTERNAL_OES, ++ true, ++ false))); ++#endif ++ ++ return OK; ++} ++ ++void android_media_update_surface_texture(MediaPlayerWrapper *mp) ++{ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return; ++ } ++ ++ mp->updateGLConsumer(); ++} ++ ++void android_media_surface_texture_get_transformation_matrix(MediaPlayerWrapper *mp, GLfloat* matrix) ++{ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return; ++ } ++ ++ mp->get_transformation_matrix_for_surface_texture(matrix); ++} ++ ++int android_media_play(MediaPlayerWrapper *mp) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ mp->start(); ++ const char *tmp = mp->isPlaying() ? "yes" : "no"; ++ ALOGV("Is playing?: %s\n", tmp); ++ ++ return OK; ++} ++ ++int android_media_pause(MediaPlayerWrapper *mp) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ mp->pause(); ++ ++ return OK; ++} ++ ++int android_media_stop(MediaPlayerWrapper *mp) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ mp->stop(); ++ ++ int fd = mp->getSourceFd(); ++ if (fd > -1) ++ close(fd); ++ ++ return OK; ++} ++ ++bool android_media_is_playing(MediaPlayerWrapper *mp) ++{ ++ if (mp != NULL) { ++ if (mp->isPlaying()) ++ return true; ++ } ++ ++ return false; ++} ++ ++int android_media_seek_to(MediaPlayerWrapper *mp, int msec) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mp->seekTo(msec); ++} ++ ++int android_media_get_current_position(MediaPlayerWrapper *mp, int *msec) ++{ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mp->getCurrentPosition(msec); ++} ++ ++int android_media_get_duration(MediaPlayerWrapper *mp, int *msec) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mp->getDuration(msec); ++} ++ ++int android_media_get_volume(MediaPlayerWrapper *mp, int *volume) ++{ ++ REPORT_FUNCTION(); ++ ++ if (volume == NULL) { ++ ALOGE("volume must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ float left_volume = 0, right_volume = 0; ++ mp->getVolume(&left_volume, &right_volume); ++ *volume = left_volume * 100; ++ ++ return OK; ++} ++ ++int android_media_set_volume(MediaPlayerWrapper *mp, int volume) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mp == NULL) { ++ ALOGE("mp must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ float left_volume = float(volume / 100); ++ float right_volume = float(volume / 100); ++ return mp->setVolume(left_volume, right_volume); ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_format_layer.cpp +@@ -0,0 +1,245 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++// Uncomment to enable verbose debug output ++#define LOG_NDEBUG 0 ++ ++#undef LOG_TAG ++#define LOG_TAG "MediaFormatLayer" ++ ++#include ++#include "media_format_layer_priv.h" ++ ++#include ++ ++#include ++ ++#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__); ++ ++using namespace android; ++ ++static inline _MediaFormat *get_internal_format(MediaFormat format) ++{ ++ if (format == NULL) ++ { ++ ALOGE("format must not be NULL"); ++ return NULL; ++ } ++ ++ _MediaFormat *mf = static_cast<_MediaFormat*>(format); ++ assert(mf->refcount >= 1); ++ ++ return mf; ++} ++ ++MediaFormat media_format_create_video_format(const char *mime, int32_t width, int32_t height, int64_t duration_us, int32_t max_input_size) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *format = new _MediaFormat(); ++ format->mime = AString(mime); ++ format->width = width; ++ format->height = height; ++ format->duration_us = duration_us; ++ format->max_input_size = max_input_size; ++ ++ return format; ++} ++ ++void media_format_destroy(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return; ++ ++ if (mf->refcount) ++ return; ++ ++ delete mf; ++} ++ ++void media_format_ref(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return; ++ ++ mf->refcount++; ++} ++ ++void media_format_unref(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return; ++ ++ if (mf->refcount) ++ mf->refcount--; ++} ++ ++void media_format_set_byte_buffer(MediaFormat format, const char *key, uint8_t *data, size_t size) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return; ++ if (key == NULL || data == NULL || size == 0) ++ return; ++ ++ mf->csd_key_name = AString(key); ++ mf->csd = sp(new ABuffer(data, size)); ++} ++ ++const char* media_format_get_mime(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return NULL; ++ ++ return mf->mime.c_str(); ++} ++ ++int64_t media_format_get_duration_us(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->duration_us; ++} ++ ++int32_t media_format_get_width(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->width; ++} ++ ++int32_t media_format_get_height(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->height; ++} ++ ++int32_t media_format_get_max_input_size(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->max_input_size; ++} ++ ++int32_t media_format_get_stride(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->stride; ++} ++ ++int32_t media_format_get_slice_height(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->height; ++} ++ ++int32_t media_format_get_color_format(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->color_format; ++} ++ ++int32_t media_format_get_crop_left(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->crop_left; ++} ++ ++int32_t media_format_get_crop_right(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->crop_right; ++} ++ ++int32_t media_format_get_crop_top(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->crop_top; ++} ++ ++int32_t media_format_get_crop_bottom(MediaFormat format) ++{ ++ REPORT_FUNCTION() ++ ++ _MediaFormat *mf = get_internal_format(format); ++ if (mf == NULL) ++ return 0; ++ ++ return mf->crop_bottom; ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_format_layer_priv.cpp +@@ -0,0 +1,50 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++struct _MediaFormat : public RefBase ++{ ++ _MediaFormat() ++ : refcount(1) ++ { ++ } ++ ++ AString mime; ++ int64_t duration_us; ++ int32_t width; ++ int32_t height; ++ int32_t max_input_size; ++ ++ unsigned int refcount; ++}; ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_format_layer_priv.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#ifndef MEDIA_FORMAT_LAYER_PRIV_H_ ++#define MEDIA_FORMAT_LAYER_PRIV_H_ ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++struct _MediaFormat : public android::RefBase ++{ ++ _MediaFormat() ++ : duration_us(0), ++ width(0), ++ height(0), ++ max_input_size(0), ++ csd(NULL), ++ stride(0), ++ slice_height(0), ++ color_format(0), ++ crop_left(0), ++ crop_right(0), ++ crop_top(0), ++ crop_bottom(0), ++ refcount(1) ++ { ++ } ++ ++ android::AString mime; ++ int64_t duration_us; ++ int32_t width; ++ int32_t height; ++ int32_t max_input_size; ++ android::AString csd_key_name; ++ android::sp csd; ++ ++ int32_t stride; ++ int32_t slice_height; ++ int32_t color_format; ++ int32_t crop_left; ++ int32_t crop_right; ++ int32_t crop_top; ++ int32_t crop_bottom; ++ ++ unsigned int refcount; ++}; ++ ++#endif // MEDIA_FORMAT_LAYER_PRIV_H_ +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/recorder_compatibility_layer.cpp +@@ -0,0 +1,457 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ * Guenter Schwann ++ * Ricardo Salveti de Araujo ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++//#define LOG_NDEBUG 0 ++#undef LOG_TAG ++#define LOG_TAG "MediaRecorderCompatibilityLayer" ++#include ++#include ++ ++#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__) ++ ++/*! ++ * \brief The MediaRecorderListenerWrapper class is used to listen to events ++ * from the MediaRecorder ++ */ ++class MediaRecorderListenerWrapper : public android::MediaRecorderListener ++{ ++ public: ++ MediaRecorderListenerWrapper() ++ : error_cb(NULL), ++ error_context(NULL) ++ { ++ } ++ ++ void notify(int msg, int ext1, int ext2) ++ { ++ ALOGV("\tmsg: %d, ext1: %d, ext2: %d \n", msg, ext1, ext2); ++ ++ switch (msg) { ++ case android::MEDIA_RECORDER_EVENT_ERROR: ++ ALOGV("\tMEDIA_RECORDER_EVENT_ERROR msg\n"); ++ // TODO: Extend this cb to include the error message ++ if (error_cb != NULL) ++ error_cb(error_context); ++ else ++ ALOGE("Failed to signal error to app layer, callback not set."); ++ break; ++ default: ++ ALOGV("\tUnknown notification\n"); ++ } ++ } ++ ++ void setErrorCb(on_recorder_msg_error cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ error_cb = cb; ++ error_context = context; ++ } ++ ++ private: ++ on_recorder_msg_error error_cb; ++ void *error_context; ++}; ++ ++/*! ++ * \brief The MediaRecorderWrapper struct wraps the MediaRecorder class ++ */ ++struct MediaRecorderWrapper : public android::MediaRecorder ++{ ++ public: ++ MediaRecorderWrapper() ++ : MediaRecorder(), ++ media_recorder_listener(new MediaRecorderListenerWrapper()) ++ { ++ setListener(media_recorder_listener); ++ } ++ ++ ~MediaRecorderWrapper() ++ { ++ reset(); ++ } ++ ++ void setErrorCb(on_recorder_msg_error cb, void *context) ++ { ++ REPORT_FUNCTION(); ++ ++ assert(media_recorder_listener != NULL); ++ media_recorder_listener->setErrorCb(cb, context); ++ } ++ ++ private: ++ android::sp media_recorder_listener; ++}; ++ ++ ++using namespace android; ++ ++/*! ++ * \brief android_recorder_set_error_cb ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param cb The callback function to be called when a recording error occurs ++ * \param context ++ */ ++void android_recorder_set_error_cb(MediaRecorderWrapper *mr, on_recorder_msg_error cb, ++ void *context) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return; ++ } ++ ++ mr->setErrorCb(cb, context); ++} ++ ++/*! ++ * \brief android_media_new_recorder creates a new MediaRecorder ++ * \return New MediaRecorder object, or NULL if the object could not be created. ++ */ ++MediaRecorderWrapper *android_media_new_recorder() ++{ ++ REPORT_FUNCTION(); ++ ++ MediaRecorderWrapper *mr = new MediaRecorderWrapper; ++ if (mr == NULL) { ++ ALOGE("Failed to create new MediaRecorderWrapper instance."); ++ return NULL; ++ } ++ ++ return mr; ++} ++ ++/*! ++ * \brief android_recorder_initCheck ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \return negative value if an error occured ++ */ ++int android_recorder_initCheck(MediaRecorderWrapper *mr) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->initCheck(); ++} ++ ++/*! ++ * \brief android_recorder_setCamera sets the camera object for recording videos ++ * from the camera ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param control Wrapper for the camera (see camera in hybris) ++ * \return negative value if an error occured ++ */ ++int android_recorder_setCamera(MediaRecorderWrapper *mr, CameraControl* control) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ if (control == NULL) { ++ ALOGE("control must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setCamera(control->camera->remote(), control->camera->getRecordingProxy()); ++} ++ ++/*! ++ * \brief android_recorder_setVideoSource sets the video source. ++ * If no video source is set, only audio is recorded. ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param vs The video source. It's either the camera of gralloc buffer ++ * \return negative value if an error occured ++ */ ++int android_recorder_setVideoSource(MediaRecorderWrapper *mr, VideoSource vs) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setVideoSource(static_cast(vs)); ++} ++ ++/*! ++ * \brief android_recorder_setAudioSource ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param as The audio source. ++ * \return negative value if an error occured ++ */ ++int android_recorder_setAudioSource(MediaRecorderWrapper *mr, AudioSource as) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setAudioSource(static_cast(as)); ++} ++ ++/*! ++ * \brief android_recorder_setOutputFormat ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param of The output file format ++ * \return negative value if an error occured ++ */ ++int android_recorder_setOutputFormat(MediaRecorderWrapper *mr, OutputFormat of) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setOutputFormat(static_cast(of)); ++} ++ ++/*! ++ * \brief android_recorder_setVideoEncoder ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param ve The video encoder sets the codec for the video ++ * \return negative value if an error occured ++ */ ++int android_recorder_setVideoEncoder(MediaRecorderWrapper *mr, VideoEncoder ve) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setVideoEncoder(static_cast(ve)); ++} ++ ++/*! ++ * \brief android_recorder_setAudioEncoder ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param ae The audio encoder sets the codec for the audio ++ * \return negative value if an error occured ++ */ ++int android_recorder_setAudioEncoder(MediaRecorderWrapper *mr, AudioEncoder ae) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setAudioEncoder(static_cast(ae)); ++} ++ ++/*! ++ * \brief android_recorder_setOutputFile sets the output file to the given file descriptor ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param fd File descriptor of an open file, that the stream can be written to ++ * \return negative value if an error occured ++ */ ++int android_recorder_setOutputFile(MediaRecorderWrapper *mr, int fd) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setOutputFile(fd, 0, 0); ++} ++ ++/*! ++ * \brief android_recorder_setVideoSize ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param width width for the video to record ++ * \param height height for the video to record ++ * \return negative value if an error occured ++ */ ++int android_recorder_setVideoSize(MediaRecorderWrapper *mr, int width, int height) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setVideoSize(width, height); ++} ++ ++/*! ++ * \brief android_recorder_setVideoFrameRate ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param frames_per_second Frames per second has typical values for a movie clip in 720p is 30 ++ * \return negative value if an error occured ++ */ ++int android_recorder_setVideoFrameRate(MediaRecorderWrapper *mr, int frames_per_second) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->setVideoFrameRate(frames_per_second); ++} ++ ++/*! ++ * \brief android_recorder_setParameters sets a parameter. Even those without ++ * explicit function. ++ * For possible parameters look for example in StagefrightRecorder::setParameter() ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \param parameters list of parameters. format is "parameter1=value;parameter2=value" ++ * \return negative value if an error occured ++ */ ++int android_recorder_setParameters(MediaRecorderWrapper *mr, const char* parameters) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ String8 params(parameters); ++ return mr->setParameters(params); ++} ++ ++/*! ++ * \brief android_recorder_start starts the recording. ++ * The MediaRecorder has to be in state "prepared" ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \return negative value if an error occured ++ */ ++int android_recorder_start(MediaRecorderWrapper *mr) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->start(); ++} ++ ++/*! ++ * \brief android_recorder_stop Stops a running recording. ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \return negative value if an error occured ++ */ ++int android_recorder_stop(MediaRecorderWrapper *mr) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->stop(); ++} ++ ++/*! ++ * \brief android_recorder_prepare put the MediaRecorder into state "prepare" ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \return negative value if an error occured ++ */ ++int android_recorder_prepare(MediaRecorderWrapper *mr) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->prepare(); ++} ++ ++/*! ++ * \brief android_recorder_reset resets the MediaRecorder ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \return negative value if an error occured ++ */ ++int android_recorder_reset(MediaRecorderWrapper *mr) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->reset(); ++} ++ ++/*! ++ * \brief android_recorder_close closes the MediaRecorder ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \return negative value if an error occured ++ */ ++int android_recorder_close(MediaRecorderWrapper *mr) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->close(); ++} ++ ++/*! ++ * \brief android_recorder_release releases the MediaRecorder resources ++ * This deletes the object. So don't use it after calling this function. ++ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() ++ * \return negative value if an error occured ++ */ ++int android_recorder_release(MediaRecorderWrapper *mr) ++{ ++ REPORT_FUNCTION(); ++ ++ if (mr == NULL) { ++ ALOGE("mr must not be NULL"); ++ return BAD_VALUE; ++ } ++ ++ return mr->release(); ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/surface_texture_client_hybris.cpp +@@ -0,0 +1,333 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++// Uncomment to enable verbose debug output ++#define LOG_NDEBUG 0 ++ ++#undef LOG_TAG ++#define LOG_TAG "SurfaceTextureClientHybris" ++ ++#include ++#include "surface_texture_client_hybris_priv.h" ++ ++#include ++#include ++#include ++#include ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++#include ++#endif ++ ++#include ++#include ++ ++#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__); ++ ++using namespace android; ++ ++// ----- Begin _SurfaceTextureClientHybris API ----- // ++ ++static inline _SurfaceTextureClientHybris *get_internal_stch(SurfaceTextureClientHybris stc, const char * func) ++{ ++ if (stc == NULL) ++ { ++ ALOGE("stc must not be NULL (%s)", func); ++ return NULL; ++ } ++ ++ _SurfaceTextureClientHybris *s = static_cast<_SurfaceTextureClientHybris*>(stc); ++ assert(s->refcount >= 1); ++ ++ return s; ++} ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++_SurfaceTextureClientHybris::_SurfaceTextureClientHybris() ++ : refcount(1), ++ ready(false) ++{ ++ REPORT_FUNCTION() ++} ++#endif ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=4 ++_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp &bq) ++ : Surface::Surface(bq, true), ++ refcount(1), ++ ready(false) ++{ ++ REPORT_FUNCTION() ++} ++#endif ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const _SurfaceTextureClientHybris &stch) ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ : SurfaceTextureClient::SurfaceTextureClient(), ++#else ++ : Surface::Surface(new BufferQueue(), true), ++#endif ++ refcount(stch.refcount), ++ ready(false) ++{ ++ REPORT_FUNCTION() ++} ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp &st) ++ : SurfaceTextureClient::SurfaceTextureClient(st), ++#else ++_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp &st) ++ : Surface::Surface(st, true), ++#endif ++ refcount(1), ++ ready(false) ++{ ++ REPORT_FUNCTION() ++} ++#endif ++ ++_SurfaceTextureClientHybris::~_SurfaceTextureClientHybris() ++{ ++ REPORT_FUNCTION() ++ ++ ready = false; ++} ++ ++bool _SurfaceTextureClientHybris::isReady() const ++{ ++ return ready; ++} ++ ++int _SurfaceTextureClientHybris::dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd) ++{ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ return SurfaceTextureClient::dequeueBuffer(buffer, fenceFd); ++#else ++ return Surface::dequeueBuffer(buffer, fenceFd); ++#endif ++} ++ ++int _SurfaceTextureClientHybris::queueBuffer(ANativeWindowBuffer* buffer, int fenceFd) ++{ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ return SurfaceTextureClient::queueBuffer(buffer, fenceFd); ++#else ++ return Surface::queueBuffer(buffer, fenceFd); ++#endif ++} ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++void _SurfaceTextureClientHybris::setISurfaceTexture(const sp& surface_texture) ++{ ++ SurfaceTextureClient::setISurfaceTexture(surface_texture); ++#else ++void _SurfaceTextureClientHybris::setISurfaceTexture(const sp& surface_texture) ++{ ++ // We don't need to set up the IGraphicBufferProducer as stc needs it when created ++#endif ++ ++ // Ready for rendering ++ ready = true; ++} ++ ++void _SurfaceTextureClientHybris::setHardwareRendering(bool do_hardware_rendering) ++{ ++ hardware_rendering = do_hardware_rendering; ++} ++ ++bool _SurfaceTextureClientHybris::hardwareRendering() ++{ ++ return hardware_rendering; ++} ++ ++// ----- End _SurfaceTextureClientHybris API ----- // ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++static inline void set_surface(_SurfaceTextureClientHybris *stch, const sp &surface_texture) ++#else ++static inline void set_surface(_SurfaceTextureClientHybris *stch, const sp &surface_texture) ++#endif ++{ ++ REPORT_FUNCTION() ++ ++ if (stch == NULL) ++ return; ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ stch->setISurfaceTexture(surface_texture->getBufferQueue()); ++#else ++ stch->setISurfaceTexture(stch->getIGraphicBufferProducer()); ++#endif ++} ++ ++SurfaceTextureClientHybris surface_texture_client_create_by_id(unsigned int texture_id) ++{ ++ REPORT_FUNCTION() ++ ++ if (texture_id == 0) ++ { ++ ALOGE("Cannot create new SurfaceTextureClientHybris, texture id must be > 0."); ++ return NULL; ++ } ++ ++ // Use a new native buffer allocator vs the default one, which means it'll use the proper one ++ // that will allow rendering to work with Mir ++ sp native_alloc(new NativeBufferAlloc()); ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 ++ sp buffer_queue(new BufferQueue(false, NULL, native_alloc)); ++ _SurfaceTextureClientHybris *stch(new _SurfaceTextureClientHybris); ++#else ++ sp buffer_queue(new BufferQueue(NULL, native_alloc)); ++ _SurfaceTextureClientHybris *stch(new _SurfaceTextureClientHybris(buffer_queue)); ++#endif ++ ++ ALOGD("stch: %p (%s)", stch, __PRETTY_FUNCTION__); ++ ++ if (stch->surface_texture != NULL) ++ stch->surface_texture.clear(); ++ ++ const bool allow_synchronous_mode = true; ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ stch->surface_texture = new SurfaceTexture(texture_id, allow_synchronous_mode, GL_TEXTURE_EXTERNAL_OES, true, buffer_queue); ++ set_surface(stch, stch->surface_texture); ++#else ++ stch->surface_texture = new GLConsumer(buffer_queue, texture_id, GL_TEXTURE_EXTERNAL_OES, true, true); ++#endif ++ set_surface(stch, stch->surface_texture); ++ ++ return stch; ++} ++ ++uint8_t surface_texture_client_is_ready_for_rendering(SurfaceTextureClientHybris stc) ++{ ++ REPORT_FUNCTION() ++ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ return false; ++ ++ return static_cast(s->isReady()); ++} ++ ++uint8_t surface_texture_client_hardware_rendering(SurfaceTextureClientHybris stc) ++{ ++ REPORT_FUNCTION() ++ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ return false; ++ ++ return s->hardwareRendering(); ++} ++ ++void surface_texture_client_set_hardware_rendering(SurfaceTextureClientHybris stc, uint8_t hardware_rendering) ++{ ++ REPORT_FUNCTION() ++ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ return; ++ ++ s->setHardwareRendering(static_cast(hardware_rendering)); ++} ++ ++void surface_texture_client_get_transformation_matrix(SurfaceTextureClientHybris stc, float *matrix) ++{ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ return; ++ ++ s->surface_texture->getTransformMatrix(static_cast(matrix)); ++} ++ ++void surface_texture_client_update_texture(SurfaceTextureClientHybris stc) ++{ ++ REPORT_FUNCTION() ++ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ return; ++ ++ s->surface_texture->updateTexImage(); ++} ++ ++void surface_texture_client_destroy(SurfaceTextureClientHybris stc) ++{ ++ REPORT_FUNCTION() ++ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ { ++ ALOGE("s == NULL, cannot destroy SurfaceTextureClientHybris instance"); ++ return; ++ } ++ ++ s->refcount = 0; ++ ++ delete s; ++} ++ ++void surface_texture_client_ref(SurfaceTextureClientHybris stc) ++{ ++ REPORT_FUNCTION() ++ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ return; ++ ++ s->refcount++; ++} ++ ++void surface_texture_client_unref(SurfaceTextureClientHybris stc) ++{ ++ REPORT_FUNCTION() ++ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ { ++ ALOGE("s == NULL, cannot unref SurfaceTextureClientHybris instance"); ++ return; ++ } ++ ++ if (s->refcount > 1) ++ s->refcount--; ++ else ++ surface_texture_client_destroy (stc); ++} ++ ++void surface_texture_client_set_surface_texture(SurfaceTextureClientHybris stc, EGLNativeWindowType native_window) ++{ ++ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__); ++ if (s == NULL) ++ return; ++ ++ if (native_window == NULL) ++ { ++ ALOGE("native_window must not be NULL"); ++ return; ++ } ++ ++ sp surface = static_cast(native_window); ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ s->setISurfaceTexture(surface->getSurfaceTexture()); ++#else ++ s->setISurfaceTexture(surface->getIGraphicBufferProducer()); ++#endif ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/compat/media/surface_texture_client_hybris_priv.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#include ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++#include ++#else ++#include ++#endif ++ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++struct _SurfaceTextureClientHybris : public android::SurfaceTextureClient ++#else ++struct _SurfaceTextureClientHybris : public android::Surface ++#endif ++{ ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ _SurfaceTextureClientHybris(); ++#endif ++ _SurfaceTextureClientHybris(const _SurfaceTextureClientHybris &stch); ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ _SurfaceTextureClientHybris(const android::sp &st); ++#else ++ _SurfaceTextureClientHybris(const android::sp &bq); ++#endif ++ ~_SurfaceTextureClientHybris(); ++ ++ /** Has a texture id or EGLNativeWindowType been passed in, meaning rendering will function? **/ ++ bool isReady() const; ++ ++public: ++ int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); ++ int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ void setISurfaceTexture(const android::sp& surface_texture); ++#else ++ void setISurfaceTexture(const android::sp& surface_texture); ++#endif ++ void setHardwareRendering(bool do_hardware_rendering); ++ bool hardwareRendering(); ++ ++ unsigned int refcount; ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 ++ android::sp surface_texture; ++#else ++ android::sp surface_texture; ++#endif ++ ++private: ++ bool ready; ++ bool hardware_rendering; ++}; ++ +--- libhybris-0.1.0+git20131207+e452e83.orig/compat/ui/Android.mk ++++ libhybris-0.1.0+git20131207+e452e83/compat/ui/Android.mk +@@ -1,5 +1,6 @@ + LOCAL_PATH:= $(call my-dir) + include $(CLEAR_VARS) ++include $(LOCAL_PATH)/../Android.common.mk + + HYBRIS_PATH := $(LOCAL_PATH)/../../hybris + +--- libhybris-0.1.0+git20131207+e452e83.orig/compat/ui/ui_compatibility_layer.cpp ++++ libhybris-0.1.0+git20131207+e452e83/compat/ui/ui_compatibility_layer.cpp +@@ -126,6 +126,7 @@ void* graphic_buffer_get_native_buffer(s + return buffer->self->getNativeBuffer(); + } + ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 + void graphic_buffer_set_index(struct graphic_buffer *buffer, int index) + { + return buffer->self->setIndex(index); +@@ -135,6 +136,7 @@ int graphic_buffer_get_index(struct grap + { + return buffer->self->getIndex(); + } ++#endif + + int graphic_buffer_init_check(struct graphic_buffer *buffer) + { +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/Makefile.am ++++ libhybris-0.1.0+git20131207+e452e83/hybris/Makefile.am +@@ -4,7 +4,7 @@ if HAS_ANDROID_4_2_0 + SUBDIRS += libsync + endif + +-SUBDIRS += egl glesv1 glesv2 ui sf input camera ++SUBDIRS += egl glesv1 glesv2 ui sf input camera media + if HAS_LIBNFC_NXP_HEADERS + SUBDIRS += libnfc_nxp libnfc_ndef_nxp + endif +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/hooks.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/common/hooks.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -42,6 +43,10 @@ + #include + #include + ++#include ++#include ++#include ++ + #include + #include + #include +@@ -64,8 +69,12 @@ static int locale_inited = 0; + + #define ANDROID_MUTEX_SHARED_MASK 0x2000 + #define ANDROID_COND_SHARED_MASK 0x0001 ++#define ANDROID_COND_COUNTER_INCREMENT 0x0002 ++#define ANDROID_COND_COUNTER_MASK (~ANDROID_COND_SHARED_MASK) + #define ANDROID_RWLOCKATTR_SHARED_MASK 0x0010 + ++#define ANDROID_COND_IS_SHARED(c) (((c)->value & ANDROID_COND_SHARED_MASK) != 0) ++ + /* For the static initializer types */ + #define ANDROID_PTHREAD_MUTEX_INITIALIZER 0 + #define ANDROID_PTHREAD_RECURSIVE_MUTEX_INITIALIZER 0x4000 +@@ -87,6 +96,11 @@ struct _hook { + void *func; + }; + ++/* pthread cond struct as done in Android */ ++typedef struct { ++ int volatile value; ++} android_cond_t; ++ + /* Helpers */ + static int hybris_check_android_shared_mutex(unsigned int mutex_addr) + { +@@ -109,9 +123,59 @@ static int hybris_check_android_shared_c + (cond_addr & ANDROID_COND_SHARED_MASK)) + return 1; + ++ /* In case android is setting up cond_addr with a negative value, ++ * used for error control */ ++ if (cond_addr > HYBRIS_SHM_MASK_TOP) ++ return 1; ++ ++ return 0; ++} ++ ++/* Based on Android's Bionic pthread implementation. ++ * This is just needed when we have a shared cond with Android */ ++static int __android_pthread_cond_pulse(android_cond_t *cond, int counter) ++{ ++ long flags; ++ int fret; ++ ++ if (cond == NULL) ++ return EINVAL; ++ ++ flags = (cond->value & ~ANDROID_COND_COUNTER_MASK); ++ for (;;) { ++ long oldval = cond->value; ++ long newval = 0; ++ /* In our case all we need to do is make sure the negative value ++ * is under our range, which is the last 0xF from SHM_MASK */ ++ if (oldval < -12) ++ newval = ((oldval + ANDROID_COND_COUNTER_INCREMENT) & ++ ANDROID_COND_COUNTER_MASK) | flags; ++ else ++ newval = ((oldval - ANDROID_COND_COUNTER_INCREMENT) & ++ ANDROID_COND_COUNTER_MASK) | flags; ++ if (__sync_bool_compare_and_swap(&cond->value, oldval, newval)) ++ break; ++ } ++ ++ int pshared = cond->value & ANDROID_COND_SHARED_MASK; ++ fret = syscall(SYS_futex , &cond->value, ++ pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, counter, ++ NULL, NULL, NULL); ++ LOGD("futex based pthread_cond_*, value %d, counter %d, ret %d", ++ cond->value, counter, fret); + return 0; + } + ++int android_pthread_cond_broadcast(android_cond_t *cond) ++{ ++ return __android_pthread_cond_pulse(cond, INT_MAX); ++} ++ ++int android_pthread_cond_signal(android_cond_t *cond) ++{ ++ return __android_pthread_cond_pulse(cond, 1); ++} ++ + static void hybris_set_mutex_attr(unsigned int android_value, pthread_mutexattr_t *attr) + { + /* Init already sets as PTHREAD_MUTEX_NORMAL */ +@@ -577,8 +641,8 @@ static int my_pthread_cond_broadcast(pth + { + unsigned int value = (*(unsigned int *) cond); + if (hybris_check_android_shared_cond(value)) { +- LOGD("shared condition with Android, not broadcasting."); +- return 0; ++ LOGD("Shared condition with Android, broadcasting with futex."); ++ return android_pthread_cond_broadcast((android_cond_t *) cond); + } + + pthread_cond_t *realcond = (pthread_cond_t *) value; +@@ -598,8 +662,8 @@ static int my_pthread_cond_signal(pthrea + unsigned int value = (*(unsigned int *) cond); + + if (hybris_check_android_shared_cond(value)) { +- LOGD("Shared condition with Android, not signaling."); +- return 0; ++ LOGD("Shared condition with Android, broadcasting with futex."); ++ return android_pthread_cond_signal((android_cond_t *) cond); + } + + pthread_cond_t *realcond = (pthread_cond_t *) value; +@@ -1217,6 +1281,56 @@ FP_ATTRIB static double my_strtod(const + return strtod_l(nptr, endptr, hybris_locale); + } + ++static int __my_system_property_read(const void *pi, char *name, char *value) ++{ ++ return property_get(name, value, NULL); ++} ++ ++static int __my_system_property_get(const char *name, char *value) ++{ ++ return property_get(name, value, NULL); ++} ++ ++static int __my_system_property_foreach(void (*propfn)(const void *pi, void *cookie), void *cookie) ++{ ++ return 0; ++} ++ ++static const void *__my_system_property_find(const char *name) ++{ ++ return NULL; ++} ++ ++static unsigned int __my_system_property_serial(const void *pi) ++{ ++ return 0; ++} ++ ++static int __my_system_property_wait(const void *pi) ++{ ++ return 0; ++} ++ ++static int __my_system_property_update(void *pi, const char *value, unsigned int len) ++{ ++ return 0; ++} ++ ++static int __my_system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen) ++{ ++ return 0; ++} ++ ++static unsigned int __my_system_property_wait_any(unsigned int serial) ++{ ++ return 0; ++} ++ ++static const void *__my_system_property_find_nth(unsigned n) ++{ ++ return NULL; ++} ++ + extern int __cxa_atexit(void (*)(void*), void*, void*); + + static struct _hook hooks[] = { +@@ -1449,6 +1563,17 @@ static struct _hook hooks[] = { + /* grp.h */ + {"getgrgid", getgrgid}, + {"__cxa_atexit", __cxa_atexit}, ++ {"__system_property_read", __my_system_property_read}, ++ {"__system_property_get", __my_system_property_get}, ++ {"__system_property_set", property_set}, ++ {"__system_property_foreach", __my_system_property_foreach}, ++ {"__system_property_find", __my_system_property_find}, ++ {"__system_property_serial", __my_system_property_serial}, ++ {"__system_property_wait", __my_system_property_wait}, ++ {"__system_property_update", __my_system_property_update}, ++ {"__system_property_add", __my_system_property_add}, ++ {"__system_property_wait_any", __my_system_property_wait_any}, ++ {"__system_property_find_nth", __my_system_property_find_nth}, + {NULL, NULL}, + }; + +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/hooks_shm.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/common/hooks_shm.c +@@ -123,7 +123,9 @@ static void _hybris_shm_init() + else { + LOGD("Creating a new shared memory segment."); + +- _hybris_shm_fd = shm_open(HYBRIS_SHM_PATH, O_RDWR | O_CREAT, 0660); ++ mode_t pumask = umask(0); ++ _hybris_shm_fd = shm_open(HYBRIS_SHM_PATH, O_RDWR | O_CREAT, 0666); ++ umask(pumask); + if (_hybris_shm_fd >= 0) { + ftruncate( _hybris_shm_fd, size_to_map ); + /* Map the memory object */ +@@ -171,11 +173,12 @@ static void _hybris_shm_extend_region() + + /* + * Determine if the pointer that has been extracted by hybris is +- * pointing to an address in the shared memory ++ * pointing to an address in the shared memory. + */ + int hybris_is_pointer_in_shm(void *ptr) + { +- if ((unsigned int)ptr >= HYBRIS_SHM_MASK) ++ if (((unsigned int) ptr >= HYBRIS_SHM_MASK) && ++ ((unsigned int) ptr <= HYBRIS_SHM_MASK_TOP)) + return 1; + + return 0; +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/hooks_shm.h ++++ libhybris-0.1.0+git20131207+e452e83/hybris/common/hooks_shm.h +@@ -20,6 +20,9 @@ + + #include + ++/* Leave space to workaround the issue that Android might pass negative int values */ ++#define HYBRIS_SHM_MASK_TOP 0xFFFFFFF0UL ++ + typedef unsigned int hybris_shm_pointer_t; + + /* +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/dlfcn.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/dlfcn.c +@@ -78,7 +78,7 @@ const char *android_dlerror(void) + void *android_dlsym(void *handle, const char *symbol) + { + soinfo *found; +- Elf32_Sym *sym; ++ Elf_Sym *sym; + unsigned bind; + + pthread_mutex_lock(&dl_lock); +@@ -142,7 +142,7 @@ int android_dladdr(const void *addr, Dl_ + info->dli_fbase = (void*)si->base; + + /* Determine if any symbol in the library contains the specified address */ +- Elf32_Sym *sym = find_containing_symbol(addr, si); ++ Elf_Sym *sym = find_containing_symbol(addr, si); + + if(sym != NULL) { + info->dli_sname = si->strtab + sym->st_name; +@@ -192,7 +192,7 @@ int android_dl_iterate_phdr(int (*cb)(st + #endif + + +-static Elf32_Sym libdl_symtab[] = { ++static Elf_Sym libdl_symtab[] = { + // total length of libdl_info.strtab, including trailing 0 + // This is actually the the STH_UNDEF entry. Technically, it's + // supposed to have st_name == 0, but instead, it points to an index +@@ -200,45 +200,45 @@ static Elf32_Sym libdl_symtab[] = { + { st_name: sizeof(ANDROID_LIBDL_STRTAB) - 1, + }, + { st_name: 0, // starting index of the name in libdl_info.strtab +- st_value: (Elf32_Addr) &android_dlopen, ++ st_value: (Elf_Addr) &android_dlopen, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, + { st_name: 7, +- st_value: (Elf32_Addr) &android_dlclose, ++ st_value: (Elf_Addr) &android_dlclose, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, + { st_name: 15, +- st_value: (Elf32_Addr) &android_dlsym, ++ st_value: (Elf_Addr) &android_dlsym, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, + { st_name: 21, +- st_value: (Elf32_Addr) &android_dlerror, ++ st_value: (Elf_Addr) &android_dlerror, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, + { st_name: 29, +- st_value: (Elf32_Addr) &android_dladdr, ++ st_value: (Elf_Addr) &android_dladdr, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, + #ifdef ANDROID_ARM_LINKER + { st_name: 36, +- st_value: (Elf32_Addr) &android_dl_unwind_find_exidx, ++ st_value: (Elf_Addr) &android_dl_unwind_find_exidx, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, + #elif defined(ANDROID_X86_LINKER) + { st_name: 36, +- st_value: (Elf32_Addr) &android_dl_iterate_phdr, ++ st_value: (Elf_Addr) &android_dl_iterate_phdr, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, + #elif defined(ANDROID_SH_LINKER) + { st_name: 36, +- st_value: (Elf32_Addr) &android_dl_iterate_phdr, ++ st_value: (Elf_Addr) &android_dl_iterate_phdr, + st_info: STB_GLOBAL << 4, + st_shndx: 1, + }, +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/linker.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/linker.c +@@ -381,10 +381,10 @@ android_dl_iterate_phdr(int (*cb)(struct + } + #endif + +-static Elf32_Sym *_elf_lookup(soinfo *si, unsigned hash, const char *name) ++static Elf_Sym *_elf_lookup(soinfo *si, unsigned hash, const char *name) + { +- Elf32_Sym *s; +- Elf32_Sym *symtab = si->symtab; ++ Elf_Sym *s; ++ Elf_Sym *symtab = si->symtab; + const char *strtab = si->strtab; + unsigned n; + +@@ -426,11 +426,11 @@ static unsigned elfhash(const char *_nam + return h; + } + +-static Elf32_Sym * ++static Elf_Sym * + _do_lookup(soinfo *si, const char *name, unsigned *base) + { + unsigned elf_hash = elfhash(name); +- Elf32_Sym *s; ++ Elf_Sym *s; + unsigned *d; + soinfo *lsi = si; + int i; +@@ -502,17 +502,17 @@ done: + /* This is used by dl_sym(). It performs symbol lookup only within the + specified soinfo object and not in any of its dependencies. + */ +-Elf32_Sym *lookup_in_library(soinfo *si, const char *name) ++Elf_Sym *lookup_in_library(soinfo *si, const char *name) + { + return _elf_lookup(si, elfhash(name), name); + } + + /* This is used by dl_sym(). It performs a global symbol lookup. + */ +-Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start) ++Elf_Sym *lookup(const char *name, soinfo **found, soinfo *start) + { + unsigned elf_hash = elfhash(name); +- Elf32_Sym *s = NULL; ++ Elf_Sym *s = NULL; + soinfo *si; + + if(start == NULL) { +@@ -553,7 +553,7 @@ soinfo *find_containing_library(const vo + return NULL; + } + +-Elf32_Sym *find_containing_symbol(const void *addr, soinfo *si) ++Elf_Sym *find_containing_symbol(const void *addr, soinfo *si) + { + unsigned int i; + unsigned soaddr = (unsigned)addr - si->base; +@@ -561,7 +561,7 @@ Elf32_Sym *find_containing_symbol(const + /* Search the library's symbol table for any defined symbol which + * contains this address */ + for(i=0; inchain; i++) { +- Elf32_Sym *sym = &si->symtab[i]; ++ Elf_Sym *sym = &si->symtab[i]; + + if(sym->st_shndx != SHN_UNDEF && + soaddr >= sym->st_value && +@@ -576,7 +576,7 @@ Elf32_Sym *find_containing_symbol(const + #if 0 + static void dump(soinfo *si) + { +- Elf32_Sym *s = si->symtab; ++ Elf_Sym *s = si->symtab; + unsigned n; + + for(n = 0; n < si->nchain; n++) { +@@ -705,7 +705,7 @@ is_prelinked(int fd, const char *name) + static int + verify_elf_object(void *base, const char *name) + { +- Elf32_Ehdr *hdr = (Elf32_Ehdr *) base; ++ Elf_Ehdr *hdr = (Elf_Ehdr *) base; + + if (hdr->e_ident[EI_MAG0] != ELFMAG0) return -1; + if (hdr->e_ident[EI_MAG1] != ELFMAG1) return -1; +@@ -750,8 +750,8 @@ get_lib_extents(int fd, const char *name + unsigned min_vaddr = 0xffffffff; + unsigned max_vaddr = 0; + unsigned char *_hdr = (unsigned char *)__hdr; +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)_hdr; +- Elf32_Phdr *phdr; ++ Elf_Ehdr *ehdr = (Elf_Ehdr *)_hdr; ++ Elf_Phdr *phdr; + int cnt; + + TRACE("[ %5d Computing extents for '%s'. ]\n", pid, name); +@@ -770,7 +770,7 @@ get_lib_extents(int fd, const char *name + TRACE("[ %5d - Non-prelinked library '%s' found. ]\n", pid, name); + } + +- phdr = (Elf32_Phdr *)(_hdr + ehdr->e_phoff); ++ phdr = (Elf_Phdr *)(_hdr + ehdr->e_phoff); + + /* find the min/max p_vaddrs from all the PT_LOAD segments so we can + * get the range. */ +@@ -885,12 +885,12 @@ err: + static int + load_segments(int fd, void *header, soinfo *si) + { +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)header; +- Elf32_Phdr *phdr = (Elf32_Phdr *)((unsigned char *)header + ehdr->e_phoff); +- Elf32_Addr base = (Elf32_Addr) si->base; ++ Elf_Ehdr *ehdr = (Elf_Ehdr *)header; ++ Elf_Phdr *phdr = (Elf_Phdr *)((unsigned char *)header + ehdr->e_phoff); ++ Elf_Addr base = (Elf_Addr) si->base; + int cnt; + unsigned len; +- Elf32_Addr tmp; ++ Elf_Addr tmp; + unsigned char *pbase; + unsigned char *extra_base; + unsigned extra_len; +@@ -956,7 +956,7 @@ load_segments(int fd, void *header, soin + * | | + * _+---------------------+ page boundary + */ +- tmp = (Elf32_Addr)(((unsigned)pbase + len + PAGE_SIZE - 1) & ++ tmp = (Elf_Addr)(((unsigned)pbase + len + PAGE_SIZE - 1) & + (~PAGE_MASK)); + if (tmp < (base + phdr->p_vaddr + phdr->p_memsz)) { + extra_len = base + phdr->p_vaddr + phdr->p_memsz - tmp; +@@ -1020,7 +1020,7 @@ load_segments(int fd, void *header, soin + phdr->p_vaddr, phdr->p_memsz); + goto fail; + } +- si->gnu_relro_start = (Elf32_Addr) (base + phdr->p_vaddr); ++ si->gnu_relro_start = (Elf_Addr) (base + phdr->p_vaddr); + si->gnu_relro_len = (unsigned) phdr->p_memsz; + } else { + #ifdef ANDROID_ARM_LINKER +@@ -1067,11 +1067,11 @@ fail: + */ + #if 0 + static unsigned +-get_wr_offset(int fd, const char *name, Elf32_Ehdr *ehdr) ++get_wr_offset(int fd, const char *name, Elf_Ehdr *ehdr) + { +- Elf32_Shdr *shdr_start; +- Elf32_Shdr *shdr; +- int shdr_sz = ehdr->e_shnum * sizeof(Elf32_Shdr); ++ Elf_Shdr *shdr_start; ++ Elf_Shdr *shdr; ++ int shdr_sz = ehdr->e_shnum * sizeof(Elf_Shdr); + int cnt; + unsigned wr_offset = 0xffffffff; + +@@ -1104,7 +1104,7 @@ load_library(const char *name) + unsigned req_base; + const char *bname; + soinfo *si = NULL; +- Elf32_Ehdr *hdr; ++ Elf_Ehdr *hdr; + + if(fd == -1) { + DL_ERR("Library '%s' not found", name); +@@ -1161,8 +1161,8 @@ load_library(const char *name) + + /* this might not be right. Technically, we don't even need this info + * once we go through 'load_segments'. */ +- hdr = (Elf32_Ehdr *)si->base; +- si->phdr = (Elf32_Phdr *)((unsigned char *)si->base + hdr->e_phoff); ++ hdr = (Elf_Ehdr *)si->base; ++ si->phdr = (Elf_Phdr *)((unsigned char *)si->base + hdr->e_phoff); + si->phnum = hdr->e_phnum; + /**/ + +@@ -1261,7 +1261,7 @@ unsigned unload_library(soinfo *si) + * in link_image. This is needed to undo the DT_NEEDED hack below. + */ + if ((si->gnu_relro_start != 0) && (si->gnu_relro_len != 0)) { +- Elf32_Addr start = (si->gnu_relro_start & ~PAGE_MASK); ++ Elf_Addr start = (si->gnu_relro_start & ~PAGE_MASK); + unsigned len = (si->gnu_relro_start - start) + si->gnu_relro_len; + if (mprotect((void *) start, len, PROT_READ | PROT_WRITE) < 0) + DL_ERR("%5d %s: could not undo GNU_RELRO protections. " +@@ -1304,16 +1304,16 @@ unsigned unload_library(soinfo *si) + } + + /* TODO: don't use unsigned for addrs below. It works, but is not +- * ideal. They should probably be either uint32_t, Elf32_Addr, or unsigned ++ * ideal. They should probably be either uint32_t, Elf_Addr, or unsigned + * long. + */ +-static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count) ++static int reloc_library(soinfo *si, Elf_Rel *rel, unsigned count) + { +- Elf32_Sym *symtab = si->symtab; ++ Elf_Sym *symtab = si->symtab; + const char *strtab = si->strtab; +- Elf32_Sym *s; ++ Elf_Sym *s; + unsigned base; +- Elf32_Rel *start = rel; ++ Elf_Rel *start = rel; + unsigned idx; + + for (idx = 0; idx < count; ++idx) { +@@ -1712,7 +1712,7 @@ static int nullify_closed_stdio (void) + static int link_image(soinfo *si, unsigned wr_offset) + { + unsigned *d; +- Elf32_Phdr *phdr = si->phdr; ++ Elf_Phdr *phdr = si->phdr; + int phnum = si->phnum; + + INFO("[ %5d linking %s ]\n", pid, si->name); +@@ -1795,7 +1795,7 @@ static int link_image(soinfo *si, unsign + phdr->p_vaddr, phdr->p_memsz); + goto fail; + } +- si->gnu_relro_start = (Elf32_Addr) (si->base + phdr->p_vaddr); ++ si->gnu_relro_start = (Elf_Addr) (si->base + phdr->p_vaddr); + si->gnu_relro_len = (unsigned) phdr->p_memsz; + } + } +@@ -1822,7 +1822,7 @@ static int link_image(soinfo *si, unsign + si->strtab = (const char *) (si->base + *d); + break; + case DT_SYMTAB: +- si->symtab = (Elf32_Sym *) (si->base + *d); ++ si->symtab = (Elf_Sym *) (si->base + *d); + break; + case DT_PLTREL: + if(*d != DT_REL) { +@@ -1831,13 +1831,13 @@ static int link_image(soinfo *si, unsign + } + break; + case DT_JMPREL: +- si->plt_rel = (Elf32_Rel*) (si->base + *d); ++ si->plt_rel = (Elf_Rel*) (si->base + *d); + break; + case DT_PLTRELSZ: + si->plt_rel_count = *d / 8; + break; + case DT_REL: +- si->rel = (Elf32_Rel*) (si->base + *d); ++ si->rel = (Elf_Rel*) (si->base + *d); + break; + case DT_RELSZ: + si->rel_count = *d / 8; +@@ -1869,7 +1869,7 @@ static int link_image(soinfo *si, unsign + pid, si->name, si->init_array); + break; + case DT_INIT_ARRAYSZ: +- si->init_array_count = ((unsigned)*d) / sizeof(Elf32_Addr); ++ si->init_array_count = ((unsigned)*d) / sizeof(Elf_Addr); + break; + case DT_FINI_ARRAY: + si->fini_array = (unsigned *)(si->base + *d); +@@ -1877,7 +1877,7 @@ static int link_image(soinfo *si, unsign + pid, si->name, si->fini_array); + break; + case DT_FINI_ARRAYSZ: +- si->fini_array_count = ((unsigned)*d) / sizeof(Elf32_Addr); ++ si->fini_array_count = ((unsigned)*d) / sizeof(Elf_Addr); + break; + case DT_PREINIT_ARRAY: + si->preinit_array = (unsigned *)(si->base + *d); +@@ -1885,7 +1885,7 @@ static int link_image(soinfo *si, unsign + pid, si->name, si->preinit_array); + break; + case DT_PREINIT_ARRAYSZ: +- si->preinit_array_count = ((unsigned)*d) / sizeof(Elf32_Addr); ++ si->preinit_array_count = ((unsigned)*d) / sizeof(Elf_Addr); + break; + case DT_TEXTREL: + /* TODO: make use of this. */ +@@ -1987,7 +1987,7 @@ static int link_image(soinfo *si, unsign + #endif + + if (si->gnu_relro_start != 0 && si->gnu_relro_len != 0) { +- Elf32_Addr start = (si->gnu_relro_start & ~PAGE_MASK); ++ Elf_Addr start = (si->gnu_relro_start & ~PAGE_MASK); + unsigned len = (si->gnu_relro_start - start) + si->gnu_relro_len; + if (mprotect((void *) start, len, PROT_READ) < 0) { + DL_ERR("%5d GNU_RELRO mprotect of library '%s' failed: %d (%s)\n", +@@ -2170,7 +2170,7 @@ sanitize: + while(vecs[0] != 0){ + switch(vecs[0]){ + case AT_PHDR: +- si->phdr = (Elf32_Phdr*) vecs[1]; ++ si->phdr = (Elf_Phdr*) vecs[1]; + break; + case AT_PHNUM: + si->phnum = (int) vecs[1]; +@@ -2190,7 +2190,7 @@ sanitize: + si->base = 0; + for ( nn = 0; nn < si->phnum; nn++ ) { + if (si->phdr[nn].p_type == PT_PHDR) { +- si->base = (Elf32_Addr) si->phdr - si->phdr[nn].p_vaddr; ++ si->base = (Elf_Addr) si->phdr - si->phdr[nn].p_vaddr; + break; + } + } +@@ -2303,9 +2303,9 @@ static unsigned find_linker_base(unsigne + */ + unsigned __linker_init(unsigned **elfdata) { + unsigned linker_addr = find_linker_base(elfdata); +- Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) linker_addr; +- Elf32_Phdr *phdr = +- (Elf32_Phdr *)((unsigned char *) linker_addr + elf_hdr->e_phoff); ++ Elf_Ehdr *elf_hdr = (Elf_Ehdr *) linker_addr; ++ Elf_Phdr *phdr = ++ (Elf_Phdr *)((unsigned char *) linker_addr + elf_hdr->e_phoff); + + soinfo linker_so; + memset(&linker_so, 0, sizeof(soinfo)); +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/linker.h ++++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/linker.h +@@ -38,6 +38,26 @@ + #define PAGE_SIZE 4096 + #define PAGE_MASK 4095 + ++#if defined(__x86_64__) ++typedef Elf64_Ehdr Elf_Ehdr; ++typedef Elf64_Shdr Elf_Shdr; ++typedef Elf64_Sym Elf_Sym; ++typedef Elf64_Addr Elf_Addr; ++typedef Elf64_Phdr Elf_Phdr; ++typedef Elf64_Half Elf_Half; ++typedef Elf64_Rel Elf_Rel; ++typedef Elf64_Rela Elf_Rela; ++#else ++typedef Elf32_Ehdr Elf_Ehdr; ++typedef Elf32_Shdr Elf_Shdr; ++typedef Elf32_Sym Elf_Sym; ++typedef Elf32_Addr Elf_Addr; ++typedef Elf32_Phdr Elf_Phdr; ++typedef Elf32_Half Elf_Half; ++typedef Elf32_Rel Elf_Rel; ++typedef Elf32_Rela Elf_Rela; ++#endif ++ + void debugger_init(); + const char *addr_to_name(unsigned addr); + +@@ -55,10 +75,10 @@ struct link_map + /* needed for dl_iterate_phdr to be passed to the callbacks provided */ + struct dl_phdr_info + { +- Elf32_Addr dlpi_addr; ++ Elf_Addr dlpi_addr; + const char *dlpi_name; +- const Elf32_Phdr *dlpi_phdr; +- Elf32_Half dlpi_phnum; ++ const Elf_Phdr *dlpi_phdr; ++ Elf_Half dlpi_phnum; + }; + + +@@ -90,7 +110,7 @@ typedef struct soinfo soinfo; + struct soinfo + { + const char name[SOINFO_NAME_LEN]; +- Elf32_Phdr *phdr; ++ Elf_Phdr *phdr; + int phnum; + unsigned entry; + unsigned base; +@@ -107,7 +127,7 @@ struct soinfo + unsigned flags; + + const char *strtab; +- Elf32_Sym *symtab; ++ Elf_Sym *symtab; + + unsigned nbucket; + unsigned nchain; +@@ -116,10 +136,10 @@ struct soinfo + + unsigned *plt_got; + +- Elf32_Rel *plt_rel; ++ Elf_Rel *plt_rel; + unsigned plt_rel_count; + +- Elf32_Rel *rel; ++ Elf_Rel *rel; + unsigned rel_count; + + unsigned *preinit_array; +@@ -144,7 +164,7 @@ struct soinfo + + int constructors_called; + +- Elf32_Addr gnu_relro_start; ++ Elf_Addr gnu_relro_start; + unsigned gnu_relro_len; + + }; +@@ -202,10 +222,10 @@ extern soinfo libdl_info; + + soinfo *find_library(const char *name); + unsigned unload_library(soinfo *si); +-Elf32_Sym *lookup_in_library(soinfo *si, const char *name); +-Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start); ++Elf_Sym *lookup_in_library(soinfo *si, const char *name); ++Elf_Sym *lookup(const char *name, soinfo **found, soinfo *start); + soinfo *find_containing_library(const void *addr); +-Elf32_Sym *find_containing_symbol(const void *addr, soinfo *si); ++Elf_Sym *find_containing_symbol(const void *addr, soinfo *si); + const char *linker_get_error(void); + void call_constructors_recursive(soinfo *si); + +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/linker_format.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/linker_format.c +@@ -268,7 +268,7 @@ static int log_vprint(int prio, const ch + result = vformat_buffer(buf, sizeof buf, fmt, args); + + if (log_fd < 0) { +- log_fd = open("/dev/log/main", O_WRONLY); ++ log_fd = open("/dev/alog/main", O_WRONLY); + if (log_fd < 0) { + log_fd = fileno(stdout); // kernel doesn't have android log + return result; +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/configure.ac ++++ libhybris-0.1.0+git20131207+e452e83/hybris/configure.ac +@@ -184,6 +184,8 @@ AC_CONFIG_FILES([ + input/libis.pc + camera/Makefile + camera/libcamera.pc ++ media/Makefile ++ media/libmedia.pc + include/Makefile + utils/Makefile + tests/Makefile +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/hardware/hardware.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/hardware/hardware.c +@@ -17,6 +17,7 @@ + + #include + #include ++#include + #include + #include + +@@ -26,15 +27,20 @@ static int (*_hw_get_module)(const char + + static int (*_hw_get_module_by_class)(const char *class_id, const char *inst, const struct hw_module_t **module) = NULL; + +-#define HARDWARE_DLSYM(fptr, sym) do { if (_libhardware == NULL) { _init_lib_hardware(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libhardware, sym); } } while (0) ++#define HARDWARE_DLSYM(fptr, sym) do { if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libhardware, sym); } } while (0) + +-static void _init_lib_hardware() ++static void *_init_lib_hardware() + { +- _libhardware = (void *) android_dlopen("/system/lib/libhardware.so", RTLD_LAZY); ++ if (!_libhardware) ++ _libhardware = (void *) android_dlopen("/system/lib/libhardware.so", RTLD_LAZY); ++ return _libhardware; + } + + int hw_get_module(const char *id, const struct hw_module_t **module) + { ++ if (!_init_lib_hardware()) ++ return -EINVAL; ++ + HARDWARE_DLSYM(&_hw_get_module, "hw_get_module"); + return (*_hw_get_module)(id, module); + } +@@ -42,6 +48,9 @@ int hw_get_module(const char *id, const + int hw_get_module_by_class(const char *class_id, const char *inst, + const struct hw_module_t **module) + { ++ if (!_init_lib_hardware()) ++ return -EINVAL; ++ + HARDWARE_DLSYM(&_hw_get_module_by_class, "hw_get_module_by_class"); + return (*_hw_get_module_by_class)(class_id, inst, module); + } +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/Makefile.am ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/Makefile.am +@@ -65,6 +65,15 @@ propertiesincludedir = $(includedir)/hyb + propertiesinclude_HEADERS = \ + hybris/properties/properties.h + ++mediaincludedir = $(includedir)/hybris/media ++mediainclude_HEADERS = \ ++ hybris/media/media_compatibility_layer.h \ ++ hybris/media/media_codec_layer.h \ ++ hybris/media/media_codec_list.h \ ++ hybris/media/media_format_layer.h \ ++ hybris/media/surface_texture_client_hybris.h \ ++ hybris/media/recorder_compatibility_layer.h ++ + dlfcnincludedir = $(includedir)/hybris/dlfcn + dlfcninclude_HEADERS = \ + hybris/dlfcn/dlfcn.h +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/input/input_stack_compatibility_layer.h ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/input/input_stack_compatibility_layer.h +@@ -109,6 +109,7 @@ extern "C" { + int input_area_height; + }; + ++ int android_input_check_availability(); + void android_input_stack_initialize( + struct AndroidEventListener* listener, + struct InputStackConfiguration* input_stack_configuration); +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/internal/camera_control.h ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/internal/camera_control.h +@@ -19,7 +19,11 @@ + + #include + #include ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 + #include ++#else ++#include ++#endif + + #include + #include +@@ -31,15 +35,22 @@ extern "C" { + struct CameraControlListener; + + struct CameraControl : public android::CameraListener, ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 + public android::SurfaceTexture::FrameAvailableListener ++#else ++ public android::GLConsumer::FrameAvailableListener ++#endif + { + android::Mutex guard; + CameraControlListener* listener; + android::sp camera; + android::CameraParameters camera_parameters; ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2 + android::sp preview_texture; +- +- // From android::SurfaceTexture::FrameAvailableListener ++#else ++ android::sp preview_texture; ++#endif ++ // From android::SurfaceTexture/GLConsumer::FrameAvailableListener + void onFrameAvailable(); + + // From android::CameraListener +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/internal/surface_flinger_compatibility_layer_internal.h ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/internal/surface_flinger_compatibility_layer_internal.h +@@ -25,6 +25,7 @@ + + #include + ++#include + #include + #include + #include +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_codec_layer.h +@@ -0,0 +1,93 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#ifndef MEDIA_CODEC_LAYER_H_ ++#define MEDIA_CODEC_LAYER_H_ ++ ++#include ++#include ++ ++#ifdef SIMPLE_PLAYER ++#include ++#endif ++ ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ typedef void* MediaCodecDelegate; ++ ++ typedef void (*on_texture_needs_update)(void *context); ++ void media_codec_set_texture_needs_update_cb(MediaCodecDelegate delegate, on_texture_needs_update cb, void *context); ++ ++ MediaCodecDelegate media_codec_create_by_codec_name(const char *name); ++ MediaCodecDelegate media_codec_create_by_codec_type(const char *type); ++ ++#ifdef SIMPLE_PLAYER ++ android::MediaCodec* media_codec_get(MediaCodecDelegate delegate); ++#endif ++ ++ void media_codec_delegate_destroy(MediaCodecDelegate delegate); ++ void media_codec_delegate_ref(MediaCodecDelegate delegate); ++ void media_codec_delegate_unref(MediaCodecDelegate delegate); ++ ++#ifdef SIMPLE_PLAYER ++ int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, void *nativeWindow, uint32_t flags); ++#else ++ int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, SurfaceTextureClientHybris stc, uint32_t flags); ++#endif ++ int media_codec_set_surface_texture_client(MediaCodecDelegate delegate, SurfaceTextureClientHybris stc); ++ ++ int media_codec_queue_csd(MediaCodecDelegate delegate, MediaFormat format); ++ int media_codec_start(MediaCodecDelegate delegate); ++ int media_codec_stop(MediaCodecDelegate delegate); ++ int media_codec_release(MediaCodecDelegate delegate); ++ int media_codec_flush(MediaCodecDelegate delegate); ++ size_t media_codec_get_input_buffers_size(MediaCodecDelegate delegate); ++ uint8_t *media_codec_get_nth_input_buffer(MediaCodecDelegate delegate, size_t n); ++ size_t media_codec_get_nth_input_buffer_capacity(MediaCodecDelegate delegate, size_t n); ++ size_t media_codec_get_output_buffers_size(MediaCodecDelegate delegate); ++ uint8_t *media_codec_get_nth_output_buffer(MediaCodecDelegate delegate, size_t n); ++ size_t media_codec_get_nth_output_buffer_capacity(MediaCodecDelegate delegate, size_t n); ++ ++ struct _MediaCodecBufferInfo ++ { ++ size_t index; ++ size_t offset; ++ size_t size; ++ int64_t presentation_time_us; ++ uint32_t flags; ++ uint8_t render_retries; ++ }; ++ typedef struct _MediaCodecBufferInfo MediaCodecBufferInfo; ++ ++ int media_codec_dequeue_output_buffer(MediaCodecDelegate delegate, MediaCodecBufferInfo *info, int64_t timeout_us); ++ int media_codec_queue_input_buffer(MediaCodecDelegate delegate, const MediaCodecBufferInfo *info); ++ int media_codec_dequeue_input_buffer(MediaCodecDelegate delegate, size_t *index, int64_t timeout_us); ++ int media_codec_release_output_buffer(MediaCodecDelegate delegate, size_t index, uint8_t render); ++ ++ MediaFormat media_codec_get_output_format(MediaCodecDelegate delegate); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // MEDIA_CODEC_LAYER_H_ +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_codec_list.h +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#ifndef MEDIA_CODEC_LIST_PRIV_H_ ++#define MEDIA_CODEC_LIST_PRIV_H_ ++ ++#include ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ssize_t media_codec_list_find_codec_by_type(const char *type, bool encoder, size_t startIndex); ++ ssize_t media_codec_list_find_codec_by_name(const char *name); ++ size_t media_codec_list_count_codecs(); ++ void media_codec_list_get_codec_info_at_id(size_t index); ++ const char *media_codec_list_get_codec_name(size_t index); ++ bool media_codec_list_is_encoder(size_t index); ++ size_t media_codec_list_get_num_supported_types(size_t index); ++ size_t media_codec_list_get_nth_supported_type_len(size_t index, size_t n); ++ int media_codec_list_get_nth_supported_type(size_t index, char *type, size_t n); ++ ++ struct _profile_level ++ { ++ uint32_t profile; ++ uint32_t level; ++ }; ++ typedef struct _profile_level profile_level; ++ ++ size_t media_codec_list_get_num_profile_levels(size_t index, const char*); ++ size_t media_codec_list_get_num_color_formats(size_t index, const char*); ++ int media_codec_list_get_nth_codec_profile_level(size_t index, const char *type, profile_level *pro_level, size_t n); ++ int media_codec_list_get_codec_color_formats(size_t index, const char *type, uint32_t *color_formats); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // MEDIA_CODEC_LIST_PRIV_H_ +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_compatibility_layer.h +@@ -0,0 +1,75 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#ifndef MEDIA_COMPATIBILITY_LAYER_H_ ++#define MEDIA_COMPATIBILITY_LAYER_H_ ++ ++#include ++#include ++#include ++ ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ // Common compat calls ++ int media_compat_check_availability(); ++ ++ // Callback types ++ typedef void (*on_msg_set_video_size)(int height, int width, void *context); ++ typedef void (*on_video_texture_needs_update)(void *context); ++ typedef void (*on_msg_error)(void *context); ++ typedef void (*on_playback_complete)(void *context); ++ typedef void (*on_media_prepared)(void *context); ++ ++ struct MediaPlayerWrapper; ++ ++ // ----- Start of C API ----- // ++ ++ // Callback setters ++ void android_media_set_video_size_cb(struct MediaPlayerWrapper *mp, on_msg_set_video_size cb, void *context); ++ void android_media_set_video_texture_needs_update_cb(struct MediaPlayerWrapper *mp, on_video_texture_needs_update cb, void *context); ++ void android_media_set_error_cb(struct MediaPlayerWrapper *mp, on_msg_error cb, void *context); ++ void android_media_set_playback_complete_cb(struct MediaPlayerWrapper *mp, on_playback_complete cb, void *context); ++ void android_media_set_media_prepared_cb(struct MediaPlayerWrapper *mp, on_media_prepared cb, void *context); ++ ++ // Main player control API ++ struct MediaPlayerWrapper *android_media_new_player(); ++ int android_media_set_data_source(struct MediaPlayerWrapper *mp, const char* url); ++ int android_media_set_preview_texture(struct MediaPlayerWrapper *mp, int texture_id); ++ void android_media_update_surface_texture(struct MediaPlayerWrapper *mp); ++ void android_media_surface_texture_get_transformation_matrix(struct MediaPlayerWrapper *mp, GLfloat*matrix); ++ int android_media_play(struct MediaPlayerWrapper *mp); ++ int android_media_pause(struct MediaPlayerWrapper *mp); ++ int android_media_stop(struct MediaPlayerWrapper *mp); ++ bool android_media_is_playing(struct MediaPlayerWrapper *mp); ++ ++ int android_media_seek_to(struct MediaPlayerWrapper *mp, int msec); ++ int android_media_get_current_position(struct MediaPlayerWrapper *mp, int *msec); ++ int android_media_get_duration(struct MediaPlayerWrapper *mp, int *msec); ++ ++ int android_media_get_volume(struct MediaPlayerWrapper *mp, int *volume); ++ int android_media_set_volume(struct MediaPlayerWrapper *mp, int volume); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // MEDIA_COMPATIBILITY_LAYER_H_ +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_format_layer.h +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#ifndef MEDIA_FORMAT_LAYER_H_ ++#define MEDIA_FORMAT_LAYER_H_ ++ ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ typedef void* MediaFormat; ++ ++ MediaFormat media_format_create_video_format(const char *mime, int32_t width, int32_t height, int64_t duration_us, int32_t max_input_size); ++ ++ void media_format_destroy(MediaFormat format); ++ void media_format_ref(MediaFormat format); ++ void media_format_unref(MediaFormat format); ++ ++ void media_format_set_byte_buffer(MediaFormat format, const char *key, uint8_t *data, size_t size); ++ ++ const char* media_format_get_mime(MediaFormat format); ++ int64_t media_format_get_duration_us(MediaFormat format); ++ int32_t media_format_get_width(MediaFormat format); ++ int32_t media_format_get_height(MediaFormat format); ++ int32_t media_format_get_max_input_size(MediaFormat format); ++ int32_t media_format_get_stride(MediaFormat format); ++ int32_t media_format_get_slice_height(MediaFormat format); ++ int32_t media_format_get_color_format(MediaFormat format); ++ int32_t media_format_get_crop_left(MediaFormat format); ++ int32_t media_format_get_crop_right(MediaFormat format); ++ int32_t media_format_get_crop_top(MediaFormat format); ++ int32_t media_format_get_crop_bottom(MediaFormat format); ++ ++ // TODO: Add getter for CSD buffer ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // MEDIA_FORMAT_LAYER_H_ +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/recorder_compatibility_layer.h +@@ -0,0 +1,126 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#ifndef RECORDER_COMPATIBILITY_LAYER_H_ ++#define RECORDER_COMPATIBILITY_LAYER_H_ ++ ++#include ++#include ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ struct MediaRecorderWrapper; ++ struct CameraControl; ++ ++ // values are from andoid /frameworks/av/include/media/mediarecorder.h ++ typedef enum ++ { ++ ANDROID_VIDEO_SOURCE_DEFAULT = 0, ++ ANDROID_VIDEO_SOURCE_CAMERA = 1, ++ ANDROID_VIDEO_SOURCE_GRALLOC_BUFFER = 2 ++ } VideoSource; ++ ++ // values are from andoid /system/core/include/system/audio.h ++ typedef enum ++ { ++ ANDROID_AUDIO_SOURCE_DEFAULT = 0, ++ ANDROID_AUDIO_SOURCE_MIC = 1, ++ ANDROID_AUDIO_SOURCE_VOICE_UPLINK = 2, ++ ANDROID_AUDIO_SOURCE_VOICE_DOWNLINK = 3, ++ ANDROID_AUDIO_SOURCE_VOICE_CALL = 4, ++ ANDROID_AUDIO_SOURCE_CAMCORDER = 5, ++ ANDROID_AUDIO_SOURCE_VOICE_RECOGNITION = 6, ++ ANDROID_AUDIO_SOURCE_VOICE_COMMUNICATION = 7, ++ ANDROID_AUDIO_SOURCE_REMOTE_SUBMIX = 8, ++ ANDROID_AUDIO_SOURCE_CNT, ++ ANDROID_AUDIO_SOURCE_MAX = ANDROID_AUDIO_SOURCE_CNT - 1 ++ } AudioSource; ++ ++ // values are from andoid /frameworks/av/include/media/mediarecorder.h ++ typedef enum ++ { ++ ANDROID_OUTPUT_FORMAT_DEFAULT = 0, ++ ANDROID_OUTPUT_FORMAT_THREE_GPP = 1, ++ ANDROID_OUTPUT_FORMAT_MPEG_4 = 2, ++ ANDROID_OUTPUT_FORMAT_AUDIO_ONLY_START = 3, ++ /* These are audio only file formats */ ++ ANDROID_OUTPUT_FORMAT_RAW_AMR = 3, //to be backward compatible ++ ANDROID_OUTPUT_FORMAT_AMR_NB = 3, ++ ANDROID_OUTPUT_FORMAT_AMR_WB = 4, ++ ANDROID_OUTPUT_FORMAT_AAC_ADIF = 5, ++ ANDROID_OUTPUT_FORMAT_AAC_ADTS = 6, ++ /* Stream over a socket, limited to a single stream */ ++ ANDROID_OUTPUT_FORMAT_RTP_AVP = 7, ++ /* H.264/AAC data encapsulated in MPEG2/TS */ ++ ANDROID_OUTPUT_FORMAT_MPEG2TS = 8 ++ } OutputFormat; ++ ++ // values are from andoid /frameworks/av/include/media/mediarecorder.h ++ typedef enum ++ { ++ ANDROID_VIDEO_ENCODER_DEFAULT = 0, ++ ANDROID_VIDEO_ENCODER_H263 = 1, ++ ANDROID_VIDEO_ENCODER_H264 = 2, ++ ANDROID_VIDEO_ENCODER_MPEG_4_SP = 3 ++ } VideoEncoder; ++ ++ // values are from andoid /frameworks/av/include/media/mediarecorder.h ++ typedef enum ++ { ++ ANDROID_AUDIO_ENCODER_DEFAULT = 0, ++ ANDROID_AUDIO_ENCODER_AMR_NB = 1, ++ ANDROID_AUDIO_ENCODER_AMR_WB = 2, ++ ANDROID_AUDIO_ENCODER_AAC = 3, ++ ANDROID_AUDIO_ENCODER_HE_AAC = 4, ++ ANDROID_AUDIO_ENCODER_AAC_ELD = 5 ++ } AudioEncoder; ++ ++ // Callback types ++ typedef void (*on_recorder_msg_error)(void *context); ++ ++ // Callback setters ++ void android_recorder_set_error_cb(struct MediaRecorderWrapper *mr, on_recorder_msg_error cb, ++ void *context); ++ ++ // Main recorder control API ++ struct MediaRecorderWrapper *android_media_new_recorder(); ++ int android_recorder_initCheck(struct MediaRecorderWrapper *mr); ++ int android_recorder_setCamera(struct MediaRecorderWrapper *mr, struct CameraControl* control); ++ int android_recorder_setVideoSource(struct MediaRecorderWrapper *mr, VideoSource vs); ++ int android_recorder_setAudioSource(struct MediaRecorderWrapper *mr, AudioSource as); ++ int android_recorder_setOutputFormat(struct MediaRecorderWrapper *mr, OutputFormat of); ++ int android_recorder_setVideoEncoder(struct MediaRecorderWrapper *mr, VideoEncoder ve); ++ int android_recorder_setAudioEncoder(struct MediaRecorderWrapper *mr, AudioEncoder ae); ++ int android_recorder_setOutputFile(struct MediaRecorderWrapper *mr, int fd); ++ int android_recorder_setVideoSize(struct MediaRecorderWrapper *mr, int width, int height); ++ int android_recorder_setVideoFrameRate(struct MediaRecorderWrapper *mr, int frames_per_second); ++ int android_recorder_setParameters(struct MediaRecorderWrapper *mr, const char* parameters); ++ int android_recorder_start(struct MediaRecorderWrapper *mr); ++ int android_recorder_stop(struct MediaRecorderWrapper *mr); ++ int android_recorder_prepare(struct MediaRecorderWrapper *mr); ++ int android_recorder_reset(struct MediaRecorderWrapper *mr); ++ int android_recorder_close(struct MediaRecorderWrapper *mr); ++ int android_recorder_release(struct MediaRecorderWrapper *mr); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/surface_texture_client_hybris.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ */ ++ ++#ifndef SURFACE_TEXTURE_CLIENT_HYBRIS_H_ ++#define SURFACE_TEXTURE_CLIENT_HYBRIS_H_ ++ ++#include ++#include ++ ++#include ++ ++#ifdef __ARM_PCS_VFP ++#define FP_ATTRIB __attribute__((pcs("aapcs"))) ++#else ++#define FP_ATTRIB ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ // Taken from native_window.h ++ enum { ++ WINDOW_FORMAT_RGBA_8888 = 1, ++ WINDOW_FORMAT_RGBX_8888 = 2, ++ WINDOW_FORMAT_RGB_565 = 4, ++ }; ++ ++ typedef void* SurfaceTextureClientHybris; ++ ++ //SurfaceTextureClientHybris surface_texture_client_get_instance(); ++ SurfaceTextureClientHybris surface_texture_client_create(EGLNativeWindowType native_window); ++ SurfaceTextureClientHybris surface_texture_client_create_by_id(unsigned int texture_id); ++ uint8_t surface_texture_client_is_ready_for_rendering(SurfaceTextureClientHybris stc); ++ uint8_t surface_texture_client_hardware_rendering(SurfaceTextureClientHybris stc); ++ void surface_texture_client_set_hardware_rendering(SurfaceTextureClientHybris stc, uint8_t hardware_rendering); ++ void surface_texture_client_get_transformation_matrix(SurfaceTextureClientHybris stc, float *matrix) FP_ATTRIB; ++ void surface_texture_client_update_texture(SurfaceTextureClientHybris stc); ++ void surface_texture_client_destroy(SurfaceTextureClientHybris stc); ++ void surface_texture_client_ref(SurfaceTextureClientHybris stc); ++ void surface_texture_client_unref(SurfaceTextureClientHybris stc); ++ void surface_texture_client_set_surface_texture(SurfaceTextureClientHybris stc, EGLNativeWindowType native_window); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // SURFACE_TEXTURE_CLIENT_HYBRIS_H_ +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/ui/ui_compatibility_layer.h ++++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/ui/ui_compatibility_layer.h +@@ -50,8 +50,10 @@ extern "C" { + + void* graphic_buffer_get_native_buffer(struct graphic_buffer *buffer); + ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 + void graphic_buffer_set_index(struct graphic_buffer *buffer, int index); + int graphic_buffer_get_index(struct graphic_buffer *buffer); ++#endif + + int graphic_buffer_init_check(struct graphic_buffer *buffer); + +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/input/is.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/input/is.c +@@ -28,6 +28,14 @@ + + HYBRIS_LIBRARY_INITIALIZE(is, COMPAT_LIBRARY_PATH); + ++int android_input_check_availability() ++{ ++ /* Both are defined via HYBRIS_LIBRARY_INITIALIZE */ ++ if (!is_handle) ++ hybris_is_initialize(); ++ return is_handle ? 1 : 0; ++} ++ + HYBRIS_IMPLEMENT_VOID_FUNCTION2(is, android_input_stack_initialize, + struct AndroidEventListener*, struct InputStackConfiguration*); + HYBRIS_IMPLEMENT_VOID_FUNCTION0(is, android_input_stack_start); +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/media/Makefile.am +@@ -0,0 +1,17 @@ ++lib_LTLIBRARIES = \ ++ libmedia.la ++ ++libmedia_la_SOURCES = media.c ++libmedia_la_CFLAGS = -I$(top_srcdir)/include ++if WANT_TRACE ++libmedia_la_CFLAGS += -DDEBUG ++endif ++if WANT_DEBUG ++libmedia_la_CFLAGS += -ggdb -O0 ++endif ++libmedia_la_LDFLAGS = \ ++ $(top_builddir)/common/libhybris-common.la \ ++ -version-info "1":"0":"0" ++ ++pkgconfigdir = $(libdir)/pkgconfig ++pkgconfig_DATA = libmedia.pc +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/media/libmedia.pc.in +@@ -0,0 +1,10 @@ ++prefix=@prefix@ ++exec_prefix=${prefix} ++libdir=@libdir@ ++includedir=@includedir@ ++ ++Name: hybris-media ++Description: libhybris media library ++Version: @VERSION@ ++Libs: -L${libdir} -lhybris-common -lmedia ++Cflags: -I${includedir} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/media/media.c +@@ -0,0 +1,272 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ * Ricardo Salveti de Araujo ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define COMPAT_LIBRARY_PATH "/system/lib/libmedia_compat_layer.so" ++ ++#ifdef __ARM_PCS_VFP ++#define FP_ATTRIB __attribute__((pcs("aapcs"))) ++#else ++#define FP_ATTRIB ++#endif ++ ++HYBRIS_LIBRARY_INITIALIZE(media, COMPAT_LIBRARY_PATH); ++ ++int media_compat_check_availability() ++{ ++ /* Both are defined via HYBRIS_LIBRARY_INITIALIZE */ ++ hybris_media_initialize(); ++ return media_handle ? 1 : 0; ++} ++ ++HYBRIS_IMPLEMENT_FUNCTION0(media, struct MediaPlayerWrapper*, ++ android_media_new_player); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, android_media_update_surface_texture, ++ struct MediaPlayerWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_media_play, ++ struct MediaPlayerWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_media_pause, ++ struct MediaPlayerWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_media_stop, ++ struct MediaPlayerWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, bool, android_media_is_playing, ++ struct MediaPlayerWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_seek_to, ++ struct MediaPlayerWrapper*, int); ++ ++// Setters ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_set_data_source, ++ struct MediaPlayerWrapper*, const char*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_set_preview_texture, ++ struct MediaPlayerWrapper*, int); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_set_volume, ++ struct MediaPlayerWrapper*, int); ++ ++// Getters ++HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, android_media_surface_texture_get_transformation_matrix, ++ struct MediaPlayerWrapper*, float*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_get_current_position, ++ struct MediaPlayerWrapper*, int*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_get_duration, ++ struct MediaPlayerWrapper*, int*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_get_volume, ++ struct MediaPlayerWrapper*, int*); ++ ++// Callbacks ++HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_video_size_cb, ++ struct MediaPlayerWrapper*, on_msg_set_video_size, void*); ++HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_video_texture_needs_update_cb, ++ struct MediaPlayerWrapper*, on_video_texture_needs_update, void*); ++HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_error_cb, ++ struct MediaPlayerWrapper*, on_msg_error, void*); ++HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_playback_complete_cb, ++ struct MediaPlayerWrapper*, on_playback_complete, void*); ++HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_media_prepared_cb, ++ struct MediaPlayerWrapper*, on_media_prepared, void*); ++ ++// Media Codecs ++HYBRIS_IMPLEMENT_FUNCTION1(media, MediaCodecDelegate, ++ media_codec_create_by_codec_name, const char*); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_delegate_destroy, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_delegate_ref, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_delegate_unref, ++ MediaCodecDelegate); ++ ++#ifdef SIMPLE_PLAYER ++HYBRIS_IMPLEMENT_FUNCTION4(media, int, media_codec_configure, ++ MediaCodecDelegate, MediaFormat, void*, uint32_t); ++#else ++HYBRIS_IMPLEMENT_FUNCTION4(media, int, media_codec_configure, ++ MediaCodecDelegate, MediaFormat, SurfaceTextureClientHybris, uint32_t); ++#endif ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, media_codec_set_surface_texture_client, ++ MediaCodecDelegate, SurfaceTextureClientHybris); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, media_codec_queue_csd, ++ MediaCodecDelegate, MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_start, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_stop, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_release, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_flush, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_FUNCTION1(media, size_t, media_codec_get_input_buffers_size, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_FUNCTION2(media, uint8_t*, media_codec_get_nth_input_buffer, ++ MediaCodecDelegate, size_t); ++HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_get_nth_input_buffer_capacity, ++ MediaCodecDelegate, size_t); ++HYBRIS_IMPLEMENT_FUNCTION1(media, size_t, media_codec_get_output_buffers_size, ++ MediaCodecDelegate); ++HYBRIS_IMPLEMENT_FUNCTION2(media, uint8_t*, media_codec_get_nth_output_buffer, ++ MediaCodecDelegate, size_t); ++HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_get_nth_output_buffer_capacity, ++ MediaCodecDelegate, size_t); ++HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_dequeue_output_buffer, ++ MediaCodecDelegate, MediaCodecBufferInfo*, int64_t); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, media_codec_queue_input_buffer, ++ MediaCodecDelegate, const MediaCodecBufferInfo*); ++HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_dequeue_input_buffer, ++ MediaCodecDelegate, size_t*, int64_t); ++HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_release_output_buffer, ++ MediaCodecDelegate, size_t, uint8_t); ++HYBRIS_IMPLEMENT_FUNCTION1(media, MediaFormat, media_codec_get_output_format, ++ MediaCodecDelegate); ++ ++HYBRIS_IMPLEMENT_FUNCTION3(media, ssize_t, media_codec_list_find_codec_by_type, ++ const char*, bool, size_t); ++HYBRIS_IMPLEMENT_FUNCTION1(media, ssize_t, media_codec_list_find_codec_by_name, ++ const char *); ++HYBRIS_IMPLEMENT_FUNCTION0(media, size_t, media_codec_list_count_codecs); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_list_get_codec_info_at_id, ++ size_t); ++HYBRIS_IMPLEMENT_FUNCTION1(media, const char*, media_codec_list_get_codec_name, ++ size_t); ++HYBRIS_IMPLEMENT_FUNCTION1(media, bool, media_codec_list_is_encoder, ++ size_t); ++HYBRIS_IMPLEMENT_FUNCTION1(media, size_t, media_codec_list_get_num_supported_types, ++ size_t); ++HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_list_get_nth_supported_type_len, ++ size_t, size_t); ++HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_list_get_nth_supported_type, ++ size_t, char *, size_t); ++HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_list_get_num_profile_levels, ++ size_t, const char*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_list_get_num_color_formats, ++ size_t, const char*); ++HYBRIS_IMPLEMENT_FUNCTION4(media, int, media_codec_list_get_nth_codec_profile_level, ++ size_t, const char*, profile_level*, size_t); ++HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_list_get_codec_color_formats, ++ size_t, const char*, uint32_t*); ++ ++HYBRIS_IMPLEMENT_FUNCTION5(media, MediaFormat, media_format_create_video_format, ++ const char*, int32_t, int32_t, int64_t, int32_t); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_format_destroy, ++ MediaFormat); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_format_ref, ++ MediaFormat); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_format_unref, ++ MediaFormat); ++HYBRIS_IMPLEMENT_VOID_FUNCTION4(media, media_format_set_byte_buffer, ++ MediaFormat, const char*, uint8_t*, size_t); ++HYBRIS_IMPLEMENT_FUNCTION1(media, const char*, media_format_get_mime, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int64_t, media_format_get_duration_us, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_width, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_height, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_max_input_size, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_stride, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_slice_height, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_color_format, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_left, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_right, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_top, ++ MediaFormat); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_bottom, ++ MediaFormat); ++ ++// SurfaceTextureClientHybris ++HYBRIS_IMPLEMENT_FUNCTION1(media, SurfaceTextureClientHybris, ++ surface_texture_client_create, EGLNativeWindowType); ++HYBRIS_IMPLEMENT_FUNCTION1(media, SurfaceTextureClientHybris, ++ surface_texture_client_create_by_id, unsigned int); ++HYBRIS_IMPLEMENT_FUNCTION1(media, uint8_t, ++ surface_texture_client_is_ready_for_rendering, SurfaceTextureClientHybris); ++HYBRIS_IMPLEMENT_FUNCTION1(media, uint8_t, ++ surface_texture_client_hardware_rendering, SurfaceTextureClientHybris); ++HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, surface_texture_client_set_hardware_rendering, ++ SurfaceTextureClientHybris, uint8_t); ++HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, surface_texture_client_get_transformation_matrix, ++ SurfaceTextureClientHybris, GLfloat*); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_update_texture, ++ SurfaceTextureClientHybris); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_destroy, ++ SurfaceTextureClientHybris); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_ref, ++ SurfaceTextureClientHybris); ++HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_unref, ++ SurfaceTextureClientHybris); ++HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, surface_texture_client_set_surface_texture, ++ SurfaceTextureClientHybris, EGLNativeWindowType); ++ ++// Recorder ++HYBRIS_IMPLEMENT_FUNCTION0(media, struct MediaRecorderWrapper*, ++ android_media_new_recorder); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_initCheck, ++ struct MediaRecorderWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setCamera, ++ struct MediaRecorderWrapper*, struct CameraControl*); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setVideoSource, ++ struct MediaRecorderWrapper*, VideoSource); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setAudioSource, ++ struct MediaRecorderWrapper*, AudioSource); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setOutputFormat, ++ struct MediaRecorderWrapper*, OutputFormat); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setVideoEncoder, ++ struct MediaRecorderWrapper*, VideoEncoder); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setAudioEncoder, ++ struct MediaRecorderWrapper*, AudioEncoder); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setOutputFile, ++ struct MediaRecorderWrapper*, int); ++HYBRIS_IMPLEMENT_FUNCTION3(media, int, android_recorder_setVideoSize, ++ struct MediaRecorderWrapper*, int, int); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setVideoFrameRate, ++ struct MediaRecorderWrapper*, int); ++HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setParameters, ++ struct MediaRecorderWrapper*, const char*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_start, ++ struct MediaRecorderWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_stop, ++ struct MediaRecorderWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_prepare, ++ struct MediaRecorderWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_reset, ++ struct MediaRecorderWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_close, ++ struct MediaRecorderWrapper*); ++HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_release, ++ struct MediaRecorderWrapper*); ++ ++// Recorder Callbacks ++HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_recorder_set_error_cb, ++ struct MediaRecorderWrapper *, on_recorder_msg_error, void*); +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/tests/Makefile.am ++++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/Makefile.am +@@ -7,6 +7,8 @@ bin_PROGRAMS = \ + test_sensors \ + test_input \ + test_camera \ ++ test_media \ ++ test_recorder \ + test_gps + + if HAS_ANDROID_4_2_0 +@@ -140,6 +142,28 @@ test_camera_LDADD = \ + $(top_builddir)/camera/libcamera.la \ + $(top_builddir)/input/libis.la + ++test_media_SOURCES = test_media.c ++test_media_CFLAGS = \ ++ -I$(top_srcdir)/include ++test_media_LDADD = \ ++ $(top_builddir)/common/libhybris-common.la \ ++ $(top_builddir)/egl/libEGL.la \ ++ $(top_builddir)/glesv2/libGLESv2.la \ ++ $(top_builddir)/media/libmedia.la \ ++ $(top_builddir)/sf/libsf.la ++ ++test_recorder_SOURCES = test_recorder.c ++test_recorder_CFLAGS = \ ++ -I$(top_srcdir)/include ++test_recorder_LDADD = \ ++ $(top_builddir)/common/libhybris-common.la \ ++ $(top_builddir)/egl/libEGL.la \ ++ $(top_builddir)/glesv2/libGLESv2.la \ ++ $(top_builddir)/media/libmedia.la \ ++ $(top_builddir)/camera/libcamera.la \ ++ $(top_builddir)/input/libis.la \ ++ $(top_builddir)/sf/libsf.la ++ + test_gps_SOURCES = test_gps.c + test_gps_CFLAGS = -pthread \ + -I$(top_srcdir)/include \ +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/test_media.c +@@ -0,0 +1,373 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ * Ricardo Salveti de Araujo ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum { ++ OK = 0, ++ NO_ERROR = 0, ++}; ++ ++static float DestWidth = 0.0, DestHeight = 0.0; ++// Actual video dimmensions ++static int Width = 0, Height = 0; ++ ++static GLuint gProgram; ++static GLuint gaPositionHandle, gaTexHandle, gsTextureHandle, gmTexMatrix; ++ ++static GLfloat positionCoordinates[8]; ++ ++struct MediaPlayerWrapper *player = NULL; ++ ++void calculate_position_coordinates() ++{ ++ // Assuming cropping output for now ++ float x = 1, y = 1; ++ ++ // Black borders ++ x = (float) (Width / DestWidth); ++ y = (float) (Height / DestHeight); ++ ++ // Make the larger side be 1 ++ if (x > y) { ++ y /= x; ++ x = 1; ++ } else { ++ x /= y; ++ y = 1; ++ } ++ ++ positionCoordinates[0] = -x; ++ positionCoordinates[1] = y; ++ positionCoordinates[2] = -x; ++ positionCoordinates[3] = -y; ++ positionCoordinates[4] = x; ++ positionCoordinates[5] = -y; ++ positionCoordinates[6] = x; ++ positionCoordinates[7] = y; ++} ++ ++struct ClientWithSurface ++{ ++ struct SfClient* client; ++ struct SfSurface* surface; ++}; ++ ++struct ClientWithSurface client_with_surface(bool setup_surface_with_egl) ++{ ++ struct ClientWithSurface cs; ++ ++ cs.client = sf_client_create(); ++ ++ if (!cs.client) { ++ printf("Problem creating client ... aborting now."); ++ return cs; ++ } ++ ++ static const size_t primary_display = 0; ++ ++ DestWidth = sf_get_display_width(primary_display); ++ DestHeight = sf_get_display_height(primary_display); ++ printf("Primary display width: %f, height: %f\n", DestWidth, DestHeight); ++ ++ SfSurfaceCreationParameters params = { ++ 0, ++ 0, ++ DestWidth, ++ DestHeight, ++ -1, //PIXEL_FORMAT_RGBA_8888, ++ 15000, ++ 0.5f, ++ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL ++ "MediaCompatLayerTestSurface" ++ }; ++ ++ cs.surface = sf_surface_create(cs.client, ¶ms); ++ ++ if (!cs.surface) { ++ printf("Problem creating surface ... aborting now."); ++ return cs; ++ } ++ ++ sf_surface_make_current(cs.surface); ++ ++ return cs; ++} ++ ++static const char *vertex_shader() ++{ ++ return ++ "attribute vec4 a_position; \n" ++ "attribute vec2 a_texCoord; \n" ++ "uniform mat4 m_texMatrix; \n" ++ "varying vec2 v_texCoord; \n" ++ "varying float topDown; \n" ++ "void main() \n" ++ "{ \n" ++ " gl_Position = a_position; \n" ++ " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n" ++ "} \n"; ++} ++ ++static const char *fragment_shader() ++{ ++ return ++ "#extension GL_OES_EGL_image_external : require \n" ++ "precision mediump float; \n" ++ "varying vec2 v_texCoord; \n" ++ "uniform samplerExternalOES s_texture; \n" ++ "void main() \n" ++ "{ \n" ++ " gl_FragColor = texture2D( s_texture, v_texCoord );\n" ++ "} \n"; ++} ++ ++static GLuint loadShader(GLenum shaderType, const char* pSource) ++{ ++ GLuint shader = glCreateShader(shaderType); ++ ++ if (shader) { ++ glShaderSource(shader, 1, &pSource, NULL); ++ glCompileShader(shader); ++ GLint compiled = 0; ++ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); ++ ++ if (!compiled) { ++ GLint infoLen = 0; ++ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); ++ if (infoLen) { ++ char* buf = (char*) malloc(infoLen); ++ if (buf) { ++ glGetShaderInfoLog(shader, infoLen, NULL, buf); ++ fprintf(stderr, "Could not compile shader %d:\n%s\n", ++ shaderType, buf); ++ free(buf); ++ } ++ glDeleteShader(shader); ++ shader = 0; ++ } ++ } ++ } else { ++ printf("Error, during shader creation: %i\n", glGetError()); ++ } ++ ++ return shader; ++} ++ ++static GLuint create_program(const char* pVertexSource, const char* pFragmentSource) ++{ ++ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); ++ if (!vertexShader) { ++ printf("vertex shader not compiled\n"); ++ return 0; ++ } ++ ++ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); ++ if (!pixelShader) { ++ printf("frag shader not compiled\n"); ++ return 0; ++ } ++ ++ GLuint program = glCreateProgram(); ++ if (program) { ++ glAttachShader(program, vertexShader); ++ glAttachShader(program, pixelShader); ++ glLinkProgram(program); ++ GLint linkStatus = GL_FALSE; ++ ++ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); ++ if (linkStatus != GL_TRUE) { ++ GLint bufLength = 0; ++ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); ++ if (bufLength) { ++ char* buf = (char*) malloc(bufLength); ++ if (buf) { ++ glGetProgramInfoLog(program, bufLength, NULL, buf); ++ fprintf(stderr, "Could not link program:\n%s\n", buf); ++ free(buf); ++ } ++ } ++ glDeleteProgram(program); ++ program = 0; ++ } ++ } ++ ++ return program; ++} ++ ++static int setup_video_texture(struct ClientWithSurface *cs, GLuint *preview_texture_id) ++{ ++ assert(cs != NULL); ++ assert(preview_texture_id != NULL); ++ ++ sf_surface_make_current(cs->surface); ++ ++ glGenTextures(1, preview_texture_id); ++ glClearColor(0, 0, 0, 0); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ ++ android_media_set_preview_texture(player, *preview_texture_id); ++ ++ return 0; ++} ++ ++void set_video_size_cb(int height, int width, void *context) ++{ ++ printf("Video height: %d, width: %d\n", height, width); ++ printf("Video dest height: %f, width: %f\n", DestHeight, DestWidth); ++ ++ Height = height; ++ Width = width; ++} ++ ++void media_prepared_cb(void *context) ++{ ++ printf("Media is prepared for playback.\n"); ++} ++ ++int main(int argc, char **argv) ++{ ++ if (argc < 2) { ++ printf("Usage: test_media \n"); ++ return EXIT_FAILURE; ++ } ++ ++ player = android_media_new_player(); ++ if (player == NULL) { ++ printf("Problem creating new media player.\n"); ++ return EXIT_FAILURE; ++ } ++ ++ // Set player event cb for when the video size is known: ++ android_media_set_video_size_cb(player, set_video_size_cb, NULL); ++ android_media_set_media_prepared_cb(player, media_prepared_cb, NULL); ++ ++ printf("Setting data source to: %s.\n", argv[1]); ++ ++ if (android_media_set_data_source(player, argv[1]) != OK) { ++ printf("Failed to set data source: %s\n", argv[1]); ++ return EXIT_FAILURE; ++ } ++ ++ printf("Creating EGL surface.\n"); ++ struct ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */); ++ if (!cs.surface) { ++ printf("Problem acquiring surface for preview"); ++ return EXIT_FAILURE; ++ } ++ ++ printf("Creating GL texture.\n"); ++ ++ GLuint preview_texture_id; ++ EGLDisplay disp = sf_client_get_egl_display(cs.client); ++ EGLSurface surface = sf_surface_get_egl_surface(cs.surface); ++ ++ sf_surface_make_current(cs.surface); ++ ++ if (setup_video_texture(&cs, &preview_texture_id) != OK) { ++ printf("Problem setting up GL texture for video surface.\n"); ++ return EXIT_FAILURE; ++ } ++ ++ printf("Starting video playback.\n"); ++ android_media_play(player); ++ ++ while (android_media_is_playing(player)) { ++ GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; ++ ++ const GLfloat textureCoordinates[] = { ++ 1.0f, 1.0f, ++ 0.0f, 1.0f, ++ 0.0f, 0.0f, ++ 1.0f, 0.0f ++ }; ++ ++ android_media_update_surface_texture(player); ++ ++ calculate_position_coordinates(); ++ ++ gProgram = create_program(vertex_shader(), fragment_shader()); ++ gaPositionHandle = glGetAttribLocation(gProgram, "a_position"); ++ gaTexHandle = glGetAttribLocation(gProgram, "a_texCoord"); ++ gsTextureHandle = glGetUniformLocation(gProgram, "s_texture"); ++ gmTexMatrix = glGetUniformLocation(gProgram, "m_texMatrix"); ++ ++ glClear(GL_COLOR_BUFFER_BIT); ++ ++ // Use the program object ++ glUseProgram(gProgram); ++ // Enable attributes ++ glEnableVertexAttribArray(gaPositionHandle); ++ glEnableVertexAttribArray(gaTexHandle); ++ // Load the vertex position ++ glVertexAttribPointer(gaPositionHandle, ++ 2, ++ GL_FLOAT, ++ GL_FALSE, ++ 0, ++ positionCoordinates); ++ // Load the texture coordinate ++ glVertexAttribPointer(gaTexHandle, ++ 2, ++ GL_FLOAT, ++ GL_FALSE, ++ 0, ++ textureCoordinates); ++ ++ GLfloat matrix[16]; ++ android_media_surface_texture_get_transformation_matrix(player, matrix); ++ ++ glUniformMatrix4fv(gmTexMatrix, 1, GL_FALSE, matrix); ++ ++ glActiveTexture(GL_TEXTURE0); ++ // Set the sampler texture unit to 0 ++ glUniform1i(gsTextureHandle, 0); ++ glUniform1i(gmTexMatrix, 0); ++ android_media_update_surface_texture(player); ++ glDrawArrays(GL_TRIANGLE_FAN, 0, 4); ++ //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); ++ glDisableVertexAttribArray(gaPositionHandle); ++ glDisableVertexAttribArray(gaTexHandle); ++ ++ eglSwapBuffers(disp, surface); ++ } ++ ++ android_media_stop(player); ++ ++ return EXIT_SUCCESS; ++} +--- /dev/null ++++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/test_recorder.c +@@ -0,0 +1,490 @@ ++/* ++ * Copyright (C) 2013 Canonical Ltd ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Authored by: Jim Hodapp ++ * Guenter Schwann ++ * Ricardo Salveti de Araujo ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int shot_counter = 1; ++int32_t current_zoom_level = 1; ++bool new_camera_frame_available = true; ++struct MediaRecorderWrapper *mr = 0; ++GLuint preview_texture_id = 0; ++ ++static GLuint gProgram; ++static GLuint gaPositionHandle, gaTexHandle, gsTextureHandle, gmTexMatrix; ++ ++void error_msg_cb(void* context) ++{ ++ printf("%s \n", __PRETTY_FUNCTION__); ++} ++ ++void shutter_msg_cb(void* context) ++{ ++ printf("%s \n", __PRETTY_FUNCTION__); ++} ++ ++void zoom_msg_cb(void* context, int32_t new_zoom_level) ++{ ++ printf("%s \n", __PRETTY_FUNCTION__); ++ ++ struct CameraControl* cc = (struct CameraControl*) context; ++ static int zoom; ++ current_zoom_level = new_zoom_level; ++} ++ ++void autofocus_msg_cb(void* context) ++{ ++ printf("%s \n", __PRETTY_FUNCTION__); ++} ++ ++void raw_data_cb(void* data, uint32_t data_size, void* context) ++{ ++ printf("%s: %d \n", __PRETTY_FUNCTION__, data_size); ++} ++ ++void jpeg_data_cb(void* data, uint32_t data_size, void* context) ++{ ++ printf("%s: %d \n", __PRETTY_FUNCTION__, data_size); ++ struct CameraControl* cc = (struct CameraControl*) context; ++ android_camera_start_preview(cc); ++} ++ ++void size_cb(void* ctx, int width, int height) ++{ ++ printf("Supported size: [%d,%d]\n", width, height); ++} ++ ++void preview_texture_needs_update_cb(void* ctx) ++{ ++ new_camera_frame_available = true; ++} ++ ++void on_new_input_event(struct Event* event, void* context) ++{ ++ assert(context); ++ ++ if (event->type == KEY_EVENT_TYPE && event->action == ISCL_KEY_EVENT_ACTION_UP) { ++ printf("We have got a key event: %d \n", event->details.key.key_code); ++ ++ struct CameraControl* cc = (struct CameraControl*) context; ++ ++ int ret; ++ switch (event->details.key.key_code) { ++ case ISCL_KEYCODE_VOLUME_UP: ++ printf("Starting video recording\n"); ++ ++ android_camera_unlock(cc); ++ ++ ret = android_recorder_setCamera(mr, cc); ++ if (ret < 0) { ++ printf("android_recorder_setCamera() failed\n"); ++ return; ++ } ++ //state initial / idle ++ ret = android_recorder_setAudioSource(mr, ANDROID_AUDIO_SOURCE_CAMCORDER); ++ if (ret < 0) { ++ printf("android_recorder_setAudioSource() failed\n"); ++ return; ++ } ++ ret = android_recorder_setVideoSource(mr, ANDROID_VIDEO_SOURCE_CAMERA); ++ if (ret < 0) { ++ printf("android_recorder_setVideoSource() failed\n"); ++ return; ++ } ++ //state initialized ++ ret = android_recorder_setOutputFormat(mr, ANDROID_OUTPUT_FORMAT_MPEG_4); ++ if (ret < 0) { ++ printf("android_recorder_setOutputFormat() failed\n"); ++ return; ++ } ++ //state DataSourceConfigured ++ ret = android_recorder_setAudioEncoder(mr, ANDROID_AUDIO_ENCODER_AAC); ++ if (ret < 0) { ++ printf("android_recorder_setAudioEncoder() failed\n"); ++ return; ++ } ++ ret = android_recorder_setVideoEncoder(mr, ANDROID_VIDEO_ENCODER_H264); ++ if (ret < 0) { ++ printf("android_recorder_setVideoEncoder() failed\n"); ++ return; ++ } ++ ++ int fd; ++ fd = open("/tmp/test_video_recorder.avi", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); ++ if (fd < 0) { ++ printf("Could not open file for video recording\n"); ++ printf("FD: %i\n", fd); ++ return; ++ } ++ ret = android_recorder_setOutputFile(mr, fd); ++ if (ret < 0) { ++ printf("android_recorder_setOutputFile() failed\n"); ++ return; ++ } ++ ++ ret = android_recorder_setVideoSize(mr, 1280, 720); ++ if (ret < 0) { ++ printf("android_recorder_setVideoSize() failed\n"); ++ return; ++ } ++ ret = android_recorder_setVideoFrameRate(mr, 30); ++ if (ret < 0) { ++ printf("android_recorder_setVideoFrameRate() failed\n"); ++ return; ++ } ++ ++ ret = android_recorder_prepare(mr); ++ if (ret < 0) { ++ printf("android_recorder_prepare() failed\n"); ++ return; ++ } ++ //state prepared ++ ret = android_recorder_start(mr); ++ if (ret < 0) { ++ printf("android_recorder_start() failed\n"); ++ return; ++ } ++ break; ++ case ISCL_KEYCODE_VOLUME_DOWN: ++ printf("Stoping video recording\n"); ++ ret = android_recorder_stop(mr); ++ ++ printf("Stoping video recording returned\n"); ++ if (ret < 0) { ++ printf("android_recorder_stop() failed\n"); ++ return; ++ } ++ printf("Stopped video recording\n"); ++ ret = android_recorder_reset(mr); ++ if (ret < 0) { ++ printf("android_recorder_reset() failed\n"); ++ return; ++ } ++ printf("Reset video recorder\n"); ++ break; ++ } ++ } ++} ++ ++struct ClientWithSurface ++{ ++ struct SfClient* client; ++ struct SfSurface* surface; ++}; ++ ++struct ClientWithSurface client_with_surface(bool setup_surface_with_egl) ++{ ++ struct ClientWithSurface cs; ++ ++ cs.client = sf_client_create(); ++ ++ if (!cs.client) { ++ printf("Problem creating client ... aborting now."); ++ return cs; ++ } ++ ++ static const size_t primary_display = 0; ++ ++ SfSurfaceCreationParameters params = { ++ 0, ++ 0, ++ sf_get_display_width(primary_display), ++ sf_get_display_height(primary_display), ++ -1, //PIXEL_FORMAT_RGBA_8888, ++ 15000, ++ 0.5f, ++ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL ++ "CameraCompatLayerTestSurface" ++ }; ++ ++ cs.surface = sf_surface_create(cs.client, ¶ms); ++ ++ if (!cs.surface) { ++ printf("Problem creating surface ... aborting now."); ++ return cs; ++ } ++ ++ sf_surface_make_current(cs.surface); ++ ++ return cs; ++} ++ ++static const char* vertex_shader() ++{ ++ return ++ "#extension GL_OES_EGL_image_external : require \n" ++ "attribute vec4 a_position; \n" ++ "attribute vec2 a_texCoord; \n" ++ "uniform mat4 m_texMatrix; \n" ++ "varying vec2 v_texCoord; \n" ++ "varying float topDown; \n" ++ "void main() \n" ++ "{ \n" ++ " gl_Position = a_position; \n" ++ " v_texCoord = a_texCoord; \n" ++ // " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n" ++ //" topDown = v_texCoord.y; \n" ++ "} \n"; ++} ++ ++static const char* fragment_shader() ++{ ++ return ++ "#extension GL_OES_EGL_image_external : require \n" ++ "precision mediump float; \n" ++ "varying vec2 v_texCoord; \n" ++ "uniform samplerExternalOES s_texture; \n" ++ "void main() \n" ++ "{ \n" ++ " gl_FragColor = texture2D( s_texture, v_texCoord );\n" ++ "} \n"; ++} ++ ++static GLuint loadShader(GLenum shaderType, const char* pSource) { ++ GLuint shader = glCreateShader(shaderType); ++ ++ if (shader) { ++ glShaderSource(shader, 1, &pSource, NULL); ++ glCompileShader(shader); ++ GLint compiled = 0; ++ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); ++ ++ if (!compiled) { ++ GLint infoLen = 0; ++ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); ++ if (infoLen) { ++ char* buf = (char*) malloc(infoLen); ++ if (buf) { ++ glGetShaderInfoLog(shader, infoLen, NULL, buf); ++ fprintf(stderr, "Could not compile shader %d:\n%s\n", ++ shaderType, buf); ++ free(buf); ++ } ++ glDeleteShader(shader); ++ shader = 0; ++ } ++ } ++ } else { ++ printf("Error, during shader creation: %i\n", glGetError()); ++ } ++ ++ return shader; ++} ++ ++static GLuint create_program(const char* pVertexSource, const char* pFragmentSource) { ++ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); ++ if (!vertexShader) { ++ printf("vertex shader not compiled\n"); ++ return 0; ++ } ++ ++ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); ++ if (!pixelShader) { ++ printf("frag shader not compiled\n"); ++ return 0; ++ } ++ ++ GLuint program = glCreateProgram(); ++ if (program) { ++ glAttachShader(program, vertexShader); ++ glAttachShader(program, pixelShader); ++ glLinkProgram(program); ++ GLint linkStatus = GL_FALSE; ++ ++ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); ++ if (linkStatus != GL_TRUE) { ++ GLint bufLength = 0; ++ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); ++ if (bufLength) { ++ char* buf = (char*) malloc(bufLength); ++ if (buf) { ++ glGetProgramInfoLog(program, bufLength, NULL, buf); ++ fprintf(stderr, "Could not link program:\n%s\n", buf); ++ free(buf); ++ } ++ } ++ glDeleteProgram(program); ++ program = 0; ++ } ++ } ++ ++ return program; ++} ++ ++int main(int argc, char** argv) ++{ ++ printf("Test application for video recording using the camera\n"); ++ printf("Recording start with volume up button. And stops with volume down.\n"); ++ printf("The result is stored to /root/test_video.avi\n\n"); ++ ++ struct CameraControlListener listener; ++ memset(&listener, 0, sizeof(listener)); ++ listener.on_msg_error_cb = error_msg_cb; ++ listener.on_msg_shutter_cb = shutter_msg_cb; ++ listener.on_msg_focus_cb = autofocus_msg_cb; ++ listener.on_msg_zoom_cb = zoom_msg_cb; ++ ++ listener.on_data_raw_image_cb = raw_data_cb; ++ listener.on_data_compressed_image_cb = jpeg_data_cb; ++ listener.on_preview_texture_needs_update_cb = preview_texture_needs_update_cb; ++ struct CameraControl* cc = android_camera_connect_to(BACK_FACING_CAMERA_TYPE, ++ &listener); ++ if (cc == NULL) { ++ printf("Problem connecting to camera"); ++ return 1; ++ } ++ ++ listener.context = cc; ++ ++ mr = android_media_new_recorder(); ++ ++ struct AndroidEventListener event_listener; ++ event_listener.on_new_event = on_new_input_event; ++ event_listener.context = cc; ++ ++ struct InputStackConfiguration input_configuration = { false, 25000 }; ++ ++ android_input_stack_initialize(&event_listener, &input_configuration); ++ android_input_stack_start(); ++ ++ android_camera_dump_parameters(cc); ++ ++ printf("Supported video sizes:\n"); ++ android_camera_enumerate_supported_video_sizes(cc, size_cb, NULL); ++ ++ int min_fps, max_fps, current_fps; ++ ++ android_camera_set_preview_size(cc, 1280, 720); ++ ++ int width, height; ++ android_camera_get_video_size(cc, &width, &height); ++ printf("Current video size: [%d,%d]\n", width, height); ++ ++ struct ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */); ++ ++ if (!cs.surface) { ++ printf("Problem acquiring surface for preview"); ++ return 1; ++ } ++ ++ EGLDisplay disp = sf_client_get_egl_display(cs.client); ++ EGLSurface surface = sf_surface_get_egl_surface(cs.surface); ++ ++ sf_surface_make_current(cs.surface); ++ ++ gProgram = create_program(vertex_shader(), fragment_shader()); ++ gaPositionHandle = glGetAttribLocation(gProgram, "a_position"); ++ gaTexHandle = glGetAttribLocation(gProgram, "a_texCoord"); ++ gsTextureHandle = glGetUniformLocation(gProgram, "s_texture"); ++ gmTexMatrix = glGetUniformLocation(gProgram, "m_texMatrix"); ++ ++ glGenTextures(1, &preview_texture_id); ++ glClearColor(1.0, 0., 0.5, 1.); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ glTexParameteri( ++ GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ glTexParameteri( ++ GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ android_camera_set_preview_texture(cc, preview_texture_id); ++ android_camera_start_preview(cc); ++ ++ GLfloat transformation_matrix[16]; ++ android_camera_get_preview_texture_transformation(cc, transformation_matrix); ++ glUniformMatrix4fv(gmTexMatrix, 1, GL_FALSE, transformation_matrix); ++ ++ printf("Started camera preview.\n"); ++ ++ while (true) { ++ /*if (new_camera_frame_available) ++ { ++ printf("Updating texture"); ++ new_camera_frame_available = false; ++ }*/ ++ static GLfloat vVertices[] = { 0.0f, 0.0f, 0.0f, // Position 0 ++ 0.0f, 0.0f, // TexCoord 0 ++ 0.0f, 1.0f, 0.0f, // Position 1 ++ 0.0f, 1.0f, // TexCoord 1 ++ 1.0f, 1.0f, 0.0f, // Position 2 ++ 1.0f, 1.0f, // TexCoord 2 ++ 1.0f, 0.0f, 0.0f, // Position 3 ++ 1.0f, 0.0f // TexCoord 3 ++ }; ++ ++ GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; ++ ++ // Set the viewport ++ // Clear the color buffer ++ glClear(GL_COLOR_BUFFER_BIT); ++ // Use the program object ++ glUseProgram(gProgram); ++ // Enable attributes ++ glEnableVertexAttribArray(gaPositionHandle); ++ glEnableVertexAttribArray(gaTexHandle); ++ // Load the vertex position ++ glVertexAttribPointer(gaPositionHandle, ++ 3, ++ GL_FLOAT, ++ GL_FALSE, ++ 5 * sizeof(GLfloat), ++ vVertices); ++ // Load the texture coordinate ++ glVertexAttribPointer(gaTexHandle, ++ 2, ++ GL_FLOAT, ++ GL_FALSE, ++ 5 * sizeof(GLfloat), ++ vVertices+3); ++ ++ glActiveTexture(GL_TEXTURE0); ++ // Set the sampler texture unit to 0 ++ glUniform1i(gsTextureHandle, 0); ++ glUniform1i(gmTexMatrix, 0); ++ android_camera_update_preview_texture(cc); ++ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); ++ glDisableVertexAttribArray(gaPositionHandle); ++ glDisableVertexAttribArray(gaTexHandle); ++ ++ eglSwapBuffers(disp, surface); ++ } ++} +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/tests/test_ui.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/test_ui.c +@@ -52,8 +52,10 @@ int main(int argc, char **argv) + graphic_buffer_lock(buffer, GRALLOC_USAGE_HW_RENDER, &vaddr); + graphic_buffer_unlock(buffer); + ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 + graphic_buffer_set_index(buffer, 11); + assert(graphic_buffer_get_index(buffer) == 11); ++#endif + + graphic_buffer_free(buffer); + +--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/ui/ui.c ++++ libhybris-0.1.0+git20131207+e452e83/hybris/ui/ui.c +@@ -48,9 +48,11 @@ HYBRIS_IMPLEMENT_FUNCTION1(ui, uint32_t, + struct graphic_buffer*); + HYBRIS_IMPLEMENT_FUNCTION1(ui, void*, graphic_buffer_get_native_buffer, + struct graphic_buffer*); ++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3 + HYBRIS_IMPLEMENT_VOID_FUNCTION2(ui, graphic_buffer_set_index, + struct graphic_buffer*, int); + HYBRIS_IMPLEMENT_FUNCTION1(ui, int, graphic_buffer_get_index, + struct graphic_buffer*); ++#endif + HYBRIS_IMPLEMENT_FUNCTION1(ui, int, graphic_buffer_init_check, + struct graphic_buffer*); diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..7bb8252 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +debian-changes diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..479337d --- /dev/null +++ b/debian/rules @@ -0,0 +1,103 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# Package names +PKG_driver := libhybris +PKG_driver_dev := libhybris-dev +PKG_driver_dbg := libhybris-dbg +PKG_version := $(shell dpkg-parsechangelog | sed -n 's/^Version: //p') +PKG_source := $(shell dpkg-parsechangelog | sed -n 's/^Source: //p') +UPS_version := $(shell echo '$(PKG_version)' | sed 's/.*://; s/-[^-]*$$//') +GIT_rev := $(shell echo '$(UPS_version)' | sed 's/.*+//') + +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +# Compiler +export CC=gcc-4.7 +export CXX=g++-4.7 + +ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) + CC :=$(DEB_HOST_GNU_TYPE)-$(CC) + CXX :=$(DEB_HOST_GNU_TYPE)-$(CXX) +endif + +# Priority of the alternatives +alt_priority := 400 + +# Directory naming schemes +PKG_dirname := $(PKG_driver)-egl +bindir := usr/bin +datadir := usr/share +libdir := usr/lib/$(DEB_HOST_MULTIARCH) +includedir := usr/include +sysconfdir := etc +PKG_libdir := $(libdir)/$(PKG_dirname) +PKG_configdir := $(PKG_libdir) +ld_so_conf_dir := $(PKG_configdir) +ld_so_conf_file := ld.so.conf +alt_ld_so_conf_file := alt_ld.so.conf +ld_so_conf_path := $(ld_so_conf_dir)/$(ld_so_conf_file) +alt_ld_so_conf_path := $(ld_so_conf_dir)/$(alt_ld_so_conf_file) + +# --remote doesn't work with github so this needs to be run from a local checkout +get-packaged-orig-source: + rm -rf $(PKG_source)-$(UPS_version) + rm -f $(PKG_source)-$(UPS_version).orig.tar.gz + git clone https://github.com/libhybris/libhybris.git $(PKG_source)-$(UPS_version) + cd $(PKG_source)-$(UPS_version) && git archive \ + --format tar \ + --prefix $(PKG_source)-$(UPS_version)/ \ + $(GIT_rev) \ + | gzip >../$(PKG_source)_$(UPS_version).orig.tar.gz + rm -rf $(PKG_source)-$(UPS_version) + +override_dh_auto_configure: +ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), armhf)) + dh_auto_configure --sourcedirectory=hybris -- --enable-wayland --enable-arch=arm --with-android-headers=/usr/include/android +else + dh_auto_configure --sourcedirectory=hybris -- --enable-wayland --enable-arch=x86 --with-android-headers=/usr/include/android +endif + +override_dh_install: + # Fill in important variables + for i in $(PKG_driver).dirs \ + $(PKG_driver).install \ + $(PKG_driver).links \ + $(PKG_driver).postinst \ + $(PKG_driver).postrm \ + $(PKG_driver).prerm; do \ + sed -e "s|#LIBDIR#|$(libdir)|g" \ + -e "s|#BINDIR#|$(bindir)|g" \ + -e "s|#SYSCONFDIR#|$(sysconfdir)|g" \ + -e "s|#LDSOCONF#|$(ld_so_conf_path)|g" \ + -e "s|#ALTLDSOCONF#|$(alt_ld_so_conf_path)|g" \ + -e "s|#ALTPRIORITY#|$(alt_priority)|g" \ + -e "s|#DATADIR#|$(datadir)|g" \ + -e "s|#PKGCONFIGDIR#|$(PKG_configdir)|g" \ + -e "s|#PKGLIBDIR#|$(PKG_libdir)|g" \ + -e "s|#DRIVERNAME#|$(PKG_driver)|g" \ + -e "s|#DRIVERSRCNAME#|$(PKG_source)|g" \ + -e "s|#VERSION#|$(PKG_version)|g" \ + -e "s|#INCLUDEDIR#|$(includedir)|g" \ + -e "s|#DEB_HOST_MULTIARCH#|$(DEB_HOST_MULTIARCH)|g" \ + debian/$$i.in > debian/$$i; \ + done + + dh_install + + # ld.so.conf + echo "/$(PKG_libdir)" > "$(CURDIR)/debian/$(PKG_driver)/$(ld_so_conf_path)" + + # empty ld.so.conf for the fake multi-arch alternative + echo "" > "$(CURDIR)/debian/$(PKG_driver)/$(alt_ld_so_conf_path)" + +override_dh_autoreconf: + NOCONFIGURE=1 dh_autoreconf ./hybris/autogen.sh + +%: + dh $@ --with quilt,autoreconf --sourcedirectory=hybris diff --git a/debian/setprop.1 b/debian/setprop.1 new file mode 100644 index 0000000..9d5ced1 --- /dev/null +++ b/debian/setprop.1 @@ -0,0 +1,21 @@ +.TH SETPROP 1 "July 1, 2013" +.SH NAME +setprop \- set property via the android property service +.SH SYNOPSIS +.B setprop +.RI "property value" +.SH DESCRIPTION +.PP +\fBsetprop\fP is an android utility to set up a property via the android property service. +.SH OPTIONS +.TP +.B property +Name of the property to be set +.TP +.B value +Value of the property (string, numbers, etc) +.SH AUTHOR +setprop is originally available in the Android AOSP project. +.PP +This manual page was written by Ricardo Salveti de Araujo , +for the Debian project (and may be used by others). diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 0000000..7423a2d --- /dev/null +++ b/debian/source/options @@ -0,0 +1 @@ +single-debian-patch diff --git a/debian/source/patch-header b/debian/source/patch-header new file mode 100644 index 0000000..245b1be --- /dev/null +++ b/debian/source/patch-header @@ -0,0 +1,10 @@ +Subject: Collected Debian patches for libhybris +Author: Ricardo Salveti de Araujo + +The libhybris package is maintained in Git rather than maintaining +patches as separate files, and separating the patches doesn't seem to +be worth the effort. They are therefore all included in this single +Debian patch. + +For full commit history and separated commits, see the packaging Git +repository.