Imported Debian patch 0.1.0+git20131207+e452e83-0ubuntu12 master debian/0.1.0+git20131207+e452e83-0ubuntu12
authorRicardo Salveti de Araujo <ricardo.salveti@canonical.com>
Thu, 20 Mar 2014 01:23:43 +0000 (22:23 -0300)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 24 Dec 2014 17:30:59 +0000 (18:30 +0100)
30 files changed:
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/getprop.1 [new file with mode: 0644]
debian/libandroid-properties-dev.install [new file with mode: 0644]
debian/libandroid-properties1.install [new file with mode: 0644]
debian/libhardware-dev.install [new file with mode: 0644]
debian/libhardware2.install [new file with mode: 0644]
debian/libhybris-common-dev.install [new file with mode: 0644]
debian/libhybris-common1.install [new file with mode: 0644]
debian/libhybris-dev.install [new file with mode: 0644]
debian/libhybris-test.install [new file with mode: 0644]
debian/libhybris-utils.install [new file with mode: 0644]
debian/libhybris-utils.manpages [new file with mode: 0644]
debian/libhybris.dirs.in [new file with mode: 0644]
debian/libhybris.install.in [new file with mode: 0644]
debian/libhybris.links.in [new file with mode: 0644]
debian/libhybris.postinst.in [new file with mode: 0644]
debian/libhybris.postrm.in [new file with mode: 0644]
debian/libhybris.prerm.in [new file with mode: 0644]
debian/libmedia-dev.install [new file with mode: 0644]
debian/libmedia1.install [new file with mode: 0644]
debian/patches/debian-changes [new file with mode: 0644]
debian/patches/series [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/setprop.1 [new file with mode: 0644]
debian/source/format [new file with mode: 0644]
debian/source/options [new file with mode: 0644]
debian/source/patch-header [new file with mode: 0644]

diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..f19cbbf
--- /dev/null
@@ -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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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
+    <deb-multi-arch>_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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <bkerensa@ubuntu.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <steve.langasek@ubuntu.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  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 <ricardo.salveti@canonical.com>  Tue, 04 Jun 2013 02:58:01 -0300
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..88605f3
--- /dev/null
@@ -0,0 +1,176 @@
+Source: libhybris
+Priority: extra
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+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 (file)
index 0000000..23dd030
--- /dev/null
@@ -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 <morphis@gravedo.de>
+License: Apache 2.0
+
+Files: hybris/include/hybris/internal/binding.h
+Copyright: 2013 Simon Busch <morphis@gravedo.de>
+           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 <carsten@merproject.org>
+           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 <m@thp.io>
+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 <carsten.munk@gmail.com>
+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 <groleo@gmail.com>
+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 <http://www.gnu.org/licenses/>.
+ .
+ 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 <Todd.Miller@courtesan.com>
+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 (file)
index 0000000..851fe9d
--- /dev/null
@@ -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 <ricardo.salveti@canonical.com>,
+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 (file)
index 0000000..25ed677
--- /dev/null
@@ -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 (file)
index 0000000..5640d04
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/*/libandroid-properties.so.*
diff --git a/debian/libhardware-dev.install b/debian/libhardware-dev.install
new file mode 100644 (file)
index 0000000..cfbd33f
--- /dev/null
@@ -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 (file)
index 0000000..44f5dca
--- /dev/null
@@ -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 (file)
index 0000000..612e3e7
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/*/libhybris-common.so
diff --git a/debian/libhybris-common1.install b/debian/libhybris-common1.install
new file mode 100644 (file)
index 0000000..148cf34
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/*/libhybris-common.so.*
diff --git a/debian/libhybris-dev.install b/debian/libhybris-dev.install
new file mode 100644 (file)
index 0000000..6c428c8
--- /dev/null
@@ -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 (file)
index 0000000..04baf6a
--- /dev/null
@@ -0,0 +1 @@
+usr/bin/test_*
diff --git a/debian/libhybris-utils.install b/debian/libhybris-utils.install
new file mode 100644 (file)
index 0000000..552d1c9
--- /dev/null
@@ -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 (file)
index 0000000..6cb23c0
--- /dev/null
@@ -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 (file)
index 0000000..1d78224
--- /dev/null
@@ -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 (file)
index 0000000..d20f0bc
--- /dev/null
@@ -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 (file)
index 0000000..12590e7
--- /dev/null
@@ -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 (file)
index 0000000..da45afb
--- /dev/null
@@ -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 (file)
index 0000000..f975b6f
--- /dev/null
@@ -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:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
+# 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 (file)
index 0000000..16d94e5
--- /dev/null
@@ -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 (file)
index 0000000..d75bd81
--- /dev/null
@@ -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 (file)
index 0000000..a1562da
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/*/libmedia.so.*
diff --git a/debian/patches/debian-changes b/debian/patches/debian-changes
new file mode 100644 (file)
index 0000000..96cd18e
--- /dev/null
@@ -0,0 +1,7670 @@
+Subject: Collected Debian patches for libhybris
+Author: Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
+
+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 <binder/ProcessState.h>
+ #include <camera/Camera.h>
+ #include <camera/CameraParameters.h>
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
+ #include <gui/SurfaceTexture.h>
++#else
++#include <gui/GLConsumer.h>
++#endif
+ #include <ui/GraphicBuffer.h>
++#include <GLES2/gl2.h>
++#include <GLES2/gl2ext.h>
++
+ #undef LOG_TAG
+ #define LOG_TAG "CameraCompatibilityLayer"
+ #include <utils/KeyedVector.h>
+ #include <utils/Log.h>
++#include <utils/String16.h>
+ #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<android::NativeBufferAlloc> native_alloc(
+                       new android::NativeBufferAlloc()
+                       );
+       android::sp<android::BufferQueue> 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<android::SurfaceTexture>(
+                               new android::SurfaceTexture(
++#else
++              control->preview_texture = android::sp<android::GLConsumer>(
++                              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<android::SurfaceTexture::FrameAvailableListener>(control));
++#else
++                      android::sp<android::GLConsumer::FrameAvailableListener>(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 <utils/Log.h>
++
++#include "SimplePlayer.h"
++
++#include <gui/Surface.h>
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
++#include <gui/SurfaceTextureClient.h>
++#endif
++#include <media/AudioTrack.h>
++#include <media/ICrypto.h>
++#include <media/stagefright/foundation/ABuffer.h>
++#include <media/stagefright/foundation/ADebug.h>
++#include <media/stagefright/foundation/AMessage.h>
++#include <media/stagefright/MediaCodec.h>
++#include <media/stagefright/MediaErrors.h>
++#include <media/stagefright/NativeWindowWrapper.h>
++#include <media/stagefright/NuMediaExtractor.h>
++
++#define USE_MEDIA_CODEC_LAYER
++
++namespace android {
++
++SimplePlayer::SimplePlayer()
++    : mState(UNINITIALIZED),
++      mDoMoreStuffGeneration(0),
++      mStartTimeRealUs(-1ll) {
++}
++
++SimplePlayer::~SimplePlayer() {
++}
++
++// static
++status_t PostAndAwaitResponse(
++        const sp<AMessage> &msg, sp<AMessage> *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<AMessage> msg = new AMessage(kWhatSetDataSource, id());
++    msg->setString("path", path);
++    sp<AMessage> response;
++    return PostAndAwaitResponse(msg, &response);
++}
++
++status_t SimplePlayer::setSurface(const sp<ISurfaceTexture> &surfaceTexture) {
++    sp<AMessage> msg = new AMessage(kWhatSetSurface, id());
++
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
++    sp<SurfaceTextureClient> surfaceTextureClient;
++    if (surfaceTexture != NULL) {
++        surfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
++    }
++#else
++    sp<Surface> surfaceTextureClient;
++    if (surfaceTexture != NULL) {
++        surfaceTextureClient = new Surface(surfaceTexture);
++    }
++#endif
++
++    msg->setObject(
++            "native-window", new NativeWindowWrapper(surfaceTextureClient));
++
++    sp<AMessage> response;
++    return PostAndAwaitResponse(msg, &response);
++}
++
++status_t SimplePlayer::prepare() {
++    sp<AMessage> msg = new AMessage(kWhatPrepare, id());
++    sp<AMessage> response;
++    return PostAndAwaitResponse(msg, &response);
++}
++
++status_t SimplePlayer::start() {
++    printf("%s\n", __PRETTY_FUNCTION__);
++    sp<AMessage> msg = new AMessage(kWhatStart, id());
++    sp<AMessage> response;
++    return PostAndAwaitResponse(msg, &response);
++}
++
++status_t SimplePlayer::stop() {
++    sp<AMessage> msg = new AMessage(kWhatStop, id());
++    sp<AMessage> response;
++    return PostAndAwaitResponse(msg, &response);
++}
++
++status_t SimplePlayer::reset() {
++    sp<AMessage> msg = new AMessage(kWhatReset, id());
++    sp<AMessage> response;
++    return PostAndAwaitResponse(msg, &response);
++}
++
++void SimplePlayer::onMessageReceived(const sp<AMessage> &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<AMessage> response = new AMessage;
++            response->setInt32("err", err);
++            response->postReply(replyID);
++            break;
++        }
++
++        case kWhatSetSurface:
++        {
++            status_t err;
++            if (mState != UNPREPARED) {
++                err = INVALID_OPERATION;
++            } else {
++                sp<RefBase> obj;
++                CHECK(msg->findObject("native-window", &obj));
++
++                mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
++
++                err = OK;
++            }
++
++            uint32_t replyID;
++            CHECK(msg->senderAwaitsResponse(&replyID));
++
++            sp<AMessage> 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<AMessage> 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<AMessage> 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<AMessage> 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<AMessage> 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<AMessage> 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<ABuffer> 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<ABuffer> 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; i<nInputBuffers; i++)
++        {
++            uint8_t *data = media_codec_get_nth_input_buffer(state->mCodecDelegate, 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<ABuffer> 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<ABuffer> &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<ABuffer> &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<AMessage> 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<ABuffer> &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<ABuffer> &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<AMessage> 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<ABuffer> &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 <media/stagefright/foundation/AHandler.h>
++#include <media/stagefright/foundation/AString.h>
++#include <utils/KeyedVector.h>
++
++#include <hybris/media/media_codec_layer.h>
++
++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<ISurfaceTexture> &surfaceTexture);
++#else
++    status_t setSurface(const sp<IGraphicBufferProducer> &surfaceTexture);
++#endif
++    status_t prepare();
++    status_t start();
++    status_t stop();
++    status_t reset();
++
++protected:
++    virtual ~SimplePlayer();
++
++    virtual void onMessageReceived(const sp<AMessage> &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<MediaCodec> mCodec;
++        MediaCodecDelegate mCodecDelegate;
++        Vector<sp<ABuffer> > mCSD;
++        Vector<sp<ABuffer> > mBuffers[2];
++
++        List<size_t> mAvailInputBufferIndices;
++        List<BufferInfo> mAvailOutputBufferInfos;
++
++        sp<AudioTrack> mAudioTrack;
++        uint32_t mNumFramesWritten;
++    };
++
++    State mState;
++    AString mPath;
++    sp<NativeWindowWrapper> mNativeWindow;
++
++    sp<NuMediaExtractor> mExtractor;
++    sp<ALooper> mCodecLooper;
++    KeyedVector<size_t, CodecState> 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<ABuffer> &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 <utils/Log.h>
++
++#include "SimplePlayer.h"
++
++#include <binder/IServiceManager.h>
++#include <binder/ProcessState.h>
++#include <media/ICrypto.h>
++#include <media/IMediaPlayerService.h>
++#include <media/stagefright/foundation/ABuffer.h>
++#include <media/stagefright/foundation/ADebug.h>
++#include <media/stagefright/foundation/ALooper.h>
++#include <media/stagefright/foundation/AMessage.h>
++#include <media/stagefright/foundation/AString.h>
++#include <media/stagefright/DataSource.h>
++#include <media/stagefright/MediaCodec.h>
++#include <media/stagefright/MediaCodecList.h>
++#include <media/stagefright/MediaDefs.h>
++#include <media/stagefright/NuMediaExtractor.h>
++#include <gui/ISurfaceComposer.h>
++#include <gui/SurfaceComposerClient.h>
++#include <ui/DisplayInfo.h>
++
++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<MediaCodec> mCodec;
++    Vector<sp<ABuffer> > mInBuffers;
++    Vector<sp<ABuffer> > mOutBuffers;
++    bool mSignalledInputEOS;
++    bool mSawOutputEOS;
++    int64_t mNumBuffersDecoded;
++    int64_t mNumBytesDecoded;
++    bool mIsAudio;
++};
++
++}  // namespace android
++
++static int decode(
++        const android::sp<android::ALooper> &looper,
++        const char *path,
++        bool useAudio,
++        bool useVideo,
++        const android::sp<android::Surface> &surface) {
++    using namespace android;
++
++    static int64_t kTimeout = 500ll;
++
++    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
++    if (extractor->setDataSource(path) != OK) {
++        fprintf(stderr, "unable to instantiate extractor.\n");
++        return 1;
++    }
++
++    KeyedVector<size_t, CodecState> stateByTrack;
++
++    bool haveAudio = false;
++    bool haveVideo = false;
++    for (size_t i = 0; i < extractor->countTracks(); ++i) {
++        sp<AMessage> 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<MediaCodec> 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<ABuffer> &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<AMessage> 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<ALooper> looper = new ALooper;
++    looper->start();
++
++    sp<SurfaceComposerClient> composerClient;
++    sp<SurfaceControl> control;
++    sp<Surface> surface;
++
++    if (playback || (useSurface && useVideo)) {
++        composerClient = new SurfaceComposerClient;
++        CHECK_EQ(composerClient->initCheck(), (status_t)OK);
++
++        sp<IBinder> 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<SimplePlayer> 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 <jim.hodapp@canonical.com>
++ *              Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
++ */
++
++#include <hybris/media/media_compatibility_layer.h>
++#include "direct_media_test.h"
++
++#include <utils/Errors.h>
++
++#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
++
++#include <GLES2/gl2.h>
++#include <GLES2/gl2ext.h>
++
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <fcntl.h>
++#include <unistd.h>
++
++#include <cassert>
++#include <cstdio>
++#include <cstdlib>
++#include <cstring>
++
++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, &params);
++
++      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 <video_to_play>\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 <jim.hodapp@canonical.com>
++ */
++
++#ifndef DIRECT_MEDIA_TEST_H_
++#define DIRECT_MEDIA_TEST_H_
++
++#include <EGL/egl.h>
++#include <GLES2/gl2.h>
++#include <utils/threads.h>
++
++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 <jim.hodapp@canonical.com>
++ */
++
++// Uncomment to enable verbose debug output
++#define LOG_NDEBUG 0
++
++#undef LOG_TAG
++#define LOG_TAG "MediaCodecLayer"
++
++#include <hybris/media/media_codec_layer.h>
++#include <hybris/media/media_compatibility_layer.h>
++#include <hybris/media/media_format_layer.h>
++
++#include "media_format_layer_priv.h"
++#include "surface_texture_client_hybris_priv.h"
++
++#include <fcntl.h>
++#include <sys/stat.h>
++
++#include <binder/ProcessState.h>
++
++#include <media/stagefright/foundation/AHandler.h>
++#include <media/stagefright/foundation/AString.h>
++#include <media/ICrypto.h>
++#include <media/stagefright/foundation/ABuffer.h>
++#include <media/stagefright/foundation/ADebug.h>
++#include <media/stagefright/foundation/AMessage.h>
++#include <media/stagefright/MediaCodec.h>
++#include <media/stagefright/MediaErrors.h>
++#include <media/stagefright/NativeWindowWrapper.h>
++
++#include <utils/Vector.h>
++#include <utils/Log.h>
++#include <utils/RefBase.h>
++
++#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<AMessage> &msg) { }
++
++public:
++    sp<MediaCodec> media_codec;
++    sp<ALooper> looper;
++
++    Vector<sp<ABuffer> > input_buffers;
++    Vector<sp<ABuffer> > output_buffers;
++    List<MediaCodecBufferInfo> available_output_buffer_infos;
++    List<size_t> 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<AMessage> 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> surfaceTextureClient = static_cast<SurfaceTextureClient*>(nativeWindow);
++#else
++    sp<Surface> surfaceTextureClient = static_cast<Surface*>(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<sp<ABuffer> > input_bufs[1];
++    err = d->media_codec->getInputBuffers(&input_bufs[0]);
++    CHECK_EQ(err, static_cast<status_t>(OK));
++
++    for (size_t i=0; i<2; ++i)
++    {
++        const sp<ABuffer> &srcBuffer = format_priv->csd;
++
++        size_t index = 0;
++        err = d->media_codec->dequeueInputBuffer(&index, -1ll);
++        CHECK_EQ(err, static_cast<status_t>(OK));
++
++        const sp<ABuffer> &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<status_t>(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<sp<ABuffer> > 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<AMessage> 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 <jim.hodapp@canonical.com>
++ */
++
++// Uncomment to enable verbose debug output
++#define LOG_NDEBUG 0
++
++#undef LOG_TAG
++#define LOG_TAG "MediaCodecList"
++
++#include <hybris/media/media_codec_list.h>
++
++#include <media/stagefright/foundation/AString.h>
++#include <media/stagefright/MediaCodecList.h>
++
++#include <utils/Log.h>
++#include <utils/Vector.h>
++
++#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<AString> 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<AString> 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<AString> types;
++    status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types);
++    for (size_t i=0; i<types[n].size(); ++i)
++        type[i] = types.itemAt(n).c_str()[i];
++
++    return err;
++}
++
++static void media_codec_list_get_num_codec_capabilities(size_t index, const char *type, size_t *num_profile_levels, size_t *num_color_formats)
++{
++    REPORT_FUNCTION()
++
++    Vector<MediaCodecList::ProfileLevel> profile_levels;
++    Vector<uint32_t> 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<MediaCodecList::ProfileLevel> profile_levels;
++    Vector<uint32_t> 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<MediaCodecList::ProfileLevel> profile_levels;
++    Vector<uint32_t> 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<formats.size(); ++i)
++    {
++        color_formats[i] = formats[i];
++        ALOGD("Color format [%d]: %d", i, formats[i]);
++    }
++
++    return OK;
++}
+--- /dev/null
++++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_compatibility_layer.cpp
+@@ -0,0 +1,660 @@
++/*
++ * 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 <jim.hodapp@canonical.com>
++ *              Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
++ */
++
++// Uncomment to enable verbose debug output
++#define LOG_NDEBUG 0
++
++#undef LOG_TAG
++#define LOG_TAG "MediaCompatibilityLayer"
++
++#include <hybris/media/media_compatibility_layer.h>
++
++#include <fcntl.h>
++#include <sys/stat.h>
++
++#include <media/mediaplayer.h>
++
++#include <binder/ProcessState.h>
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
++#include <gui/SurfaceTexture.h>
++#else
++#include <gui/GLConsumer.h>
++#endif
++
++#include <GLES2/gl2.h>
++#include <GLES2/gl2ext.h>
++
++#include <ui/GraphicBuffer.h>
++
++#include <utils/Log.h>
++
++#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
++
++namespace android
++{
++NativeBufferAlloc::NativeBufferAlloc() {
++}
++
++NativeBufferAlloc::~NativeBufferAlloc() {
++}
++
++sp<GraphicBuffer> NativeBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
++                      PixelFormat format, uint32_t usage, status_t* error) {
++      sp<GraphicBuffer> 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<android::SurfaceTexture> &surfaceTexture)
++#else
++              android::status_t setVideoSurfaceTexture(android::sp<android::BufferQueue> bq, const android::sp<android::GLConsumer> &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<android::SurfaceTexture> texture;
++#else
++              android::sp<android::GLConsumer> texture;
++#endif
++              android::sp<MediaPlayerListenerWrapper> media_player_listener;
++              android::sp<FrameAvailableListener> 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<android::NativeBufferAlloc> native_alloc(
++                      new android::NativeBufferAlloc()
++                      );
++
++      android::sp<android::BufferQueue> 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<android::SurfaceTexture>(
++                              new android::SurfaceTexture(
++#else
++      mp->setVideoSurfaceTexture(buffer_queue, android::sp<android::GLConsumer>(
++                              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 <jim.hodapp@canonical.com>
++ */
++
++// Uncomment to enable verbose debug output
++#define LOG_NDEBUG 0
++
++#undef LOG_TAG
++#define LOG_TAG "MediaFormatLayer"
++
++#include <hybris/media/media_format_layer.h>
++#include "media_format_layer_priv.h"
++
++#include <assert.h>
++
++#include <utils/Log.h>
++
++#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<ABuffer>(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 <jim.hodapp@canonical.com>
++ */
++
++#include <stddef.h>
++#include <unistd.h>
++
++#include <media/stagefright/foundation/AString.h>
++
++#include <utils/RefBase.h>
++
++#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 <jim.hodapp@canonical.com>
++ */
++
++#ifndef MEDIA_FORMAT_LAYER_PRIV_H_
++#define MEDIA_FORMAT_LAYER_PRIV_H_
++
++#include <stddef.h>
++#include <unistd.h>
++
++#include <media/stagefright/foundation/AString.h>
++#include <media/stagefright/foundation/ABuffer.h>
++
++#include <utils/RefBase.h>
++
++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<android::ABuffer> 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 <jim.hodapp@canonical.com>
++ *              Guenter Schwann <guenter.schwann@canonical.com>
++ *              Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
++ */
++
++#include <hybris/internal/camera_control.h>
++#include <hybris/media/recorder_compatibility_layer.h>
++
++#include <camera/Camera.h>
++#include <camera/ICamera.h>
++#include <media/mediarecorder.h>
++
++//#define LOG_NDEBUG 0
++#undef LOG_TAG
++#define LOG_TAG "MediaRecorderCompatibilityLayer"
++#include <utils/KeyedVector.h>
++#include <utils/Log.h>
++
++#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<MediaRecorderListenerWrapper> 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<int>(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<int>(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<int>(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<int>(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<int>(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 <jim.hodapp@canonical.com>
++ */
++
++// Uncomment to enable verbose debug output
++#define LOG_NDEBUG 0
++
++#undef LOG_TAG
++#define LOG_TAG "SurfaceTextureClientHybris"
++
++#include <hybris/media/surface_texture_client_hybris.h>
++#include "surface_texture_client_hybris_priv.h"
++
++#include <ui/GraphicBuffer.h>
++#include <utils/Log.h>
++#include <ui/Region.h>
++#include <gui/Surface.h>
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
++#include <gui/SurfaceTextureClient.h>
++#endif
++
++#include <GLES2/gl2.h>
++#include <GLES2/gl2ext.h>
++
++#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<BufferQueue> &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<ISurfaceTexture> &st)
++    : SurfaceTextureClient::SurfaceTextureClient(st),
++#else
++_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp<IGraphicBufferProducer> &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<ISurfaceTexture>& surface_texture)
++{
++    SurfaceTextureClient::setISurfaceTexture(surface_texture);
++#else
++void _SurfaceTextureClientHybris::setISurfaceTexture(const sp<IGraphicBufferProducer>& 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<SurfaceTexture> &surface_texture)
++#else
++static inline void set_surface(_SurfaceTextureClientHybris *stch, const sp<GLConsumer> &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<NativeBufferAlloc> native_alloc(new NativeBufferAlloc());
++
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
++    sp<BufferQueue> buffer_queue(new BufferQueue(false, NULL, native_alloc));
++    _SurfaceTextureClientHybris *stch(new _SurfaceTextureClientHybris);
++#else
++    sp<BufferQueue> 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<uint8_t>(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<bool>(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<GLfloat*>(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> surface = static_cast<Surface*>(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 <jim.hodapp@canonical.com>
++ */
++
++#include <gui/Surface.h>
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
++#include <gui/SurfaceTextureClient.h>
++#else
++#include <gui/GLConsumer.h>
++#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<android::ISurfaceTexture> &st);
++#else
++    _SurfaceTextureClientHybris(const android::sp<android::BufferQueue> &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<android::ISurfaceTexture>& surface_texture);
++#else
++    void setISurfaceTexture(const android::sp<android::IGraphicBufferProducer>& 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<android::SurfaceTexture> surface_texture;
++#else
++    android::sp<android::GLConsumer> 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 <stdio_ext.h>
+ #include <stddef.h>
+ #include <stdlib.h>
++#include <limits.h>
+ #include <malloc.h>
+ #include <string.h>
+ #include <strings.h>
+@@ -42,6 +43,10 @@
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
++#include <linux/futex.h>
++#include <sys/syscall.h>
++#include <sys/time.h>
++
+ #include <netdb.h>
+ #include <unistd.h>
+ #include <syslog.h>
+@@ -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 <stddef.h>
++/* 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; i<si->nchain; 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 <dlfcn.h>
+ #include <stddef.h>
++#include <errno.h>
+ #include <android/hardware/hardware.h>
+ #include <hybris/internal/binding.h>
+@@ -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 <camera/Camera.h>
+ #include <camera/CameraParameters.h>
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
+ #include <gui/SurfaceTexture.h>
++#else
++#include <gui/GLConsumer.h>
++#endif
+ #include <stdint.h>
+ #include <unistd.h>
+@@ -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<android::Camera> camera;
+     android::CameraParameters camera_parameters;
++#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
+     android::sp<android::SurfaceTexture> preview_texture;
+-
+-    // From android::SurfaceTexture::FrameAvailableListener
++#else
++    android::sp<android::GLConsumer> 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 <utils/misc.h>
++#include <gui/Surface.h>
+ #include <gui/SurfaceComposerClient.h>
+ #include <ui/PixelFormat.h>
+ #include <ui/Region.h>
+--- /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 <jim.hodapp@canonical.com>
++ */
++
++#ifndef MEDIA_CODEC_LAYER_H_
++#define MEDIA_CODEC_LAYER_H_
++
++#include <stdint.h>
++#include <unistd.h>
++
++#ifdef SIMPLE_PLAYER
++#include <media/stagefright/MediaCodec.h>
++#endif
++
++#include <hybris/media/media_format_layer.h>
++#include <hybris/media/surface_texture_client_hybris.h>
++
++#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 <jim.hodapp@canonical.com>
++ */
++
++#ifndef MEDIA_CODEC_LIST_PRIV_H_
++#define MEDIA_CODEC_LIST_PRIV_H_
++
++#include <stddef.h>
++#include <stdbool.h>
++#include <unistd.h>
++
++#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 <jim.hodapp@canonical.com>
++ */
++
++#ifndef MEDIA_COMPATIBILITY_LAYER_H_
++#define MEDIA_COMPATIBILITY_LAYER_H_
++
++#include <stdint.h>
++#include <unistd.h>
++#include <stdbool.h>
++
++#include <GLES2/gl2.h>
++
++#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 <jim.hodapp@canonical.com>
++ */
++
++#ifndef MEDIA_FORMAT_LAYER_H_
++#define MEDIA_FORMAT_LAYER_H_
++
++#include <stddef.h>
++#include <unistd.h>
++
++#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 <stdint.h>
++#include <unistd.h>
++#include <stdint.h>
++#include <stdbool.h>
++
++#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 <jim.hodapp@canonical.com>
++ */
++
++#ifndef SURFACE_TEXTURE_CLIENT_HYBRIS_H_
++#define SURFACE_TEXTURE_CLIENT_HYBRIS_H_
++
++#include <stdint.h>
++#include <unistd.h>
++
++#include <EGL/egl.h>
++
++#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 <jim.hodapp@canonical.com>
++ *              Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
++ */
++
++#include <assert.h>
++#include <dlfcn.h>
++#include <stddef.h>
++#include <stdbool.h>
++
++#include <hybris/internal/binding.h>
++#include <hybris/media/media_compatibility_layer.h>
++#include <hybris/media/recorder_compatibility_layer.h>
++#include <hybris/media/media_codec_layer.h>
++#include <hybris/media/media_codec_list.h>
++#include <hybris/media/media_format_layer.h>
++#include <hybris/media/surface_texture_client_hybris.h>
++
++#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 <jim.hodapp@canonical.com>
++ *              Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
++ */
++
++#include <hybris/media/media_compatibility_layer.h>
++#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
++
++#include <EGL/egl.h>
++#include <GLES2/gl2.h>
++#include <GLES2/gl2ext.h>
++
++#include <assert.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <stdbool.h>
++#include <limits.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++
++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, &params);
++
++      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 <video_to_play>\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 <jim.hodapp@canonical.com>
++ *              Guenter Schwann <guenter.schwann@canonical.com>
++ *              Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
++ */
++
++#include <hybris/camera/camera_compatibility_layer.h>
++#include <hybris/camera/camera_compatibility_layer_capabilities.h>
++
++#include <hybris/media/recorder_compatibility_layer.h>
++
++#include <hybris/input/input_stack_compatibility_layer.h>
++#include <hybris/input/input_stack_compatibility_layer_codes_key.h>
++#include <hybris/input/input_stack_compatibility_layer_flags_key.h>
++
++#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
++
++#include <EGL/egl.h>
++#include <GLES2/gl2.h>
++#include <GLES2/gl2ext.h>
++
++#include <assert.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <stdbool.h>
++#include <limits.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++
++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, &params);
++
++      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 (file)
index 0000000..7bb8252
--- /dev/null
@@ -0,0 +1 @@
+debian-changes
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..479337d
--- /dev/null
@@ -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 (file)
index 0000000..9d5ced1
--- /dev/null
@@ -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 <ricardo.salveti@canonical.com>,
+for the Debian project (and may be used by others).
diff --git a/debian/source/format b/debian/source/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/source/options b/debian/source/options
new file mode 100644 (file)
index 0000000..7423a2d
--- /dev/null
@@ -0,0 +1 @@
+single-debian-patch
diff --git a/debian/source/patch-header b/debian/source/patch-header
new file mode 100644 (file)
index 0000000..245b1be
--- /dev/null
@@ -0,0 +1,10 @@
+Subject: Collected Debian patches for libhybris
+Author: Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
+
+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.