Merge lp:~morphis/platform-api/add-hybris-compat-layer into lp:platform-api

Proposed by Simon Fels
Status: Needs review
Proposed branch: lp:~morphis/platform-api/add-hybris-compat-layer
Merge into: lp:platform-api
Diff against target: 14700 lines (+14058/-22)
95 files modified
CMakeLists.txt (+4/-5)
android/compat/Android.common.mk (+10/-0)
android/compat/camera/Android.mk (+58/-0)
android/compat/camera/camera_compatibility_layer.cpp (+1016/-0)
android/compat/camera/direct_camera_test.cpp (+683/-0)
android/compat/input/Android.mk (+77/-0)
android/compat/input/direct_input_test.cpp (+85/-0)
android/compat/input/input_compatibility_layer.cpp (+384/-0)
android/compat/media/Android.mk (+187/-0)
android/compat/media/SimplePlayer.cpp (+777/-0)
android/compat/media/SimplePlayer.h (+120/-0)
android/compat/media/camera_service.cpp (+52/-0)
android/compat/media/codec.cpp (+433/-0)
android/compat/media/decoding_service.cpp (+366/-0)
android/compat/media/decoding_service_priv.h (+208/-0)
android/compat/media/direct_media_test.cpp (+417/-0)
android/compat/media/direct_media_test.h (+58/-0)
android/compat/media/media_codec_layer.cpp (+879/-0)
android/compat/media/media_codec_list.cpp (+281/-0)
android/compat/media/media_compatibility_layer.cpp (+693/-0)
android/compat/media/media_format_layer.cpp (+245/-0)
android/compat/media/media_format_layer_priv.cpp (+50/-0)
android/compat/media/media_format_layer_priv.h (+68/-0)
android/compat/media/media_recorder.cpp (+747/-0)
android/compat/media/media_recorder.h (+269/-0)
android/compat/media/media_recorder_client.cpp (+333/-0)
android/compat/media/media_recorder_client.h (+81/-0)
android/compat/media/media_recorder_factory.cpp (+133/-0)
android/compat/media/media_recorder_factory.h (+72/-0)
android/compat/media/media_recorder_layer.cpp (+506/-0)
android/compat/media/media_recorder_observer.cpp (+127/-0)
android/compat/media/media_recorder_observer.h (+97/-0)
android/compat/media/surface_texture_client_hybris.cpp (+466/-0)
android/compat/media/surface_texture_client_hybris_priv.h (+138/-0)
android/compat/surface_flinger/Android.mk (+45/-0)
android/compat/surface_flinger/direct_sf_test.cpp (+233/-0)
android/compat/surface_flinger/surface_flinger_compatibility_layer.cpp (+366/-0)
android/compat/ui/Android.mk (+26/-0)
android/compat/ui/ui_compatibility_layer.cpp (+144/-0)
debian/control (+50/-11)
debian/libandroid-compat-dev.install (+10/-0)
debian/libandroid-compat1.install (+5/-0)
debian/libmedia-dev.install (+3/-0)
debian/libmedia1.install (+1/-0)
include/CMakeLists.txt (+1/-0)
include/hybris/CMakeLists.txt (+5/-0)
include/hybris/camera/CMakeLists.txt (+6/-0)
include/hybris/camera/camera_compatibility_layer.h (+156/-0)
include/hybris/camera/camera_compatibility_layer_capabilities.h (+160/-0)
include/hybris/camera/camera_compatibility_layer_configuration_translator.h (+186/-0)
include/hybris/input/CMakeLists.txt (+8/-0)
include/hybris/input/input_stack_compatibility_layer.h (+127/-0)
include/hybris/input/input_stack_compatibility_layer_codes_key.h (+266/-0)
include/hybris/input/input_stack_compatibility_layer_flags.h (+72/-0)
include/hybris/input/input_stack_compatibility_layer_flags_key.h (+190/-0)
include/hybris/input/input_stack_compatibility_layer_flags_motion.h (+149/-0)
include/hybris/media/CMakeLists.txt (+11/-0)
include/hybris/media/decoding_service.h (+39/-0)
include/hybris/media/media_codec_layer.h (+102/-0)
include/hybris/media/media_codec_list.h (+56/-0)
include/hybris/media/media_compatibility_layer.h (+75/-0)
include/hybris/media/media_format_layer.h (+58/-0)
include/hybris/media/media_recorder_layer.h (+141/-0)
include/hybris/media/recorder_compatibility_layer.h (+126/-0)
include/hybris/media/surface_texture_client_hybris.h (+78/-0)
include/hybris/surface_flinger/CMakeLists.txt (+4/-0)
include/hybris/surface_flinger/surface_flinger_compatibility_layer.h (+85/-0)
include/hybris/ui/CMakeLists.txt (+4/-0)
include/hybris/ui/ui_compatibility_layer.h (+64/-0)
src/CMakeLists.txt (+1/-0)
src/compat/CMakeLists.txt (+6/-0)
src/compat/camera/CMakeLists.txt (+17/-0)
src/compat/camera/camera.c (+144/-0)
src/compat/camera/libcamera.pc.in (+10/-0)
src/compat/input/CMakeLists.txt (+17/-0)
src/compat/input/Makefile.am (+17/-0)
src/compat/input/is.c (+44/-0)
src/compat/input/libis.pc.in (+10/-0)
src/compat/media/CMakeLists.txt (+17/-0)
src/compat/media/Makefile.am (+17/-0)
src/compat/media/libmedia.pc.in (+10/-0)
src/compat/media/media.c (+302/-0)
src/compat/sf/CMakeLists.txt (+17/-0)
src/compat/sf/Makefile.am (+17/-0)
src/compat/sf/libsf.pc.in (+10/-0)
src/compat/sf/sf.c (+59/-0)
src/compat/ui/CMakeLists.txt (+13/-0)
src/compat/ui/ui.c (+58/-0)
src/compat/wifi/CMakeLists.txt (+17/-0)
src/compat/wifi/Makefile.am (+17/-0)
src/compat/wifi/libwifi.pc.in (+10/-0)
src/compat/wifi/wifi.c (+51/-0)
src/ubuntu/application/CMakeLists.txt (+2/-3)
src/ubuntu/hardware/CMakeLists.txt (+1/-1)
src/ubuntu/hardware/alarms/CMakeLists.txt (+2/-2)
To merge this branch: bzr merge lp:~morphis/platform-api/add-hybris-compat-layer
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Ubuntu Phablet Team Pending
Review via email: mp+281987@code.launchpad.net

Commit message

Adding Android compatibility from libhybris which should not be part of libhybris anymore as its Ubuntu specific and already dropped upstream.

Description of the change

Adding Android compatibility from libhybris which should not be part of libhybris anymore as its Ubuntu specific and already dropped upstream.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:317
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~morphis/platform-api/add-hybris-compat-layer/+merge/281987/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/platform-api-ci/455/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/platform-api-vivid-amd64-ci/68/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/platform-api-vivid-armhf-ci/68/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/platform-api-vivid-i386-ci/68/console

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/platform-api-ci/455/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Simon Fels (morphis) wrote :

CI must fail as this depends on newer libhybris/android-headers packages not yet in the overlay ppa or the xenial archive.

318. By Simon Fels

Add necessary debian packaging

319. By Simon Fels

Correct pkgconfig file references

320. By Simon Fels

Add temporary build-dep on libhybris-dev

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
321. By Simon Fels

Only depend on hybris for platforms its available on

322. By Simon Fels

Check correct variable to find out if hybris is available or not

323. By Simon Fels

Add arch specifier for android-headers too

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
324. By Simon Fels

Correct android-headers dependency

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
325. By Simon Fels

debian: only build on platforms we support

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

325. By Simon Fels

debian: only build on platforms we support

324. By Simon Fels

Correct android-headers dependency

323. By Simon Fels

Add arch specifier for android-headers too

322. By Simon Fels

Check correct variable to find out if hybris is available or not

321. By Simon Fels

Only depend on hybris for platforms its available on

320. By Simon Fels

Add temporary build-dep on libhybris-dev

319. By Simon Fels

Correct pkgconfig file references

318. By Simon Fels

Add necessary debian packaging

317. By Simon Fels

Integrate libhybris compatibility layer

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-03-25 23:01:58 +0000
3+++ CMakeLists.txt 2016-01-11 14:31:46 +0000
4@@ -60,16 +60,15 @@
5 find_package(PkgConfig)
6 pkg_check_modules(MIRCLIENT REQUIRED mirclient)
7
8-# Try to find hybris, and disable hybris from build if not found
9-find_library(Hybris
10- NAMES hybris-common
11-)
12+pkg_check_modules(HYBRIS_COMMON hybris-common)
13
14-if(NOT Hybris)
15+if(NOT HYBRIS_COMMON_FOUND)
16 message(STATUS "Notice: libhybris-common.so not found, disabling hybris support")
17 set(ENABLE_HYBRIS_IMPLEMENTATION OFF)
18 endif()
19
20+pkg_check_modules(ANDROID_HEADERS android-headers)
21+
22 include_directories(include)
23 include_directories(android/include)
24 include_directories(
25
26=== added directory 'android/compat'
27=== added file 'android/compat/Android.common.mk'
28--- android/compat/Android.common.mk 1970-01-01 00:00:00 +0000
29+++ android/compat/Android.common.mk 2016-01-11 14:31:46 +0000
30@@ -0,0 +1,10 @@
31+# define ANDROID_VERSION MAJOR, MINOR and PATCH
32+
33+ANDROID_VERSION_MAJOR := $(word 1, $(subst ., , $(PLATFORM_VERSION)))
34+ANDROID_VERSION_MINOR := $(word 2, $(subst ., , $(PLATFORM_VERSION)))
35+ANDROID_VERSION_PATCH := $(word 3, $(subst ., , $(PLATFORM_VERSION)))
36+
37+LOCAL_CFLAGS += \
38+ -DANDROID_VERSION_MAJOR=$(ANDROID_VERSION_MAJOR) \
39+ -DANDROID_VERSION_MINOR=$(ANDROID_VERSION_MINOR) \
40+ -DANDROID_VERSION_PATCH=$(ANDROID_VERSION_PATCH)
41
42=== added directory 'android/compat/camera'
43=== added file 'android/compat/camera/Android.mk'
44--- android/compat/camera/Android.mk 1970-01-01 00:00:00 +0000
45+++ android/compat/camera/Android.mk 2016-01-11 14:31:46 +0000
46@@ -0,0 +1,58 @@
47+LOCAL_PATH:= $(call my-dir)
48+include $(CLEAR_VARS)
49+include $(LOCAL_PATH)/../Android.common.mk
50+
51+HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
52+
53+LOCAL_SRC_FILES := camera_compatibility_layer.cpp
54+
55+LOCAL_MODULE := libcamera_compat_layer
56+LOCAL_MODULE_TAGS := optional
57+
58+LOCAL_C_INCLUDES := \
59+ $(HYBRIS_PATH)/include
60+
61+LOCAL_SHARED_LIBRARIES := \
62+ libcutils \
63+ libcamera_client \
64+ libutils \
65+ libbinder \
66+ libhardware \
67+ libui \
68+ libgui
69+
70+include $(BUILD_SHARED_LIBRARY)
71+
72+include $(CLEAR_VARS)
73+
74+HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
75+
76+LOCAL_SRC_FILES := direct_camera_test.cpp
77+
78+LOCAL_MODULE := direct_camera_test
79+LOCAL_MODULE_TAGS := optional
80+
81+LOCAL_C_INCLUDES := \
82+ $(HYBRIS_PATH)/include \
83+ bionic \
84+ bionic/libstdc++/include \
85+ external/gtest/include \
86+ external/stlport/stlport \
87+ external/skia/include/core \
88+
89+LOCAL_SHARED_LIBRARIES := \
90+ libis_compat_layer \
91+ libsf_compat_layer \
92+ libcamera_compat_layer \
93+ libmedia_compat_layer \
94+ libcutils \
95+ libcamera_client \
96+ libutils \
97+ libbinder \
98+ libhardware \
99+ libui \
100+ libgui \
101+ libEGL \
102+ libGLESv2
103+
104+include $(BUILD_EXECUTABLE)
105
106=== added file 'android/compat/camera/camera_compatibility_layer.cpp'
107--- android/compat/camera/camera_compatibility_layer.cpp 1970-01-01 00:00:00 +0000
108+++ android/compat/camera/camera_compatibility_layer.cpp 2016-01-11 14:31:46 +0000
109@@ -0,0 +1,1016 @@
110+/*
111+ * Copyright (C) 2013-2014 Canonical Ltd
112+ *
113+ * Licensed under the Apache License, Version 2.0 (the "License");
114+ * you may not use this file except in compliance with the License.
115+ * You may obtain a copy of the License at
116+ *
117+ * http://www.apache.org/licenses/LICENSE-2.0
118+ *
119+ * Unless required by applicable law or agreed to in writing, software
120+ * distributed under the License is distributed on an "AS IS" BASIS,
121+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122+ * See the License for the specific language governing permissions and
123+ * limitations under the License.
124+ *
125+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
126+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
127+ * Jim Hodapp <jim.hodapp@canonical.com>
128+ */
129+
130+//#define LOG_NDEBUG 0
131+
132+#include <hybris/internal/camera_control.h>
133+#include <hybris/camera/camera_compatibility_layer.h>
134+#include <hybris/camera/camera_compatibility_layer_capabilities.h>
135+#include <hybris/camera/camera_compatibility_layer_configuration_translator.h>
136+
137+#include <hybris/internal/surface_flinger_compatibility_layer_internal.h>
138+
139+#include <binder/ProcessState.h>
140+#include <camera/Camera.h>
141+#include <camera/CameraParameters.h>
142+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
143+#include <gui/SurfaceTexture.h>
144+#else
145+#include <gui/GLConsumer.h>
146+#endif
147+#if ANDROID_VERSION_MAJOR==5
148+#include <gui/IGraphicBufferProducer.h>
149+#endif
150+#include <ui/GraphicBuffer.h>
151+
152+#include <GLES2/gl2.h>
153+#include <GLES2/gl2ext.h>
154+
155+#undef LOG_TAG
156+#define LOG_TAG "CameraCompatibilityLayer"
157+#include <utils/Debug.h>
158+#include <utils/Errors.h>
159+#include <utils/KeyedVector.h>
160+#include <utils/Log.h>
161+#include <utils/String16.h>
162+
163+#include <gui/NativeBufferAlloc.h>
164+
165+#include <cstring>
166+
167+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
168+
169+using android::CompileTimeAssert; // So COMPILE_TIME_ASSERT works
170+
171+// From android::GLConsumer::FrameAvailableListener
172+#if ANDROID_VERSION_MAJOR==5 && ANDROID_VERSION_MINOR>=1
173+ void CameraControl::onFrameAvailable(const android::BufferItem& item)
174+#else
175+ void CameraControl::onFrameAvailable()
176+#endif
177+{
178+ REPORT_FUNCTION();
179+ if (listener)
180+ listener->on_preview_texture_needs_update_cb(listener->context);
181+}
182+
183+// From android::CameraListener
184+void CameraControl::notify(int32_t msg_type, int32_t ext1, int32_t ext2)
185+{
186+ REPORT_FUNCTION();
187+ printf("\text1: %d, ext2: %d \n", ext1, ext2);
188+
189+ if (!listener)
190+ return;
191+
192+ switch (msg_type) {
193+ case CAMERA_MSG_ERROR:
194+ if (listener->on_msg_error_cb)
195+ listener->on_msg_error_cb(listener->context);
196+ break;
197+ case CAMERA_MSG_SHUTTER:
198+ if (listener->on_msg_shutter_cb)
199+ listener->on_msg_shutter_cb(listener->context);
200+ break;
201+ case CAMERA_MSG_ZOOM:
202+ if (listener->on_msg_zoom_cb)
203+ listener->on_msg_zoom_cb(listener->context, ext1);
204+ break;
205+ case CAMERA_MSG_FOCUS:
206+ if (listener->on_msg_focus_cb)
207+ listener->on_msg_focus_cb(listener->context);
208+ break;
209+ default:
210+ break;
211+ }
212+}
213+
214+void CameraControl::postData(
215+ int32_t msg_type,
216+ const android::sp<android::IMemory>& data,
217+ camera_frame_metadata_t* metadata)
218+{
219+ REPORT_FUNCTION();
220+
221+ if (!listener)
222+ return;
223+
224+ switch (msg_type) {
225+ case CAMERA_MSG_RAW_IMAGE:
226+ if (listener->on_data_raw_image_cb)
227+ listener->on_data_raw_image_cb(data->pointer(), data->size(), listener->context);
228+ break;
229+ case CAMERA_MSG_COMPRESSED_IMAGE:
230+ if (listener->on_data_compressed_image_cb)
231+ listener->on_data_compressed_image_cb(data->pointer(), data->size(), listener->context);
232+ break;
233+ case CAMERA_MSG_PREVIEW_FRAME:
234+ if (listener->on_preview_frame_cb)
235+ listener->on_preview_frame_cb(data->pointer(), data->size(), listener->context);
236+ default:
237+ break;
238+ }
239+}
240+
241+void CameraControl::postDataTimestamp(
242+ nsecs_t timestamp,
243+ int32_t msg_type,
244+ const android::sp<android::IMemory>& data)
245+{
246+ REPORT_FUNCTION();
247+ (void) timestamp;
248+ (void) msg_type;
249+ (void) data;
250+}
251+
252+namespace android
253+{
254+NativeBufferAlloc::NativeBufferAlloc() {
255+}
256+
257+NativeBufferAlloc::~NativeBufferAlloc() {
258+}
259+
260+sp<GraphicBuffer> NativeBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
261+ PixelFormat format, uint32_t usage, status_t* error) {
262+ sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
263+ status_t err = graphicBuffer->initCheck();
264+ *error = err;
265+ if (err != 0 || graphicBuffer->handle == 0) {
266+ if (err == NO_MEMORY) {
267+ GraphicBuffer::dumpAllocationsToSystemLog();
268+ }
269+ ALOGI("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
270+ "failed (%s), handle=%p",
271+ w, h, strerror(-err), graphicBuffer->handle);
272+ return 0;
273+ }
274+ return graphicBuffer;
275+}
276+}
277+
278+int android_camera_get_number_of_devices()
279+{
280+ REPORT_FUNCTION();
281+ return android::Camera::getNumberOfCameras();
282+}
283+
284+int android_camera_get_device_info(int32_t camera_id, int* facing, int* orientation)
285+{
286+ REPORT_FUNCTION();
287+
288+ if (!facing || !orientation)
289+ return android::BAD_VALUE;
290+
291+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(CAMERA_FACING_BACK == static_cast<int>(BACK_FACING_CAMERA_TYPE));
292+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(CAMERA_FACING_FRONT == static_cast<int>(FRONT_FACING_CAMERA_TYPE));
293+
294+ android::CameraInfo ci;
295+
296+ int rv = android::Camera::getCameraInfo(camera_id, &ci);
297+ if (rv != android::OK)
298+ return rv;
299+
300+ *facing = ci.facing;
301+ *orientation = ci.orientation;
302+
303+ return android::OK;
304+}
305+
306+CameraControl* android_camera_connect_to(CameraType camera_type, CameraControlListener* listener)
307+{
308+ REPORT_FUNCTION();
309+
310+ const int32_t camera_count = android::Camera::getNumberOfCameras();
311+
312+ for (int32_t camera_id = 0; camera_id < camera_count; camera_id++) {
313+ android::CameraInfo ci;
314+ android::Camera::getCameraInfo(camera_id, &ci);
315+
316+ if (ci.facing != camera_type)
317+ continue;
318+
319+ return android_camera_connect_by_id(camera_id, listener);
320+ }
321+
322+ return NULL;
323+}
324+
325+CameraControl* android_camera_connect_by_id(int32_t camera_id, struct CameraControlListener* listener)
326+{
327+ if (camera_id < 0 || camera_id >= android::Camera::getNumberOfCameras())
328+ return NULL;
329+
330+ android::sp<CameraControl> cc = new CameraControl();
331+ cc->listener = listener;
332+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3 || ANDROID_VERSION_MAJOR==5
333+ cc->camera = android::Camera::connect(camera_id, android::String16("hybris"), android::Camera::USE_CALLING_UID);
334+#else
335+ cc->camera = android::Camera::connect(camera_id);
336+#endif
337+
338+ if (cc->camera == NULL)
339+ return NULL;
340+
341+ cc->camera_parameters = android::CameraParameters(cc->camera->getParameters());
342+
343+ // android::Camera holds a strong reference to the listener, keeping
344+ // |cc| alive
345+ cc->camera->setListener(cc);
346+ cc->camera->lock();
347+
348+ // TODO: Move this to a more generic component
349+ android::ProcessState::self()->startThreadPool();
350+
351+ return cc.get();
352+}
353+
354+void android_camera_disconnect(CameraControl* control)
355+{
356+ REPORT_FUNCTION();
357+ assert(control);
358+
359+ android::Mutex::Autolock al(control->guard);
360+
361+ if (control->preview_texture != NULL)
362+ control->preview_texture->abandon();
363+
364+ control->camera->disconnect();
365+ control->camera->unlock();
366+}
367+
368+int android_camera_lock(CameraControl* control)
369+{
370+ android::Mutex::Autolock al(control->guard);
371+ return control->camera->lock();
372+}
373+
374+int android_camera_unlock(CameraControl* control)
375+{
376+ android::Mutex::Autolock al(control->guard);
377+ return control->camera->unlock();
378+}
379+
380+void android_camera_delete(CameraControl* control)
381+{
382+ android::sp<android::Camera> camera = control->camera;
383+ control->camera.clear();
384+ camera.clear();
385+}
386+
387+void android_camera_dump_parameters(CameraControl* control)
388+{
389+ REPORT_FUNCTION();
390+ assert(control);
391+
392+ printf("%s \n", control->camera->getParameters().string());
393+}
394+
395+void android_camera_set_flash_mode(CameraControl* control, FlashMode mode)
396+{
397+ REPORT_FUNCTION();
398+ assert(control);
399+
400+ android::Mutex::Autolock al(control->guard);
401+ control->camera_parameters.set(
402+ android::CameraParameters::KEY_FLASH_MODE,
403+ flash_modes[mode]);
404+ control->camera->setParameters(control->camera_parameters.flatten());
405+}
406+
407+void android_camera_get_flash_mode(CameraControl* control, FlashMode* mode)
408+{
409+ REPORT_FUNCTION();
410+ assert(control);
411+
412+ android::Mutex::Autolock al(control->guard);
413+ static const char* flash_mode = control->camera_parameters.get(
414+ android::CameraParameters::KEY_FLASH_MODE);
415+ if (flash_mode)
416+ *mode = flash_modes_lut.valueFor(android::String8(flash_mode));
417+ else
418+ *mode = FLASH_MODE_OFF;
419+}
420+
421+void android_camera_enumerate_supported_flash_modes(CameraControl* control, flash_mode_callback cb, void* ctx)
422+{
423+ REPORT_FUNCTION();
424+ assert(control);
425+
426+ android::Mutex::Autolock al(control->guard);
427+ android::String8 raw_modes;
428+ raw_modes = android::String8(
429+ control->camera_parameters.get(
430+ android::CameraParameters::KEY_SUPPORTED_FLASH_MODES));
431+
432+ const char delimiter[2] = ",";
433+ char *token;
434+ android::String8 mode;
435+ char *raw_modes_mutable = strdup(raw_modes.string());
436+
437+ token = strtok(raw_modes_mutable, delimiter);
438+
439+ while (token != NULL) {
440+ uint32_t index = flash_modes_lut.indexOfKey(mode);
441+
442+ mode = android::String8(token);
443+ if (flash_modes_lut.indexOfKey(mode) >= 0) {
444+ cb(ctx, flash_modes_lut.valueFor(mode));
445+ }
446+ token = strtok(NULL, delimiter);
447+ }
448+}
449+
450+void android_camera_set_white_balance_mode(CameraControl* control, WhiteBalanceMode mode)
451+{
452+ REPORT_FUNCTION();
453+ assert(control);
454+
455+ android::Mutex::Autolock al(control->guard);
456+
457+ control->camera_parameters.set(
458+ android::CameraParameters::KEY_WHITE_BALANCE,
459+ white_balance_modes[mode]);
460+ control->camera->setParameters(control->camera_parameters.flatten());
461+}
462+
463+void android_camera_get_white_balance_mode(CameraControl* control, WhiteBalanceMode* mode)
464+{
465+ REPORT_FUNCTION();
466+ assert(control);
467+
468+ android::Mutex::Autolock al(control->guard);
469+
470+ *mode = white_balance_modes_lut.valueFor(
471+ android::String8(
472+ control->camera_parameters.get(
473+ android::CameraParameters::KEY_WHITE_BALANCE)));
474+}
475+
476+void android_camera_set_scene_mode(CameraControl* control, SceneMode mode)
477+{
478+ REPORT_FUNCTION();
479+ assert(control);
480+
481+ android::Mutex::Autolock al(control->guard);
482+
483+ control->camera_parameters.set(
484+ android::CameraParameters::KEY_SCENE_MODE,
485+ scene_modes[mode]);
486+ control->camera->setParameters(control->camera_parameters.flatten());
487+}
488+
489+void android_camera_enumerate_supported_scene_modes(CameraControl* control, scene_mode_callback cb, void* ctx)
490+{
491+ REPORT_FUNCTION();
492+ assert(control);
493+
494+ android::Mutex::Autolock al(control->guard);
495+ android::String8 raw_modes;
496+ raw_modes = android::String8(
497+ control->camera_parameters.get(
498+ android::CameraParameters::KEY_SUPPORTED_SCENE_MODES));
499+
500+ const char delimiter[2] = ",";
501+ char *token;
502+ android::String8 mode;
503+ char *raw_modes_mutable = strdup(raw_modes.string());
504+
505+ token = strtok(raw_modes_mutable, delimiter);
506+
507+ while (token != NULL) {
508+ mode = android::String8(token);
509+ cb(ctx, scene_modes_lut.valueFor(mode));
510+ token = strtok(NULL, delimiter);
511+ }
512+}
513+
514+void android_camera_get_scene_mode(CameraControl* control, SceneMode* mode)
515+{
516+ REPORT_FUNCTION();
517+ assert(control);
518+
519+ android::Mutex::Autolock al(control->guard);
520+
521+ *mode = scene_modes_lut.valueFor(
522+ android::String8(
523+ control->camera_parameters.get(
524+ android::CameraParameters::KEY_SCENE_MODE)));
525+}
526+
527+void android_camera_set_auto_focus_mode(CameraControl* control, AutoFocusMode mode)
528+{
529+ REPORT_FUNCTION();
530+ assert(control);
531+
532+ android::Mutex::Autolock al(control->guard);
533+
534+ control->camera_parameters.set(
535+ android::CameraParameters::KEY_FOCUS_MODE,
536+ auto_focus_modes[mode]);
537+ control->camera->setParameters(control->camera_parameters.flatten());
538+}
539+
540+void android_camera_get_auto_focus_mode(CameraControl* control, AutoFocusMode* mode)
541+{
542+ REPORT_FUNCTION();
543+ assert(control);
544+
545+ android::Mutex::Autolock al(control->guard);
546+
547+ *mode = auto_focus_modes_lut.valueFor(
548+ android::String8(
549+ control->camera_parameters.get(
550+ android::CameraParameters::KEY_FOCUS_MODE)));
551+}
552+
553+
554+void android_camera_set_effect_mode(CameraControl* control, EffectMode mode)
555+{
556+ REPORT_FUNCTION();
557+ assert(control);
558+
559+ android::Mutex::Autolock al(control->guard);
560+
561+ control->camera_parameters.set(
562+ android::CameraParameters::KEY_EFFECT,
563+ effect_modes[mode]);
564+ control->camera->setParameters(control->camera_parameters.flatten());
565+}
566+
567+void android_camera_get_effect_mode(CameraControl* control, EffectMode* mode)
568+{
569+ REPORT_FUNCTION();
570+ assert(control);
571+
572+ android::Mutex::Autolock al(control->guard);
573+
574+ *mode = effect_modes_lut.valueFor(
575+ android::String8(
576+ control->camera_parameters.get(
577+ android::CameraParameters::KEY_EFFECT)));
578+}
579+
580+void android_camera_get_preview_fps_range(CameraControl* control, int* min, int* max)
581+{
582+ REPORT_FUNCTION();
583+ assert(control);
584+
585+ android::Mutex::Autolock al(control->guard);
586+
587+ control->camera_parameters.getPreviewFpsRange(min, max);
588+}
589+
590+void android_camera_set_preview_fps(CameraControl* control, int fps)
591+{
592+ REPORT_FUNCTION();
593+ assert(control);
594+
595+ android::Mutex::Autolock al(control->guard);
596+ control->camera_parameters.setPreviewFrameRate(fps);
597+ control->camera->setParameters(control->camera_parameters.flatten());
598+}
599+
600+void android_camera_get_preview_fps(CameraControl* control, int* fps)
601+{
602+ REPORT_FUNCTION();
603+ assert(control);
604+
605+ android::Mutex::Autolock al(control->guard);
606+ *fps = control->camera_parameters.getPreviewFrameRate();
607+}
608+
609+void android_camera_enumerate_supported_preview_sizes(CameraControl* control, size_callback cb, void* ctx)
610+{
611+ REPORT_FUNCTION();
612+ assert(control);
613+
614+ android::Mutex::Autolock al(control->guard);
615+ android::Vector<android::Size> sizes;
616+ control->camera_parameters.getSupportedPreviewSizes(sizes);
617+
618+ for (unsigned int i = 0; i < sizes.size(); i++) {
619+ cb(ctx, sizes[i].width, sizes[i].height);
620+ }
621+}
622+
623+void android_camera_enumerate_supported_picture_sizes(CameraControl* control, size_callback cb, void* ctx)
624+{
625+ REPORT_FUNCTION();
626+ assert(control);
627+
628+ android::Mutex::Autolock al(control->guard);
629+ android::Vector<android::Size> sizes;
630+ control->camera_parameters.getSupportedPictureSizes(sizes);
631+
632+ for (unsigned int i = 0; i < sizes.size(); i++) {
633+ cb(ctx, sizes[i].width, sizes[i].height);
634+ }
635+}
636+
637+void android_camera_get_preview_size(CameraControl* control, int* width, int* height)
638+{
639+ REPORT_FUNCTION();
640+ assert(control);
641+
642+ android::Mutex::Autolock al(control->guard);
643+
644+ control->camera_parameters.getPreviewSize(width, height);
645+}
646+
647+void android_camera_set_preview_size(CameraControl* control, int width, int height)
648+{
649+ REPORT_FUNCTION();
650+ assert(control);
651+
652+ android::Mutex::Autolock al(control->guard);
653+
654+ control->camera_parameters.setPreviewSize(width, height);
655+ control->camera->setParameters(control->camera_parameters.flatten());
656+}
657+
658+void android_camera_get_picture_size(CameraControl* control, int* width, int* height)
659+{
660+ REPORT_FUNCTION();
661+ assert(control);
662+
663+ android::Mutex::Autolock al(control->guard);
664+
665+ control->camera_parameters.getPictureSize(width, height);
666+}
667+
668+void android_camera_set_thumbnail_size(struct CameraControl* control, int width, int height)
669+{
670+ REPORT_FUNCTION();
671+ assert(control);
672+
673+ android::Mutex::Autolock al(control->guard);
674+
675+ control->camera_parameters.set(
676+ android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
677+ width);
678+ control->camera_parameters.set(
679+ android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
680+ height);
681+ control->camera->setParameters(control->camera_parameters.flatten());
682+}
683+
684+void android_camera_get_thumbnail_size(struct CameraControl* control, int* width, int* height)
685+{
686+ REPORT_FUNCTION();
687+ assert(control);
688+
689+ android::Mutex::Autolock al(control->guard);
690+
691+ *width = atoi(control->camera_parameters.get(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH));
692+ *height = atoi(control->camera_parameters.get(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT));
693+}
694+
695+void android_camera_enumerate_supported_thumbnail_sizes(struct CameraControl* control, size_callback cb, void* ctx)
696+{
697+ REPORT_FUNCTION();
698+ assert(control);
699+
700+ android::Mutex::Autolock al(control->guard);
701+ // e.g. 800x600,320x240
702+ android::String8 sizes = android::String8(
703+ control->camera_parameters.get(
704+ android::CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
705+
706+ const char delimiter[2] = ",";
707+ const char size_delimiter[2] = "x";
708+ char *token, *save_ptr, *save_ptr1;
709+ int height = 0, width = 0;
710+ char *sizes_mutable = strdup(sizes.string());
711+
712+ ALOGD("Supported thumbnail sizes: %s", sizes.string());
713+ // Get the first <width>x<height to the left of ','
714+ token = strtok_r(sizes_mutable, delimiter, &save_ptr);
715+
716+ while (token != NULL) {
717+ // Parse <width>x<height> token
718+ char *w = strtok_r(token, size_delimiter, &save_ptr1);
719+ char *h = strtok_r(NULL, size_delimiter, &save_ptr1);
720+ width = atoi(w);
721+ height = atoi(h);
722+ if (width > 0 && height > 0)
723+ cb(ctx, width, height);
724+ // Get the next <width>x<height> pair
725+ token = strtok_r(NULL, delimiter, &save_ptr);
726+ }
727+}
728+
729+void android_camera_set_picture_size(CameraControl* control, int width, int height)
730+{
731+ REPORT_FUNCTION();
732+ assert(control);
733+
734+ android::Mutex::Autolock al(control->guard);
735+
736+ control->camera_parameters.setPictureSize(width, height);
737+ control->camera->setParameters(control->camera_parameters.flatten());
738+}
739+
740+void android_camera_get_current_zoom(CameraControl* control, int* zoom)
741+{
742+ REPORT_FUNCTION();
743+ assert(control);
744+
745+ android::Mutex::Autolock al(control->guard);
746+
747+ *zoom = control->camera_parameters.getInt(android::CameraParameters::KEY_ZOOM);
748+}
749+
750+void android_camera_get_max_zoom(CameraControl* control, int* zoom)
751+{
752+ REPORT_FUNCTION();
753+ assert(control);
754+
755+ android::Mutex::Autolock al(control->guard);
756+
757+ *zoom = control->camera_parameters.getInt(android::CameraParameters::KEY_MAX_ZOOM);
758+}
759+
760+void android_camera_set_display_orientation(CameraControl* control, int32_t clockwise_rotation_degree)
761+{
762+ REPORT_FUNCTION();
763+ assert(control);
764+
765+ android::Mutex::Autolock al(control->guard);
766+ static const int32_t ignored_parameter = 0;
767+ control->camera->sendCommand(CAMERA_CMD_SET_DISPLAY_ORIENTATION, clockwise_rotation_degree, ignored_parameter);
768+}
769+
770+void android_camera_get_preview_texture_transformation(CameraControl* control, float m[16])
771+{
772+ REPORT_FUNCTION();
773+ assert(control);
774+
775+ if (control->preview_texture == NULL)
776+ return;
777+
778+ control->preview_texture->getTransformMatrix(m);
779+}
780+
781+void android_camera_update_preview_texture(CameraControl* control)
782+{
783+ REPORT_FUNCTION();
784+ assert(control);
785+
786+ control->preview_texture->updateTexImage();
787+}
788+
789+void android_camera_set_preview_texture(CameraControl* control, int texture_id)
790+{
791+ REPORT_FUNCTION();
792+ assert(control);
793+
794+ static const bool allow_synchronous_mode = false;
795+ static const bool is_controlled_by_app = true;
796+
797+ android::sp<android::NativeBufferAlloc> native_alloc(
798+ new android::NativeBufferAlloc()
799+ );
800+
801+#if ANDROID_VERSION_MAJOR==5
802+ android::sp<android::IGraphicBufferProducer> producer;
803+ android::sp<android::IGraphicBufferConsumer> consumer;
804+ android::BufferQueue::createBufferQueue(&producer, &consumer);
805+#else
806+ android::sp<android::BufferQueue> buffer_queue(
807+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
808+ new android::BufferQueue(false, NULL, native_alloc)
809+#else
810+ new android::BufferQueue(NULL)
811+#endif
812+ );
813+#endif
814+
815+ if (control->preview_texture == NULL) {
816+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
817+ control->preview_texture = android::sp<android::SurfaceTexture>(
818+ new android::SurfaceTexture(
819+#else
820+ control->preview_texture = android::sp<android::GLConsumer>(
821+ new android::GLConsumer(
822+#endif
823+#if ANDROID_VERSION_MAJOR==5
824+ consumer,
825+ texture_id,
826+ GL_TEXTURE_EXTERNAL_OES,
827+ true,
828+ is_controlled_by_app));
829+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
830+ texture_id,
831+ allow_synchronous_mode,
832+ GL_TEXTURE_EXTERNAL_OES,
833+ true,
834+ buffer_queue));
835+#else
836+ buffer_queue,
837+ texture_id,
838+ GL_TEXTURE_EXTERNAL_OES,
839+ true,
840+ is_controlled_by_app));
841+#endif
842+ }
843+
844+ control->preview_texture->setFrameAvailableListener(
845+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
846+ android::sp<android::SurfaceTexture::FrameAvailableListener>(control));
847+#else
848+ android::sp<android::GLConsumer::FrameAvailableListener>(control));
849+#endif
850+
851+#if ANDROID_VERSION_MAJOR==5
852+ control->camera->setPreviewTarget(producer);
853+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
854+ control->camera->setPreviewTexture(control->preview_texture->getBufferQueue());
855+#else
856+ control->camera->setPreviewTarget(buffer_queue);
857+#endif
858+}
859+
860+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
861+void android_camera_set_preview_surface(CameraControl* control, SfSurface* surface)
862+{
863+ REPORT_FUNCTION();
864+ assert(control);
865+ assert(surface);
866+
867+ android::Mutex::Autolock al(control->guard);
868+ control->camera->setPreviewDisplay(surface->surface);
869+}
870+#endif
871+
872+void android_camera_start_preview(CameraControl* control)
873+{
874+ REPORT_FUNCTION();
875+ assert(control);
876+
877+ android::Mutex::Autolock al(control->guard);
878+ control->camera->startPreview();
879+}
880+
881+void android_camera_stop_preview(CameraControl* control)
882+{
883+ REPORT_FUNCTION();
884+ assert(control);
885+
886+ android::Mutex::Autolock al(control->guard);
887+ control->camera->stopPreview();
888+}
889+
890+void android_camera_start_autofocus(CameraControl* control)
891+{
892+ REPORT_FUNCTION();
893+ assert(control);
894+
895+ android::Mutex::Autolock al(control->guard);
896+ control->camera->autoFocus();
897+}
898+
899+void android_camera_stop_autofocus(CameraControl* control)
900+{
901+ REPORT_FUNCTION();
902+ assert(control);
903+
904+ android::Mutex::Autolock al(control->guard);
905+ control->camera->cancelAutoFocus();
906+}
907+
908+void android_camera_start_zoom(CameraControl* control, int32_t zoom)
909+{
910+ REPORT_FUNCTION();
911+ assert(control);
912+
913+ static const int ignored_argument = 0;
914+
915+ android::Mutex::Autolock al(control->guard);
916+ control->camera->sendCommand(CAMERA_CMD_START_SMOOTH_ZOOM,
917+ zoom,
918+ ignored_argument);
919+}
920+
921+// Adjust the zoom level immediately as opposed to smoothly zoomin gin.
922+void android_camera_set_zoom(CameraControl* control, int32_t zoom)
923+{
924+ REPORT_FUNCTION();
925+ assert(control);
926+
927+ android::Mutex::Autolock al(control->guard);
928+
929+ control->camera_parameters.set(
930+ android::CameraParameters::KEY_ZOOM,
931+ zoom);
932+
933+ control->camera->setParameters(control->camera_parameters.flatten());
934+}
935+
936+void android_camera_stop_zoom(CameraControl* control)
937+{
938+ REPORT_FUNCTION();
939+ assert(control);
940+
941+ static const int ignored_argument = 0;
942+
943+ android::Mutex::Autolock al(control->guard);
944+ control->camera->sendCommand(CAMERA_CMD_STOP_SMOOTH_ZOOM,
945+ ignored_argument,
946+ ignored_argument);
947+}
948+
949+void android_camera_take_snapshot(CameraControl* control)
950+{
951+ REPORT_FUNCTION();
952+ assert(control);
953+ android::Mutex::Autolock al(control->guard);
954+ control->camera->takePicture(CAMERA_MSG_SHUTTER | CAMERA_MSG_COMPRESSED_IMAGE);
955+}
956+
957+int android_camera_set_preview_callback_mode(CameraControl* control, PreviewCallbackMode mode)
958+{
959+ REPORT_FUNCTION();
960+
961+ if (!control)
962+ return android::BAD_VALUE;
963+
964+ android::Mutex::Autolock al(control->guard);
965+
966+ control->camera->setPreviewCallbackFlags(
967+ mode == PREVIEW_CALLBACK_ENABLED ?
968+ CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER : CAMERA_FRAME_CALLBACK_FLAG_NOOP);
969+
970+ return android::OK;
971+}
972+
973+void android_camera_set_preview_format(CameraControl* control, CameraPixelFormat pf)
974+{
975+ REPORT_FUNCTION();
976+ assert(control);
977+
978+ android::Mutex::Autolock al(control->guard);
979+
980+ control->camera_parameters.set(
981+ android::CameraParameters::KEY_PREVIEW_FORMAT,
982+ camera_pixel_formats[pf]);
983+
984+ control->camera->setParameters(control->camera_parameters.flatten());
985+}
986+
987+void android_camera_get_preview_format(CameraControl* control, CameraPixelFormat* pf)
988+{
989+ REPORT_FUNCTION();
990+ assert(control);
991+
992+ android::Mutex::Autolock al(control->guard);
993+
994+ *pf = pixel_formats_lut.valueFor(
995+ android::String8(
996+ control->camera_parameters.get(
997+ android::CameraParameters::KEY_PREVIEW_FORMAT)));
998+}
999+
1000+void android_camera_set_focus_region(
1001+ CameraControl* control,
1002+ FocusRegion* region)
1003+{
1004+ REPORT_FUNCTION();
1005+ assert(control);
1006+
1007+ android::Mutex::Autolock al(control->guard);
1008+ static const char* focus_region_pattern = "(%d,%d,%d,%d,%d)";
1009+ static char focus_region[256];
1010+ snprintf(focus_region,
1011+ sizeof(focus_region),
1012+ focus_region_pattern,
1013+ region->left,
1014+ region->top,
1015+ region->right,
1016+ region->bottom,
1017+ region->weight);
1018+
1019+ control->camera_parameters.set(
1020+ android::CameraParameters::KEY_FOCUS_AREAS,
1021+ focus_region);
1022+
1023+ control->camera->setParameters(control->camera_parameters.flatten());
1024+}
1025+
1026+void android_camera_reset_focus_region(CameraControl* control)
1027+{
1028+ static FocusRegion region = { 0, 0, 0, 0, 0 };
1029+
1030+ android_camera_set_focus_region(control, &region);
1031+}
1032+
1033+void android_camera_set_rotation(CameraControl* control, int rotation)
1034+{
1035+ REPORT_FUNCTION();
1036+ assert(control);
1037+
1038+ android::Mutex::Autolock al(control->guard);
1039+ control->camera_parameters.set(
1040+ android::CameraParameters::KEY_ROTATION,
1041+ rotation);
1042+ control->camera->setParameters(control->camera_parameters.flatten());
1043+}
1044+
1045+void android_camera_set_location(CameraControl* control, const float* latitude, const float* longitude, const float* altitude, int timestamp, const char* method)
1046+{
1047+ REPORT_FUNCTION();
1048+ assert(control);
1049+
1050+ android::Mutex::Autolock al(control->guard);
1051+ control->camera_parameters.setFloat(
1052+ android::CameraParameters::KEY_GPS_LATITUDE,
1053+ *latitude);
1054+ control->camera_parameters.setFloat(
1055+ android::CameraParameters::KEY_GPS_LONGITUDE,
1056+ *longitude);
1057+ control->camera_parameters.setFloat(
1058+ android::CameraParameters::KEY_GPS_ALTITUDE,
1059+ *altitude);
1060+ control->camera_parameters.set(
1061+ android::CameraParameters::KEY_GPS_TIMESTAMP,
1062+ timestamp);
1063+ control->camera_parameters.set(
1064+ android::CameraParameters::KEY_GPS_PROCESSING_METHOD,
1065+ method);
1066+ control->camera->setParameters(control->camera_parameters.flatten());
1067+}
1068+
1069+void android_camera_enumerate_supported_video_sizes(CameraControl* control, size_callback cb, void* ctx)
1070+{
1071+ REPORT_FUNCTION();
1072+ assert(control);
1073+ assert(cb);
1074+
1075+ android::Mutex::Autolock al(control->guard);
1076+ android::Vector<android::Size> sizes;
1077+ control->camera_parameters.getSupportedVideoSizes(sizes);
1078+
1079+ for (unsigned int i = 0; i < sizes.size(); i++) {
1080+ cb(ctx, sizes[i].width, sizes[i].height);
1081+ }
1082+}
1083+
1084+void android_camera_get_video_size(CameraControl* control, int* width, int* height)
1085+{
1086+ REPORT_FUNCTION();
1087+ assert(control);
1088+
1089+ android::Mutex::Autolock al(control->guard);
1090+
1091+ control->camera_parameters.getVideoSize(width, height);
1092+}
1093+
1094+void android_camera_set_video_size(CameraControl* control, int width, int height)
1095+{
1096+ REPORT_FUNCTION();
1097+ assert(control);
1098+
1099+ android::Mutex::Autolock al(control->guard);
1100+
1101+ control->camera_parameters.setVideoSize(width, height);
1102+ control->camera->setParameters(control->camera_parameters.flatten());
1103+}
1104+
1105+void android_camera_set_jpeg_quality(CameraControl* control, int quality)
1106+{
1107+ REPORT_FUNCTION();
1108+ assert(control);
1109+
1110+ android::Mutex::Autolock al(control->guard);
1111+ control->camera_parameters.set(
1112+ android::CameraParameters::KEY_JPEG_QUALITY,
1113+ quality);
1114+ control->camera->setParameters(control->camera_parameters.flatten());
1115+}
1116+
1117+void android_camera_get_jpeg_quality(CameraControl* control, int* quality)
1118+{
1119+ REPORT_FUNCTION();
1120+ assert(control);
1121+
1122+ android::Mutex::Autolock al(control->guard);
1123+ *quality = atoi(control->camera_parameters.get(
1124+ android::CameraParameters::KEY_JPEG_QUALITY));
1125+}
1126
1127=== added file 'android/compat/camera/direct_camera_test.cpp'
1128--- android/compat/camera/direct_camera_test.cpp 1970-01-01 00:00:00 +0000
1129+++ android/compat/camera/direct_camera_test.cpp 2016-01-11 14:31:46 +0000
1130@@ -0,0 +1,683 @@
1131+/*
1132+ * Copyright (C) 2013-2014 Canonical Ltd
1133+ *
1134+ * Licensed under the Apache License, Version 2.0 (the "License");
1135+ * you may not use this file except in compliance with the License.
1136+ * You may obtain a copy of the License at
1137+ *
1138+ * http://www.apache.org/licenses/LICENSE-2.0
1139+ *
1140+ * Unless required by applicable law or agreed to in writing, software
1141+ * distributed under the License is distributed on an "AS IS" BASIS,
1142+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1143+ * See the License for the specific language governing permissions and
1144+ * limitations under the License.
1145+ *
1146+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
1147+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
1148+ * Jim Hodapp <jim.hodapp@canonical.com>
1149+ */
1150+
1151+#include <hybris/camera/camera_compatibility_layer.h>
1152+#include <hybris/camera/camera_compatibility_layer_capabilities.h>
1153+#include <hybris/media/media_recorder_layer.h>
1154+
1155+#include <hybris/input/input_stack_compatibility_layer.h>
1156+#include <hybris/input/input_stack_compatibility_layer_codes_key.h>
1157+#include <hybris/input/input_stack_compatibility_layer_flags_key.h>
1158+#include <hybris/input/input_stack_compatibility_layer_flags_motion.h>
1159+
1160+#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
1161+
1162+#include <gui/ISurfaceComposer.h>
1163+
1164+#include <GLES2/gl2.h>
1165+#include <GLES2/gl2ext.h>
1166+
1167+#include <sys/stat.h>
1168+#include <sys/types.h>
1169+#include <fcntl.h>
1170+#include <unistd.h>
1171+
1172+#include <cassert>
1173+#include <cstdio>
1174+#include <cstdlib>
1175+#include <cstring>
1176+
1177+int shot_counter = 1;
1178+int32_t current_zoom_level = 1;
1179+bool new_camera_frame_available = true;
1180+static CameraControl* camera_control = NULL;
1181+int camera_width = 0, camera_height = 0;
1182+int thumbnail_width = 0, thumbnail_height = 0;
1183+static MediaRecorderWrapper *recorder = NULL;
1184+bool recording = false;
1185+
1186+EffectMode next_effect()
1187+{
1188+ static EffectMode current_effect = EFFECT_MODE_NONE;
1189+
1190+ EffectMode next = current_effect;
1191+
1192+ switch (current_effect) {
1193+ case EFFECT_MODE_NONE:
1194+ next = EFFECT_MODE_MONO;
1195+ break;
1196+ case EFFECT_MODE_MONO:
1197+ next = EFFECT_MODE_NEGATIVE;
1198+ break;
1199+ case EFFECT_MODE_NEGATIVE:
1200+ next = EFFECT_MODE_SOLARIZE;
1201+ break;
1202+ case EFFECT_MODE_SOLARIZE:
1203+ next = EFFECT_MODE_SEPIA;
1204+ break;
1205+ case EFFECT_MODE_SEPIA:
1206+ next = EFFECT_MODE_POSTERIZE;
1207+ break;
1208+ case EFFECT_MODE_POSTERIZE:
1209+ next = EFFECT_MODE_WHITEBOARD;
1210+ break;
1211+ case EFFECT_MODE_WHITEBOARD:
1212+ next = EFFECT_MODE_BLACKBOARD;
1213+ break;
1214+ case EFFECT_MODE_BLACKBOARD:
1215+ next = EFFECT_MODE_AQUA;
1216+ break;
1217+ case EFFECT_MODE_AQUA:
1218+ next = EFFECT_MODE_NONE;
1219+ break;
1220+ }
1221+
1222+ current_effect = next;
1223+ return next;
1224+}
1225+
1226+void error_msg_cb(void* context)
1227+{
1228+ printf("%s \n", __PRETTY_FUNCTION__);
1229+}
1230+
1231+void shutter_msg_cb(void* context)
1232+{
1233+ printf("%s \n", __PRETTY_FUNCTION__);
1234+}
1235+
1236+void zoom_msg_cb(void* context, int32_t new_zoom_level)
1237+{
1238+ printf("%s \n", __PRETTY_FUNCTION__);
1239+
1240+ CameraControl* cc = static_cast<CameraControl*>(context);
1241+ static int zoom;
1242+ android_camera_get_current_zoom(cc, &zoom);
1243+ printf("\t Current zoom: %d\n", zoom);
1244+ current_zoom_level = new_zoom_level;
1245+}
1246+
1247+void autofocus_msg_cb(void* context)
1248+{
1249+ printf("%s \n", __PRETTY_FUNCTION__);
1250+}
1251+
1252+void raw_data_cb(void* data, uint32_t data_size, void* context)
1253+{
1254+ printf("%s: %d \n", __PRETTY_FUNCTION__, data_size);
1255+}
1256+
1257+void jpeg_data_cb(void* data, uint32_t data_size, void* context)
1258+{
1259+ printf("%s: %d \n", __PRETTY_FUNCTION__, data_size);
1260+
1261+ char fn[256];
1262+ sprintf(fn, "/cache/shot_%d.jpeg", shot_counter);
1263+ int fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
1264+ write(fd, data, data_size);
1265+ close(fd);
1266+ shot_counter++;
1267+
1268+ CameraControl* cc = static_cast<CameraControl*>(context);
1269+ android_camera_start_preview(cc);
1270+}
1271+
1272+void size_cb(void* ctx, int width, int height)
1273+{
1274+ printf("Supported size: [%d,%d]\n", width, height);
1275+ if (width == 1024 && height == 768) {
1276+ camera_width = 1024;
1277+ camera_height = 768;
1278+ }
1279+}
1280+
1281+void thumbnail_size_cb(void* ctx, int width, int height)
1282+{
1283+ static bool do_once = true;
1284+ printf("Supported thumbnail size: [%d,%d]\n", width, height);
1285+ if (do_once) {
1286+ printf("Selecting thumbnail size: [%dx%d]\n", width, height);
1287+ thumbnail_width = width;
1288+ thumbnail_height = height;
1289+ }
1290+}
1291+
1292+struct RenderData
1293+{
1294+ static const char* vertex_shader()
1295+ {
1296+ return
1297+ "#extension GL_OES_EGL_image_external : require \n"
1298+ "attribute vec4 a_position; \n"
1299+ "attribute vec2 a_texCoord; \n"
1300+ "uniform mat4 m_texMatrix; \n"
1301+ "varying vec2 v_texCoord; \n"
1302+ "varying float topDown; \n"
1303+ "void main() \n"
1304+ "{ \n"
1305+ " gl_Position = a_position; \n"
1306+ " v_texCoord = a_texCoord; \n"
1307+ // " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
1308+ //" topDown = v_texCoord.y; \n"
1309+ "} \n";
1310+ }
1311+
1312+ static const char* fragment_shader()
1313+ {
1314+ return
1315+ "#extension GL_OES_EGL_image_external : require \n"
1316+ "precision mediump float; \n"
1317+ "varying vec2 v_texCoord; \n"
1318+ "uniform samplerExternalOES s_texture; \n"
1319+ "void main() \n"
1320+ "{ \n"
1321+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
1322+ "} \n";
1323+ }
1324+
1325+ static GLuint loadShader(GLenum shaderType, const char* pSource)
1326+ {
1327+ GLuint shader = glCreateShader(shaderType);
1328+
1329+ if (shader) {
1330+ glShaderSource(shader, 1, &pSource, NULL);
1331+ glCompileShader(shader);
1332+ GLint compiled = 0;
1333+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
1334+
1335+ if (!compiled) {
1336+ GLint infoLen = 0;
1337+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
1338+ if (infoLen) {
1339+ char* buf = (char*) malloc(infoLen);
1340+ if (buf) {
1341+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
1342+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
1343+ shaderType, buf);
1344+ free(buf);
1345+ }
1346+ glDeleteShader(shader);
1347+ shader = 0;
1348+ }
1349+ }
1350+ } else {
1351+ printf("Error, during shader creation: %i\n", glGetError());
1352+ }
1353+
1354+ return shader;
1355+ }
1356+
1357+ static GLuint create_program(const char* pVertexSource, const char* pFragmentSource)
1358+ {
1359+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
1360+ if (!vertexShader) {
1361+ printf("vertex shader not compiled\n");
1362+ return 0;
1363+ }
1364+
1365+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
1366+ if (!pixelShader) {
1367+ printf("frag shader not compiled\n");
1368+ return 0;
1369+ }
1370+
1371+ GLuint program = glCreateProgram();
1372+ if (program) {
1373+ glAttachShader(program, vertexShader);
1374+ glAttachShader(program, pixelShader);
1375+ glLinkProgram(program);
1376+ GLint linkStatus = GL_FALSE;
1377+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
1378+
1379+ if (linkStatus != GL_TRUE) {
1380+ GLint bufLength = 0;
1381+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
1382+ if (bufLength) {
1383+ char* buf = (char*) malloc(bufLength);
1384+ if (buf) {
1385+ glGetProgramInfoLog(program, bufLength, NULL, buf);
1386+ fprintf(stderr, "Could not link program:\n%s\n", buf);
1387+ free(buf);
1388+ }
1389+ }
1390+ glDeleteProgram(program);
1391+ program = 0;
1392+ }
1393+ }
1394+
1395+ return program;
1396+ }
1397+
1398+ RenderData() : program_object(create_program(vertex_shader(), fragment_shader()))
1399+ {
1400+ position_loc = glGetAttribLocation(program_object, "a_position");
1401+ tex_coord_loc = glGetAttribLocation(program_object, "a_texCoord");
1402+ sampler_loc = glGetUniformLocation(program_object, "s_texture");
1403+ matrix_loc = glGetUniformLocation(program_object, "m_texMatrix");
1404+ }
1405+
1406+ // Handle to a program object
1407+ GLuint program_object;
1408+ // Attribute locations
1409+ GLint position_loc;
1410+ GLint tex_coord_loc;
1411+ // Sampler location
1412+ GLint sampler_loc;
1413+ // Matrix location
1414+ GLint matrix_loc;
1415+};
1416+
1417+
1418+static RenderData render_data;
1419+static EGLDisplay disp;
1420+static EGLSurface surface;
1421+
1422+void preview_texture_needs_update_cb(void* ctx)
1423+{
1424+ ALOGD("Updating preview texture");
1425+ new_camera_frame_available = true;
1426+ static GLfloat vVertices[] = { 0.0f, 0.0f, 0.0f, // Position 0
1427+ 0.0f, 0.0f, // TexCoord 0
1428+ 0.0f, 1.0f, 0.0f, // Position 1
1429+ 0.0f, 1.0f, // TexCoord 1
1430+ 1.0f, 1.0f, 0.0f, // Position 2
1431+ 1.0f, 1.0f, // TexCoord 2
1432+ 1.0f, 0.0f, 0.0f, // Position 3
1433+ 1.0f, 0.0f // TexCoord 3
1434+ };
1435+
1436+ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
1437+
1438+ // Set the viewport
1439+ // Clear the color buffer
1440+ glClear(GL_COLOR_BUFFER_BIT);
1441+ // Use the program object
1442+ glUseProgram(render_data.program_object);
1443+ // Enable attributes
1444+ glEnableVertexAttribArray(render_data.position_loc);
1445+ glEnableVertexAttribArray(render_data.tex_coord_loc);
1446+ // Load the vertex position
1447+ glVertexAttribPointer(render_data.position_loc,
1448+ 3,
1449+ GL_FLOAT,
1450+ GL_FALSE,
1451+ 5 * sizeof(GLfloat),
1452+ vVertices);
1453+ // Load the texture coordinate
1454+ glVertexAttribPointer(render_data.tex_coord_loc,
1455+ 2,
1456+ GL_FLOAT,
1457+ GL_FALSE,
1458+ 5 * sizeof(GLfloat),
1459+ vVertices+3);
1460+
1461+ glActiveTexture(GL_TEXTURE0);
1462+ // Set the sampler texture unit to 0
1463+ glUniform1i(render_data.sampler_loc, 0);
1464+ glUniform1i(render_data.matrix_loc, 0);
1465+ ALOGD("Updating the preview texture");
1466+ if (camera_control != NULL)
1467+ android_camera_update_preview_texture(camera_control);
1468+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
1469+ glDisableVertexAttribArray(render_data.position_loc);
1470+ glDisableVertexAttribArray(render_data.tex_coord_loc);
1471+
1472+ eglSwapBuffers(disp, surface);
1473+}
1474+
1475+static void errorCB(void *context)
1476+{
1477+ ALOGE("Error while recording.");
1478+}
1479+
1480+static MediaRecorderWrapper *start_video_recording(CameraControl *camera_control)
1481+{
1482+ int ret = 0;
1483+ struct MediaRecorderWrapper *recorder = android_media_new_recorder();
1484+ android_recorder_set_error_cb(recorder, &errorCB, NULL);
1485+
1486+ ALOGD("Unlocking camera");
1487+ android_camera_unlock(camera_control);
1488+ if (recorder == NULL)
1489+ ALOGW("recorder is NULL: %d", __LINE__);
1490+
1491+ ret = android_recorder_setCamera(recorder, camera_control);
1492+ if (ret < 0) {
1493+ ALOGE("android_recorder_setCamera() failed");
1494+ return NULL;
1495+ }
1496+ ret = android_recorder_setAudioSource(recorder, ANDROID_AUDIO_SOURCE_CAMCORDER);
1497+ if (ret < 0) {
1498+ ALOGE("android_recorder_setAudioSource() failed");
1499+ return NULL;
1500+ }
1501+ ret = android_recorder_setVideoSource(recorder, ANDROID_VIDEO_SOURCE_CAMERA);
1502+ if (ret < 0) {
1503+ ALOGE("android_recorder_setVideoSource() failed");
1504+ return NULL;
1505+ }
1506+ ret = android_recorder_setOutputFormat(recorder, ANDROID_OUTPUT_FORMAT_MPEG_4);
1507+ if (ret < 0) {
1508+ ALOGE("android_recorder_setOutputFormat() failed");
1509+ return NULL;
1510+ }
1511+ ret = android_recorder_setAudioEncoder(recorder, ANDROID_AUDIO_ENCODER_AAC);
1512+ if (ret < 0) {
1513+ ALOGE("android_recorder_setAudioEncoder() failed");
1514+ return NULL;
1515+ }
1516+ ret = android_recorder_setVideoEncoder(recorder, ANDROID_VIDEO_ENCODER_H264);
1517+ if (ret < 0) {
1518+ ALOGE("android_recorder_setVideoEncoder() failed");
1519+ return NULL;
1520+ }
1521+ int fd = -1;
1522+ char *out_file = "/cache/test_recording.mp4";
1523+ fd = open(out_file, O_WRONLY | O_CREAT,
1524+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
1525+ if (fd < 0) {
1526+ ALOGE("Couldn't open output video file for recording: %s", out_file);
1527+ return NULL;
1528+ }
1529+ ret = android_recorder_setOutputFile(recorder, fd);
1530+ if (ret < 0) {
1531+ ALOGE("android_recorder_setOutputFile() failed");
1532+ return NULL;
1533+ }
1534+ ret = android_recorder_setVideoSize(recorder, camera_width, camera_height);
1535+ if (ret < 0) {
1536+ ALOGE("android_recorder_setVideoSize() failed");
1537+ return NULL;
1538+ }
1539+ ret = android_recorder_setVideoFrameRate(recorder, 30);
1540+ if (ret < 0) {
1541+ ALOGE("android_recorder_setVideoFrameRate() failed");
1542+ return NULL;
1543+ }
1544+ android_recorder_setParameters(recorder, "video-param-encoding-bitrate=5505024"); // 7*1024*768
1545+ android_recorder_setParameters(recorder, "audio-param-encoding-bitrate=48000");
1546+ android_recorder_setParameters(recorder, "audio-param-number-of-channels=2");
1547+ android_recorder_setParameters(recorder, "audio-param-sampling-rate=96000");
1548+ android_recorder_setParameters(recorder, "video-param-rotation-angle-degrees=90");
1549+ ALOGD("Preparing video recording");
1550+ ret = android_recorder_prepare(recorder);
1551+ if (ret < 0) {
1552+ ALOGE("android_recorder_prepare() failed");
1553+ return NULL;
1554+ }
1555+ ALOGD("Starting video recording");
1556+ ret = android_recorder_start(recorder);
1557+ if (ret < 0) {
1558+ ALOGE("android_recorder_start() failed");
1559+ return NULL;
1560+ }
1561+
1562+ return recorder;
1563+}
1564+
1565+static void stop_video_recording(MediaRecorderWrapper *recorder)
1566+{
1567+ if (recording) {
1568+ ALOGD("Stopping video recording");
1569+ android_recorder_stop(recorder);
1570+ android_recorder_reset(recorder);
1571+ android_recorder_release(recorder);
1572+ ALOGD("Stopped video recording");
1573+ }
1574+}
1575+
1576+void on_new_input_event(Event* event, void* context)
1577+{
1578+ assert(context);
1579+
1580+ if (event->type == KEY_EVENT_TYPE && event->action == ISCL_KEY_EVENT_ACTION_UP) {
1581+ printf("We got a key event: %d \n", event->details.key.key_code);
1582+
1583+ CameraControl* cc = static_cast<CameraControl*>(context);
1584+
1585+ switch(event->details.key.key_code) {
1586+ case ISCL_KEYCODE_VOLUME_UP:
1587+ printf("Starting video recording to /cache/test_recording.mp4\n");
1588+ start_video_recording(cc);
1589+ recording = true;
1590+ break;
1591+ case ISCL_KEYCODE_VOLUME_DOWN:
1592+ printf("Stopping video recording\n");
1593+ stop_video_recording(recorder);
1594+ recording = false;
1595+ break;
1596+ case ISCL_KEYCODE_POWER:
1597+ printf("\tTaking a photo now.\n");
1598+ android_camera_take_snapshot(cc);
1599+ break;
1600+ case ISCL_KEYCODE_HEADSETHOOK:
1601+ printf("\tSwitching effect.\n");
1602+ android_camera_set_effect_mode(cc, next_effect());
1603+ }
1604+ } else if (event->type == MOTION_EVENT_TYPE &&
1605+ event->details.motion.pointer_count == 1) {
1606+ if ((event->action & ISCL_MOTION_EVENT_ACTION_MASK) == ISCL_MOTION_EVENT_ACTION_UP) {
1607+ printf("\tMotion event(Action up): (%f, %f) \n",
1608+ event->details.motion.pointer_coordinates[0].x,
1609+ event->details.motion.pointer_coordinates[0].y);
1610+ }
1611+
1612+ if ((event->action & ISCL_MOTION_EVENT_ACTION_MASK) == ISCL_MOTION_EVENT_ACTION_DOWN) {
1613+ printf("\tMotion event(Action down): (%f, %f) \n",
1614+ event->details.motion.pointer_coordinates[0].x,
1615+ event->details.motion.pointer_coordinates[0].y);
1616+ }
1617+ }
1618+}
1619+
1620+struct ClientWithSurface
1621+{
1622+ SfClient* client;
1623+ SfSurface* surface;
1624+};
1625+
1626+ClientWithSurface client_with_surface(bool setup_surface_with_egl)
1627+{
1628+ ClientWithSurface cs = ClientWithSurface();
1629+
1630+ cs.client = sf_client_create();
1631+
1632+ if (!cs.client) {
1633+ printf("Problem creating client ... aborting now.");
1634+ return cs;
1635+ }
1636+
1637+ static const size_t primary_display = 0;
1638+
1639+ SfSurfaceCreationParameters params = {
1640+ 0,
1641+ 0,
1642+ (int) sf_get_display_width(primary_display),
1643+ (int) sf_get_display_height(primary_display),
1644+ -1, //PIXEL_FORMAT_RGBA_8888,
1645+ 15000,
1646+ 0.5f,
1647+ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL
1648+ "CameraCompatLayerTestSurface"
1649+ };
1650+
1651+ cs.surface = sf_surface_create(cs.client, &params);
1652+
1653+ if (!cs.surface) {
1654+ printf("Problem creating surface ... aborting now.");
1655+ return cs;
1656+ }
1657+
1658+ sf_surface_make_current(cs.surface);
1659+
1660+ return cs;
1661+}
1662+
1663+#define PRINT_GLERROR() printf("GL error@%d: %x\n", __LINE__, glGetError());
1664+
1665+int main(int argc, char** argv)
1666+{
1667+ CameraControlListener listener;
1668+ memset(&listener, 0, sizeof(listener));
1669+ listener.on_msg_error_cb = error_msg_cb;
1670+ listener.on_msg_shutter_cb = shutter_msg_cb;
1671+ listener.on_msg_focus_cb = autofocus_msg_cb;
1672+ listener.on_msg_zoom_cb = zoom_msg_cb;
1673+
1674+ listener.on_data_raw_image_cb = raw_data_cb;
1675+ listener.on_data_compressed_image_cb = jpeg_data_cb;
1676+ listener.on_preview_texture_needs_update_cb = preview_texture_needs_update_cb;
1677+ camera_control = android_camera_connect_to(BACK_FACING_CAMERA_TYPE,
1678+ &listener);
1679+
1680+ if (camera_control == NULL) {
1681+ printf("Problem connecting to camera");
1682+ return 1;
1683+ }
1684+ listener.context = camera_control;
1685+
1686+ AndroidEventListener event_listener;
1687+ event_listener.on_new_event = on_new_input_event;
1688+ event_listener.context = camera_control;
1689+
1690+ InputStackConfiguration input_configuration = {
1691+ enable_touch_point_visualization : true,
1692+ default_layer_for_touch_point_visualization : 10000,
1693+ input_area_width : 1024,
1694+ input_area_height : 1024
1695+ };
1696+
1697+ android_input_stack_initialize(&event_listener, &input_configuration);
1698+ android_input_stack_start();
1699+
1700+ // Set the still photo size
1701+ android_camera_enumerate_supported_picture_sizes(camera_control, size_cb, NULL);
1702+ if (camera_width == 0 && camera_height == 0) {
1703+ camera_width = 320;
1704+ camera_height = 240;
1705+ }
1706+ android_camera_set_picture_size(camera_control, camera_width, camera_height);
1707+
1708+ // Set the still photo thumbnail size
1709+ android_camera_enumerate_supported_thumbnail_sizes(camera_control, thumbnail_size_cb, NULL);
1710+ if (thumbnail_width == 0 && thumbnail_height == 0) {
1711+ thumbnail_width = 320;
1712+ thumbnail_height = 240;
1713+ }
1714+ android_camera_set_thumbnail_size(camera_control, thumbnail_width, thumbnail_height);
1715+
1716+ AutoFocusMode af_mode;
1717+ android_camera_get_auto_focus_mode(camera_control, &af_mode);
1718+ printf("Current af mode: %d \n", af_mode);
1719+
1720+ int zoom;
1721+ android_camera_set_zoom(camera_control, 0);
1722+ android_camera_get_max_zoom(camera_control, &zoom);
1723+ printf("Max zoom: %d \n", zoom);
1724+
1725+ android_camera_enumerate_supported_video_sizes(camera_control, size_cb, NULL);
1726+ android_camera_enumerate_supported_preview_sizes(camera_control, size_cb, NULL);
1727+ android_camera_set_preview_size(camera_control, camera_width, camera_height);
1728+
1729+ int min_fps, max_fps, current_fps;
1730+ android_camera_get_preview_fps_range(camera_control, &min_fps, &max_fps);
1731+ printf("Preview fps range: [%d,%d]\n", min_fps, max_fps);
1732+ android_camera_get_preview_fps(camera_control, &current_fps);
1733+ printf("Current preview fps range: %d\n", current_fps);
1734+
1735+#if 0
1736+ android_camera_dump_parameters(camera_control);
1737+
1738+ android_camera_set_display_orientation(camera_control, 90);
1739+
1740+ int width, height;
1741+ android_camera_get_preview_size(camera_control, &width, &height);
1742+ printf("Current preview size: [%d,%d]\n", width, height);
1743+ android_camera_get_picture_size(camera_control, &width, &height);
1744+ printf("Current picture size: [%d,%d]\n", width, height);
1745+ android_camera_get_current_zoom(camera_control, &zoom);
1746+ printf("Current zoom: %d \n", zoom);
1747+
1748+ EffectMode effect_mode;
1749+ FlashMode flash_mode;
1750+ WhiteBalanceMode wb_mode;
1751+ //SceneMode scene_mode;
1752+ CameraPixelFormat pixel_format;
1753+ android_camera_get_effect_mode(camera_control, &effect_mode);
1754+ printf("Current effect mode: %d \n", effect_mode);
1755+ android_camera_get_flash_mode(camera_control, &flash_mode);
1756+ printf("Current flash mode: %d \n", flash_mode);
1757+ android_camera_get_white_balance_mode(camera_control, &wb_mode);
1758+ ALOGD("Current wb mode: %d \n", wb_mode);
1759+#if 0
1760+ // Disabled, causes the test app to crash
1761+ android_camera_get_scene_mode(camera_control, &scene_mode);
1762+ printf("Current scene mode: %d \n", scene_mode);
1763+#endif
1764+ android_camera_get_preview_format(camera_control, &pixel_format);
1765+ printf("Current preview pixel format: %d \n", pixel_format);
1766+ //android_camera_set_focus_region(camera_control, -200, -200, 200, 200, 300);
1767+#endif
1768+
1769+ printf("Creating client with surface");
1770+ ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */);
1771+
1772+ if (!cs.surface) {
1773+ printf("Problem acquiring surface for preview");
1774+ return 1;
1775+ }
1776+ printf("Finished creating client with surface\n");
1777+
1778+ disp = sf_client_get_egl_display(cs.client);
1779+ surface = sf_surface_get_egl_surface(cs.surface);
1780+
1781+ GLuint preview_texture_id;
1782+ printf("Getting a texture id\n");
1783+ glGenTextures(1, &preview_texture_id);
1784+ glClearColor(1.0, 0., 0.5, 1.);
1785+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1786+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1787+ glTexParameteri(
1788+ GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1789+ glTexParameteri(
1790+ GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1791+ printf("About to set preview texture\n");
1792+ android_camera_set_preview_texture(camera_control, preview_texture_id);
1793+#if 0
1794+ android_camera_set_effect_mode(camera_control, EFFECT_MODE_SEPIA);
1795+ android_camera_set_flash_mode(camera_control, FLASH_MODE_AUTO);
1796+ android_camera_set_auto_focus_mode(camera_control, AUTO_FOCUS_MODE_CONTINUOUS_PICTURE);
1797+#endif
1798+ android_camera_start_preview(camera_control);
1799+
1800+ GLfloat transformation_matrix[16];
1801+ android_camera_get_preview_texture_transformation(camera_control, transformation_matrix);
1802+ glUniformMatrix4fv(render_data.matrix_loc, 1, GL_FALSE, transformation_matrix);
1803+
1804+ printf("Started camera preview.\n");
1805+
1806+ while (1) {
1807+ usleep(50);
1808+ }
1809+
1810+ stop_video_recording(recorder);
1811+ android_camera_stop_preview(camera_control);
1812+ android_camera_disconnect(camera_control);
1813+}
1814
1815=== added directory 'android/compat/input'
1816=== added file 'android/compat/input/Android.mk'
1817--- android/compat/input/Android.mk 1970-01-01 00:00:00 +0000
1818+++ android/compat/input/Android.mk 2016-01-11 14:31:46 +0000
1819@@ -0,0 +1,77 @@
1820+LOCAL_PATH := $(call my-dir)
1821+include $(CLEAR_VARS)
1822+include $(LOCAL_PATH)/../Android.common.mk
1823+
1824+HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
1825+
1826+LOCAL_CFLAGS += -std=gnu++0x
1827+
1828+LOCAL_SRC_FILES:= input_compatibility_layer.cpp
1829+
1830+LOCAL_MODULE:= libis_compat_layer
1831+LOCAL_MODULE_TAGS := optional
1832+
1833+LOCAL_SHARED_LIBRARIES := \
1834+ libinput \
1835+ libcutils \
1836+ libutils \
1837+ libskia \
1838+ libgui \
1839+ libandroidfw
1840+
1841+LOCAL_C_INCLUDES := \
1842+ $(HYBRIS_PATH)/include \
1843+ external/skia/include/core
1844+
1845+HAS_LIBINPUTSERVICE := $(shell test $(ANDROID_VERSION_MAJOR) -eq 4 -a $(ANDROID_VERSION_MINOR) -gt 2 && echo true)
1846+ifeq ($(HAS_LIBINPUTSERVICE),true)
1847+LOCAL_SHARED_LIBRARIES += libinputservice
1848+LOCAL_C_INCLUDES += frameworks/base/services/input
1849+endif
1850+
1851+HAS_LIBINPUTFLINGER := $(shell test $(ANDROID_VERSION_MAJOR) -eq 5 && echo true)
1852+ifeq ($(HAS_LIBINPUTFLINGER),true)
1853+LOCAL_SHARED_LIBRARIES += libinputflinger libinputservice
1854+LOCAL_C_INCLUDES += \
1855+ frameworks/base/libs/input \
1856+ frameworks/native/services
1857+endif
1858+
1859+
1860+
1861+
1862+include $(BUILD_SHARED_LIBRARY)
1863+
1864+include $(CLEAR_VARS)
1865+
1866+HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
1867+
1868+LOCAL_CFLAGS += -std=gnu++0x
1869+
1870+LOCAL_SRC_FILES:= \
1871+ direct_input_test.cpp
1872+
1873+LOCAL_MODULE:= direct_input_test
1874+LOCAL_MODULE_TAGS := optional
1875+
1876+LOCAL_C_INCLUDES := \
1877+ $(HYBRIS_PATH)/include \
1878+ bionic \
1879+ bionic/libstdc++/include \
1880+ external/gtest/include \
1881+ external/stlport/stlport \
1882+ external/skia/include/core
1883+
1884+LOCAL_SHARED_LIBRARIES := \
1885+ libis_compat_layer \
1886+ libcutils \
1887+ libutils \
1888+ libskia \
1889+ libgui \
1890+ libandroidfw
1891+
1892+static_libraries := \
1893+ libgtest \
1894+ libgtest_main
1895+
1896+include $(BUILD_EXECUTABLE)
1897
1898=== added file 'android/compat/input/direct_input_test.cpp'
1899--- android/compat/input/direct_input_test.cpp 1970-01-01 00:00:00 +0000
1900+++ android/compat/input/direct_input_test.cpp 2016-01-11 14:31:46 +0000
1901@@ -0,0 +1,85 @@
1902+/*
1903+ * Copyright (C) 2013 Canonical Ltd
1904+ *
1905+ * Licensed under the Apache License, Version 2.0 (the "License");
1906+ * you may not use this file except in compliance with the License.
1907+ * You may obtain a copy of the License at
1908+ *
1909+ * http://www.apache.org/licenses/LICENSE-2.0
1910+ *
1911+ * Unless required by applicable law or agreed to in writing, software
1912+ * distributed under the License is distributed on an "AS IS" BASIS,
1913+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1914+ * See the License for the specific language governing permissions and
1915+ * limitations under the License.
1916+ *
1917+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
1918+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
1919+ */
1920+
1921+#include <hybris/input/input_stack_compatibility_layer.h>
1922+
1923+#include <gtest/gtest.h>
1924+#include <utils/threads.h>
1925+
1926+#include <signal.h>
1927+
1928+namespace
1929+{
1930+
1931+bool g_stop = false;
1932+
1933+void signal_handler(int)
1934+{
1935+ g_stop = true;
1936+}
1937+
1938+void on_new_event(Event* event, void* context)
1939+{
1940+ printf("%s", __PRETTY_FUNCTION__);
1941+
1942+ printf("\tEventType: %d \n", event->type);
1943+ printf("\tdevice_id: %d \n", event->device_id);
1944+ printf("\tsource_id: %d \n", event->source_id);
1945+ printf("\taction: %d \n", event->action);
1946+ printf("\tflags: %d \n", event->flags);
1947+ printf("\tmeta_state: %d \n", event->meta_state);
1948+
1949+ switch (event->type) {
1950+ case MOTION_EVENT_TYPE:
1951+ printf("\tdetails.motion.event_time: %lld\n",
1952+ event->details.motion.event_time);
1953+ printf("\tdetails.motion.pointer_coords.x: %f\n",
1954+ event->details.motion.pointer_coordinates[0].x);
1955+ printf("\tdetails.motion.pointer_coords.y: %f\n",
1956+ event->details.motion.pointer_coordinates[0].y);
1957+ break;
1958+ default:
1959+ break;
1960+ }
1961+}
1962+
1963+}
1964+
1965+int main(int argc, char** argv)
1966+{
1967+ g_stop = false;
1968+ signal(SIGINT, signal_handler);
1969+
1970+ AndroidEventListener listener;
1971+ listener.on_new_event = on_new_event;
1972+ listener.context = NULL;
1973+
1974+ InputStackConfiguration config = {
1975+ enable_touch_point_visualization : true,
1976+ default_layer_for_touch_point_visualization : 10000,
1977+ input_area_width : 1024,
1978+ input_area_height : 1024
1979+ };
1980+
1981+ android_input_stack_initialize(&listener, &config);
1982+ android_input_stack_start_waiting_for_flag(&g_stop);
1983+
1984+ android_input_stack_stop();
1985+ android_input_stack_shutdown();
1986+}
1987
1988=== added file 'android/compat/input/input_compatibility_layer.cpp'
1989--- android/compat/input/input_compatibility_layer.cpp 1970-01-01 00:00:00 +0000
1990+++ android/compat/input/input_compatibility_layer.cpp 2016-01-11 14:31:46 +0000
1991@@ -0,0 +1,384 @@
1992+/*
1993+ * Copyright (C) 2013 Canonical Ltd
1994+ *
1995+ * Licensed under the Apache License, Version 2.0 (the "License");
1996+ * you may not use this file except in compliance with the License.
1997+ * You may obtain a copy of the License at
1998+ *
1999+ * http://www.apache.org/licenses/LICENSE-2.0
2000+ *
2001+ * Unless required by applicable law or agreed to in writing, software
2002+ * distributed under the License is distributed on an "AS IS" BASIS,
2003+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2004+ * See the License for the specific language governing permissions and
2005+ * limitations under the License.
2006+ *
2007+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2008+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
2009+ */
2010+
2011+#include <hybris/input/input_stack_compatibility_layer.h>
2012+
2013+#if ANDROID_VERSION_MAJOR<=4
2014+ #include "InputListener.h"
2015+ #include "InputReader.h"
2016+#elif ANDROID_VERSION_MAJOR==5
2017+ #include "inputflinger/InputListener.h"
2018+ #include "inputflinger/InputReader.h"
2019+#endif
2020+
2021+#include "PointerController.h"
2022+#include "SpriteController.h"
2023+#include <gui/ISurfaceComposer.h>
2024+#include <gui/SurfaceComposerClient.h>
2025+
2026+#undef LOG_TAG
2027+#define LOG_TAG "InputStackCompatibilityLayer"
2028+#include <utils/Log.h>
2029+
2030+namespace
2031+{
2032+static bool enable_verbose_function_reporting = false;
2033+}
2034+
2035+#define REPORT_FUNCTION() ALOGV("%s\n", __PRETTY_FUNCTION__);
2036+
2037+namespace
2038+{
2039+
2040+class DefaultPointerControllerPolicy : public android::PointerControllerPolicyInterface
2041+{
2042+public:
2043+ static const size_t bitmap_width = 64;
2044+ static const size_t bitmap_height = 64;
2045+
2046+ DefaultPointerControllerPolicy()
2047+ {
2048+#if ANDROID_VERSION_MAJOR<=4
2049+ bitmap.setConfig(
2050+ SkBitmap::kARGB_8888_Config,
2051+ bitmap_width,
2052+ bitmap_height);
2053+#elif ANDROID_VERSION_MAJOR==5
2054+ SkColorType ct = SkBitmapConfigToColorType(SkBitmap::kARGB_8888_Config);
2055+ bitmap.setInfo(
2056+ SkImageInfo::Make(bitmap_width,
2057+ bitmap_height,
2058+ ct,
2059+ SkAlphaType::kPremul_SkAlphaType),
2060+ 0);
2061+#endif
2062+ bitmap.allocPixels();
2063+
2064+ // Icon for spot touches
2065+ bitmap.eraseARGB(125, 0, 255, 0);
2066+ spotTouchIcon = android::SpriteIcon(
2067+ bitmap,
2068+ bitmap_width/2,
2069+ bitmap_height/2);
2070+
2071+ // Icon for anchor touches
2072+ bitmap.eraseARGB(125, 0, 0, 255);
2073+ spotAnchorIcon = android::SpriteIcon(
2074+ bitmap,
2075+ bitmap_width/2,
2076+ bitmap_height/2);
2077+
2078+ // Icon for hovering touches
2079+ bitmap.eraseARGB(125, 255, 0, 0);
2080+ spotHoverIcon = android::SpriteIcon(
2081+ bitmap,
2082+ bitmap_width/2,
2083+ bitmap_height/2);
2084+ }
2085+
2086+ void loadPointerResources(android::PointerResources* outResources)
2087+ {
2088+ outResources->spotHover = spotHoverIcon.copy();
2089+ outResources->spotTouch = spotTouchIcon.copy();
2090+ outResources->spotAnchor = spotAnchorIcon.copy();
2091+ }
2092+
2093+ android::SpriteIcon spotHoverIcon;
2094+ android::SpriteIcon spotTouchIcon;
2095+ android::SpriteIcon spotAnchorIcon;
2096+ SkBitmap bitmap;
2097+};
2098+
2099+class DefaultInputReaderPolicyInterface : public android::InputReaderPolicyInterface
2100+{
2101+public:
2102+ static const int32_t internal_display_id = android::ISurfaceComposer::eDisplayIdMain;
2103+ static const int32_t external_display_id = android::ISurfaceComposer::eDisplayIdHdmi;
2104+
2105+ DefaultInputReaderPolicyInterface(
2106+ InputStackConfiguration* configuration,
2107+ const android::sp<android::Looper>& looper)
2108+ : looper(looper),
2109+ default_layer_for_touch_point_visualization(configuration->default_layer_for_touch_point_visualization),
2110+ input_area_width(configuration->input_area_width),
2111+ input_area_height(configuration->input_area_height)
2112+ {
2113+ default_configuration.showTouches = configuration->enable_touch_point_visualization;
2114+
2115+ android::DisplayViewport viewport;
2116+ viewport.setNonDisplayViewport(input_area_width, input_area_height);
2117+ viewport.displayId = android::ISurfaceComposer::eDisplayIdMain;
2118+ default_configuration.setDisplayInfo(
2119+ false, /* external */
2120+ viewport);
2121+ }
2122+
2123+ void getReaderConfiguration(android::InputReaderConfiguration* outConfig)
2124+ {
2125+ *outConfig = default_configuration;
2126+ }
2127+
2128+ android::sp<android::PointerControllerInterface> obtainPointerController(int32_t deviceId)
2129+ {
2130+ (void) deviceId;
2131+
2132+ android::sp<android::SpriteController> sprite_controller(
2133+ new android::SpriteController(
2134+ looper,
2135+ default_layer_for_touch_point_visualization));
2136+ android::sp<android::PointerController> pointer_controller(
2137+ new android::PointerController(
2138+ android::sp<DefaultPointerControllerPolicy>(new DefaultPointerControllerPolicy()),
2139+ looper,
2140+ sprite_controller));
2141+ pointer_controller->setPresentation(
2142+ android::PointerControllerInterface::PRESENTATION_SPOT);
2143+
2144+ pointer_controller->setDisplayViewport(input_area_width, input_area_height, 0);
2145+ return pointer_controller;
2146+ }
2147+
2148+ virtual void notifyInputDevicesChanged(const android::Vector<android::InputDeviceInfo>& inputDevices) {
2149+ mInputDevices = inputDevices;
2150+ }
2151+
2152+#if ANDROID_VERSION_MAJOR<=4
2153+ virtual android::sp<android::KeyCharacterMap> getKeyboardLayoutOverlay(const android::String8& inputDeviceDescriptor) {
2154+#elif ANDROID_VERSION_MAJOR==5
2155+ virtual android::sp<android::KeyCharacterMap> getKeyboardLayoutOverlay(const android::InputDeviceIdentifier& identifier) {
2156+#endif
2157+ return NULL;
2158+ }
2159+
2160+ virtual android::String8 getDeviceAlias(const android::InputDeviceIdentifier& identifier) {
2161+ return android::String8::empty();
2162+ }
2163+
2164+#if ANDROID_VERSION_MAJOR==5
2165+ virtual android::TouchAffineTransformation getTouchAffineTransformation(const android::String8& inputDeviceDescriptor, int32_t surfaceRotation) {
2166+ return android::TouchAffineTransformation();
2167+ }
2168+#endif
2169+
2170+private:
2171+ android::sp<android::Looper> looper;
2172+ int default_layer_for_touch_point_visualization;
2173+ android::InputReaderConfiguration default_configuration;
2174+ android::Vector<android::InputDeviceInfo> mInputDevices;
2175+ int input_area_width;
2176+ int input_area_height;
2177+};
2178+
2179+class ExportedInputListener : public android::InputListenerInterface
2180+{
2181+public:
2182+ ExportedInputListener(AndroidEventListener* external_listener) : external_listener(external_listener)
2183+ {
2184+ }
2185+
2186+ void notifyConfigurationChanged(const android::NotifyConfigurationChangedArgs* args)
2187+ {
2188+ REPORT_FUNCTION();
2189+ (void) args;
2190+ }
2191+
2192+ void notifyKey(const android::NotifyKeyArgs* args)
2193+ {
2194+ REPORT_FUNCTION();
2195+
2196+ current_event.type = KEY_EVENT_TYPE;
2197+ current_event.device_id = args->deviceId;
2198+ current_event.source_id = args->source;
2199+ current_event.action = args->action;
2200+ current_event.flags = args->flags;
2201+ current_event.meta_state = args->metaState;
2202+
2203+ current_event.details.key.key_code = args->keyCode;
2204+ current_event.details.key.scan_code = args->scanCode;
2205+ current_event.details.key.down_time = args->downTime;
2206+ current_event.details.key.event_time = args->eventTime;
2207+
2208+ current_event.details.key.is_system_key = false;
2209+
2210+ external_listener->on_new_event(&current_event, external_listener->context);
2211+ }
2212+
2213+ void notifyMotion(const android::NotifyMotionArgs* args)
2214+ {
2215+ REPORT_FUNCTION();
2216+
2217+ current_event.type = MOTION_EVENT_TYPE;
2218+ current_event.device_id = args->deviceId;
2219+ current_event.source_id = args->source;
2220+ current_event.action = args->action;
2221+ current_event.flags = args->flags;
2222+ current_event.meta_state = args->metaState;
2223+
2224+ current_event.details.motion.button_state = args->buttonState;
2225+ current_event.details.motion.down_time = args->downTime;
2226+ current_event.details.motion.event_time = args->eventTime;
2227+ current_event.details.motion.edge_flags = args->edgeFlags;
2228+ current_event.details.motion.x_precision = args->xPrecision;
2229+ current_event.details.motion.y_precision = args->yPrecision;
2230+ current_event.details.motion.pointer_count = args->pointerCount;
2231+
2232+ for (unsigned int i = 0; i < current_event.details.motion.pointer_count; i++) {
2233+ current_event.details.motion.pointer_coordinates[i].id = args->pointerProperties[i].id;
2234+ current_event.details.motion.pointer_coordinates[i].x
2235+ = current_event.details.motion.pointer_coordinates[i].raw_x
2236+ = args->pointerCoords[i].getX();
2237+ current_event.details.motion.pointer_coordinates[i].y
2238+ = current_event.details.motion.pointer_coordinates[i].raw_y
2239+ = args->pointerCoords[i].getY();
2240+ current_event.details.motion.pointer_coordinates[i].touch_major
2241+ = args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
2242+ current_event.details.motion.pointer_coordinates[i].touch_minor
2243+ = args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR);
2244+ current_event.details.motion.pointer_coordinates[i].pressure
2245+ = args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
2246+ current_event.details.motion.pointer_coordinates[i].size
2247+ = args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE);
2248+ current_event.details.motion.pointer_coordinates[i].orientation
2249+ = args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
2250+
2251+ }
2252+
2253+ external_listener->on_new_event(&current_event, external_listener->context);
2254+ }
2255+
2256+ void notifySwitch(const android::NotifySwitchArgs* args)
2257+ {
2258+ REPORT_FUNCTION();
2259+ current_event.type = HW_SWITCH_EVENT_TYPE;
2260+
2261+ current_event.details.hw_switch.event_time = args->eventTime;
2262+ current_event.details.hw_switch.policy_flags = args->policyFlags;
2263+ current_event.details.hw_switch.switch_values = args->switchValues;
2264+ current_event.details.hw_switch.switch_mask = args->switchMask;
2265+
2266+ external_listener->on_new_event(&current_event, external_listener->context);
2267+ }
2268+
2269+ void notifyDeviceReset(const android::NotifyDeviceResetArgs* args)
2270+ {
2271+ REPORT_FUNCTION();
2272+ (void) args;
2273+ }
2274+
2275+private:
2276+ AndroidEventListener* external_listener;
2277+ Event current_event;
2278+};
2279+
2280+class LooperThread : public android::Thread
2281+{
2282+public:
2283+ static const int default_poll_timeout_ms = -1;
2284+
2285+ LooperThread(const android::sp<android::Looper>& looper) : looper(looper)
2286+ {
2287+ }
2288+
2289+private:
2290+ bool threadLoop()
2291+ {
2292+ if (ALOOPER_POLL_ERROR == looper->pollAll(default_poll_timeout_ms))
2293+ return false;
2294+ return true;
2295+ }
2296+
2297+ android::sp<android::Looper> looper;
2298+};
2299+
2300+struct State : public android::RefBase
2301+{
2302+ State(AndroidEventListener* listener,
2303+ InputStackConfiguration* configuration)
2304+ : looper(new android::Looper(false)),
2305+ looper_thread(new LooperThread(looper)),
2306+ event_hub(new android::EventHub()),
2307+ input_reader_policy(new DefaultInputReaderPolicyInterface(configuration, looper)),
2308+ input_listener(new ExportedInputListener(listener)),
2309+ input_reader(new android::InputReader(
2310+ event_hub,
2311+ input_reader_policy,
2312+ input_listener)),
2313+ input_reader_thread(new android::InputReaderThread(input_reader))
2314+ {
2315+ }
2316+
2317+ ~State()
2318+ {
2319+ input_reader_thread->requestExit();
2320+ }
2321+
2322+ android::sp<android::Looper> looper;
2323+ android::sp<LooperThread> looper_thread;
2324+
2325+ android::sp<android::EventHubInterface> event_hub;
2326+ android::sp<android::InputReaderPolicyInterface> input_reader_policy;
2327+ android::sp<android::InputListenerInterface> input_listener;
2328+ android::sp<android::InputReaderInterface> input_reader;
2329+ android::sp<android::InputReaderThread> input_reader_thread;
2330+
2331+ android::Condition wait_condition;
2332+ android::Mutex wait_guard;
2333+};
2334+
2335+android::sp<State> global_state;
2336+
2337+}
2338+
2339+void android_input_stack_initialize(AndroidEventListener* listener, InputStackConfiguration* config)
2340+{
2341+ global_state = new State(listener, config);
2342+}
2343+
2344+void android_input_stack_loop_once()
2345+{
2346+ global_state->input_reader->loopOnce();
2347+}
2348+
2349+void android_input_stack_start()
2350+{
2351+ global_state->input_reader_thread->run();
2352+ global_state->looper_thread->run();
2353+}
2354+
2355+void android_input_stack_start_waiting_for_flag(bool* flag)
2356+{
2357+ global_state->input_reader_thread->run();
2358+ global_state->looper_thread->run();
2359+
2360+ while (!*flag) {
2361+ global_state->wait_condition.waitRelative(
2362+ global_state->wait_guard,
2363+ 10 * 1000 * 1000);
2364+ }
2365+}
2366+
2367+void android_input_stack_stop()
2368+{
2369+ global_state->input_reader_thread->requestExit();
2370+}
2371+
2372+void android_input_stack_shutdown()
2373+{
2374+ global_state = NULL;
2375+}
2376
2377=== added directory 'android/compat/media'
2378=== added file 'android/compat/media/Android.mk'
2379--- android/compat/media/Android.mk 1970-01-01 00:00:00 +0000
2380+++ android/compat/media/Android.mk 2016-01-11 14:31:46 +0000
2381@@ -0,0 +1,187 @@
2382+LOCAL_PATH:= $(call my-dir)
2383+include $(CLEAR_VARS)
2384+include $(LOCAL_PATH)/../Android.common.mk
2385+
2386+LOCAL_SRC_FILES := \
2387+ camera_service.cpp
2388+
2389+LOCAL_SHARED_LIBRARIES := \
2390+ libcameraservice \
2391+ libmedialogservice \
2392+ libcutils \
2393+ libmedia \
2394+ libmedia_compat_layer \
2395+ libmediaplayerservice \
2396+ libutils \
2397+ liblog \
2398+ libbinder
2399+
2400+LOCAL_C_INCLUDES := \
2401+ frameworks/av/media/libmediaplayerservice \
2402+ frameworks/av/services/medialog \
2403+ frameworks/av/services/camera/libcameraservice
2404+
2405+IS_ANDROID_5 := $(shell test $(ANDROID_VERSION_MAJOR) -eq 5 && echo true)
2406+ifeq ($(IS_ANDROID_5),true)
2407+LOCAL_C_INCLUDES += system/media/camera/include
2408+endif
2409+
2410+LOCAL_MODULE := camera_service
2411+
2412+LOCAL_32_BIT_ONLY := true
2413+
2414+include $(BUILD_EXECUTABLE)
2415+
2416+# -------------------------------------------------
2417+
2418+include $(CLEAR_VARS)
2419+include $(LOCAL_PATH)/../Android.common.mk
2420+
2421+HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
2422+
2423+LOCAL_CFLAGS += -std=gnu++0x
2424+
2425+ifeq ($(BOARD_HAS_MEDIA_PLAYER_PAUSE),true)
2426+LOCAL_CFLAGS += -DBOARD_HAS_MEDIA_PLAYER_PAUSE
2427+endif
2428+
2429+LOCAL_SRC_FILES:= \
2430+ media_compatibility_layer.cpp \
2431+ media_codec_layer.cpp \
2432+ media_codec_list.cpp \
2433+ media_format_layer.cpp \
2434+ surface_texture_client_hybris.cpp \
2435+ decoding_service.cpp \
2436+ media_recorder_layer.cpp \
2437+ media_recorder.cpp \
2438+ media_recorder_client.cpp \
2439+ media_recorder_factory.cpp \
2440+ media_recorder_observer.cpp
2441+
2442+LOCAL_MODULE:= libmedia_compat_layer
2443+LOCAL_MODULE_TAGS := optional
2444+
2445+LOCAL_SHARED_LIBRARIES := \
2446+ libcutils \
2447+ libcamera_client \
2448+ libutils \
2449+ libbinder \
2450+ libhardware \
2451+ libui \
2452+ libgui \
2453+ libstagefright \
2454+ libstagefright_foundation \
2455+ libEGL \
2456+ libGLESv2 \
2457+ libmedia \
2458+ libaudioutils \
2459+ libmediaplayerservice
2460+
2461+LOCAL_C_INCLUDES := \
2462+ $(HYBRIS_PATH)/include \
2463+ frameworks/base/media/libstagefright/include \
2464+ frameworks/base/include/media/stagefright \
2465+ frameworks/base/include/media \
2466+ frameworks/av/media \
2467+ frameworks/av/media/libstagefright/include \
2468+ frameworks/av/include \
2469+ frameworks/native/include \
2470+ system/media/audio_utils/include \
2471+ frameworks/av/services/camera/libcameraservice
2472+
2473+IS_ANDROID_5 := $(shell test $(ANDROID_VERSION_MAJOR) -eq 5 && echo true)
2474+ifeq ($(IS_ANDROID_5),true)
2475+LOCAL_C_INCLUDES += frameworks/native/include/media/openmax
2476+endif
2477+
2478+ifeq ($(strip $(MTK_CAMERA_BSP_SUPPORT)),yes)
2479+LOCAL_C_INCLUDES += $(TOP)/mediatek/kernel/include/linux/vcodec
2480+LOCAL_SHARED_LIBRARIES += \
2481+ libvcodecdrv
2482+
2483+LOCAL_C_INCLUDES+= \
2484+ $(TOP)/$(MTK_PATH_SOURCE)/frameworks-ext/av/media/libmediaplayerservice \
2485+ $(TOP)/$(MTK_PATH_SOURCE)/frameworks-ext/av/include \
2486+ $(TOP)/$(MTK_PATH_SOURCE)/frameworks-ext/av/media/libstagefright/include \
2487+ $(TOP)/$(MTK_PATH_PLATFORM)/frameworks/libmtkplayer \
2488+ $(TOP)/$(MTK_PATH_SOURCE)/frameworks/av/include
2489+endif
2490+
2491+LOCAL_32_BIT_ONLY := true
2492+
2493+include $(BUILD_SHARED_LIBRARY)
2494+
2495+# -------------------------------------------------
2496+
2497+include $(CLEAR_VARS)
2498+include $(LOCAL_PATH)/../Android.common.mk
2499+
2500+LOCAL_SRC_FILES:= \
2501+ direct_media_test.cpp
2502+
2503+LOCAL_MODULE:= direct_media_test
2504+LOCAL_MODULE_TAGS := optional
2505+
2506+LOCAL_C_INCLUDES := \
2507+ $(HYBRIS_PATH)/include \
2508+ bionic \
2509+ bionic/libstdc++/include \
2510+ external/gtest/include \
2511+ external/stlport/stlport \
2512+ external/skia/include/core \
2513+ frameworks/base/include
2514+
2515+LOCAL_SHARED_LIBRARIES := \
2516+ libis_compat_layer \
2517+ libsf_compat_layer \
2518+ libmedia_compat_layer \
2519+ libcutils \
2520+ libutils \
2521+ libbinder \
2522+ libhardware \
2523+ libui \
2524+ libgui \
2525+ libEGL \
2526+ libGLESv2
2527+
2528+LOCAL_32_BIT_ONLY := true
2529+
2530+include $(BUILD_EXECUTABLE)
2531+
2532+include $(CLEAR_VARS)
2533+include $(LOCAL_PATH)/../Android.common.mk
2534+
2535+LOCAL_CFLAGS += -Wno-multichar -D SIMPLE_PLAYER -std=gnu++0x
2536+
2537+LOCAL_SRC_FILES:= \
2538+ media_codec_layer.cpp \
2539+ media_codec_list.cpp \
2540+ media_format_layer.cpp \
2541+ codec.cpp \
2542+ SimplePlayer.cpp
2543+
2544+LOCAL_SHARED_LIBRARIES := \
2545+ libstagefright \
2546+ libstagefright_foundation \
2547+ liblog \
2548+ libutils \
2549+ libbinder \
2550+ libmedia \
2551+ libgui \
2552+ libcutils \
2553+ libui
2554+
2555+LOCAL_C_INCLUDES:= \
2556+ $(HYBRIS_PATH)/include \
2557+ frameworks/av/media/libstagefright \
2558+ frameworks/native/include/media/openmax \
2559+ frameworks/base/media/libstagefright/include \
2560+ frameworks/base/include/media/stagefright \
2561+ frameworks/base/include/media
2562+
2563+LOCAL_MODULE:= codec
2564+LOCAL_MODULE_TAGS := optional
2565+
2566+LOCAL_32_BIT_ONLY := true
2567+
2568+include $(BUILD_EXECUTABLE)
2569
2570=== added file 'android/compat/media/SimplePlayer.cpp'
2571--- android/compat/media/SimplePlayer.cpp 1970-01-01 00:00:00 +0000
2572+++ android/compat/media/SimplePlayer.cpp 2016-01-11 14:31:46 +0000
2573@@ -0,0 +1,777 @@
2574+/*
2575+ * Copyright (C) 2012 The Android Open Source Project
2576+ *
2577+ * Licensed under the Apache License, Version 2.0 (the "License");
2578+ * you may not use this file except in compliance with the License.
2579+ * You may obtain a copy of the License at
2580+ *
2581+ * http://www.apache.org/licenses/LICENSE-2.0
2582+ *
2583+ * Unless required by applicable law or agreed to in writing, software
2584+ * distributed under the License is distributed on an "AS IS" BASIS,
2585+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2586+ * See the License for the specific language governing permissions and
2587+ * limitations under the License.
2588+ */
2589+
2590+//#define LOG_NDEBUG 0
2591+#define LOG_TAG "SimplePlayer"
2592+#include <utils/Log.h>
2593+
2594+#include "SimplePlayer.h"
2595+
2596+#include <gui/Surface.h>
2597+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
2598+#include <gui/SurfaceTextureClient.h>
2599+#endif
2600+#include <media/AudioTrack.h>
2601+#include <media/ICrypto.h>
2602+#include <media/stagefright/foundation/ABuffer.h>
2603+#include <media/stagefright/foundation/ADebug.h>
2604+#include <media/stagefright/foundation/AMessage.h>
2605+#include <media/stagefright/MediaCodec.h>
2606+#include <media/stagefright/MediaErrors.h>
2607+#include <media/stagefright/NativeWindowWrapper.h>
2608+#include <media/stagefright/NuMediaExtractor.h>
2609+
2610+#define USE_MEDIA_CODEC_LAYER
2611+
2612+namespace android {
2613+
2614+SimplePlayer::SimplePlayer()
2615+ : mState(UNINITIALIZED),
2616+ mDoMoreStuffGeneration(0),
2617+ mStartTimeRealUs(-1ll) {
2618+}
2619+
2620+SimplePlayer::~SimplePlayer() {
2621+}
2622+
2623+// static
2624+status_t PostAndAwaitResponse(
2625+ const sp<AMessage> &msg, sp<AMessage> *response) {
2626+ status_t err = msg->postAndAwaitResponse(response);
2627+ printf("%s\n", __PRETTY_FUNCTION__);
2628+
2629+ if (err != OK) {
2630+ return err;
2631+ }
2632+
2633+ if (!(*response)->findInt32("err", &err)) {
2634+ err = OK;
2635+ }
2636+
2637+ return err;
2638+}
2639+status_t SimplePlayer::setDataSource(const char *path) {
2640+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
2641+ msg->setString("path", path);
2642+ sp<AMessage> response;
2643+ return PostAndAwaitResponse(msg, &response);
2644+}
2645+
2646+status_t SimplePlayer::setSurface(const sp<ISurfaceTexture> &surfaceTexture) {
2647+ sp<AMessage> msg = new AMessage(kWhatSetSurface, id());
2648+
2649+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
2650+ sp<SurfaceTextureClient> surfaceTextureClient;
2651+ if (surfaceTexture != NULL) {
2652+ surfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
2653+ }
2654+#else
2655+ sp<Surface> surfaceTextureClient;
2656+ if (surfaceTexture != NULL) {
2657+ surfaceTextureClient = new Surface(surfaceTexture);
2658+ }
2659+#endif
2660+
2661+ msg->setObject(
2662+ "native-window", new NativeWindowWrapper(surfaceTextureClient));
2663+
2664+ sp<AMessage> response;
2665+ return PostAndAwaitResponse(msg, &response);
2666+}
2667+
2668+status_t SimplePlayer::prepare() {
2669+ sp<AMessage> msg = new AMessage(kWhatPrepare, id());
2670+ sp<AMessage> response;
2671+ return PostAndAwaitResponse(msg, &response);
2672+}
2673+
2674+status_t SimplePlayer::start() {
2675+ printf("%s\n", __PRETTY_FUNCTION__);
2676+ sp<AMessage> msg = new AMessage(kWhatStart, id());
2677+ sp<AMessage> response;
2678+ return PostAndAwaitResponse(msg, &response);
2679+}
2680+
2681+status_t SimplePlayer::stop() {
2682+ sp<AMessage> msg = new AMessage(kWhatStop, id());
2683+ sp<AMessage> response;
2684+ return PostAndAwaitResponse(msg, &response);
2685+}
2686+
2687+status_t SimplePlayer::reset() {
2688+ sp<AMessage> msg = new AMessage(kWhatReset, id());
2689+ sp<AMessage> response;
2690+ return PostAndAwaitResponse(msg, &response);
2691+}
2692+
2693+void SimplePlayer::onMessageReceived(const sp<AMessage> &msg) {
2694+ switch (msg->what()) {
2695+ case kWhatSetDataSource:
2696+ {
2697+ status_t err;
2698+ if (mState != UNINITIALIZED) {
2699+ err = INVALID_OPERATION;
2700+ } else {
2701+ CHECK(msg->findString("path", &mPath));
2702+ mState = UNPREPARED;
2703+ }
2704+
2705+ uint32_t replyID;
2706+ CHECK(msg->senderAwaitsResponse(&replyID));
2707+
2708+ sp<AMessage> response = new AMessage;
2709+ response->setInt32("err", err);
2710+ response->postReply(replyID);
2711+ break;
2712+ }
2713+
2714+ case kWhatSetSurface:
2715+ {
2716+ status_t err;
2717+ if (mState != UNPREPARED) {
2718+ err = INVALID_OPERATION;
2719+ } else {
2720+ sp<RefBase> obj;
2721+ CHECK(msg->findObject("native-window", &obj));
2722+
2723+ mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
2724+
2725+ err = OK;
2726+ }
2727+
2728+ uint32_t replyID;
2729+ CHECK(msg->senderAwaitsResponse(&replyID));
2730+
2731+ sp<AMessage> response = new AMessage;
2732+ response->setInt32("err", err);
2733+ response->postReply(replyID);
2734+ break;
2735+ }
2736+
2737+ case kWhatPrepare:
2738+ {
2739+ status_t err;
2740+ if (mState != UNPREPARED) {
2741+ err = INVALID_OPERATION;
2742+ } else {
2743+ err = onPrepare();
2744+
2745+ if (err == OK) {
2746+ mState = STOPPED;
2747+ }
2748+ }
2749+
2750+ uint32_t replyID;
2751+ CHECK(msg->senderAwaitsResponse(&replyID));
2752+
2753+ sp<AMessage> response = new AMessage;
2754+ response->setInt32("err", err);
2755+ response->postReply(replyID);
2756+ break;
2757+ }
2758+
2759+ case kWhatStart:
2760+ {
2761+ status_t err = OK;
2762+
2763+ if (mState == UNPREPARED) {
2764+ err = onPrepare();
2765+
2766+ if (err == OK) {
2767+ mState = STOPPED;
2768+ }
2769+ }
2770+
2771+ if (err == OK) {
2772+ if (mState != STOPPED) {
2773+ err = INVALID_OPERATION;
2774+ } else {
2775+ err = onStart();
2776+
2777+ if (err == OK) {
2778+ mState = STARTED;
2779+ }
2780+ }
2781+ }
2782+
2783+ uint32_t replyID;
2784+ CHECK(msg->senderAwaitsResponse(&replyID));
2785+
2786+ sp<AMessage> response = new AMessage;
2787+ response->setInt32("err", err);
2788+ response->postReply(replyID);
2789+ break;
2790+ }
2791+
2792+ case kWhatStop:
2793+ {
2794+ status_t err;
2795+
2796+ if (mState != STARTED) {
2797+ err = INVALID_OPERATION;
2798+ } else {
2799+ err = onStop();
2800+
2801+ if (err == OK) {
2802+ mState = STOPPED;
2803+ }
2804+ }
2805+
2806+ uint32_t replyID;
2807+ CHECK(msg->senderAwaitsResponse(&replyID));
2808+
2809+ sp<AMessage> response = new AMessage;
2810+ response->setInt32("err", err);
2811+ response->postReply(replyID);
2812+ break;
2813+ }
2814+
2815+ case kWhatReset:
2816+ {
2817+ status_t err = OK;
2818+
2819+ if (mState == STARTED) {
2820+ CHECK_EQ(onStop(), (status_t)OK);
2821+ mState = STOPPED;
2822+ }
2823+
2824+ if (mState == STOPPED) {
2825+ err = onReset();
2826+ mState = UNINITIALIZED;
2827+ }
2828+
2829+ uint32_t replyID;
2830+ CHECK(msg->senderAwaitsResponse(&replyID));
2831+
2832+ sp<AMessage> response = new AMessage;
2833+ response->setInt32("err", err);
2834+ response->postReply(replyID);
2835+ break;
2836+ }
2837+
2838+ case kWhatDoMoreStuff:
2839+ {
2840+ int32_t generation;
2841+ CHECK(msg->findInt32("generation", &generation));
2842+
2843+ if (generation != mDoMoreStuffGeneration) {
2844+ break;
2845+ }
2846+
2847+ status_t err = onDoMoreStuff();
2848+
2849+ if (err == OK) {
2850+ msg->post(10000ll);
2851+ }
2852+ break;
2853+ }
2854+
2855+ default:
2856+ TRESPASS();
2857+ }
2858+}
2859+
2860+status_t SimplePlayer::onPrepare() {
2861+ CHECK_EQ(mState, UNPREPARED);
2862+ printf("%s\n", __PRETTY_FUNCTION__);
2863+
2864+ mExtractor = new NuMediaExtractor;
2865+
2866+ status_t err = mExtractor->setDataSource(mPath.c_str());
2867+
2868+ if (err != OK) {
2869+ mExtractor.clear();
2870+ return err;
2871+ }
2872+
2873+ if (mCodecLooper == NULL) {
2874+ mCodecLooper = new ALooper;
2875+ mCodecLooper->start();
2876+ }
2877+
2878+ bool haveAudio = false;
2879+ bool haveVideo = false;
2880+ for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
2881+ sp<AMessage> format;
2882+ status_t err = mExtractor->getTrackFormat(i, &format);
2883+ CHECK_EQ(err, (status_t)OK);
2884+
2885+ AString mime;
2886+ int32_t width = 0, height = 0, maxInputSize = 0;
2887+ int64_t durationUs = 0;
2888+ sp<ABuffer> csd0, csd1;
2889+#ifdef USE_MEDIA_CODEC_LAYER
2890+ MediaFormat mformat;
2891+#endif
2892+ CHECK(format->findString("mime", &mime));
2893+
2894+ if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) {
2895+ //haveAudio = true;
2896+ printf("*** Have audio but skipping it!\n");
2897+ continue;
2898+ } else if (!haveVideo && !strncasecmp(mime.c_str(), "video/", 6)) {
2899+ haveVideo = true;
2900+ CHECK(format->findInt32("width", &width));
2901+ CHECK(format->findInt32("height", &height));
2902+ CHECK(format->findInt64("durationUs", &durationUs));
2903+ CHECK(format->findInt32("max-input-size", &maxInputSize));
2904+ CHECK(format->findBuffer("csd-0", &csd0));
2905+ CHECK(format->findBuffer("csd-1", &csd1));
2906+#ifdef USE_MEDIA_CODEC_LAYER
2907+ mformat = media_format_create_video_format(mime.c_str(), width, height, durationUs, maxInputSize);
2908+ media_format_set_byte_buffer(mformat, "csd-0", csd0->data(), csd0->size());
2909+ media_format_set_byte_buffer(mformat, "csd-1", csd1->data(), csd1->size());
2910+#endif
2911+ } else {
2912+ continue;
2913+ }
2914+
2915+ err = mExtractor->selectTrack(i);
2916+ CHECK_EQ(err, (status_t)OK);
2917+
2918+ CodecState *state =
2919+ &mStateByTrackIndex.editValueAt(
2920+ mStateByTrackIndex.add(i, CodecState()));
2921+
2922+ state->mNumFramesWritten = 0;
2923+#ifdef USE_MEDIA_CODEC_LAYER
2924+ state->mCodecDelegate = media_codec_create_by_codec_type(mime.c_str());
2925+ state->mCodec = media_codec_get(state->mCodecDelegate);
2926+ CHECK(state->mCodecDelegate != NULL);
2927+#else
2928+ state->mCodec = MediaCodec::CreateByType(
2929+ mCodecLooper, mime.c_str(), false /* encoder */);
2930+#endif
2931+
2932+ CHECK(state->mCodec != NULL);
2933+
2934+#ifdef USE_MEDIA_CODEC_LAYER
2935+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
2936+ err = media_codec_configure(state->mCodecDelegate, mformat, mNativeWindow->getSurfaceTextureClient().get(), 0);
2937+#else
2938+ err = media_codec_configure(state->mCodecDelegate, mformat, mNativeWindow->getSurface().get(), 0);
2939+#endif
2940+#else
2941+ err = state->mCodec->configure(
2942+ format,
2943+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
2944+ mNativeWindow->getSurfaceTextureClient(),
2945+#else
2946+ mNativeWindow->getSurface(),
2947+#endif
2948+ NULL /* crypto */,
2949+ 0 /* flags */);
2950+#endif
2951+
2952+ CHECK_EQ(err, (status_t)OK);
2953+
2954+ size_t j = 0;
2955+ sp<ABuffer> buffer;
2956+ // Place the CSD data into the source buffer
2957+ while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
2958+ state->mCSD.push_back(buffer);
2959+
2960+ ++j;
2961+ }
2962+ }
2963+
2964+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
2965+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
2966+
2967+#ifdef USE_MEDIA_CODEC_LAYER
2968+ status_t err = media_codec_start(state->mCodecDelegate);
2969+#else
2970+ status_t err = state->mCodec->start();
2971+#endif
2972+ CHECK_EQ(err, (status_t)OK);
2973+
2974+#ifdef USE_MEDIA_CODEC_LAYER
2975+ size_t nInputBuffers = media_codec_get_input_buffers_size(state->mCodecDelegate);
2976+ ALOGD("nInputBuffers: %u", nInputBuffers);
2977+ for (size_t i=0; i<nInputBuffers; i++)
2978+ {
2979+ uint8_t *data = media_codec_get_nth_input_buffer(state->mCodecDelegate, i);
2980+ CHECK(data != NULL);
2981+ size_t size = media_codec_get_nth_input_buffer_capacity(state->mCodecDelegate, i);
2982+ ALOGD("input buffer[%d] size: %d", i, size);
2983+ sp<ABuffer> buf = new ABuffer(data, size);
2984+ state->mBuffers[0].insertAt(new ABuffer(data, size), i);
2985+ }
2986+#else
2987+ err = state->mCodec->getInputBuffers(&state->mBuffers[0]);
2988+ CHECK_EQ(err, (status_t)OK);
2989+#endif
2990+
2991+ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
2992+ CHECK_EQ(err, (status_t)OK);
2993+
2994+ for (size_t j = 0; j < state->mCSD.size(); ++j) {
2995+ const sp<ABuffer> &srcBuffer = state->mCSD.itemAt(j);
2996+
2997+ size_t index;
2998+#ifdef USE_MEDIA_CODEC_LAYER
2999+ err = media_codec_dequeue_input_buffer(state->mCodecDelegate, &index, -1ll);
3000+#else
3001+ err = state->mCodec->dequeueInputBuffer(&index, -1ll);
3002+#endif
3003+ CHECK_EQ(err, (status_t)OK);
3004+
3005+ const sp<ABuffer> &dstBuffer = state->mBuffers[0].itemAt(index);
3006+
3007+ CHECK_LE(srcBuffer->size(), dstBuffer->capacity());
3008+ dstBuffer->setRange(0, srcBuffer->size());
3009+ memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size());
3010+
3011+#ifdef USE_MEDIA_CODEC_LAYER
3012+ MediaCodecBufferInfo bufInfo;
3013+ bufInfo.index = index;
3014+ bufInfo.offset = 0;
3015+ bufInfo.size = dstBuffer->size();
3016+ bufInfo.presentation_time_us = 0ll;
3017+ bufInfo.flags = MediaCodec::BUFFER_FLAG_CODECCONFIG;
3018+
3019+ err = media_codec_queue_input_buffer(
3020+ state->mCodecDelegate,
3021+ &bufInfo);
3022+
3023+#else
3024+ err = state->mCodec->queueInputBuffer(
3025+ index,
3026+ 0,
3027+ dstBuffer->size(),
3028+ 0ll,
3029+ MediaCodec::BUFFER_FLAG_CODECCONFIG);
3030+#endif
3031+ CHECK_EQ(err, (status_t)OK);
3032+ }
3033+ }
3034+
3035+ return OK;
3036+}
3037+
3038+status_t SimplePlayer::onStart() {
3039+ CHECK_EQ(mState, STOPPED);
3040+
3041+ mStartTimeRealUs = -1ll;
3042+
3043+ sp<AMessage> msg = new AMessage(kWhatDoMoreStuff, id());
3044+ msg->setInt32("generation", ++mDoMoreStuffGeneration);
3045+ msg->post();
3046+
3047+ return OK;
3048+}
3049+
3050+status_t SimplePlayer::onStop() {
3051+ CHECK_EQ(mState, STARTED);
3052+
3053+ ++mDoMoreStuffGeneration;
3054+
3055+ return OK;
3056+}
3057+
3058+status_t SimplePlayer::onReset() {
3059+ CHECK_EQ(mState, STOPPED);
3060+
3061+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
3062+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
3063+
3064+ CHECK_EQ(state->mCodec->release(), (status_t)OK);
3065+ }
3066+
3067+ mStartTimeRealUs = -1ll;
3068+
3069+ mStateByTrackIndex.clear();
3070+ mCodecLooper.clear();
3071+ mExtractor.clear();
3072+ mNativeWindow.clear();
3073+ mPath.clear();
3074+
3075+ return OK;
3076+}
3077+
3078+status_t SimplePlayer::onDoMoreStuff() {
3079+ ALOGV("onDoMoreStuff");
3080+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
3081+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
3082+
3083+ status_t err;
3084+ do {
3085+ size_t index;
3086+#ifdef USE_MEDIA_CODEC_LAYER
3087+ err = media_codec_dequeue_input_buffer(state->mCodecDelegate, &index, 0ll);
3088+#else
3089+ err = state->mCodec->dequeueInputBuffer(&index);
3090+#endif
3091+
3092+ if (err == OK) {
3093+ ALOGD("dequeued input buffer on track %d",
3094+ mStateByTrackIndex.keyAt(i));
3095+
3096+ state->mAvailInputBufferIndices.push_back(index);
3097+ } else {
3098+ ALOGD("dequeueInputBuffer on track %d returned %d",
3099+ mStateByTrackIndex.keyAt(i), err);
3100+ }
3101+ } while (err == OK);
3102+
3103+ do {
3104+#ifdef USE_MEDIA_CODEC_LAYER
3105+ BufferInfo info;
3106+ MediaCodecBufferInfo bufInfo;
3107+ err = media_codec_dequeue_output_buffer(
3108+ state->mCodecDelegate,
3109+ &bufInfo,
3110+ 0ll);
3111+
3112+ info.mIndex = bufInfo.index;
3113+ info.mOffset = bufInfo.offset;
3114+ info.mSize = bufInfo.size;
3115+ info.mPresentationTimeUs = bufInfo.presentation_time_us;
3116+ info.mFlags = bufInfo.flags;
3117+
3118+#else
3119+ BufferInfo info;
3120+ err = state->mCodec->dequeueOutputBuffer(
3121+ &info.mIndex,
3122+ &info.mOffset,
3123+ &info.mSize,
3124+ &info.mPresentationTimeUs,
3125+ &info.mFlags);
3126+#endif
3127+
3128+ if (err == OK) {
3129+ ALOGV("dequeued output buffer on track %d",
3130+ mStateByTrackIndex.keyAt(i));
3131+
3132+ state->mAvailOutputBufferInfos.push_back(info);
3133+ } else if (err == INFO_FORMAT_CHANGED) {
3134+ err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state);
3135+ CHECK_EQ(err, (status_t)OK);
3136+ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
3137+ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
3138+ CHECK_EQ(err, (status_t)OK);
3139+ } else {
3140+ ALOGV("dequeueOutputBuffer on track %d returned %d",
3141+ mStateByTrackIndex.keyAt(i), err);
3142+ }
3143+ } while (err == OK
3144+ || err == INFO_FORMAT_CHANGED
3145+ || err == INFO_OUTPUT_BUFFERS_CHANGED);
3146+ }
3147+
3148+ for (;;) {
3149+ size_t trackIndex;
3150+ status_t err = mExtractor->getSampleTrackIndex(&trackIndex);
3151+
3152+ if (err != OK) {
3153+ ALOGI("encountered input EOS.");
3154+ break;
3155+ } else {
3156+ CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex);
3157+
3158+ if (state->mAvailInputBufferIndices.empty()) {
3159+ break;
3160+ }
3161+
3162+ size_t index = *state->mAvailInputBufferIndices.begin();
3163+ state->mAvailInputBufferIndices.erase(
3164+ state->mAvailInputBufferIndices.begin());
3165+
3166+ const sp<ABuffer> &dstBuffer =
3167+ state->mBuffers[0].itemAt(index);
3168+
3169+ err = mExtractor->readSampleData(dstBuffer);
3170+ CHECK_EQ(err, (status_t)OK);
3171+
3172+ int64_t timeUs;
3173+ CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK);
3174+
3175+#ifdef USE_MEDIA_CODEC_LAYER
3176+ MediaCodecBufferInfo bufInfo;
3177+ bufInfo.index = index;
3178+ bufInfo.offset = dstBuffer->offset();
3179+ bufInfo.size = dstBuffer->size();
3180+ bufInfo.presentation_time_us = timeUs;
3181+ bufInfo.flags = 0;
3182+
3183+ err = media_codec_queue_input_buffer(
3184+ state->mCodecDelegate,
3185+ &bufInfo);
3186+
3187+#else
3188+ err = state->mCodec->queueInputBuffer(
3189+ index,
3190+ dstBuffer->offset(),
3191+ dstBuffer->size(),
3192+ timeUs,
3193+ 0);
3194+#endif
3195+ CHECK_EQ(err, (status_t)OK);
3196+
3197+ ALOGV("enqueued input data on track %d", trackIndex);
3198+
3199+ err = mExtractor->advance();
3200+ CHECK_EQ(err, (status_t)OK);
3201+ }
3202+ }
3203+
3204+ int64_t nowUs = ALooper::GetNowUs();
3205+
3206+ if (mStartTimeRealUs < 0ll) {
3207+ mStartTimeRealUs = nowUs + 1000000ll;
3208+ }
3209+
3210+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
3211+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
3212+
3213+ while (!state->mAvailOutputBufferInfos.empty()) {
3214+ BufferInfo *info = &*state->mAvailOutputBufferInfos.begin();
3215+
3216+ int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs;
3217+ int64_t lateByUs = nowUs - whenRealUs;
3218+
3219+ if (lateByUs > -10000ll) {
3220+ bool release = true;
3221+
3222+ if (lateByUs > 30000ll) {
3223+ ALOGI("track %d buffer late by %lld us, dropping.",
3224+ mStateByTrackIndex.keyAt(i), lateByUs);
3225+ state->mCodec->releaseOutputBuffer(info->mIndex);
3226+ } else {
3227+ if (state->mAudioTrack != NULL) {
3228+ const sp<ABuffer> &srcBuffer =
3229+ state->mBuffers[1].itemAt(info->mIndex);
3230+
3231+ renderAudio(state, info, srcBuffer);
3232+
3233+ if (info->mSize > 0) {
3234+ release = false;
3235+ }
3236+ }
3237+
3238+ if (release) {
3239+#ifdef USE_MEDIA_CODEC_LAYER
3240+ ALOGD("Rendering output buffer index %d and releasing", info->mIndex);
3241+ state->mCodec->renderOutputBufferAndRelease(
3242+ info->mIndex);
3243+#else
3244+ ALOGD("Releasing output buffer index %d", info->mIndex);
3245+ state->mCodec->releaseOutputBuffer(info->mIndex);
3246+#endif
3247+ }
3248+ }
3249+
3250+ if (release) {
3251+ state->mAvailOutputBufferInfos.erase(
3252+ state->mAvailOutputBufferInfos.begin());
3253+
3254+ info = NULL;
3255+ } else {
3256+ break;
3257+ }
3258+ } else {
3259+ ALOGV("track %d buffer early by %lld us.",
3260+ mStateByTrackIndex.keyAt(i), -lateByUs);
3261+ break;
3262+ }
3263+ }
3264+ }
3265+
3266+ return OK;
3267+}
3268+
3269+status_t SimplePlayer::onOutputFormatChanged(
3270+ size_t trackIndex, CodecState *state) {
3271+ sp<AMessage> format;
3272+ status_t err = state->mCodec->getOutputFormat(&format);
3273+
3274+ if (err != OK) {
3275+ return err;
3276+ }
3277+
3278+ AString mime;
3279+ CHECK(format->findString("mime", &mime));
3280+
3281+ if (!strncasecmp(mime.c_str(), "audio/", 6)) {
3282+ int32_t channelCount;
3283+ int32_t sampleRate;
3284+ CHECK(format->findInt32("channel-count", &channelCount));
3285+ CHECK(format->findInt32("sample-rate", &sampleRate));
3286+
3287+ state->mAudioTrack = new AudioTrack(
3288+ AUDIO_STREAM_MUSIC,
3289+ sampleRate,
3290+ AUDIO_FORMAT_PCM_16_BIT,
3291+ audio_channel_out_mask_from_count(channelCount),
3292+ 0);
3293+
3294+ state->mNumFramesWritten = 0;
3295+ }
3296+
3297+ return OK;
3298+}
3299+
3300+void SimplePlayer::renderAudio(
3301+ CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer) {
3302+ CHECK(state->mAudioTrack != NULL);
3303+
3304+ if (state->mAudioTrack->stopped()) {
3305+ state->mAudioTrack->start();
3306+ }
3307+
3308+ uint32_t numFramesPlayed;
3309+ CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK);
3310+
3311+ uint32_t numFramesAvailableToWrite =
3312+ state->mAudioTrack->frameCount()
3313+ - (state->mNumFramesWritten - numFramesPlayed);
3314+
3315+ size_t numBytesAvailableToWrite =
3316+ numFramesAvailableToWrite * state->mAudioTrack->frameSize();
3317+
3318+ size_t copy = info->mSize;
3319+ if (copy > numBytesAvailableToWrite) {
3320+ copy = numBytesAvailableToWrite;
3321+ }
3322+
3323+ if (copy == 0) {
3324+ return;
3325+ }
3326+
3327+ int64_t startTimeUs = ALooper::GetNowUs();
3328+
3329+ ssize_t nbytes = state->mAudioTrack->write(
3330+ buffer->base() + info->mOffset, copy);
3331+
3332+ CHECK_EQ(nbytes, (ssize_t)copy);
3333+
3334+ int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
3335+
3336+ uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize();
3337+
3338+ if (delayUs > 2000ll) {
3339+ ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, "
3340+ "numFramesWritten=%u",
3341+ delayUs, numFramesAvailableToWrite, numFramesWritten);
3342+ }
3343+
3344+ info->mOffset += nbytes;
3345+ info->mSize -= nbytes;
3346+
3347+ state->mNumFramesWritten += numFramesWritten;
3348+}
3349+
3350+} // namespace android
3351
3352=== added file 'android/compat/media/SimplePlayer.h'
3353--- android/compat/media/SimplePlayer.h 1970-01-01 00:00:00 +0000
3354+++ android/compat/media/SimplePlayer.h 2016-01-11 14:31:46 +0000
3355@@ -0,0 +1,120 @@
3356+/*
3357+ * Copyright (C) 2012 The Android Open Source Project
3358+ *
3359+ * Licensed under the Apache License, Version 2.0 (the "License");
3360+ * you may not use this file except in compliance with the License.
3361+ * You may obtain a copy of the License at
3362+ *
3363+ * http://www.apache.org/licenses/LICENSE-2.0
3364+ *
3365+ * Unless required by applicable law or agreed to in writing, software
3366+ * distributed under the License is distributed on an "AS IS" BASIS,
3367+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3368+ * See the License for the specific language governing permissions and
3369+ * limitations under the License.
3370+ */
3371+
3372+#include <media/stagefright/foundation/AHandler.h>
3373+#include <media/stagefright/foundation/AString.h>
3374+#include <utils/KeyedVector.h>
3375+
3376+#include <hybris/media/media_codec_layer.h>
3377+
3378+namespace android {
3379+
3380+struct ABuffer;
3381+struct ALooper;
3382+struct AudioTrack;
3383+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3384+struct ISurfaceTexture;
3385+#else
3386+struct IGraphicBufferProducer;
3387+#endif
3388+struct MediaCodec;
3389+struct NativeWindowWrapper;
3390+struct NuMediaExtractor;
3391+
3392+struct SimplePlayer : public AHandler {
3393+ SimplePlayer();
3394+
3395+ status_t setDataSource(const char *path);
3396+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3397+ status_t setSurface(const sp<ISurfaceTexture> &surfaceTexture);
3398+#else
3399+ status_t setSurface(const sp<IGraphicBufferProducer> &surfaceTexture);
3400+#endif
3401+ status_t prepare();
3402+ status_t start();
3403+ status_t stop();
3404+ status_t reset();
3405+
3406+protected:
3407+ virtual ~SimplePlayer();
3408+
3409+ virtual void onMessageReceived(const sp<AMessage> &msg);
3410+
3411+private:
3412+ enum State {
3413+ UNINITIALIZED,
3414+ UNPREPARED,
3415+ STOPPED,
3416+ STARTED
3417+ };
3418+
3419+ enum {
3420+ kWhatSetDataSource,
3421+ kWhatSetSurface,
3422+ kWhatPrepare,
3423+ kWhatStart,
3424+ kWhatStop,
3425+ kWhatReset,
3426+ kWhatDoMoreStuff,
3427+ };
3428+
3429+ struct BufferInfo {
3430+ size_t mIndex;
3431+ size_t mOffset;
3432+ size_t mSize;
3433+ int64_t mPresentationTimeUs;
3434+ uint32_t mFlags;
3435+ };
3436+
3437+ struct CodecState
3438+ {
3439+ sp<MediaCodec> mCodec;
3440+ MediaCodecDelegate mCodecDelegate;
3441+ Vector<sp<ABuffer> > mCSD;
3442+ Vector<sp<ABuffer> > mBuffers[2];
3443+
3444+ List<size_t> mAvailInputBufferIndices;
3445+ List<BufferInfo> mAvailOutputBufferInfos;
3446+
3447+ sp<AudioTrack> mAudioTrack;
3448+ uint32_t mNumFramesWritten;
3449+ };
3450+
3451+ State mState;
3452+ AString mPath;
3453+ sp<NativeWindowWrapper> mNativeWindow;
3454+
3455+ sp<NuMediaExtractor> mExtractor;
3456+ sp<ALooper> mCodecLooper;
3457+ KeyedVector<size_t, CodecState> mStateByTrackIndex;
3458+ int32_t mDoMoreStuffGeneration;
3459+
3460+ int64_t mStartTimeRealUs;
3461+
3462+ status_t onPrepare();
3463+ status_t onStart();
3464+ status_t onStop();
3465+ status_t onReset();
3466+ status_t onDoMoreStuff();
3467+ status_t onOutputFormatChanged(size_t trackIndex, CodecState *state);
3468+
3469+ void renderAudio(
3470+ CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer);
3471+
3472+ DISALLOW_EVIL_CONSTRUCTORS(SimplePlayer);
3473+};
3474+
3475+} // namespace android
3476
3477=== added file 'android/compat/media/camera_service.cpp'
3478--- android/compat/media/camera_service.cpp 1970-01-01 00:00:00 +0000
3479+++ android/compat/media/camera_service.cpp 2016-01-11 14:31:46 +0000
3480@@ -0,0 +1,52 @@
3481+/*
3482+ * Copyright (C) 2014 Canonical Ltd
3483+ *
3484+ * Licensed under the Apache License, Version 2.0 (the "License");
3485+ * you may not use this file except in compliance with the License.
3486+ * You may obtain a copy of the License at
3487+ *
3488+ * http://www.apache.org/licenses/LICENSE-2.0
3489+ *
3490+ * Unless required by applicable law or agreed to in writing, software
3491+ * distributed under the License is distributed on an "AS IS" BASIS,
3492+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3493+ * See the License for the specific language governing permissions and
3494+ * limitations under the License.
3495+ *
3496+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
3497+ */
3498+
3499+#define LOG_NDEBUG 0
3500+#undef LOG_TAG
3501+#define LOG_TAG "CameraServiceCompatLayer"
3502+
3503+#include "media_recorder_factory.h"
3504+#include "media_recorder.h"
3505+
3506+#include <media/camera_record_service.h>
3507+#include <CameraService.h>
3508+
3509+#include <signal.h>
3510+
3511+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
3512+
3513+using namespace android;
3514+
3515+/*!
3516+ * \brief main() instantiates the MediaRecorderFactory Binder server and the CameraService
3517+ */
3518+int main(int argc, char** argv)
3519+{
3520+ signal(SIGPIPE, SIG_IGN);
3521+
3522+ ALOGV("Starting camera services (MediaRecorderFactory, CameraRecordService & CameraService)");
3523+
3524+ // Instantiate the in-process MediaRecorderFactory which is responsible
3525+ // for creating a new IMediaRecorder (MediaRecorder) instance over Binder
3526+ MediaRecorderFactory::instantiate();
3527+ // Enable audio recording for camera recording
3528+ CameraRecordService::instantiate();
3529+ CameraService::instantiate();
3530+ ProcessState::self()->startThreadPool();
3531+ IPCThreadState::self()->joinThreadPool();
3532+}
3533
3534=== added file 'android/compat/media/codec.cpp'
3535--- android/compat/media/codec.cpp 1970-01-01 00:00:00 +0000
3536+++ android/compat/media/codec.cpp 2016-01-11 14:31:46 +0000
3537@@ -0,0 +1,433 @@
3538+/*
3539+ * Copyright (C) 2012 The Android Open Source Project
3540+ *
3541+ * Licensed under the Apache License, Version 2.0 (the "License");
3542+ * you may not use this file except in compliance with the License.
3543+ * You may obtain a copy of the License at
3544+ *
3545+ * http://www.apache.org/licenses/LICENSE-2.0
3546+ *
3547+ * Unless required by applicable law or agreed to in writing, software
3548+ * distributed under the License is distributed on an "AS IS" BASIS,
3549+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3550+ * See the License for the specific language governing permissions and
3551+ * limitations under the License.
3552+ */
3553+
3554+#define LOG_NDEBUG 0
3555+#define LOG_TAG "codec"
3556+#include <utils/Log.h>
3557+
3558+#include "SimplePlayer.h"
3559+
3560+#include <binder/IServiceManager.h>
3561+#include <binder/ProcessState.h>
3562+#include <media/ICrypto.h>
3563+#include <media/IMediaPlayerService.h>
3564+#include <media/stagefright/foundation/ABuffer.h>
3565+#include <media/stagefright/foundation/ADebug.h>
3566+#include <media/stagefright/foundation/ALooper.h>
3567+#include <media/stagefright/foundation/AMessage.h>
3568+#include <media/stagefright/foundation/AString.h>
3569+#include <media/stagefright/DataSource.h>
3570+#include <media/stagefright/MediaCodec.h>
3571+#include <media/stagefright/MediaCodecList.h>
3572+#include <media/stagefright/MediaDefs.h>
3573+#include <media/stagefright/NuMediaExtractor.h>
3574+#include <gui/ISurfaceComposer.h>
3575+#include <gui/SurfaceComposerClient.h>
3576+#include <ui/DisplayInfo.h>
3577+
3578+static void usage(const char *me) {
3579+ fprintf(stderr, "usage: %s [-a] use audio\n"
3580+ "\t\t[-v] use video\n"
3581+ "\t\t[-p] playback\n"
3582+ "\t\t[-S] allocate buffers from a surface\n",
3583+ me);
3584+
3585+ exit(1);
3586+}
3587+
3588+namespace android {
3589+
3590+struct CodecState {
3591+ sp<MediaCodec> mCodec;
3592+ Vector<sp<ABuffer> > mInBuffers;
3593+ Vector<sp<ABuffer> > mOutBuffers;
3594+ bool mSignalledInputEOS;
3595+ bool mSawOutputEOS;
3596+ int64_t mNumBuffersDecoded;
3597+ int64_t mNumBytesDecoded;
3598+ bool mIsAudio;
3599+};
3600+
3601+} // namespace android
3602+
3603+static int decode(
3604+ const android::sp<android::ALooper> &looper,
3605+ const char *path,
3606+ bool useAudio,
3607+ bool useVideo,
3608+ const android::sp<android::Surface> &surface) {
3609+ using namespace android;
3610+
3611+ static int64_t kTimeout = 500ll;
3612+
3613+ sp<NuMediaExtractor> extractor = new NuMediaExtractor;
3614+ if (extractor->setDataSource(path) != OK) {
3615+ fprintf(stderr, "unable to instantiate extractor.\n");
3616+ return 1;
3617+ }
3618+
3619+ KeyedVector<size_t, CodecState> stateByTrack;
3620+
3621+ bool haveAudio = false;
3622+ bool haveVideo = false;
3623+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
3624+ sp<AMessage> format;
3625+ status_t err = extractor->getTrackFormat(i, &format);
3626+ CHECK_EQ(err, (status_t)OK);
3627+
3628+ AString mime;
3629+ CHECK(format->findString("mime", &mime));
3630+
3631+ bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
3632+ bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
3633+
3634+ if (useAudio && !haveAudio && isAudio) {
3635+ haveAudio = true;
3636+ } else if (useVideo && !haveVideo && isVideo) {
3637+ haveVideo = true;
3638+ } else {
3639+ continue;
3640+ }
3641+
3642+ ALOGV("selecting track %d", i);
3643+
3644+ err = extractor->selectTrack(i);
3645+ CHECK_EQ(err, (status_t)OK);
3646+
3647+ CodecState *state =
3648+ &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
3649+
3650+ state->mNumBytesDecoded = 0;
3651+ state->mNumBuffersDecoded = 0;
3652+ state->mIsAudio = isAudio;
3653+
3654+ state->mCodec = MediaCodec::CreateByType(
3655+ looper, mime.c_str(), false /* encoder */);
3656+
3657+ CHECK(state->mCodec != NULL);
3658+
3659+ err = state->mCodec->configure(
3660+ format, isVideo ? surface : NULL,
3661+ NULL /* crypto */,
3662+ 0 /* flags */);
3663+
3664+ CHECK_EQ(err, (status_t)OK);
3665+
3666+ state->mSignalledInputEOS = false;
3667+ state->mSawOutputEOS = false;
3668+ }
3669+
3670+ CHECK(!stateByTrack.isEmpty());
3671+
3672+ int64_t startTimeUs = ALooper::GetNowUs();
3673+
3674+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
3675+ CodecState *state = &stateByTrack.editValueAt(i);
3676+
3677+ sp<MediaCodec> codec = state->mCodec;
3678+
3679+ CHECK_EQ((status_t)OK, codec->start());
3680+
3681+ CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
3682+ CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers));
3683+
3684+ ALOGV("got %d input and %d output buffers",
3685+ state->mInBuffers.size(), state->mOutBuffers.size());
3686+ }
3687+
3688+ bool sawInputEOS = false;
3689+
3690+ for (;;) {
3691+ if (!sawInputEOS) {
3692+ size_t trackIndex;
3693+ status_t err = extractor->getSampleTrackIndex(&trackIndex);
3694+
3695+ if (err != OK) {
3696+ ALOGV("saw input eos");
3697+ sawInputEOS = true;
3698+ } else {
3699+ CodecState *state = &stateByTrack.editValueFor(trackIndex);
3700+
3701+ size_t index;
3702+ err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
3703+
3704+ if (err == OK) {
3705+ ALOGV("filling input buffer %d", index);
3706+
3707+ const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
3708+
3709+ err = extractor->readSampleData(buffer);
3710+ CHECK_EQ(err, (status_t)OK);
3711+
3712+ int64_t timeUs;
3713+ err = extractor->getSampleTime(&timeUs);
3714+ CHECK_EQ(err, (status_t)OK);
3715+
3716+ uint32_t bufferFlags = 0;
3717+
3718+ err = state->mCodec->queueInputBuffer(
3719+ index,
3720+ 0 /* offset */,
3721+ buffer->size(),
3722+ timeUs,
3723+ bufferFlags);
3724+
3725+ CHECK_EQ(err, (status_t)OK);
3726+
3727+ extractor->advance();
3728+ } else {
3729+ CHECK_EQ(err, -EAGAIN);
3730+ }
3731+ }
3732+ } else {
3733+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
3734+ CodecState *state = &stateByTrack.editValueAt(i);
3735+
3736+ if (!state->mSignalledInputEOS) {
3737+ size_t index;
3738+ status_t err =
3739+ state->mCodec->dequeueInputBuffer(&index, kTimeout);
3740+
3741+ if (err == OK) {
3742+ ALOGV("signalling input EOS on track %d", i);
3743+
3744+ err = state->mCodec->queueInputBuffer(
3745+ index,
3746+ 0 /* offset */,
3747+ 0 /* size */,
3748+ 0ll /* timeUs */,
3749+ MediaCodec::BUFFER_FLAG_EOS);
3750+
3751+ CHECK_EQ(err, (status_t)OK);
3752+
3753+ state->mSignalledInputEOS = true;
3754+ } else {
3755+ CHECK_EQ(err, -EAGAIN);
3756+ }
3757+ }
3758+ }
3759+ }
3760+
3761+ bool sawOutputEOSOnAllTracks = true;
3762+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
3763+ CodecState *state = &stateByTrack.editValueAt(i);
3764+ if (!state->mSawOutputEOS) {
3765+ sawOutputEOSOnAllTracks = false;
3766+ break;
3767+ }
3768+ }
3769+
3770+ if (sawOutputEOSOnAllTracks) {
3771+ break;
3772+ }
3773+
3774+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
3775+ CodecState *state = &stateByTrack.editValueAt(i);
3776+
3777+ if (state->mSawOutputEOS) {
3778+ continue;
3779+ }
3780+
3781+ size_t index;
3782+ size_t offset;
3783+ size_t size;
3784+ int64_t presentationTimeUs;
3785+ uint32_t flags;
3786+ status_t err = state->mCodec->dequeueOutputBuffer(
3787+ &index, &offset, &size, &presentationTimeUs, &flags,
3788+ kTimeout);
3789+
3790+ if (err == OK) {
3791+ ALOGV("draining output buffer %d, time = %lld us",
3792+ index, presentationTimeUs);
3793+
3794+ ++state->mNumBuffersDecoded;
3795+ state->mNumBytesDecoded += size;
3796+
3797+ err = state->mCodec->releaseOutputBuffer(index);
3798+ CHECK_EQ(err, (status_t)OK);
3799+
3800+ if (flags & MediaCodec::BUFFER_FLAG_EOS) {
3801+ ALOGV("reached EOS on output.");
3802+
3803+ state->mSawOutputEOS = true;
3804+ }
3805+ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
3806+ ALOGV("INFO_OUTPUT_BUFFERS_CHANGED");
3807+ CHECK_EQ((status_t)OK,
3808+ state->mCodec->getOutputBuffers(&state->mOutBuffers));
3809+
3810+ ALOGV("got %d output buffers", state->mOutBuffers.size());
3811+ } else if (err == INFO_FORMAT_CHANGED) {
3812+ sp<AMessage> format;
3813+ CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format));
3814+
3815+ ALOGV("INFO_FORMAT_CHANGED: %s", format->debugString().c_str());
3816+ } else {
3817+ CHECK_EQ(err, -EAGAIN);
3818+ }
3819+ }
3820+ }
3821+
3822+ int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
3823+
3824+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
3825+ CodecState *state = &stateByTrack.editValueAt(i);
3826+
3827+ CHECK_EQ((status_t)OK, state->mCodec->release());
3828+
3829+ if (state->mIsAudio) {
3830+ ALOGD("track %d: %lld bytes received. %.2f KB/sec\n",
3831+ i,
3832+ state->mNumBytesDecoded,
3833+ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
3834+ } else {
3835+ ALOGD("track %d: %lld frames decoded, %.2f fps. %lld bytes "
3836+ "received. %.2f KB/sec\n",
3837+ i,
3838+ state->mNumBuffersDecoded,
3839+ state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
3840+ state->mNumBytesDecoded,
3841+ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
3842+ }
3843+ }
3844+
3845+ return 0;
3846+}
3847+
3848+int main(int argc, char **argv) {
3849+ using namespace android;
3850+
3851+ const char *me = argv[0];
3852+
3853+ bool useAudio = false;
3854+ bool useVideo = false;
3855+ bool playback = false;
3856+ bool useSurface = false;
3857+
3858+ int res;
3859+ while ((res = getopt(argc, argv, "havpSD")) >= 0) {
3860+ switch (res) {
3861+ case 'a':
3862+ {
3863+ useAudio = true;
3864+ break;
3865+ }
3866+
3867+ case 'v':
3868+ {
3869+ useVideo = true;
3870+ break;
3871+ }
3872+
3873+ case 'p':
3874+ {
3875+ playback = true;
3876+ break;
3877+ }
3878+
3879+ case 'S':
3880+ {
3881+ useSurface = true;
3882+ break;
3883+ }
3884+
3885+ case '?':
3886+ case 'h':
3887+ default:
3888+ {
3889+ usage(me);
3890+ }
3891+ }
3892+ }
3893+
3894+ argc -= optind;
3895+ argv += optind;
3896+
3897+ if (argc != 1) {
3898+ usage(me);
3899+ }
3900+
3901+ if (!useAudio && !useVideo) {
3902+ useAudio = useVideo = true;
3903+ }
3904+
3905+ ProcessState::self()->startThreadPool();
3906+
3907+ DataSource::RegisterDefaultSniffers();
3908+
3909+ sp<ALooper> looper = new ALooper;
3910+ looper->start();
3911+
3912+ sp<SurfaceComposerClient> composerClient;
3913+ sp<SurfaceControl> control;
3914+ sp<Surface> surface;
3915+
3916+ if (playback || (useSurface && useVideo)) {
3917+ composerClient = new SurfaceComposerClient;
3918+ CHECK_EQ(composerClient->initCheck(), (status_t)OK);
3919+
3920+ sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
3921+ ISurfaceComposer::eDisplayIdMain));
3922+ DisplayInfo info;
3923+ SurfaceComposerClient::getDisplayInfo(display, &info);
3924+ ssize_t displayWidth = info.w;
3925+ ssize_t displayHeight = info.h;
3926+
3927+ ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);
3928+
3929+ control = composerClient->createSurface(
3930+ String8("A Surface"),
3931+ displayWidth,
3932+ displayHeight,
3933+ PIXEL_FORMAT_RGB_565,
3934+ 0);
3935+
3936+ CHECK(control != NULL);
3937+ CHECK(control->isValid());
3938+
3939+ SurfaceComposerClient::openGlobalTransaction();
3940+ CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
3941+ CHECK_EQ(control->show(), (status_t)OK);
3942+ SurfaceComposerClient::closeGlobalTransaction();
3943+
3944+ surface = control->getSurface();
3945+ CHECK(surface != NULL);
3946+ }
3947+
3948+ if (playback) {
3949+ sp<SimplePlayer> player = new SimplePlayer;
3950+ looper->registerHandler(player);
3951+
3952+ player->setDataSource(argv[0]);
3953+ player->setSurface(surface->getSurfaceTexture());
3954+ player->start();
3955+ ALOGD("Playing for 60 seconds\n");
3956+ sleep(60);
3957+ player->stop();
3958+ player->reset();
3959+ } else {
3960+ decode(looper, argv[0], useAudio, useVideo, surface);
3961+ }
3962+
3963+ if (playback || (useSurface && useVideo)) {
3964+ composerClient->dispose();
3965+ }
3966+
3967+ looper->stop();
3968+
3969+ return 0;
3970+}
3971
3972=== added file 'android/compat/media/decoding_service.cpp'
3973--- android/compat/media/decoding_service.cpp 1970-01-01 00:00:00 +0000
3974+++ android/compat/media/decoding_service.cpp 2016-01-11 14:31:46 +0000
3975@@ -0,0 +1,366 @@
3976+/*
3977+ * Copyright (C) 2014 Canonical Ltd
3978+ *
3979+ * Licensed under the Apache License, Version 2.0 (the "License");
3980+ * you may not use this file except in compliance with the License.
3981+ * You may obtain a copy of the License at
3982+ *
3983+ * http://www.apache.org/licenses/LICENSE-2.0
3984+ *
3985+ * Unless required by applicable law or agreed to in writing, software
3986+ * distributed under the License is distributed on an "AS IS" BASIS,
3987+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3988+ * See the License for the specific language governing permissions and
3989+ * limitations under the License.
3990+ *
3991+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
3992+ */
3993+
3994+// Uncomment to enable verbose debug output
3995+#define LOG_NDEBUG 0
3996+
3997+#undef LOG_TAG
3998+#define LOG_TAG "DecodingService"
3999+
4000+#include "decoding_service_priv.h"
4001+
4002+#include <binder/IServiceManager.h>
4003+#include <binder/Parcel.h>
4004+#include <binder/IPCThreadState.h>
4005+#include <binder/ProcessState.h>
4006+#include <binder/BpBinder.h>
4007+
4008+typedef void* EGLDisplay;
4009+typedef void* EGLSyncKHR;
4010+
4011+#include <ui/GraphicBuffer.h>
4012+#include <gui/GraphicBufferAlloc.h>
4013+#include <gui/IGraphicBufferProducer.h>
4014+#include <gui/IGraphicBufferConsumer.h>
4015+#include <gui/Surface.h>
4016+#include <gui/NativeBufferAlloc.h>
4017+
4018+namespace android {
4019+
4020+IMPLEMENT_META_INTERFACE(DecodingService, "android.media.IDecodingService");
4021+IMPLEMENT_META_INTERFACE(DecodingServiceSession, "android.media.IDecodingServiceSession");
4022+
4023+enum {
4024+ GET_IGRAPHICBUFFERCONSUMER = IBinder::FIRST_CALL_TRANSACTION,
4025+ GET_IGRAPHICBUFFERPRODUCER,
4026+ REGISTER_SESSION,
4027+ UNREGISTER_SESSION,
4028+};
4029+
4030+// ----------------------------------------------------------------------
4031+
4032+status_t BnDecodingService::onTransact(
4033+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
4034+{
4035+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4036+ switch (code) {
4037+ case GET_IGRAPHICBUFFERCONSUMER: {
4038+ CHECK_INTERFACE(IDecodingService, data, reply);
4039+ sp<IGraphicBufferConsumer> gbc;
4040+ status_t res = getIGraphicBufferConsumer(&gbc);
4041+
4042+ reply->writeStrongBinder(gbc->asBinder());
4043+ reply->writeInt32(res);
4044+
4045+ return NO_ERROR;
4046+ } break;
4047+ case GET_IGRAPHICBUFFERPRODUCER: {
4048+ CHECK_INTERFACE(IDecodingService, data, reply);
4049+ sp<IGraphicBufferProducer> gbp;
4050+ status_t res = getIGraphicBufferProducer(&gbp);
4051+
4052+ reply->writeStrongBinder(gbp->asBinder());
4053+ reply->writeInt32(res);
4054+
4055+ return NO_ERROR;
4056+ } break;
4057+ case REGISTER_SESSION: {
4058+ CHECK_INTERFACE(IDecodingService, data, reply);
4059+ sp<IBinder> binder = data.readStrongBinder();
4060+ uint32_t handle = data.readInt32();
4061+ sp<IDecodingServiceSession> session(new BpDecodingServiceSession(binder));
4062+ registerSession(session, handle);
4063+
4064+ return NO_ERROR;
4065+ } break;
4066+ case UNREGISTER_SESSION: {
4067+ CHECK_INTERFACE(IDecodingService, data, reply);
4068+ unregisterSession();
4069+
4070+ return NO_ERROR;
4071+ } break;
4072+ default:
4073+ return BBinder::onTransact(code, data, reply, flags);
4074+ }
4075+}
4076+
4077+status_t BpDecodingService::getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>* gbc)
4078+{
4079+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4080+ Parcel data, reply;
4081+ data.writeInterfaceToken(IDecodingService::getInterfaceDescriptor());
4082+ remote()->transact(GET_IGRAPHICBUFFERCONSUMER, data, &reply);
4083+ *gbc = interface_cast<IGraphicBufferConsumer>(reply.readStrongBinder());
4084+ return reply.readInt32();
4085+}
4086+
4087+status_t BpDecodingService::getIGraphicBufferProducer(sp<IGraphicBufferProducer>* gbp)
4088+{
4089+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4090+ Parcel data, reply;
4091+ data.writeInterfaceToken(IDecodingService::getInterfaceDescriptor());
4092+ remote()->transact(GET_IGRAPHICBUFFERPRODUCER, data, &reply);
4093+ *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
4094+ return NO_ERROR;
4095+}
4096+
4097+status_t BpDecodingService::registerSession(const sp<IDecodingServiceSession>& session, uint32_t handle)
4098+{
4099+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4100+ Parcel data, reply;
4101+ data.writeInterfaceToken(IDecodingService::getInterfaceDescriptor());
4102+ data.writeStrongBinder(session->asBinder());
4103+ data.writeInt32(handle);
4104+ remote()->transact(REGISTER_SESSION, data, &reply);
4105+ return NO_ERROR;
4106+}
4107+
4108+status_t BpDecodingService::unregisterSession()
4109+{
4110+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4111+ Parcel data, reply;
4112+ data.writeInterfaceToken(IDecodingService::getInterfaceDescriptor());
4113+ remote()->transact(UNREGISTER_SESSION, data, &reply);
4114+ return NO_ERROR;
4115+}
4116+
4117+sp<DecodingService> DecodingService::decoding_service = NULL;
4118+
4119+DecodingService::DecodingService()
4120+ : client_death_cb(NULL),
4121+ client_death_context(NULL)
4122+{
4123+ ALOGD("%s", __PRETTY_FUNCTION__);
4124+}
4125+
4126+DecodingService::~DecodingService()
4127+{
4128+ ALOGD("%s", __PRETTY_FUNCTION__);
4129+}
4130+
4131+void DecodingService::instantiate()
4132+{
4133+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4134+ defaultServiceManager()->addService(
4135+ String16(IDecodingService::exported_service_name()), service_instance());
4136+ ALOGD("Added Binder service '%s' to ServiceManager", IDecodingService::exported_service_name());
4137+
4138+ service_instance()->createBufferQueue();
4139+}
4140+
4141+sp<DecodingService>& DecodingService::service_instance()
4142+{
4143+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4144+
4145+ // TODO Add a mutex here
4146+ if (decoding_service == NULL)
4147+ {
4148+ ALOGD("Creating new static instance of DecodingService");
4149+ decoding_service = new DecodingService();
4150+ }
4151+
4152+ return decoding_service;
4153+}
4154+
4155+void DecodingService::setDecodingClientDeathCb(DecodingClientDeathCbHybris cb, uint32_t handle, void* context)
4156+{
4157+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4158+
4159+ ClientCb *holder = (ClientCb*) malloc(sizeof(ClientCb));
4160+ holder->cb = cb;
4161+ holder->context = context;
4162+
4163+ clients.add(handle, holder);
4164+}
4165+
4166+status_t DecodingService::getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>* gbc)
4167+{
4168+ // TODO: Make sure instantiate() has been called first
4169+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4170+ pid_t pid = IPCThreadState::self()->getCallingPid();
4171+ ALOGD("Calling Pid: %d", pid);
4172+
4173+#if ANDROID_VERSION_MAJOR==5
4174+ *gbc = consumer;
4175+#else
4176+ *gbc = buffer_queue;
4177+#endif
4178+
4179+ return OK;
4180+}
4181+
4182+status_t DecodingService::getIGraphicBufferProducer(sp<IGraphicBufferProducer>* gbp)
4183+{
4184+ pid_t pid = IPCThreadState::self()->getCallingPid();
4185+ ALOGD("Calling Pid: %d", pid);
4186+
4187+#if ANDROID_VERSION_MAJOR==5
4188+ *gbp = producer;
4189+#else
4190+ *gbp = buffer_queue;
4191+#endif
4192+ ALOGD("producer(gbp): %p", (void*)gbp->get());
4193+ return OK;
4194+}
4195+
4196+status_t DecodingService::registerSession(const sp<IDecodingServiceSession>& session, uint32_t handle)
4197+{
4198+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4199+
4200+ // Add session/handle to running clients map and connect death observer
4201+ status_t ret = session->asBinder()->linkToDeath(sp<IBinder::DeathRecipient>(this));
4202+ clientCbs.add(session->asBinder(), clients.valueFor(handle));
4203+ clients.removeItem(handle);
4204+
4205+ // Create a new BufferQueue instance so that the next created client plays
4206+ // video correctly
4207+ createBufferQueue();
4208+
4209+ return ret;
4210+}
4211+
4212+status_t DecodingService::unregisterSession()
4213+{
4214+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4215+ if (session != NULL)
4216+ {
4217+ session->asBinder()->unlinkToDeath(this);
4218+ session.clear();
4219+ // Reset the BufferQueue instance so that the next created client plays
4220+ // video correctly
4221+#if ANDROID_VERSION_MAJOR==5
4222+ producer.clear();
4223+ consumer.clear();
4224+#else
4225+ buffer_queue.clear();
4226+#endif
4227+ }
4228+
4229+ return OK;
4230+}
4231+
4232+void DecodingService::createBufferQueue()
4233+{
4234+ // Use a new native buffer allocator vs the default one, which means it'll use the proper one
4235+ // that will allow rendering to work with Mir
4236+ sp<IGraphicBufferAlloc> g_buffer_alloc(new GraphicBufferAlloc());
4237+
4238+ // This BuferQueue is shared between the client and the service
4239+#if ANDROID_VERSION_MAJOR==5
4240+ BufferQueue::createBufferQueue(&producer, &consumer);
4241+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
4242+ sp<NativeBufferAlloc> native_alloc(new NativeBufferAlloc());
4243+ buffer_queue = new BufferQueue(false, NULL, native_alloc);
4244+#else
4245+ buffer_queue = new BufferQueue(NULL);
4246+ ALOGD("buffer_queue: %p", (void*)buffer_queue.get());
4247+#endif
4248+#if ANDROID_VERSION_MAJOR==5
4249+ producer->setBufferCount(5);
4250+#else
4251+ buffer_queue->setBufferCount(5);
4252+#endif
4253+}
4254+
4255+void DecodingService::binderDied(const wp<IBinder>& who)
4256+{
4257+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4258+
4259+ sp<IBinder> sp = who.promote();
4260+ ClientCb *cb = clientCbs.valueFor(sp);
4261+
4262+ if (cb && cb->cb != NULL) {
4263+ cb->cb(cb->context);
4264+ free(cb);
4265+ clientCbs.removeItem(sp);
4266+ }
4267+
4268+ unregisterSession();
4269+}
4270+
4271+sp<BpDecodingService> DecodingClient::decoding_service = NULL;
4272+
4273+DecodingClient::DecodingClient()
4274+{
4275+ ALOGD("%s", __PRETTY_FUNCTION__);
4276+
4277+ ProcessState::self()->startThreadPool();
4278+}
4279+
4280+DecodingClient::~DecodingClient()
4281+{
4282+ ALOGD("%s", __PRETTY_FUNCTION__);
4283+}
4284+
4285+sp<BpDecodingService>& DecodingClient::service_instance()
4286+{
4287+ ALOGD("%s", __PRETTY_FUNCTION__);
4288+ // TODO: Add a mutex here
4289+ if (decoding_service == NULL)
4290+ {
4291+ ALOGD("Creating a new static BpDecodingService instance");
4292+ sp<IServiceManager> service_manager = defaultServiceManager();
4293+ sp<IBinder> service = service_manager->getService(
4294+ String16(IDecodingService::exported_service_name()));
4295+ decoding_service = new BpDecodingService(service);
4296+ }
4297+
4298+ return decoding_service;
4299+}
4300+
4301+status_t DecodingClient::getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>* gbc)
4302+{
4303+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4304+ return service_instance()->getIGraphicBufferConsumer(gbc);
4305+}
4306+
4307+// IDecodingServiceSession
4308+
4309+BpDecodingServiceSession::BpDecodingServiceSession(const sp<IBinder>& impl)
4310+ : BpInterface<IDecodingServiceSession>(impl)
4311+{
4312+ ALOGD("%s", __PRETTY_FUNCTION__);
4313+}
4314+
4315+BpDecodingServiceSession::~BpDecodingServiceSession()
4316+{
4317+ ALOGD("%s", __PRETTY_FUNCTION__);
4318+}
4319+
4320+BnDecodingServiceSession::BnDecodingServiceSession()
4321+{
4322+ ALOGD("%s", __PRETTY_FUNCTION__);
4323+}
4324+
4325+BnDecodingServiceSession::~BnDecodingServiceSession()
4326+{
4327+ ALOGD("%s", __PRETTY_FUNCTION__);
4328+}
4329+
4330+status_t BnDecodingServiceSession::onTransact(uint32_t code, const Parcel& data,
4331+ Parcel* reply, uint32_t flags)
4332+{
4333+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4334+
4335+ return NO_ERROR;
4336+}
4337+
4338+// ----- C API ----- //
4339+
4340+
4341+}; // namespace android
4342
4343=== added file 'android/compat/media/decoding_service_priv.h'
4344--- android/compat/media/decoding_service_priv.h 1970-01-01 00:00:00 +0000
4345+++ android/compat/media/decoding_service_priv.h 2016-01-11 14:31:46 +0000
4346@@ -0,0 +1,208 @@
4347+/*
4348+ * Copyright (C) 2014 Canonical Ltd
4349+ *
4350+ * Licensed under the Apache License, Version 2.0 (the "License");
4351+ * you may not use this file except in compliance with the License.
4352+ * You may obtain a copy of the License at
4353+ *
4354+ * http://www.apache.org/licenses/LICENSE-2.0
4355+ *
4356+ * Unless required by applicable law or agreed to in writing, software
4357+ * distributed under the License is distributed on an "AS IS" BASIS,
4358+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4359+ * See the License for the specific language governing permissions and
4360+ * limitations under the License.
4361+ *
4362+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4363+ */
4364+
4365+#ifndef DECODING_SERVICE_PRIV_H_
4366+#define DECODING_SERVICE_PRIV_H_
4367+
4368+#include "surface_texture_client_hybris_priv.h"
4369+
4370+#include <binder/IInterface.h>
4371+#include <binder/Parcel.h>
4372+
4373+namespace android {
4374+
4375+typedef struct {
4376+ DecodingClientDeathCbHybris cb;
4377+ void *context;
4378+} ClientCb;
4379+
4380+class IGraphicBufferConsumer;
4381+class IGraphicBufferProducer;
4382+class BufferQueue;
4383+class GLConsumer;
4384+
4385+class IDecodingServiceSession : public IInterface
4386+{
4387+public:
4388+ DECLARE_META_INTERFACE(DecodingServiceSession);
4389+
4390+ static const char* exported_service_name() { return "android.media.IDecodingServiceSession"; }
4391+
4392+};
4393+
4394+class BnDecodingServiceSession : public BnInterface<IDecodingServiceSession>
4395+{
4396+public:
4397+ BnDecodingServiceSession();
4398+ virtual ~BnDecodingServiceSession();
4399+
4400+ virtual status_t onTransact(uint32_t code, const Parcel& data,
4401+ Parcel* reply, uint32_t flags = 0);
4402+};
4403+
4404+enum {
4405+ SET_DECODING_CLIENT_DEATH_CB = IBinder::FIRST_CALL_TRANSACTION,
4406+};
4407+
4408+class BpDecodingServiceSession : public BpInterface<IDecodingServiceSession>
4409+{
4410+public:
4411+ BpDecodingServiceSession(const sp<IBinder>& impl);
4412+ ~BpDecodingServiceSession();
4413+};
4414+
4415+class IDecodingService: public IInterface
4416+{
4417+public:
4418+ DECLARE_META_INTERFACE(DecodingService);
4419+
4420+ static const char* exported_service_name() { return "android.media.IDecodingService"; }
4421+
4422+ virtual status_t getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>* gbc) = 0;
4423+ virtual status_t getIGraphicBufferProducer(sp<IGraphicBufferProducer>* gbp) = 0;
4424+ virtual status_t registerSession(const sp<IDecodingServiceSession>& session, uint32_t handle) = 0;
4425+ virtual status_t unregisterSession() = 0;
4426+};
4427+
4428+class BnDecodingService: public BnInterface<IDecodingService>
4429+{
4430+public:
4431+ virtual status_t onTransact( uint32_t code,
4432+ const Parcel& data,
4433+ Parcel* reply,
4434+ uint32_t flags = 0);
4435+};
4436+
4437+class BpDecodingService: public BpInterface<IDecodingService>
4438+{
4439+public:
4440+ BpDecodingService(const sp<IBinder>& impl)
4441+ : BpInterface<IDecodingService>(impl)
4442+ {
4443+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4444+ }
4445+
4446+ virtual status_t getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>* gbc);
4447+ virtual status_t getIGraphicBufferProducer(sp<IGraphicBufferProducer>* gbp);
4448+ virtual status_t registerSession(const sp<IDecodingServiceSession>& session, uint32_t handle);
4449+ virtual status_t unregisterSession();
4450+};
4451+
4452+class DecodingService : public BnDecodingService,
4453+ public IBinder::DeathRecipient
4454+{
4455+public:
4456+ DecodingService();
4457+ virtual ~DecodingService();
4458+ /** Adds the decoding service to the default service manager in Binder **/
4459+ static void instantiate();
4460+ static sp<DecodingService>& service_instance();
4461+
4462+ virtual void setDecodingClientDeathCb(DecodingClientDeathCbHybris cb, uint32_t handle, void* context);
4463+
4464+ // IDecodingService interface:
4465+ virtual status_t getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>* gbc);
4466+ virtual status_t getIGraphicBufferProducer(sp<IGraphicBufferProducer>* gbp);
4467+
4468+ virtual status_t registerSession(const sp<IDecodingServiceSession>& session, uint32_t handle);
4469+ virtual status_t unregisterSession();
4470+
4471+ /** Get notified when the Binder connection to the client dies **/
4472+ virtual void binderDied(const wp<IBinder>& who);
4473+
4474+protected:
4475+ virtual void createBufferQueue();
4476+
4477+private:
4478+ static sp<DecodingService> decoding_service;
4479+#if ANDROID_VERSION_MAJOR==5
4480+ sp<IGraphicBufferProducer> producer;
4481+ sp<IGraphicBufferConsumer> consumer;
4482+#else
4483+ sp<BufferQueue> buffer_queue;
4484+#endif
4485+ sp<IDecodingServiceSession> session;
4486+ DecodingClientDeathCbHybris client_death_cb;
4487+ void *client_death_context;
4488+ KeyedVector< uint32_t, ClientCb* > clients;
4489+ KeyedVector< sp<IBinder>, ClientCb* > clientCbs;
4490+};
4491+
4492+class DecodingClient
4493+{
4494+public:
4495+ DecodingClient();
4496+ virtual ~DecodingClient();
4497+
4498+ static sp<BpDecodingService>& service_instance();
4499+
4500+ virtual status_t getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>* gbc);
4501+
4502+private:
4503+ static sp<BpDecodingService> decoding_service;
4504+};
4505+
4506+struct IGBCWrapper
4507+{
4508+ IGBCWrapper(const sp<IGraphicBufferConsumer>& igbc)
4509+ {
4510+ consumer = igbc;
4511+ }
4512+
4513+ sp<IGraphicBufferConsumer> consumer;
4514+};
4515+
4516+struct IGBPWrapper
4517+{
4518+ IGBPWrapper(const sp<IGraphicBufferProducer>& igbp)
4519+ {
4520+ producer = igbp;
4521+ }
4522+
4523+ sp<IGraphicBufferProducer> producer;
4524+};
4525+
4526+struct GLConsumerWrapper
4527+{
4528+ GLConsumerWrapper(const sp<_GLConsumerHybris>& gl_consumer)
4529+ {
4530+ consumer = gl_consumer;
4531+ }
4532+
4533+ sp<_GLConsumerHybris> consumer;
4534+};
4535+
4536+struct DSSessionWrapper
4537+{
4538+ DSSessionWrapper(const sp<IDecodingServiceSession>& session)
4539+ {
4540+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4541+ this->session = session;
4542+ }
4543+
4544+ ~DSSessionWrapper()
4545+ {
4546+ ALOGD("Entering %s", __PRETTY_FUNCTION__);
4547+ }
4548+
4549+ sp<IDecodingServiceSession> session;
4550+};
4551+
4552+}; // namespace android
4553+
4554+#endif
4555
4556=== added file 'android/compat/media/direct_media_test.cpp'
4557--- android/compat/media/direct_media_test.cpp 1970-01-01 00:00:00 +0000
4558+++ android/compat/media/direct_media_test.cpp 2016-01-11 14:31:46 +0000
4559@@ -0,0 +1,417 @@
4560+/*
4561+ * Copyright (C) 2013 Canonical Ltd
4562+ *
4563+ * Licensed under the Apache License, Version 2.0 (the "License");
4564+ * you may not use this file except in compliance with the License.
4565+ * You may obtain a copy of the License at
4566+ *
4567+ * http://www.apache.org/licenses/LICENSE-2.0
4568+ *
4569+ * Unless required by applicable law or agreed to in writing, software
4570+ * distributed under the License is distributed on an "AS IS" BASIS,
4571+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4572+ * See the License for the specific language governing permissions and
4573+ * limitations under the License.
4574+ *
4575+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4576+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
4577+ */
4578+
4579+#include <hybris/media/media_compatibility_layer.h>
4580+#include "direct_media_test.h"
4581+
4582+#include <utils/Errors.h>
4583+
4584+#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
4585+
4586+#include <GLES2/gl2.h>
4587+#include <GLES2/gl2ext.h>
4588+
4589+#include <sys/stat.h>
4590+#include <sys/types.h>
4591+#include <fcntl.h>
4592+#include <unistd.h>
4593+
4594+#include <cassert>
4595+#include <cstdio>
4596+#include <cstdlib>
4597+#include <cstring>
4598+
4599+using namespace android;
4600+
4601+static float DestWidth = 0.0, DestHeight = 0.0;
4602+// Actual video dimmensions
4603+static int Width = 0, Height = 0;
4604+
4605+static GLfloat positionCoordinates[8];
4606+
4607+MediaPlayerWrapper *player = NULL;
4608+
4609+void calculate_position_coordinates()
4610+{
4611+ // Assuming cropping output for now
4612+ float x = 1, y = 1;
4613+
4614+ // Black borders
4615+ x = float(Width / DestWidth);
4616+ y = float(Height / DestHeight);
4617+
4618+ // Make the larger side be 1
4619+ if (x > y) {
4620+ y /= x;
4621+ x = 1;
4622+ } else {
4623+ x /= y;
4624+ y = 1;
4625+ }
4626+
4627+ positionCoordinates[0] = -x;
4628+ positionCoordinates[1] = y;
4629+ positionCoordinates[2] = -x;
4630+ positionCoordinates[3] = -y;
4631+ positionCoordinates[4] = x;
4632+ positionCoordinates[5] = -y;
4633+ positionCoordinates[6] = x;
4634+ positionCoordinates[7] = y;
4635+}
4636+
4637+WindowRenderer::WindowRenderer(int width, int height)
4638+ : mThreadCmd(CMD_IDLE)
4639+{
4640+ createThread(threadStart, this);
4641+}
4642+
4643+WindowRenderer::~WindowRenderer()
4644+{
4645+}
4646+
4647+int WindowRenderer::threadStart(void* self)
4648+{
4649+ ((WindowRenderer *)self)->glThread();
4650+ return 0;
4651+}
4652+
4653+void WindowRenderer::glThread()
4654+{
4655+ printf("%s\n", __PRETTY_FUNCTION__);
4656+
4657+ Mutex::Autolock autoLock(mLock);
4658+}
4659+
4660+struct ClientWithSurface
4661+{
4662+ SfClient* client;
4663+ SfSurface* surface;
4664+};
4665+
4666+ClientWithSurface client_with_surface(bool setup_surface_with_egl)
4667+{
4668+ ClientWithSurface cs = ClientWithSurface();
4669+
4670+ cs.client = sf_client_create();
4671+
4672+ if (!cs.client) {
4673+ printf("Problem creating client ... aborting now.");
4674+ return cs;
4675+ }
4676+
4677+ static const size_t primary_display = 0;
4678+
4679+ DestWidth = sf_get_display_width(primary_display);
4680+ DestHeight = sf_get_display_height(primary_display);
4681+ printf("Primary display width: %f, height: %f\n", DestWidth, DestHeight);
4682+
4683+ SfSurfaceCreationParameters params = {
4684+ 0,
4685+ 0,
4686+ (int) DestWidth,
4687+ (int) DestHeight,
4688+ -1, //PIXEL_FORMAT_RGBA_8888,
4689+ 15000,
4690+ 0.5f,
4691+ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL
4692+ "MediaCompatLayerTestSurface"
4693+ };
4694+
4695+ cs.surface = sf_surface_create(cs.client, &params);
4696+
4697+ if (!cs.surface) {
4698+ printf("Problem creating surface ... aborting now.");
4699+ return cs;
4700+ }
4701+
4702+ sf_surface_make_current(cs.surface);
4703+
4704+ return cs;
4705+}
4706+
4707+struct RenderData
4708+{
4709+ static const char *vertex_shader()
4710+ {
4711+ return
4712+ "attribute vec4 a_position; \n"
4713+ "attribute vec2 a_texCoord; \n"
4714+ "uniform mat4 m_texMatrix; \n"
4715+ "varying vec2 v_texCoord; \n"
4716+ "varying float topDown; \n"
4717+ "void main() \n"
4718+ "{ \n"
4719+ " gl_Position = a_position; \n"
4720+ " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
4721+ "} \n";
4722+ }
4723+
4724+ static const char *fragment_shader()
4725+ {
4726+ return
4727+ "#extension GL_OES_EGL_image_external : require \n"
4728+ "precision mediump float; \n"
4729+ "varying vec2 v_texCoord; \n"
4730+ "uniform samplerExternalOES s_texture; \n"
4731+ "void main() \n"
4732+ "{ \n"
4733+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
4734+ "} \n";
4735+ }
4736+
4737+ static GLuint loadShader(GLenum shaderType, const char* pSource)
4738+ {
4739+ GLuint shader = glCreateShader(shaderType);
4740+
4741+ if (shader) {
4742+ glShaderSource(shader, 1, &pSource, NULL);
4743+ glCompileShader(shader);
4744+ GLint compiled = 0;
4745+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
4746+
4747+ if (!compiled) {
4748+ GLint infoLen = 0;
4749+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
4750+ if (infoLen) {
4751+ char* buf = (char*) malloc(infoLen);
4752+ if (buf) {
4753+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
4754+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
4755+ shaderType, buf);
4756+ free(buf);
4757+ }
4758+ glDeleteShader(shader);
4759+ shader = 0;
4760+ }
4761+ }
4762+ } else {
4763+ printf("Error, during shader creation: %i\n", glGetError());
4764+ }
4765+
4766+ return shader;
4767+ }
4768+
4769+ static GLuint create_program(const char* pVertexSource, const char* pFragmentSource)
4770+ {
4771+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
4772+ if (!vertexShader) {
4773+ printf("vertex shader not compiled\n");
4774+ return 0;
4775+ }
4776+
4777+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
4778+ if (!pixelShader) {
4779+ printf("frag shader not compiled\n");
4780+ return 0;
4781+ }
4782+
4783+ GLuint program = glCreateProgram();
4784+ if (program) {
4785+ glAttachShader(program, vertexShader);
4786+ glAttachShader(program, pixelShader);
4787+ glLinkProgram(program);
4788+ GLint linkStatus = GL_FALSE;
4789+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
4790+
4791+ if (linkStatus != GL_TRUE) {
4792+ GLint bufLength = 0;
4793+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
4794+ if (bufLength) {
4795+ char* buf = (char*) malloc(bufLength);
4796+ if (buf) {
4797+ glGetProgramInfoLog(program, bufLength, NULL, buf);
4798+ fprintf(stderr, "Could not link program:\n%s\n", buf);
4799+ free(buf);
4800+ }
4801+ }
4802+ glDeleteProgram(program);
4803+ program = 0;
4804+ }
4805+ }
4806+
4807+ return program;
4808+ }
4809+
4810+ RenderData() : program_object(create_program(vertex_shader(), fragment_shader()))
4811+ {
4812+ position_loc = glGetAttribLocation(program_object, "a_position");
4813+ tex_coord_loc = glGetAttribLocation(program_object, "a_texCoord");
4814+ sampler_loc = glGetUniformLocation(program_object, "s_texture");
4815+ matrix_loc = glGetUniformLocation(program_object, "m_texMatrix");
4816+ }
4817+
4818+ // Handle to a program object
4819+ GLuint program_object;
4820+ // Attribute locations
4821+ GLint position_loc;
4822+ GLint tex_coord_loc;
4823+ // Sampler location
4824+ GLint sampler_loc;
4825+ // Matrix location
4826+ GLint matrix_loc;
4827+};
4828+
4829+static int setup_video_texture(ClientWithSurface *cs, GLuint *preview_texture_id)
4830+{
4831+ assert(cs != NULL);
4832+ assert(preview_texture_id != NULL);
4833+
4834+ sf_surface_make_current(cs->surface);
4835+
4836+ glGenTextures(1, preview_texture_id);
4837+ glClearColor(0, 0, 0, 0);
4838+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4839+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4840+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4841+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4842+
4843+ android_media_set_preview_texture(player, *preview_texture_id);
4844+
4845+ return 0;
4846+}
4847+
4848+static void print_gl_error(unsigned int line)
4849+{
4850+ GLint error = glGetError();
4851+ printf("GL error: %#04x (line: %d)\n", error, line);
4852+}
4853+
4854+static int update_gl_buffer(RenderData *render_data, EGLDisplay *disp, EGLSurface *surface)
4855+{
4856+ assert(disp != NULL);
4857+ assert(surface != NULL);
4858+
4859+ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
4860+
4861+ const GLfloat textureCoordinates[] = {
4862+ 1.0f, 1.0f,
4863+ 0.0f, 1.0f,
4864+ 0.0f, 0.0f,
4865+ 1.0f, 0.0f
4866+ };
4867+
4868+ calculate_position_coordinates();
4869+
4870+ glClear(GL_COLOR_BUFFER_BIT);
4871+ // Use the program object
4872+ glUseProgram(render_data->program_object);
4873+ // Enable attributes
4874+ glEnableVertexAttribArray(render_data->position_loc);
4875+ glEnableVertexAttribArray(render_data->tex_coord_loc);
4876+ // Load the vertex position
4877+ glVertexAttribPointer(render_data->position_loc,
4878+ 2,
4879+ GL_FLOAT,
4880+ GL_FALSE,
4881+ 0,
4882+ positionCoordinates);
4883+ // Load the texture coordinate
4884+ glVertexAttribPointer(render_data->tex_coord_loc,
4885+ 2,
4886+ GL_FLOAT,
4887+ GL_FALSE,
4888+ 0,
4889+ textureCoordinates);
4890+
4891+ GLfloat matrix[16];
4892+ android_media_surface_texture_get_transformation_matrix(player, matrix);
4893+
4894+ glUniformMatrix4fv(render_data->matrix_loc, 1, GL_FALSE, matrix);
4895+
4896+ glActiveTexture(GL_TEXTURE0);
4897+ // Set the sampler texture unit to 0
4898+ glUniform1i(render_data->sampler_loc, 0);
4899+ glUniform1i(render_data->matrix_loc, 0);
4900+ android_media_update_surface_texture(player);
4901+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
4902+ //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
4903+ glDisableVertexAttribArray(render_data->position_loc);
4904+ glDisableVertexAttribArray(render_data->tex_coord_loc);
4905+
4906+ eglSwapBuffers(*disp, *surface);
4907+
4908+ return 0;
4909+}
4910+
4911+void set_video_size_cb(int height, int width, void *context)
4912+{
4913+ printf("Video height: %d, width: %d\n", height, width);
4914+ printf("Video dest height: %f, width: %f\n", DestHeight, DestWidth);
4915+
4916+ Height = height;
4917+ Width = width;
4918+}
4919+
4920+int main(int argc, char **argv)
4921+{
4922+ if (argc < 2) {
4923+ printf("Usage: direct_media_test <video_to_play>\n");
4924+ return EXIT_FAILURE;
4925+ }
4926+
4927+ player = android_media_new_player();
4928+ if (player == NULL) {
4929+ printf("Problem creating new media player.\n");
4930+ return EXIT_FAILURE;
4931+ }
4932+
4933+ // Set player event cb for when the video size is known:
4934+ android_media_set_video_size_cb(player, set_video_size_cb, NULL);
4935+
4936+ printf("Setting data source to: %s.\n", argv[1]);
4937+
4938+ if (android_media_set_data_source(player, argv[1]) != OK) {
4939+ printf("Failed to set data source: %s\n", argv[1]);
4940+ return EXIT_FAILURE;
4941+ }
4942+
4943+ WindowRenderer renderer(DestWidth, DestHeight);
4944+
4945+ printf("Creating EGL surface.\n");
4946+ ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */);
4947+ if (!cs.surface) {
4948+ printf("Problem acquiring surface for preview");
4949+ return EXIT_FAILURE;
4950+ }
4951+
4952+ printf("Creating GL texture.\n");
4953+ GLuint preview_texture_id;
4954+ EGLDisplay disp = sf_client_get_egl_display(cs.client);
4955+ EGLSurface surface = sf_surface_get_egl_surface(cs.surface);
4956+
4957+ sf_surface_make_current(cs.surface);
4958+ if (setup_video_texture(&cs, &preview_texture_id) != OK) {
4959+ printf("Problem setting up GL texture for video surface.\n");
4960+ return EXIT_FAILURE;
4961+ }
4962+
4963+ RenderData render_data;
4964+
4965+ printf("Starting video playback.\n");
4966+ android_media_play(player);
4967+
4968+ printf("Updating gl buffer continuously...\n");
4969+ while (android_media_is_playing(player)) {
4970+ update_gl_buffer(&render_data, &disp, &surface);
4971+ }
4972+
4973+ android_media_stop(player);
4974+
4975+ return EXIT_SUCCESS;
4976+}
4977
4978=== added file 'android/compat/media/direct_media_test.h'
4979--- android/compat/media/direct_media_test.h 1970-01-01 00:00:00 +0000
4980+++ android/compat/media/direct_media_test.h 2016-01-11 14:31:46 +0000
4981@@ -0,0 +1,58 @@
4982+/*
4983+ * Copyright (C) 2013 Canonical Ltd
4984+ *
4985+ * Licensed under the Apache License, Version 2.0 (the "License");
4986+ * you may not use this file except in compliance with the License.
4987+ * You may obtain a copy of the License at
4988+ *
4989+ * http://www.apache.org/licenses/LICENSE-2.0
4990+ *
4991+ * Unless required by applicable law or agreed to in writing, software
4992+ * distributed under the License is distributed on an "AS IS" BASIS,
4993+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4994+ * See the License for the specific language governing permissions and
4995+ * limitations under the License.
4996+ *
4997+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4998+ */
4999+
5000+#ifndef DIRECT_MEDIA_TEST_H_
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches