Imported Debian patch 0.1.0+git20131207+e452e83-0ubuntu12
[deb_libhybris.git] / debian / patches / debian-changes
CommitLineData
4395b8c4
RSA
1Subject: Collected Debian patches for libhybris
2Author: Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
3
4The libhybris package is maintained in Git rather than maintaining
5patches as separate files, and separating the patches doesn't seem to
6be worth the effort. They are therefore all included in this single
7Debian patch.
8
9For full commit history and separated commits, see the packaging Git
10repository.
11--- /dev/null
12+++ libhybris-0.1.0+git20131207+e452e83/compat/Android.common.mk
13@@ -0,0 +1,10 @@
14+# define ANDROID_VERSION MAJOR, MINOR and PATCH
15+
16+ANDROID_VERSION_MAJOR := $(word 1, $(subst ., , $(PLATFORM_VERSION)))
17+ANDROID_VERSION_MINOR := $(word 2, $(subst ., , $(PLATFORM_VERSION)))
18+ANDROID_VERSION_PATCH := $(word 3, $(subst ., , $(PLATFORM_VERSION)))
19+
20+LOCAL_CFLAGS += \
21+ -DANDROID_VERSION_MAJOR=$(ANDROID_VERSION_MAJOR) \
22+ -DANDROID_VERSION_MINOR=$(ANDROID_VERSION_MINOR) \
23+ -DANDROID_VERSION_PATCH=$(ANDROID_VERSION_PATCH)
24--- libhybris-0.1.0+git20131207+e452e83.orig/compat/camera/Android.mk
25+++ libhybris-0.1.0+git20131207+e452e83/compat/camera/Android.mk
26@@ -1,5 +1,6 @@
27 LOCAL_PATH:= $(call my-dir)
28 include $(CLEAR_VARS)
29+include $(LOCAL_PATH)/../Android.common.mk
30
31 HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
32
33--- libhybris-0.1.0+git20131207+e452e83.orig/compat/camera/camera_compatibility_layer.cpp
34+++ libhybris-0.1.0+git20131207+e452e83/compat/camera/camera_compatibility_layer.cpp
35@@ -27,17 +27,25 @@
36 #include <binder/ProcessState.h>
37 #include <camera/Camera.h>
38 #include <camera/CameraParameters.h>
39+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
40 #include <gui/SurfaceTexture.h>
41+#else
42+#include <gui/GLConsumer.h>
43+#endif
44 #include <ui/GraphicBuffer.h>
45
46+#include <GLES2/gl2.h>
47+#include <GLES2/gl2ext.h>
48+
49 #undef LOG_TAG
50 #define LOG_TAG "CameraCompatibilityLayer"
51 #include <utils/KeyedVector.h>
52 #include <utils/Log.h>
53+#include <utils/String16.h>
54
55 #define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
56
57-// From android::SurfaceTexture::FrameAvailableListener
58+// From android::GLConsumer::FrameAvailableListener
59 void CameraControl::onFrameAvailable()
60 {
61 REPORT_FUNCTION();
62@@ -170,7 +178,11 @@ CameraControl* android_camera_connect_to
63
64 CameraControl* cc = new CameraControl();
65 cc->listener = listener;
66+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3
67+ cc->camera = android::Camera::connect(camera_id, android::String16("hybris"), android::Camera::USE_CALLING_UID);
68+#else
69 cc->camera = android::Camera::connect(camera_id);
70+#endif
71
72 if (cc->camera == NULL)
73 return NULL;
74@@ -511,30 +523,57 @@ void android_camera_set_preview_texture(
75 assert(control);
76
77 static const bool allow_synchronous_mode = false;
78+ static const bool is_controlled_by_app = true;
79
80 android::sp<android::NativeBufferAlloc> native_alloc(
81 new android::NativeBufferAlloc()
82 );
83
84 android::sp<android::BufferQueue> buffer_queue(
85+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
86 new android::BufferQueue(false, NULL, native_alloc)
87+#else
88+ new android::BufferQueue(NULL, native_alloc)
89+#endif
90 );
91
92 if (control->preview_texture == NULL) {
93+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
94 control->preview_texture = android::sp<android::SurfaceTexture>(
95 new android::SurfaceTexture(
96+#else
97+ control->preview_texture = android::sp<android::GLConsumer>(
98+ new android::GLConsumer(
99+#endif
100+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
101 texture_id,
102 allow_synchronous_mode,
103 GL_TEXTURE_EXTERNAL_OES,
104 true,
105 buffer_queue));
106+#else
107+ buffer_queue,
108+ texture_id,
109+ GL_TEXTURE_EXTERNAL_OES,
110+ true,
111+ is_controlled_by_app));
112+#endif
113 }
114
115 control->preview_texture->setFrameAvailableListener(
116+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
117 android::sp<android::SurfaceTexture::FrameAvailableListener>(control));
118+#else
119+ android::sp<android::GLConsumer::FrameAvailableListener>(control));
120+#endif
121+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
122 control->camera->setPreviewTexture(control->preview_texture->getBufferQueue());
123+#else
124+ control->camera->setPreviewTarget(buffer_queue);
125+#endif
126 }
127
128+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
129 void android_camera_set_preview_surface(CameraControl* control, SfSurface* surface)
130 {
131 REPORT_FUNCTION();
132@@ -544,6 +583,7 @@ void android_camera_set_preview_surface(
133 android::Mutex::Autolock al(control->guard);
134 control->camera->setPreviewDisplay(surface->surface);
135 }
136+#endif
137
138 void android_camera_start_preview(CameraControl* control)
139 {
140--- libhybris-0.1.0+git20131207+e452e83.orig/compat/input/Android.mk
141+++ libhybris-0.1.0+git20131207+e452e83/compat/input/Android.mk
142@@ -18,6 +18,11 @@ LOCAL_SHARED_LIBRARIES := \
143 libgui \
144 libandroidfw
145
146+HAS_LIBINPUTSERVICE := $(shell test $(ANDROID_VERSION_MAJOR) -eq 4 -a $(ANDROID_VERSION_MINOR) -gt 2 && echo true)
147+ifeq ($(HAS_LIBINPUTSERVICE),true)
148+LOCAL_SHARED_LIBRARIES += libinputservice
149+endif
150+
151 LOCAL_C_INCLUDES := \
152 $(HYBRIS_PATH)/include \
153 external/skia/include/core \
154--- /dev/null
155+++ libhybris-0.1.0+git20131207+e452e83/compat/media/Android.mk
156@@ -0,0 +1,109 @@
157+LOCAL_PATH:= $(call my-dir)
158+include $(CLEAR_VARS)
159+include $(LOCAL_PATH)/../Android.common.mk
160+
161+HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
162+
163+LOCAL_CFLAGS += -std=gnu++0x
164+
165+LOCAL_SRC_FILES:= \
166+ media_compatibility_layer.cpp \
167+ media_codec_layer.cpp \
168+ media_codec_list.cpp \
169+ media_format_layer.cpp \
170+ surface_texture_client_hybris.cpp \
171+ recorder_compatibility_layer.cpp
172+
173+LOCAL_MODULE:= libmedia_compat_layer
174+LOCAL_MODULE_TAGS := optional
175+
176+LOCAL_SHARED_LIBRARIES := \
177+ libcutils \
178+ libcamera_client \
179+ libutils \
180+ libbinder \
181+ libhardware \
182+ libui \
183+ libgui \
184+ libstagefright \
185+ libstagefright_foundation \
186+ libEGL \
187+ libGLESv2 \
188+ libmedia
189+
190+LOCAL_C_INCLUDES := \
191+ $(HYBRIS_PATH)/include \
192+ frameworks/base/media/libstagefright/include \
193+ frameworks/base/include/media/stagefright \
194+ frameworks/base/include/media
195+
196+include $(BUILD_SHARED_LIBRARY)
197+
198+include $(CLEAR_VARS)
199+include $(LOCAL_PATH)/../Android.common.mk
200+
201+LOCAL_SRC_FILES:= \
202+ direct_media_test.cpp
203+
204+LOCAL_MODULE:= direct_media_test
205+LOCAL_MODULE_TAGS := optional
206+
207+LOCAL_C_INCLUDES := \
208+ $(HYBRIS_PATH)/include \
209+ bionic \
210+ bionic/libstdc++/include \
211+ external/gtest/include \
212+ external/stlport/stlport \
213+ external/skia/include/core \
214+ frameworks/base/include
215+
216+LOCAL_SHARED_LIBRARIES := \
217+ libis_compat_layer \
218+ libsf_compat_layer \
219+ libmedia_compat_layer \
220+ libcutils \
221+ libutils \
222+ libbinder \
223+ libhardware \
224+ libui \
225+ libgui \
226+ libEGL \
227+ libGLESv2
228+
229+include $(BUILD_EXECUTABLE)
230+
231+include $(CLEAR_VARS)
232+include $(LOCAL_PATH)/../Android.common.mk
233+
234+LOCAL_CFLAGS += -Wno-multichar -D SIMPLE_PLAYER -std=gnu++0x
235+
236+LOCAL_SRC_FILES:= \
237+ media_codec_layer.cpp \
238+ media_codec_list.cpp \
239+ media_format_layer.cpp \
240+ codec.cpp \
241+ SimplePlayer.cpp
242+
243+LOCAL_SHARED_LIBRARIES := \
244+ libstagefright \
245+ libstagefright_foundation \
246+ liblog \
247+ libutils \
248+ libbinder \
249+ libmedia \
250+ libgui \
251+ libcutils \
252+ libui
253+
254+LOCAL_C_INCLUDES:= \
255+ $(HYBRIS_PATH)/include \
256+ frameworks/av/media/libstagefright \
257+ frameworks/native/include/media/openmax \
258+ frameworks/base/media/libstagefright/include \
259+ frameworks/base/include/media/stagefright \
260+ frameworks/base/include/media
261+
262+LOCAL_MODULE:= codec
263+LOCAL_MODULE_TAGS := optional
264+
265+include $(BUILD_EXECUTABLE)
266--- /dev/null
267+++ libhybris-0.1.0+git20131207+e452e83/compat/media/SimplePlayer.cpp
268@@ -0,0 +1,777 @@
269+/*
270+ * Copyright (C) 2012 The Android Open Source Project
271+ *
272+ * Licensed under the Apache License, Version 2.0 (the "License");
273+ * you may not use this file except in compliance with the License.
274+ * You may obtain a copy of the License at
275+ *
276+ * http://www.apache.org/licenses/LICENSE-2.0
277+ *
278+ * Unless required by applicable law or agreed to in writing, software
279+ * distributed under the License is distributed on an "AS IS" BASIS,
280+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
281+ * See the License for the specific language governing permissions and
282+ * limitations under the License.
283+ */
284+
285+//#define LOG_NDEBUG 0
286+#define LOG_TAG "SimplePlayer"
287+#include <utils/Log.h>
288+
289+#include "SimplePlayer.h"
290+
291+#include <gui/Surface.h>
292+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
293+#include <gui/SurfaceTextureClient.h>
294+#endif
295+#include <media/AudioTrack.h>
296+#include <media/ICrypto.h>
297+#include <media/stagefright/foundation/ABuffer.h>
298+#include <media/stagefright/foundation/ADebug.h>
299+#include <media/stagefright/foundation/AMessage.h>
300+#include <media/stagefright/MediaCodec.h>
301+#include <media/stagefright/MediaErrors.h>
302+#include <media/stagefright/NativeWindowWrapper.h>
303+#include <media/stagefright/NuMediaExtractor.h>
304+
305+#define USE_MEDIA_CODEC_LAYER
306+
307+namespace android {
308+
309+SimplePlayer::SimplePlayer()
310+ : mState(UNINITIALIZED),
311+ mDoMoreStuffGeneration(0),
312+ mStartTimeRealUs(-1ll) {
313+}
314+
315+SimplePlayer::~SimplePlayer() {
316+}
317+
318+// static
319+status_t PostAndAwaitResponse(
320+ const sp<AMessage> &msg, sp<AMessage> *response) {
321+ status_t err = msg->postAndAwaitResponse(response);
322+ printf("%s\n", __PRETTY_FUNCTION__);
323+
324+ if (err != OK) {
325+ return err;
326+ }
327+
328+ if (!(*response)->findInt32("err", &err)) {
329+ err = OK;
330+ }
331+
332+ return err;
333+}
334+status_t SimplePlayer::setDataSource(const char *path) {
335+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
336+ msg->setString("path", path);
337+ sp<AMessage> response;
338+ return PostAndAwaitResponse(msg, &response);
339+}
340+
341+status_t SimplePlayer::setSurface(const sp<ISurfaceTexture> &surfaceTexture) {
342+ sp<AMessage> msg = new AMessage(kWhatSetSurface, id());
343+
344+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
345+ sp<SurfaceTextureClient> surfaceTextureClient;
346+ if (surfaceTexture != NULL) {
347+ surfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
348+ }
349+#else
350+ sp<Surface> surfaceTextureClient;
351+ if (surfaceTexture != NULL) {
352+ surfaceTextureClient = new Surface(surfaceTexture);
353+ }
354+#endif
355+
356+ msg->setObject(
357+ "native-window", new NativeWindowWrapper(surfaceTextureClient));
358+
359+ sp<AMessage> response;
360+ return PostAndAwaitResponse(msg, &response);
361+}
362+
363+status_t SimplePlayer::prepare() {
364+ sp<AMessage> msg = new AMessage(kWhatPrepare, id());
365+ sp<AMessage> response;
366+ return PostAndAwaitResponse(msg, &response);
367+}
368+
369+status_t SimplePlayer::start() {
370+ printf("%s\n", __PRETTY_FUNCTION__);
371+ sp<AMessage> msg = new AMessage(kWhatStart, id());
372+ sp<AMessage> response;
373+ return PostAndAwaitResponse(msg, &response);
374+}
375+
376+status_t SimplePlayer::stop() {
377+ sp<AMessage> msg = new AMessage(kWhatStop, id());
378+ sp<AMessage> response;
379+ return PostAndAwaitResponse(msg, &response);
380+}
381+
382+status_t SimplePlayer::reset() {
383+ sp<AMessage> msg = new AMessage(kWhatReset, id());
384+ sp<AMessage> response;
385+ return PostAndAwaitResponse(msg, &response);
386+}
387+
388+void SimplePlayer::onMessageReceived(const sp<AMessage> &msg) {
389+ switch (msg->what()) {
390+ case kWhatSetDataSource:
391+ {
392+ status_t err;
393+ if (mState != UNINITIALIZED) {
394+ err = INVALID_OPERATION;
395+ } else {
396+ CHECK(msg->findString("path", &mPath));
397+ mState = UNPREPARED;
398+ }
399+
400+ uint32_t replyID;
401+ CHECK(msg->senderAwaitsResponse(&replyID));
402+
403+ sp<AMessage> response = new AMessage;
404+ response->setInt32("err", err);
405+ response->postReply(replyID);
406+ break;
407+ }
408+
409+ case kWhatSetSurface:
410+ {
411+ status_t err;
412+ if (mState != UNPREPARED) {
413+ err = INVALID_OPERATION;
414+ } else {
415+ sp<RefBase> obj;
416+ CHECK(msg->findObject("native-window", &obj));
417+
418+ mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
419+
420+ err = OK;
421+ }
422+
423+ uint32_t replyID;
424+ CHECK(msg->senderAwaitsResponse(&replyID));
425+
426+ sp<AMessage> response = new AMessage;
427+ response->setInt32("err", err);
428+ response->postReply(replyID);
429+ break;
430+ }
431+
432+ case kWhatPrepare:
433+ {
434+ status_t err;
435+ if (mState != UNPREPARED) {
436+ err = INVALID_OPERATION;
437+ } else {
438+ err = onPrepare();
439+
440+ if (err == OK) {
441+ mState = STOPPED;
442+ }
443+ }
444+
445+ uint32_t replyID;
446+ CHECK(msg->senderAwaitsResponse(&replyID));
447+
448+ sp<AMessage> response = new AMessage;
449+ response->setInt32("err", err);
450+ response->postReply(replyID);
451+ break;
452+ }
453+
454+ case kWhatStart:
455+ {
456+ status_t err = OK;
457+
458+ if (mState == UNPREPARED) {
459+ err = onPrepare();
460+
461+ if (err == OK) {
462+ mState = STOPPED;
463+ }
464+ }
465+
466+ if (err == OK) {
467+ if (mState != STOPPED) {
468+ err = INVALID_OPERATION;
469+ } else {
470+ err = onStart();
471+
472+ if (err == OK) {
473+ mState = STARTED;
474+ }
475+ }
476+ }
477+
478+ uint32_t replyID;
479+ CHECK(msg->senderAwaitsResponse(&replyID));
480+
481+ sp<AMessage> response = new AMessage;
482+ response->setInt32("err", err);
483+ response->postReply(replyID);
484+ break;
485+ }
486+
487+ case kWhatStop:
488+ {
489+ status_t err;
490+
491+ if (mState != STARTED) {
492+ err = INVALID_OPERATION;
493+ } else {
494+ err = onStop();
495+
496+ if (err == OK) {
497+ mState = STOPPED;
498+ }
499+ }
500+
501+ uint32_t replyID;
502+ CHECK(msg->senderAwaitsResponse(&replyID));
503+
504+ sp<AMessage> response = new AMessage;
505+ response->setInt32("err", err);
506+ response->postReply(replyID);
507+ break;
508+ }
509+
510+ case kWhatReset:
511+ {
512+ status_t err = OK;
513+
514+ if (mState == STARTED) {
515+ CHECK_EQ(onStop(), (status_t)OK);
516+ mState = STOPPED;
517+ }
518+
519+ if (mState == STOPPED) {
520+ err = onReset();
521+ mState = UNINITIALIZED;
522+ }
523+
524+ uint32_t replyID;
525+ CHECK(msg->senderAwaitsResponse(&replyID));
526+
527+ sp<AMessage> response = new AMessage;
528+ response->setInt32("err", err);
529+ response->postReply(replyID);
530+ break;
531+ }
532+
533+ case kWhatDoMoreStuff:
534+ {
535+ int32_t generation;
536+ CHECK(msg->findInt32("generation", &generation));
537+
538+ if (generation != mDoMoreStuffGeneration) {
539+ break;
540+ }
541+
542+ status_t err = onDoMoreStuff();
543+
544+ if (err == OK) {
545+ msg->post(10000ll);
546+ }
547+ break;
548+ }
549+
550+ default:
551+ TRESPASS();
552+ }
553+}
554+
555+status_t SimplePlayer::onPrepare() {
556+ CHECK_EQ(mState, UNPREPARED);
557+ printf("%s\n", __PRETTY_FUNCTION__);
558+
559+ mExtractor = new NuMediaExtractor;
560+
561+ status_t err = mExtractor->setDataSource(mPath.c_str());
562+
563+ if (err != OK) {
564+ mExtractor.clear();
565+ return err;
566+ }
567+
568+ if (mCodecLooper == NULL) {
569+ mCodecLooper = new ALooper;
570+ mCodecLooper->start();
571+ }
572+
573+ bool haveAudio = false;
574+ bool haveVideo = false;
575+ for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
576+ sp<AMessage> format;
577+ status_t err = mExtractor->getTrackFormat(i, &format);
578+ CHECK_EQ(err, (status_t)OK);
579+
580+ AString mime;
581+ int32_t width = 0, height = 0, maxInputSize = 0;
582+ int64_t durationUs = 0;
583+ sp<ABuffer> csd0, csd1;
584+#ifdef USE_MEDIA_CODEC_LAYER
585+ MediaFormat mformat;
586+#endif
587+ CHECK(format->findString("mime", &mime));
588+
589+ if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) {
590+ //haveAudio = true;
591+ printf("*** Have audio but skipping it!\n");
592+ continue;
593+ } else if (!haveVideo && !strncasecmp(mime.c_str(), "video/", 6)) {
594+ haveVideo = true;
595+ CHECK(format->findInt32("width", &width));
596+ CHECK(format->findInt32("height", &height));
597+ CHECK(format->findInt64("durationUs", &durationUs));
598+ CHECK(format->findInt32("max-input-size", &maxInputSize));
599+ CHECK(format->findBuffer("csd-0", &csd0));
600+ CHECK(format->findBuffer("csd-1", &csd1));
601+#ifdef USE_MEDIA_CODEC_LAYER
602+ mformat = media_format_create_video_format(mime.c_str(), width, height, durationUs, maxInputSize);
603+ media_format_set_byte_buffer(mformat, "csd-0", csd0->data(), csd0->size());
604+ media_format_set_byte_buffer(mformat, "csd-1", csd1->data(), csd1->size());
605+#endif
606+ } else {
607+ continue;
608+ }
609+
610+ err = mExtractor->selectTrack(i);
611+ CHECK_EQ(err, (status_t)OK);
612+
613+ CodecState *state =
614+ &mStateByTrackIndex.editValueAt(
615+ mStateByTrackIndex.add(i, CodecState()));
616+
617+ state->mNumFramesWritten = 0;
618+#ifdef USE_MEDIA_CODEC_LAYER
619+ state->mCodecDelegate = media_codec_create_by_codec_type(mime.c_str());
620+ state->mCodec = media_codec_get(state->mCodecDelegate);
621+ CHECK(state->mCodecDelegate != NULL);
622+#else
623+ state->mCodec = MediaCodec::CreateByType(
624+ mCodecLooper, mime.c_str(), false /* encoder */);
625+#endif
626+
627+ CHECK(state->mCodec != NULL);
628+
629+#ifdef USE_MEDIA_CODEC_LAYER
630+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
631+ err = media_codec_configure(state->mCodecDelegate, mformat, mNativeWindow->getSurfaceTextureClient().get(), 0);
632+#else
633+ err = media_codec_configure(state->mCodecDelegate, mformat, mNativeWindow->getSurface().get(), 0);
634+#endif
635+#else
636+ err = state->mCodec->configure(
637+ format,
638+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
639+ mNativeWindow->getSurfaceTextureClient(),
640+#else
641+ mNativeWindow->getSurface(),
642+#endif
643+ NULL /* crypto */,
644+ 0 /* flags */);
645+#endif
646+
647+ CHECK_EQ(err, (status_t)OK);
648+
649+ size_t j = 0;
650+ sp<ABuffer> buffer;
651+ // Place the CSD data into the source buffer
652+ while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
653+ state->mCSD.push_back(buffer);
654+
655+ ++j;
656+ }
657+ }
658+
659+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
660+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
661+
662+#ifdef USE_MEDIA_CODEC_LAYER
663+ status_t err = media_codec_start(state->mCodecDelegate);
664+#else
665+ status_t err = state->mCodec->start();
666+#endif
667+ CHECK_EQ(err, (status_t)OK);
668+
669+#ifdef USE_MEDIA_CODEC_LAYER
670+ size_t nInputBuffers = media_codec_get_input_buffers_size(state->mCodecDelegate);
671+ ALOGD("nInputBuffers: %u", nInputBuffers);
672+ for (size_t i=0; i<nInputBuffers; i++)
673+ {
674+ uint8_t *data = media_codec_get_nth_input_buffer(state->mCodecDelegate, i);
675+ CHECK(data != NULL);
676+ size_t size = media_codec_get_nth_input_buffer_capacity(state->mCodecDelegate, i);
677+ ALOGD("input buffer[%d] size: %d", i, size);
678+ sp<ABuffer> buf = new ABuffer(data, size);
679+ state->mBuffers[0].insertAt(new ABuffer(data, size), i);
680+ }
681+#else
682+ err = state->mCodec->getInputBuffers(&state->mBuffers[0]);
683+ CHECK_EQ(err, (status_t)OK);
684+#endif
685+
686+ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
687+ CHECK_EQ(err, (status_t)OK);
688+
689+ for (size_t j = 0; j < state->mCSD.size(); ++j) {
690+ const sp<ABuffer> &srcBuffer = state->mCSD.itemAt(j);
691+
692+ size_t index;
693+#ifdef USE_MEDIA_CODEC_LAYER
694+ err = media_codec_dequeue_input_buffer(state->mCodecDelegate, &index, -1ll);
695+#else
696+ err = state->mCodec->dequeueInputBuffer(&index, -1ll);
697+#endif
698+ CHECK_EQ(err, (status_t)OK);
699+
700+ const sp<ABuffer> &dstBuffer = state->mBuffers[0].itemAt(index);
701+
702+ CHECK_LE(srcBuffer->size(), dstBuffer->capacity());
703+ dstBuffer->setRange(0, srcBuffer->size());
704+ memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size());
705+
706+#ifdef USE_MEDIA_CODEC_LAYER
707+ MediaCodecBufferInfo bufInfo;
708+ bufInfo.index = index;
709+ bufInfo.offset = 0;
710+ bufInfo.size = dstBuffer->size();
711+ bufInfo.presentation_time_us = 0ll;
712+ bufInfo.flags = MediaCodec::BUFFER_FLAG_CODECCONFIG;
713+
714+ err = media_codec_queue_input_buffer(
715+ state->mCodecDelegate,
716+ &bufInfo);
717+
718+#else
719+ err = state->mCodec->queueInputBuffer(
720+ index,
721+ 0,
722+ dstBuffer->size(),
723+ 0ll,
724+ MediaCodec::BUFFER_FLAG_CODECCONFIG);
725+#endif
726+ CHECK_EQ(err, (status_t)OK);
727+ }
728+ }
729+
730+ return OK;
731+}
732+
733+status_t SimplePlayer::onStart() {
734+ CHECK_EQ(mState, STOPPED);
735+
736+ mStartTimeRealUs = -1ll;
737+
738+ sp<AMessage> msg = new AMessage(kWhatDoMoreStuff, id());
739+ msg->setInt32("generation", ++mDoMoreStuffGeneration);
740+ msg->post();
741+
742+ return OK;
743+}
744+
745+status_t SimplePlayer::onStop() {
746+ CHECK_EQ(mState, STARTED);
747+
748+ ++mDoMoreStuffGeneration;
749+
750+ return OK;
751+}
752+
753+status_t SimplePlayer::onReset() {
754+ CHECK_EQ(mState, STOPPED);
755+
756+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
757+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
758+
759+ CHECK_EQ(state->mCodec->release(), (status_t)OK);
760+ }
761+
762+ mStartTimeRealUs = -1ll;
763+
764+ mStateByTrackIndex.clear();
765+ mCodecLooper.clear();
766+ mExtractor.clear();
767+ mNativeWindow.clear();
768+ mPath.clear();
769+
770+ return OK;
771+}
772+
773+status_t SimplePlayer::onDoMoreStuff() {
774+ ALOGV("onDoMoreStuff");
775+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
776+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
777+
778+ status_t err;
779+ do {
780+ size_t index;
781+#ifdef USE_MEDIA_CODEC_LAYER
782+ err = media_codec_dequeue_input_buffer(state->mCodecDelegate, &index, 0ll);
783+#else
784+ err = state->mCodec->dequeueInputBuffer(&index);
785+#endif
786+
787+ if (err == OK) {
788+ ALOGD("dequeued input buffer on track %d",
789+ mStateByTrackIndex.keyAt(i));
790+
791+ state->mAvailInputBufferIndices.push_back(index);
792+ } else {
793+ ALOGD("dequeueInputBuffer on track %d returned %d",
794+ mStateByTrackIndex.keyAt(i), err);
795+ }
796+ } while (err == OK);
797+
798+ do {
799+#ifdef USE_MEDIA_CODEC_LAYER
800+ BufferInfo info;
801+ MediaCodecBufferInfo bufInfo;
802+ err = media_codec_dequeue_output_buffer(
803+ state->mCodecDelegate,
804+ &bufInfo,
805+ 0ll);
806+
807+ info.mIndex = bufInfo.index;
808+ info.mOffset = bufInfo.offset;
809+ info.mSize = bufInfo.size;
810+ info.mPresentationTimeUs = bufInfo.presentation_time_us;
811+ info.mFlags = bufInfo.flags;
812+
813+#else
814+ BufferInfo info;
815+ err = state->mCodec->dequeueOutputBuffer(
816+ &info.mIndex,
817+ &info.mOffset,
818+ &info.mSize,
819+ &info.mPresentationTimeUs,
820+ &info.mFlags);
821+#endif
822+
823+ if (err == OK) {
824+ ALOGV("dequeued output buffer on track %d",
825+ mStateByTrackIndex.keyAt(i));
826+
827+ state->mAvailOutputBufferInfos.push_back(info);
828+ } else if (err == INFO_FORMAT_CHANGED) {
829+ err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state);
830+ CHECK_EQ(err, (status_t)OK);
831+ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
832+ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
833+ CHECK_EQ(err, (status_t)OK);
834+ } else {
835+ ALOGV("dequeueOutputBuffer on track %d returned %d",
836+ mStateByTrackIndex.keyAt(i), err);
837+ }
838+ } while (err == OK
839+ || err == INFO_FORMAT_CHANGED
840+ || err == INFO_OUTPUT_BUFFERS_CHANGED);
841+ }
842+
843+ for (;;) {
844+ size_t trackIndex;
845+ status_t err = mExtractor->getSampleTrackIndex(&trackIndex);
846+
847+ if (err != OK) {
848+ ALOGI("encountered input EOS.");
849+ break;
850+ } else {
851+ CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex);
852+
853+ if (state->mAvailInputBufferIndices.empty()) {
854+ break;
855+ }
856+
857+ size_t index = *state->mAvailInputBufferIndices.begin();
858+ state->mAvailInputBufferIndices.erase(
859+ state->mAvailInputBufferIndices.begin());
860+
861+ const sp<ABuffer> &dstBuffer =
862+ state->mBuffers[0].itemAt(index);
863+
864+ err = mExtractor->readSampleData(dstBuffer);
865+ CHECK_EQ(err, (status_t)OK);
866+
867+ int64_t timeUs;
868+ CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK);
869+
870+#ifdef USE_MEDIA_CODEC_LAYER
871+ MediaCodecBufferInfo bufInfo;
872+ bufInfo.index = index;
873+ bufInfo.offset = dstBuffer->offset();
874+ bufInfo.size = dstBuffer->size();
875+ bufInfo.presentation_time_us = timeUs;
876+ bufInfo.flags = 0;
877+
878+ err = media_codec_queue_input_buffer(
879+ state->mCodecDelegate,
880+ &bufInfo);
881+
882+#else
883+ err = state->mCodec->queueInputBuffer(
884+ index,
885+ dstBuffer->offset(),
886+ dstBuffer->size(),
887+ timeUs,
888+ 0);
889+#endif
890+ CHECK_EQ(err, (status_t)OK);
891+
892+ ALOGV("enqueued input data on track %d", trackIndex);
893+
894+ err = mExtractor->advance();
895+ CHECK_EQ(err, (status_t)OK);
896+ }
897+ }
898+
899+ int64_t nowUs = ALooper::GetNowUs();
900+
901+ if (mStartTimeRealUs < 0ll) {
902+ mStartTimeRealUs = nowUs + 1000000ll;
903+ }
904+
905+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
906+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
907+
908+ while (!state->mAvailOutputBufferInfos.empty()) {
909+ BufferInfo *info = &*state->mAvailOutputBufferInfos.begin();
910+
911+ int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs;
912+ int64_t lateByUs = nowUs - whenRealUs;
913+
914+ if (lateByUs > -10000ll) {
915+ bool release = true;
916+
917+ if (lateByUs > 30000ll) {
918+ ALOGI("track %d buffer late by %lld us, dropping.",
919+ mStateByTrackIndex.keyAt(i), lateByUs);
920+ state->mCodec->releaseOutputBuffer(info->mIndex);
921+ } else {
922+ if (state->mAudioTrack != NULL) {
923+ const sp<ABuffer> &srcBuffer =
924+ state->mBuffers[1].itemAt(info->mIndex);
925+
926+ renderAudio(state, info, srcBuffer);
927+
928+ if (info->mSize > 0) {
929+ release = false;
930+ }
931+ }
932+
933+ if (release) {
934+#ifdef USE_MEDIA_CODEC_LAYER
935+ ALOGD("Rendering output buffer index %d and releasing", info->mIndex);
936+ state->mCodec->renderOutputBufferAndRelease(
937+ info->mIndex);
938+#else
939+ ALOGD("Releasing output buffer index %d", info->mIndex);
940+ state->mCodec->releaseOutputBuffer(info->mIndex);
941+#endif
942+ }
943+ }
944+
945+ if (release) {
946+ state->mAvailOutputBufferInfos.erase(
947+ state->mAvailOutputBufferInfos.begin());
948+
949+ info = NULL;
950+ } else {
951+ break;
952+ }
953+ } else {
954+ ALOGV("track %d buffer early by %lld us.",
955+ mStateByTrackIndex.keyAt(i), -lateByUs);
956+ break;
957+ }
958+ }
959+ }
960+
961+ return OK;
962+}
963+
964+status_t SimplePlayer::onOutputFormatChanged(
965+ size_t trackIndex, CodecState *state) {
966+ sp<AMessage> format;
967+ status_t err = state->mCodec->getOutputFormat(&format);
968+
969+ if (err != OK) {
970+ return err;
971+ }
972+
973+ AString mime;
974+ CHECK(format->findString("mime", &mime));
975+
976+ if (!strncasecmp(mime.c_str(), "audio/", 6)) {
977+ int32_t channelCount;
978+ int32_t sampleRate;
979+ CHECK(format->findInt32("channel-count", &channelCount));
980+ CHECK(format->findInt32("sample-rate", &sampleRate));
981+
982+ state->mAudioTrack = new AudioTrack(
983+ AUDIO_STREAM_MUSIC,
984+ sampleRate,
985+ AUDIO_FORMAT_PCM_16_BIT,
986+ audio_channel_out_mask_from_count(channelCount),
987+ 0);
988+
989+ state->mNumFramesWritten = 0;
990+ }
991+
992+ return OK;
993+}
994+
995+void SimplePlayer::renderAudio(
996+ CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer) {
997+ CHECK(state->mAudioTrack != NULL);
998+
999+ if (state->mAudioTrack->stopped()) {
1000+ state->mAudioTrack->start();
1001+ }
1002+
1003+ uint32_t numFramesPlayed;
1004+ CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK);
1005+
1006+ uint32_t numFramesAvailableToWrite =
1007+ state->mAudioTrack->frameCount()
1008+ - (state->mNumFramesWritten - numFramesPlayed);
1009+
1010+ size_t numBytesAvailableToWrite =
1011+ numFramesAvailableToWrite * state->mAudioTrack->frameSize();
1012+
1013+ size_t copy = info->mSize;
1014+ if (copy > numBytesAvailableToWrite) {
1015+ copy = numBytesAvailableToWrite;
1016+ }
1017+
1018+ if (copy == 0) {
1019+ return;
1020+ }
1021+
1022+ int64_t startTimeUs = ALooper::GetNowUs();
1023+
1024+ ssize_t nbytes = state->mAudioTrack->write(
1025+ buffer->base() + info->mOffset, copy);
1026+
1027+ CHECK_EQ(nbytes, (ssize_t)copy);
1028+
1029+ int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
1030+
1031+ uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize();
1032+
1033+ if (delayUs > 2000ll) {
1034+ ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, "
1035+ "numFramesWritten=%u",
1036+ delayUs, numFramesAvailableToWrite, numFramesWritten);
1037+ }
1038+
1039+ info->mOffset += nbytes;
1040+ info->mSize -= nbytes;
1041+
1042+ state->mNumFramesWritten += numFramesWritten;
1043+}
1044+
1045+} // namespace android
1046--- /dev/null
1047+++ libhybris-0.1.0+git20131207+e452e83/compat/media/SimplePlayer.h
1048@@ -0,0 +1,120 @@
1049+/*
1050+ * Copyright (C) 2012 The Android Open Source Project
1051+ *
1052+ * Licensed under the Apache License, Version 2.0 (the "License");
1053+ * you may not use this file except in compliance with the License.
1054+ * You may obtain a copy of the License at
1055+ *
1056+ * http://www.apache.org/licenses/LICENSE-2.0
1057+ *
1058+ * Unless required by applicable law or agreed to in writing, software
1059+ * distributed under the License is distributed on an "AS IS" BASIS,
1060+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1061+ * See the License for the specific language governing permissions and
1062+ * limitations under the License.
1063+ */
1064+
1065+#include <media/stagefright/foundation/AHandler.h>
1066+#include <media/stagefright/foundation/AString.h>
1067+#include <utils/KeyedVector.h>
1068+
1069+#include <hybris/media/media_codec_layer.h>
1070+
1071+namespace android {
1072+
1073+struct ABuffer;
1074+struct ALooper;
1075+struct AudioTrack;
1076+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
1077+struct ISurfaceTexture;
1078+#else
1079+struct IGraphicBufferProducer;
1080+#endif
1081+struct MediaCodec;
1082+struct NativeWindowWrapper;
1083+struct NuMediaExtractor;
1084+
1085+struct SimplePlayer : public AHandler {
1086+ SimplePlayer();
1087+
1088+ status_t setDataSource(const char *path);
1089+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
1090+ status_t setSurface(const sp<ISurfaceTexture> &surfaceTexture);
1091+#else
1092+ status_t setSurface(const sp<IGraphicBufferProducer> &surfaceTexture);
1093+#endif
1094+ status_t prepare();
1095+ status_t start();
1096+ status_t stop();
1097+ status_t reset();
1098+
1099+protected:
1100+ virtual ~SimplePlayer();
1101+
1102+ virtual void onMessageReceived(const sp<AMessage> &msg);
1103+
1104+private:
1105+ enum State {
1106+ UNINITIALIZED,
1107+ UNPREPARED,
1108+ STOPPED,
1109+ STARTED
1110+ };
1111+
1112+ enum {
1113+ kWhatSetDataSource,
1114+ kWhatSetSurface,
1115+ kWhatPrepare,
1116+ kWhatStart,
1117+ kWhatStop,
1118+ kWhatReset,
1119+ kWhatDoMoreStuff,
1120+ };
1121+
1122+ struct BufferInfo {
1123+ size_t mIndex;
1124+ size_t mOffset;
1125+ size_t mSize;
1126+ int64_t mPresentationTimeUs;
1127+ uint32_t mFlags;
1128+ };
1129+
1130+ struct CodecState
1131+ {
1132+ sp<MediaCodec> mCodec;
1133+ MediaCodecDelegate mCodecDelegate;
1134+ Vector<sp<ABuffer> > mCSD;
1135+ Vector<sp<ABuffer> > mBuffers[2];
1136+
1137+ List<size_t> mAvailInputBufferIndices;
1138+ List<BufferInfo> mAvailOutputBufferInfos;
1139+
1140+ sp<AudioTrack> mAudioTrack;
1141+ uint32_t mNumFramesWritten;
1142+ };
1143+
1144+ State mState;
1145+ AString mPath;
1146+ sp<NativeWindowWrapper> mNativeWindow;
1147+
1148+ sp<NuMediaExtractor> mExtractor;
1149+ sp<ALooper> mCodecLooper;
1150+ KeyedVector<size_t, CodecState> mStateByTrackIndex;
1151+ int32_t mDoMoreStuffGeneration;
1152+
1153+ int64_t mStartTimeRealUs;
1154+
1155+ status_t onPrepare();
1156+ status_t onStart();
1157+ status_t onStop();
1158+ status_t onReset();
1159+ status_t onDoMoreStuff();
1160+ status_t onOutputFormatChanged(size_t trackIndex, CodecState *state);
1161+
1162+ void renderAudio(
1163+ CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer);
1164+
1165+ DISALLOW_EVIL_CONSTRUCTORS(SimplePlayer);
1166+};
1167+
1168+} // namespace android
1169--- /dev/null
1170+++ libhybris-0.1.0+git20131207+e452e83/compat/media/codec.cpp
1171@@ -0,0 +1,433 @@
1172+/*
1173+ * Copyright (C) 2012 The Android Open Source Project
1174+ *
1175+ * Licensed under the Apache License, Version 2.0 (the "License");
1176+ * you may not use this file except in compliance with the License.
1177+ * You may obtain a copy of the License at
1178+ *
1179+ * http://www.apache.org/licenses/LICENSE-2.0
1180+ *
1181+ * Unless required by applicable law or agreed to in writing, software
1182+ * distributed under the License is distributed on an "AS IS" BASIS,
1183+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1184+ * See the License for the specific language governing permissions and
1185+ * limitations under the License.
1186+ */
1187+
1188+#define LOG_NDEBUG 0
1189+#define LOG_TAG "codec"
1190+#include <utils/Log.h>
1191+
1192+#include "SimplePlayer.h"
1193+
1194+#include <binder/IServiceManager.h>
1195+#include <binder/ProcessState.h>
1196+#include <media/ICrypto.h>
1197+#include <media/IMediaPlayerService.h>
1198+#include <media/stagefright/foundation/ABuffer.h>
1199+#include <media/stagefright/foundation/ADebug.h>
1200+#include <media/stagefright/foundation/ALooper.h>
1201+#include <media/stagefright/foundation/AMessage.h>
1202+#include <media/stagefright/foundation/AString.h>
1203+#include <media/stagefright/DataSource.h>
1204+#include <media/stagefright/MediaCodec.h>
1205+#include <media/stagefright/MediaCodecList.h>
1206+#include <media/stagefright/MediaDefs.h>
1207+#include <media/stagefright/NuMediaExtractor.h>
1208+#include <gui/ISurfaceComposer.h>
1209+#include <gui/SurfaceComposerClient.h>
1210+#include <ui/DisplayInfo.h>
1211+
1212+static void usage(const char *me) {
1213+ fprintf(stderr, "usage: %s [-a] use audio\n"
1214+ "\t\t[-v] use video\n"
1215+ "\t\t[-p] playback\n"
1216+ "\t\t[-S] allocate buffers from a surface\n",
1217+ me);
1218+
1219+ exit(1);
1220+}
1221+
1222+namespace android {
1223+
1224+struct CodecState {
1225+ sp<MediaCodec> mCodec;
1226+ Vector<sp<ABuffer> > mInBuffers;
1227+ Vector<sp<ABuffer> > mOutBuffers;
1228+ bool mSignalledInputEOS;
1229+ bool mSawOutputEOS;
1230+ int64_t mNumBuffersDecoded;
1231+ int64_t mNumBytesDecoded;
1232+ bool mIsAudio;
1233+};
1234+
1235+} // namespace android
1236+
1237+static int decode(
1238+ const android::sp<android::ALooper> &looper,
1239+ const char *path,
1240+ bool useAudio,
1241+ bool useVideo,
1242+ const android::sp<android::Surface> &surface) {
1243+ using namespace android;
1244+
1245+ static int64_t kTimeout = 500ll;
1246+
1247+ sp<NuMediaExtractor> extractor = new NuMediaExtractor;
1248+ if (extractor->setDataSource(path) != OK) {
1249+ fprintf(stderr, "unable to instantiate extractor.\n");
1250+ return 1;
1251+ }
1252+
1253+ KeyedVector<size_t, CodecState> stateByTrack;
1254+
1255+ bool haveAudio = false;
1256+ bool haveVideo = false;
1257+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
1258+ sp<AMessage> format;
1259+ status_t err = extractor->getTrackFormat(i, &format);
1260+ CHECK_EQ(err, (status_t)OK);
1261+
1262+ AString mime;
1263+ CHECK(format->findString("mime", &mime));
1264+
1265+ bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
1266+ bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
1267+
1268+ if (useAudio && !haveAudio && isAudio) {
1269+ haveAudio = true;
1270+ } else if (useVideo && !haveVideo && isVideo) {
1271+ haveVideo = true;
1272+ } else {
1273+ continue;
1274+ }
1275+
1276+ ALOGV("selecting track %d", i);
1277+
1278+ err = extractor->selectTrack(i);
1279+ CHECK_EQ(err, (status_t)OK);
1280+
1281+ CodecState *state =
1282+ &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
1283+
1284+ state->mNumBytesDecoded = 0;
1285+ state->mNumBuffersDecoded = 0;
1286+ state->mIsAudio = isAudio;
1287+
1288+ state->mCodec = MediaCodec::CreateByType(
1289+ looper, mime.c_str(), false /* encoder */);
1290+
1291+ CHECK(state->mCodec != NULL);
1292+
1293+ err = state->mCodec->configure(
1294+ format, isVideo ? surface : NULL,
1295+ NULL /* crypto */,
1296+ 0 /* flags */);
1297+
1298+ CHECK_EQ(err, (status_t)OK);
1299+
1300+ state->mSignalledInputEOS = false;
1301+ state->mSawOutputEOS = false;
1302+ }
1303+
1304+ CHECK(!stateByTrack.isEmpty());
1305+
1306+ int64_t startTimeUs = ALooper::GetNowUs();
1307+
1308+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
1309+ CodecState *state = &stateByTrack.editValueAt(i);
1310+
1311+ sp<MediaCodec> codec = state->mCodec;
1312+
1313+ CHECK_EQ((status_t)OK, codec->start());
1314+
1315+ CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
1316+ CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers));
1317+
1318+ ALOGV("got %d input and %d output buffers",
1319+ state->mInBuffers.size(), state->mOutBuffers.size());
1320+ }
1321+
1322+ bool sawInputEOS = false;
1323+
1324+ for (;;) {
1325+ if (!sawInputEOS) {
1326+ size_t trackIndex;
1327+ status_t err = extractor->getSampleTrackIndex(&trackIndex);
1328+
1329+ if (err != OK) {
1330+ ALOGV("saw input eos");
1331+ sawInputEOS = true;
1332+ } else {
1333+ CodecState *state = &stateByTrack.editValueFor(trackIndex);
1334+
1335+ size_t index;
1336+ err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
1337+
1338+ if (err == OK) {
1339+ ALOGV("filling input buffer %d", index);
1340+
1341+ const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
1342+
1343+ err = extractor->readSampleData(buffer);
1344+ CHECK_EQ(err, (status_t)OK);
1345+
1346+ int64_t timeUs;
1347+ err = extractor->getSampleTime(&timeUs);
1348+ CHECK_EQ(err, (status_t)OK);
1349+
1350+ uint32_t bufferFlags = 0;
1351+
1352+ err = state->mCodec->queueInputBuffer(
1353+ index,
1354+ 0 /* offset */,
1355+ buffer->size(),
1356+ timeUs,
1357+ bufferFlags);
1358+
1359+ CHECK_EQ(err, (status_t)OK);
1360+
1361+ extractor->advance();
1362+ } else {
1363+ CHECK_EQ(err, -EAGAIN);
1364+ }
1365+ }
1366+ } else {
1367+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
1368+ CodecState *state = &stateByTrack.editValueAt(i);
1369+
1370+ if (!state->mSignalledInputEOS) {
1371+ size_t index;
1372+ status_t err =
1373+ state->mCodec->dequeueInputBuffer(&index, kTimeout);
1374+
1375+ if (err == OK) {
1376+ ALOGV("signalling input EOS on track %d", i);
1377+
1378+ err = state->mCodec->queueInputBuffer(
1379+ index,
1380+ 0 /* offset */,
1381+ 0 /* size */,
1382+ 0ll /* timeUs */,
1383+ MediaCodec::BUFFER_FLAG_EOS);
1384+
1385+ CHECK_EQ(err, (status_t)OK);
1386+
1387+ state->mSignalledInputEOS = true;
1388+ } else {
1389+ CHECK_EQ(err, -EAGAIN);
1390+ }
1391+ }
1392+ }
1393+ }
1394+
1395+ bool sawOutputEOSOnAllTracks = true;
1396+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
1397+ CodecState *state = &stateByTrack.editValueAt(i);
1398+ if (!state->mSawOutputEOS) {
1399+ sawOutputEOSOnAllTracks = false;
1400+ break;
1401+ }
1402+ }
1403+
1404+ if (sawOutputEOSOnAllTracks) {
1405+ break;
1406+ }
1407+
1408+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
1409+ CodecState *state = &stateByTrack.editValueAt(i);
1410+
1411+ if (state->mSawOutputEOS) {
1412+ continue;
1413+ }
1414+
1415+ size_t index;
1416+ size_t offset;
1417+ size_t size;
1418+ int64_t presentationTimeUs;
1419+ uint32_t flags;
1420+ status_t err = state->mCodec->dequeueOutputBuffer(
1421+ &index, &offset, &size, &presentationTimeUs, &flags,
1422+ kTimeout);
1423+
1424+ if (err == OK) {
1425+ ALOGV("draining output buffer %d, time = %lld us",
1426+ index, presentationTimeUs);
1427+
1428+ ++state->mNumBuffersDecoded;
1429+ state->mNumBytesDecoded += size;
1430+
1431+ err = state->mCodec->releaseOutputBuffer(index);
1432+ CHECK_EQ(err, (status_t)OK);
1433+
1434+ if (flags & MediaCodec::BUFFER_FLAG_EOS) {
1435+ ALOGV("reached EOS on output.");
1436+
1437+ state->mSawOutputEOS = true;
1438+ }
1439+ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
1440+ ALOGV("INFO_OUTPUT_BUFFERS_CHANGED");
1441+ CHECK_EQ((status_t)OK,
1442+ state->mCodec->getOutputBuffers(&state->mOutBuffers));
1443+
1444+ ALOGV("got %d output buffers", state->mOutBuffers.size());
1445+ } else if (err == INFO_FORMAT_CHANGED) {
1446+ sp<AMessage> format;
1447+ CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format));
1448+
1449+ ALOGV("INFO_FORMAT_CHANGED: %s", format->debugString().c_str());
1450+ } else {
1451+ CHECK_EQ(err, -EAGAIN);
1452+ }
1453+ }
1454+ }
1455+
1456+ int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
1457+
1458+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
1459+ CodecState *state = &stateByTrack.editValueAt(i);
1460+
1461+ CHECK_EQ((status_t)OK, state->mCodec->release());
1462+
1463+ if (state->mIsAudio) {
1464+ ALOGD("track %d: %lld bytes received. %.2f KB/sec\n",
1465+ i,
1466+ state->mNumBytesDecoded,
1467+ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
1468+ } else {
1469+ ALOGD("track %d: %lld frames decoded, %.2f fps. %lld bytes "
1470+ "received. %.2f KB/sec\n",
1471+ i,
1472+ state->mNumBuffersDecoded,
1473+ state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
1474+ state->mNumBytesDecoded,
1475+ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
1476+ }
1477+ }
1478+
1479+ return 0;
1480+}
1481+
1482+int main(int argc, char **argv) {
1483+ using namespace android;
1484+
1485+ const char *me = argv[0];
1486+
1487+ bool useAudio = false;
1488+ bool useVideo = false;
1489+ bool playback = false;
1490+ bool useSurface = false;
1491+
1492+ int res;
1493+ while ((res = getopt(argc, argv, "havpSD")) >= 0) {
1494+ switch (res) {
1495+ case 'a':
1496+ {
1497+ useAudio = true;
1498+ break;
1499+ }
1500+
1501+ case 'v':
1502+ {
1503+ useVideo = true;
1504+ break;
1505+ }
1506+
1507+ case 'p':
1508+ {
1509+ playback = true;
1510+ break;
1511+ }
1512+
1513+ case 'S':
1514+ {
1515+ useSurface = true;
1516+ break;
1517+ }
1518+
1519+ case '?':
1520+ case 'h':
1521+ default:
1522+ {
1523+ usage(me);
1524+ }
1525+ }
1526+ }
1527+
1528+ argc -= optind;
1529+ argv += optind;
1530+
1531+ if (argc != 1) {
1532+ usage(me);
1533+ }
1534+
1535+ if (!useAudio && !useVideo) {
1536+ useAudio = useVideo = true;
1537+ }
1538+
1539+ ProcessState::self()->startThreadPool();
1540+
1541+ DataSource::RegisterDefaultSniffers();
1542+
1543+ sp<ALooper> looper = new ALooper;
1544+ looper->start();
1545+
1546+ sp<SurfaceComposerClient> composerClient;
1547+ sp<SurfaceControl> control;
1548+ sp<Surface> surface;
1549+
1550+ if (playback || (useSurface && useVideo)) {
1551+ composerClient = new SurfaceComposerClient;
1552+ CHECK_EQ(composerClient->initCheck(), (status_t)OK);
1553+
1554+ sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
1555+ ISurfaceComposer::eDisplayIdMain));
1556+ DisplayInfo info;
1557+ SurfaceComposerClient::getDisplayInfo(display, &info);
1558+ ssize_t displayWidth = info.w;
1559+ ssize_t displayHeight = info.h;
1560+
1561+ ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);
1562+
1563+ control = composerClient->createSurface(
1564+ String8("A Surface"),
1565+ displayWidth,
1566+ displayHeight,
1567+ PIXEL_FORMAT_RGB_565,
1568+ 0);
1569+
1570+ CHECK(control != NULL);
1571+ CHECK(control->isValid());
1572+
1573+ SurfaceComposerClient::openGlobalTransaction();
1574+ CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
1575+ CHECK_EQ(control->show(), (status_t)OK);
1576+ SurfaceComposerClient::closeGlobalTransaction();
1577+
1578+ surface = control->getSurface();
1579+ CHECK(surface != NULL);
1580+ }
1581+
1582+ if (playback) {
1583+ sp<SimplePlayer> player = new SimplePlayer;
1584+ looper->registerHandler(player);
1585+
1586+ player->setDataSource(argv[0]);
1587+ player->setSurface(surface->getSurfaceTexture());
1588+ player->start();
1589+ ALOGD("Playing for 60 seconds\n");
1590+ sleep(60);
1591+ player->stop();
1592+ player->reset();
1593+ } else {
1594+ decode(looper, argv[0], useAudio, useVideo, surface);
1595+ }
1596+
1597+ if (playback || (useSurface && useVideo)) {
1598+ composerClient->dispose();
1599+ }
1600+
1601+ looper->stop();
1602+
1603+ return 0;
1604+}
1605--- /dev/null
1606+++ libhybris-0.1.0+git20131207+e452e83/compat/media/direct_media_test.cpp
1607@@ -0,0 +1,417 @@
1608+/*
1609+ * Copyright (C) 2013 Canonical Ltd
1610+ *
1611+ * Licensed under the Apache License, Version 2.0 (the "License");
1612+ * you may not use this file except in compliance with the License.
1613+ * You may obtain a copy of the License at
1614+ *
1615+ * http://www.apache.org/licenses/LICENSE-2.0
1616+ *
1617+ * Unless required by applicable law or agreed to in writing, software
1618+ * distributed under the License is distributed on an "AS IS" BASIS,
1619+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1620+ * See the License for the specific language governing permissions and
1621+ * limitations under the License.
1622+ *
1623+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
1624+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
1625+ */
1626+
1627+#include <hybris/media/media_compatibility_layer.h>
1628+#include "direct_media_test.h"
1629+
1630+#include <utils/Errors.h>
1631+
1632+#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
1633+
1634+#include <GLES2/gl2.h>
1635+#include <GLES2/gl2ext.h>
1636+
1637+#include <sys/stat.h>
1638+#include <sys/types.h>
1639+#include <fcntl.h>
1640+#include <unistd.h>
1641+
1642+#include <cassert>
1643+#include <cstdio>
1644+#include <cstdlib>
1645+#include <cstring>
1646+
1647+using namespace android;
1648+
1649+static float DestWidth = 0.0, DestHeight = 0.0;
1650+// Actual video dimmensions
1651+static int Width = 0, Height = 0;
1652+
1653+static GLfloat positionCoordinates[8];
1654+
1655+MediaPlayerWrapper *player = NULL;
1656+
1657+void calculate_position_coordinates()
1658+{
1659+ // Assuming cropping output for now
1660+ float x = 1, y = 1;
1661+
1662+ // Black borders
1663+ x = float(Width / DestWidth);
1664+ y = float(Height / DestHeight);
1665+
1666+ // Make the larger side be 1
1667+ if (x > y) {
1668+ y /= x;
1669+ x = 1;
1670+ } else {
1671+ x /= y;
1672+ y = 1;
1673+ }
1674+
1675+ positionCoordinates[0] = -x;
1676+ positionCoordinates[1] = y;
1677+ positionCoordinates[2] = -x;
1678+ positionCoordinates[3] = -y;
1679+ positionCoordinates[4] = x;
1680+ positionCoordinates[5] = -y;
1681+ positionCoordinates[6] = x;
1682+ positionCoordinates[7] = y;
1683+}
1684+
1685+WindowRenderer::WindowRenderer(int width, int height)
1686+ : mThreadCmd(CMD_IDLE)
1687+{
1688+ createThread(threadStart, this);
1689+}
1690+
1691+WindowRenderer::~WindowRenderer()
1692+{
1693+}
1694+
1695+int WindowRenderer::threadStart(void* self)
1696+{
1697+ ((WindowRenderer *)self)->glThread();
1698+ return 0;
1699+}
1700+
1701+void WindowRenderer::glThread()
1702+{
1703+ printf("%s\n", __PRETTY_FUNCTION__);
1704+
1705+ Mutex::Autolock autoLock(mLock);
1706+}
1707+
1708+struct ClientWithSurface
1709+{
1710+ SfClient* client;
1711+ SfSurface* surface;
1712+};
1713+
1714+ClientWithSurface client_with_surface(bool setup_surface_with_egl)
1715+{
1716+ ClientWithSurface cs = ClientWithSurface();
1717+
1718+ cs.client = sf_client_create();
1719+
1720+ if (!cs.client) {
1721+ printf("Problem creating client ... aborting now.");
1722+ return cs;
1723+ }
1724+
1725+ static const size_t primary_display = 0;
1726+
1727+ DestWidth = sf_get_display_width(primary_display);
1728+ DestHeight = sf_get_display_height(primary_display);
1729+ printf("Primary display width: %f, height: %f\n", DestWidth, DestHeight);
1730+
1731+ SfSurfaceCreationParameters params = {
1732+ 0,
1733+ 0,
1734+ (int) DestWidth,
1735+ (int) DestHeight,
1736+ -1, //PIXEL_FORMAT_RGBA_8888,
1737+ 15000,
1738+ 0.5f,
1739+ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL
1740+ "MediaCompatLayerTestSurface"
1741+ };
1742+
1743+ cs.surface = sf_surface_create(cs.client, &params);
1744+
1745+ if (!cs.surface) {
1746+ printf("Problem creating surface ... aborting now.");
1747+ return cs;
1748+ }
1749+
1750+ sf_surface_make_current(cs.surface);
1751+
1752+ return cs;
1753+}
1754+
1755+struct RenderData
1756+{
1757+ static const char *vertex_shader()
1758+ {
1759+ return
1760+ "attribute vec4 a_position; \n"
1761+ "attribute vec2 a_texCoord; \n"
1762+ "uniform mat4 m_texMatrix; \n"
1763+ "varying vec2 v_texCoord; \n"
1764+ "varying float topDown; \n"
1765+ "void main() \n"
1766+ "{ \n"
1767+ " gl_Position = a_position; \n"
1768+ " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
1769+ "} \n";
1770+ }
1771+
1772+ static const char *fragment_shader()
1773+ {
1774+ return
1775+ "#extension GL_OES_EGL_image_external : require \n"
1776+ "precision mediump float; \n"
1777+ "varying vec2 v_texCoord; \n"
1778+ "uniform samplerExternalOES s_texture; \n"
1779+ "void main() \n"
1780+ "{ \n"
1781+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
1782+ "} \n";
1783+ }
1784+
1785+ static GLuint loadShader(GLenum shaderType, const char* pSource)
1786+ {
1787+ GLuint shader = glCreateShader(shaderType);
1788+
1789+ if (shader) {
1790+ glShaderSource(shader, 1, &pSource, NULL);
1791+ glCompileShader(shader);
1792+ GLint compiled = 0;
1793+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
1794+
1795+ if (!compiled) {
1796+ GLint infoLen = 0;
1797+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
1798+ if (infoLen) {
1799+ char* buf = (char*) malloc(infoLen);
1800+ if (buf) {
1801+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
1802+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
1803+ shaderType, buf);
1804+ free(buf);
1805+ }
1806+ glDeleteShader(shader);
1807+ shader = 0;
1808+ }
1809+ }
1810+ } else {
1811+ printf("Error, during shader creation: %i\n", glGetError());
1812+ }
1813+
1814+ return shader;
1815+ }
1816+
1817+ static GLuint create_program(const char* pVertexSource, const char* pFragmentSource)
1818+ {
1819+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
1820+ if (!vertexShader) {
1821+ printf("vertex shader not compiled\n");
1822+ return 0;
1823+ }
1824+
1825+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
1826+ if (!pixelShader) {
1827+ printf("frag shader not compiled\n");
1828+ return 0;
1829+ }
1830+
1831+ GLuint program = glCreateProgram();
1832+ if (program) {
1833+ glAttachShader(program, vertexShader);
1834+ glAttachShader(program, pixelShader);
1835+ glLinkProgram(program);
1836+ GLint linkStatus = GL_FALSE;
1837+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
1838+
1839+ if (linkStatus != GL_TRUE) {
1840+ GLint bufLength = 0;
1841+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
1842+ if (bufLength) {
1843+ char* buf = (char*) malloc(bufLength);
1844+ if (buf) {
1845+ glGetProgramInfoLog(program, bufLength, NULL, buf);
1846+ fprintf(stderr, "Could not link program:\n%s\n", buf);
1847+ free(buf);
1848+ }
1849+ }
1850+ glDeleteProgram(program);
1851+ program = 0;
1852+ }
1853+ }
1854+
1855+ return program;
1856+ }
1857+
1858+ RenderData() : program_object(create_program(vertex_shader(), fragment_shader()))
1859+ {
1860+ position_loc = glGetAttribLocation(program_object, "a_position");
1861+ tex_coord_loc = glGetAttribLocation(program_object, "a_texCoord");
1862+ sampler_loc = glGetUniformLocation(program_object, "s_texture");
1863+ matrix_loc = glGetUniformLocation(program_object, "m_texMatrix");
1864+ }
1865+
1866+ // Handle to a program object
1867+ GLuint program_object;
1868+ // Attribute locations
1869+ GLint position_loc;
1870+ GLint tex_coord_loc;
1871+ // Sampler location
1872+ GLint sampler_loc;
1873+ // Matrix location
1874+ GLint matrix_loc;
1875+};
1876+
1877+static int setup_video_texture(ClientWithSurface *cs, GLuint *preview_texture_id)
1878+{
1879+ assert(cs != NULL);
1880+ assert(preview_texture_id != NULL);
1881+
1882+ sf_surface_make_current(cs->surface);
1883+
1884+ glGenTextures(1, preview_texture_id);
1885+ glClearColor(0, 0, 0, 0);
1886+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1887+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1888+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1889+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1890+
1891+ android_media_set_preview_texture(player, *preview_texture_id);
1892+
1893+ return 0;
1894+}
1895+
1896+static void print_gl_error(unsigned int line)
1897+{
1898+ GLint error = glGetError();
1899+ printf("GL error: %#04x (line: %d)\n", error, line);
1900+}
1901+
1902+static int update_gl_buffer(RenderData *render_data, EGLDisplay *disp, EGLSurface *surface)
1903+{
1904+ assert(disp != NULL);
1905+ assert(surface != NULL);
1906+
1907+ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
1908+
1909+ const GLfloat textureCoordinates[] = {
1910+ 1.0f, 1.0f,
1911+ 0.0f, 1.0f,
1912+ 0.0f, 0.0f,
1913+ 1.0f, 0.0f
1914+ };
1915+
1916+ calculate_position_coordinates();
1917+
1918+ glClear(GL_COLOR_BUFFER_BIT);
1919+ // Use the program object
1920+ glUseProgram(render_data->program_object);
1921+ // Enable attributes
1922+ glEnableVertexAttribArray(render_data->position_loc);
1923+ glEnableVertexAttribArray(render_data->tex_coord_loc);
1924+ // Load the vertex position
1925+ glVertexAttribPointer(render_data->position_loc,
1926+ 2,
1927+ GL_FLOAT,
1928+ GL_FALSE,
1929+ 0,
1930+ positionCoordinates);
1931+ // Load the texture coordinate
1932+ glVertexAttribPointer(render_data->tex_coord_loc,
1933+ 2,
1934+ GL_FLOAT,
1935+ GL_FALSE,
1936+ 0,
1937+ textureCoordinates);
1938+
1939+ GLfloat matrix[16];
1940+ android_media_surface_texture_get_transformation_matrix(player, matrix);
1941+
1942+ glUniformMatrix4fv(render_data->matrix_loc, 1, GL_FALSE, matrix);
1943+
1944+ glActiveTexture(GL_TEXTURE0);
1945+ // Set the sampler texture unit to 0
1946+ glUniform1i(render_data->sampler_loc, 0);
1947+ glUniform1i(render_data->matrix_loc, 0);
1948+ android_media_update_surface_texture(player);
1949+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1950+ //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
1951+ glDisableVertexAttribArray(render_data->position_loc);
1952+ glDisableVertexAttribArray(render_data->tex_coord_loc);
1953+
1954+ eglSwapBuffers(*disp, *surface);
1955+
1956+ return 0;
1957+}
1958+
1959+void set_video_size_cb(int height, int width, void *context)
1960+{
1961+ printf("Video height: %d, width: %d\n", height, width);
1962+ printf("Video dest height: %f, width: %f\n", DestHeight, DestWidth);
1963+
1964+ Height = height;
1965+ Width = width;
1966+}
1967+
1968+int main(int argc, char **argv)
1969+{
1970+ if (argc < 2) {
1971+ printf("Usage: direct_media_test <video_to_play>\n");
1972+ return EXIT_FAILURE;
1973+ }
1974+
1975+ player = android_media_new_player();
1976+ if (player == NULL) {
1977+ printf("Problem creating new media player.\n");
1978+ return EXIT_FAILURE;
1979+ }
1980+
1981+ // Set player event cb for when the video size is known:
1982+ android_media_set_video_size_cb(player, set_video_size_cb, NULL);
1983+
1984+ printf("Setting data source to: %s.\n", argv[1]);
1985+
1986+ if (android_media_set_data_source(player, argv[1]) != OK) {
1987+ printf("Failed to set data source: %s\n", argv[1]);
1988+ return EXIT_FAILURE;
1989+ }
1990+
1991+ WindowRenderer renderer(DestWidth, DestHeight);
1992+
1993+ printf("Creating EGL surface.\n");
1994+ ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */);
1995+ if (!cs.surface) {
1996+ printf("Problem acquiring surface for preview");
1997+ return EXIT_FAILURE;
1998+ }
1999+
2000+ printf("Creating GL texture.\n");
2001+ GLuint preview_texture_id;
2002+ EGLDisplay disp = sf_client_get_egl_display(cs.client);
2003+ EGLSurface surface = sf_surface_get_egl_surface(cs.surface);
2004+
2005+ sf_surface_make_current(cs.surface);
2006+ if (setup_video_texture(&cs, &preview_texture_id) != OK) {
2007+ printf("Problem setting up GL texture for video surface.\n");
2008+ return EXIT_FAILURE;
2009+ }
2010+
2011+ RenderData render_data;
2012+
2013+ printf("Starting video playback.\n");
2014+ android_media_play(player);
2015+
2016+ printf("Updating gl buffer continuously...\n");
2017+ while (android_media_is_playing(player)) {
2018+ update_gl_buffer(&render_data, &disp, &surface);
2019+ }
2020+
2021+ android_media_stop(player);
2022+
2023+ return EXIT_SUCCESS;
2024+}
2025--- /dev/null
2026+++ libhybris-0.1.0+git20131207+e452e83/compat/media/direct_media_test.h
2027@@ -0,0 +1,58 @@
2028+/*
2029+ * Copyright (C) 2013 Canonical Ltd
2030+ *
2031+ * Licensed under the Apache License, Version 2.0 (the "License");
2032+ * you may not use this file except in compliance with the License.
2033+ * You may obtain a copy of the License at
2034+ *
2035+ * http://www.apache.org/licenses/LICENSE-2.0
2036+ *
2037+ * Unless required by applicable law or agreed to in writing, software
2038+ * distributed under the License is distributed on an "AS IS" BASIS,
2039+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2040+ * See the License for the specific language governing permissions and
2041+ * limitations under the License.
2042+ *
2043+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
2044+ */
2045+
2046+#ifndef DIRECT_MEDIA_TEST_H_
2047+#define DIRECT_MEDIA_TEST_H_
2048+
2049+#include <EGL/egl.h>
2050+#include <GLES2/gl2.h>
2051+#include <utils/threads.h>
2052+
2053+namespace android {
2054+
2055+class RenderInput;
2056+
2057+class WindowRenderer
2058+{
2059+public:
2060+ WindowRenderer(int width, int height);
2061+ ~WindowRenderer();
2062+
2063+private:
2064+ // The GL thread functions
2065+ static int threadStart(void* self);
2066+ void glThread();
2067+
2068+ // These variables are used to communicate between the GL thread and
2069+ // other threads.
2070+ Mutex mLock;
2071+ Condition mCond;
2072+ enum {
2073+ CMD_IDLE,
2074+ CMD_RENDER_INPUT,
2075+ CMD_RESERVE_TEXTURE,
2076+ CMD_DELETE_TEXTURE,
2077+ CMD_QUIT,
2078+ };
2079+ int mThreadCmd;
2080+ RenderInput* mThreadRenderInput;
2081+ GLuint mThreadTextureId;
2082+};
2083+} // android
2084+
2085+#endif
2086--- /dev/null
2087+++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_codec_layer.cpp
2088@@ -0,0 +1,763 @@
2089+/*
2090+ * Copyright (C) 2013 Canonical Ltd
2091+ *
2092+ * Licensed under the Apache License, Version 2.0 (the "License");
2093+ * you may not use this file except in compliance with the License.
2094+ * You may obtain a copy of the License at
2095+ *
2096+ * http://www.apache.org/licenses/LICENSE-2.0
2097+ *
2098+ * Unless required by applicable law or agreed to in writing, software
2099+ * distributed under the License is distributed on an "AS IS" BASIS,
2100+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2101+ * See the License for the specific language governing permissions and
2102+ * limitations under the License.
2103+ *
2104+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
2105+ */
2106+
2107+// Uncomment to enable verbose debug output
2108+#define LOG_NDEBUG 0
2109+
2110+#undef LOG_TAG
2111+#define LOG_TAG "MediaCodecLayer"
2112+
2113+#include <hybris/media/media_codec_layer.h>
2114+#include <hybris/media/media_compatibility_layer.h>
2115+#include <hybris/media/media_format_layer.h>
2116+
2117+#include "media_format_layer_priv.h"
2118+#include "surface_texture_client_hybris_priv.h"
2119+
2120+#include <fcntl.h>
2121+#include <sys/stat.h>
2122+
2123+#include <binder/ProcessState.h>
2124+
2125+#include <media/stagefright/foundation/AHandler.h>
2126+#include <media/stagefright/foundation/AString.h>
2127+#include <media/ICrypto.h>
2128+#include <media/stagefright/foundation/ABuffer.h>
2129+#include <media/stagefright/foundation/ADebug.h>
2130+#include <media/stagefright/foundation/AMessage.h>
2131+#include <media/stagefright/MediaCodec.h>
2132+#include <media/stagefright/MediaErrors.h>
2133+#include <media/stagefright/NativeWindowWrapper.h>
2134+
2135+#include <utils/Vector.h>
2136+#include <utils/Log.h>
2137+#include <utils/RefBase.h>
2138+
2139+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__);
2140+
2141+using namespace android;
2142+
2143+struct _MediaCodecDelegate : public AHandler
2144+{
2145+public:
2146+ typedef sp<_MediaCodecDelegate> Ptr;
2147+
2148+ explicit _MediaCodecDelegate(void *context);
2149+ virtual ~_MediaCodecDelegate();
2150+
2151+protected:
2152+ virtual void onMessageReceived(const sp<AMessage> &msg) { }
2153+
2154+public:
2155+ sp<MediaCodec> media_codec;
2156+ sp<ALooper> looper;
2157+
2158+ Vector<sp<ABuffer> > input_buffers;
2159+ Vector<sp<ABuffer> > output_buffers;
2160+ List<MediaCodecBufferInfo> available_output_buffer_infos;
2161+ List<size_t> available_input_buffer_indices;
2162+ bool output_format_changed;
2163+ bool hardware_rendering;
2164+
2165+ void *context;
2166+ unsigned int refcount;
2167+};
2168+
2169+_MediaCodecDelegate::_MediaCodecDelegate(void *context)
2170+ : output_format_changed(false),
2171+ hardware_rendering(false),
2172+ context(context),
2173+ refcount(1)
2174+{
2175+ REPORT_FUNCTION()
2176+}
2177+
2178+_MediaCodecDelegate::~_MediaCodecDelegate()
2179+{
2180+ REPORT_FUNCTION()
2181+}
2182+
2183+static inline _MediaCodecDelegate *get_internal_delegate(MediaCodecDelegate delegate)
2184+{
2185+ if (delegate == NULL)
2186+ {
2187+ ALOGE("delegate must not be NULL");
2188+ return NULL;
2189+ }
2190+
2191+ _MediaCodecDelegate *d = static_cast<_MediaCodecDelegate*>(delegate);
2192+ // Some simple sanity checks that must be true for a valid MediaCodecDelegate instance
2193+ if (d->media_codec == NULL || d->refcount < 1)
2194+ return NULL;
2195+
2196+ return d;
2197+}
2198+
2199+MediaCodecDelegate media_codec_create_by_codec_name(const char *name)
2200+{
2201+ REPORT_FUNCTION()
2202+
2203+ if (name == NULL)
2204+ {
2205+ ALOGE("name must not be NULL");
2206+ return NULL;
2207+ }
2208+
2209+ ALOGD("Creating codec '%s'", name);
2210+
2211+ ProcessState::self()->startThreadPool();
2212+
2213+ _MediaCodecDelegate *d(new _MediaCodecDelegate(NULL));
2214+ d->looper = new ALooper;
2215+ d->looper->start();
2216+
2217+ d->media_codec = android::MediaCodec::CreateByComponentName(d->looper, name);
2218+
2219+ return d;
2220+}
2221+
2222+#ifdef SIMPLE_PLAYER
2223+MediaCodec* media_codec_get(MediaCodecDelegate delegate)
2224+{
2225+ REPORT_FUNCTION()
2226+
2227+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2228+ if (d == NULL)
2229+ return NULL;
2230+
2231+ return d->media_codec.get();
2232+}
2233+#endif
2234+
2235+MediaCodecDelegate media_codec_create_by_codec_type(const char *type)
2236+{
2237+ REPORT_FUNCTION()
2238+
2239+ if (type == NULL)
2240+ {
2241+ ALOGE("type must not be NULL");
2242+ return NULL;
2243+ }
2244+
2245+ ALOGD("Creating codec by type '%s'", type);
2246+
2247+ ProcessState::self()->startThreadPool();
2248+
2249+ _MediaCodecDelegate *d(new _MediaCodecDelegate(NULL));
2250+ d->looper = new ALooper;
2251+ d->looper->start();
2252+
2253+ d->media_codec = android::MediaCodec::CreateByType(d->looper, type, false);
2254+
2255+ return d;
2256+}
2257+
2258+void media_codec_delegate_destroy(MediaCodecDelegate delegate)
2259+{
2260+ REPORT_FUNCTION()
2261+
2262+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2263+ if (d == NULL)
2264+ {
2265+ ALOGE("d == NULL, cannot destroy MediaCodecDelegate instance");
2266+ return;
2267+ }
2268+
2269+ ALOGI("Releasing media_codec");
2270+ d->media_codec->release();
2271+ ALOGI("Stopping looper");
2272+ d->looper->stop();
2273+
2274+ ALOGI("Setting refcount = 0");
2275+ d->refcount = 0;
2276+
2277+ ALOGI("Deleting the MediaCodecDelegate instance");
2278+ delete d;
2279+}
2280+
2281+void media_codec_delegate_ref(MediaCodecDelegate delegate)
2282+{
2283+ REPORT_FUNCTION()
2284+
2285+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2286+ if (d == NULL)
2287+ return;
2288+
2289+ d->refcount++;
2290+}
2291+
2292+void media_codec_delegate_unref(MediaCodecDelegate delegate)
2293+{
2294+ REPORT_FUNCTION()
2295+
2296+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2297+ if (d == NULL)
2298+ {
2299+ ALOGE("d == NULL, cannot unref MediaCodecDelegate instance");
2300+ return;
2301+ }
2302+
2303+ if (d->refcount > 1)
2304+ d->refcount--;
2305+ else
2306+ media_codec_delegate_destroy (delegate);
2307+}
2308+
2309+#ifdef SIMPLE_PLAYER
2310+int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, void *nativeWindow, uint32_t flags)
2311+#else
2312+int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, SurfaceTextureClientHybris stc, uint32_t flags)
2313+#endif
2314+{
2315+ REPORT_FUNCTION()
2316+
2317+ if (format == NULL)
2318+ {
2319+ ALOGE("format must not be NULL");
2320+ return BAD_VALUE;
2321+ }
2322+
2323+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2324+ if (d == NULL)
2325+ return BAD_VALUE;
2326+
2327+ _MediaFormat *format_priv = static_cast<_MediaFormat*>(format);
2328+#ifndef SIMPLE_PLAYER
2329+ _SurfaceTextureClientHybris *stch = static_cast<_SurfaceTextureClientHybris*>(stc);
2330+#endif
2331+
2332+ sp<AMessage> aformat = new AMessage;
2333+ aformat->setString("mime", format_priv->mime.c_str());
2334+ if (format_priv->duration_us > 0)
2335+ aformat->setInt64("durationUs", format_priv->duration_us);
2336+ aformat->setInt32("width", format_priv->width);
2337+ aformat->setInt32("height", format_priv->height);
2338+ if (format_priv->max_input_size > 0)
2339+ aformat->setInt32("max-input-size", format_priv->max_input_size);
2340+
2341+ ALOGD("Format: %s", aformat->debugString().c_str());
2342+
2343+#ifdef SIMPLE_PLAYER
2344+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
2345+ sp<SurfaceTextureClient> surfaceTextureClient = static_cast<SurfaceTextureClient*>(nativeWindow);
2346+#else
2347+ sp<Surface> surfaceTextureClient = static_cast<Surface*>(nativeWindow);
2348+#endif
2349+ // TODO: Don't just pass NULL for the security when DRM is needed
2350+ d->media_codec->configure(aformat, surfaceTextureClient, NULL, flags);
2351+#else
2352+ ALOGD("SurfaceTextureClientHybris: %p", stch);
2353+
2354+ // Make sure we're ready to configure the codec and the Surface/SurfaceTextureClient together
2355+ if (stch != NULL && stch->hardwareRendering() && stch->isReady())
2356+ {
2357+ ALOGD("Doing hardware decoding with hardware rendering");
2358+ // TODO: Don't just pass NULL for the security when DRM is needed
2359+ d->media_codec->configure(aformat, stch, NULL, flags);
2360+ }
2361+ else
2362+ {
2363+ ALOGD("Doing hardware decoding path with software rendering");
2364+ // This scenario is for hardware video decoding, but software rendering, therefore there's
2365+ // no need to pass a valid Surface/SurfaceTextureClient instance to configure()
2366+ d->media_codec->configure(aformat, NULL, NULL, flags);
2367+ }
2368+
2369+#endif
2370+
2371+ return OK;
2372+}
2373+
2374+int media_codec_set_surface_texture_client(MediaCodecDelegate delegate, SurfaceTextureClientHybris stc)
2375+{
2376+ REPORT_FUNCTION()
2377+
2378+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2379+ if (d == NULL)
2380+ return BAD_VALUE;
2381+ if (stc == NULL)
2382+ {
2383+ ALOGE("stc must not be NULL");
2384+ return BAD_VALUE;
2385+ }
2386+
2387+ _SurfaceTextureClientHybris *stcu = static_cast<_SurfaceTextureClientHybris*>(stc);
2388+ status_t err = native_window_api_connect(stcu, NATIVE_WINDOW_API_MEDIA);
2389+ if (err != OK)
2390+ {
2391+ ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
2392+ return err;
2393+ }
2394+
2395+ return OK;
2396+}
2397+
2398+int media_codec_queue_csd(MediaCodecDelegate delegate, MediaFormat format)
2399+{
2400+ REPORT_FUNCTION()
2401+
2402+ if (format == NULL)
2403+ {
2404+ ALOGE("format must not be NULL");
2405+ return BAD_VALUE;
2406+ }
2407+
2408+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2409+ _MediaFormat *format_priv = static_cast<_MediaFormat*>(format);
2410+ assert(format_priv->csd != NULL);
2411+
2412+ status_t err = OK;
2413+
2414+ Vector<sp<ABuffer> > input_bufs[1];
2415+ err = d->media_codec->getInputBuffers(&input_bufs[0]);
2416+ CHECK_EQ(err, static_cast<status_t>(OK));
2417+
2418+ for (size_t i=0; i<2; ++i)
2419+ {
2420+ const sp<ABuffer> &srcBuffer = format_priv->csd;
2421+
2422+ size_t index = 0;
2423+ err = d->media_codec->dequeueInputBuffer(&index, -1ll);
2424+ CHECK_EQ(err, static_cast<status_t>(OK));
2425+
2426+ const sp<ABuffer> &dstBuffer = input_bufs[0].itemAt(index);
2427+
2428+ CHECK_LE(srcBuffer->size(), dstBuffer->capacity());
2429+ dstBuffer->setRange(0, srcBuffer->size());
2430+ memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size());
2431+
2432+ AString err_msg;
2433+ err = d->media_codec->queueInputBuffer(
2434+ index,
2435+ 0,
2436+ dstBuffer->size(),
2437+ 0ll,
2438+ MediaCodec::BUFFER_FLAG_CODECCONFIG);
2439+ CHECK_EQ(err, static_cast<status_t>(OK));
2440+ }
2441+
2442+ return err;
2443+}
2444+
2445+int media_codec_start(MediaCodecDelegate delegate)
2446+{
2447+ REPORT_FUNCTION()
2448+
2449+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2450+ if (d == NULL)
2451+ return BAD_VALUE;
2452+
2453+ return d->media_codec->start();
2454+}
2455+
2456+int media_codec_stop(MediaCodecDelegate delegate)
2457+{
2458+ REPORT_FUNCTION()
2459+
2460+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2461+ if (d == NULL)
2462+ return BAD_VALUE;
2463+
2464+ return d->media_codec->stop();
2465+}
2466+
2467+int media_codec_release(MediaCodecDelegate delegate)
2468+{
2469+ REPORT_FUNCTION()
2470+
2471+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2472+ if (d == NULL)
2473+ return BAD_VALUE;
2474+
2475+ return d->media_codec->release();
2476+}
2477+
2478+int media_codec_flush(MediaCodecDelegate delegate)
2479+{
2480+ REPORT_FUNCTION()
2481+
2482+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2483+ if (d == NULL)
2484+ return BAD_VALUE;
2485+
2486+ d->available_output_buffer_infos.clear();
2487+
2488+ return d->media_codec->flush();
2489+}
2490+
2491+size_t media_codec_get_input_buffers_size(MediaCodecDelegate delegate)
2492+{
2493+ REPORT_FUNCTION()
2494+
2495+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2496+ if (d == NULL)
2497+ return BAD_VALUE;
2498+
2499+ status_t ret = d->media_codec->getInputBuffers(&d->input_buffers);
2500+ if (ret != OK)
2501+ {
2502+ ALOGE("Failed to get input buffers size");
2503+ return 0;
2504+ }
2505+ ALOGD("Got %d input buffers", d->input_buffers.size());
2506+
2507+ return d->input_buffers.size();
2508+}
2509+
2510+uint8_t *media_codec_get_nth_input_buffer(MediaCodecDelegate delegate, size_t n)
2511+{
2512+ REPORT_FUNCTION()
2513+
2514+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2515+ if (d == NULL)
2516+ return NULL;
2517+
2518+ if (d->input_buffers.size() == 0)
2519+ {
2520+ status_t ret = d->media_codec->getInputBuffers(&d->input_buffers);
2521+ if (ret != OK)
2522+ {
2523+ ALOGE("Failed to get input buffers");
2524+ return NULL;
2525+ }
2526+ }
2527+
2528+ if (n > d->input_buffers.size())
2529+ {
2530+ ALOGE("Failed to get %uth input buffer, n > total buffer size", n);
2531+ return NULL;
2532+ }
2533+
2534+ return d->input_buffers.itemAt(n).get()->data();
2535+}
2536+
2537+size_t media_codec_get_nth_input_buffer_capacity(MediaCodecDelegate delegate, size_t n)
2538+{
2539+ REPORT_FUNCTION()
2540+
2541+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2542+ if (d == NULL)
2543+ return BAD_VALUE;
2544+
2545+ Vector<sp<ABuffer> > input_buffers;
2546+ status_t ret = d->media_codec->getInputBuffers(&input_buffers);
2547+ if (ret != OK)
2548+ {
2549+ ALOGE("Failed to get input buffers");
2550+ return 0;
2551+ }
2552+
2553+ if (n > input_buffers.size())
2554+ {
2555+ ALOGE("Failed to get %uth input buffer capacity, n > total buffer size", n);
2556+ return 0;
2557+ }
2558+
2559+ return input_buffers[n].get()->capacity();
2560+}
2561+
2562+size_t media_codec_get_output_buffers_size(MediaCodecDelegate delegate)
2563+{
2564+ REPORT_FUNCTION()
2565+
2566+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2567+ if (d == NULL)
2568+ return BAD_VALUE;
2569+
2570+ status_t ret = d->media_codec->getOutputBuffers(&d->output_buffers);
2571+ if (ret != OK)
2572+ {
2573+ ALOGE("Failed to get output buffers size");
2574+ return 0;
2575+ }
2576+ ALOGD("Got %d output buffers", d->output_buffers.size());
2577+
2578+ return d->output_buffers.size();
2579+}
2580+
2581+uint8_t *media_codec_get_nth_output_buffer(MediaCodecDelegate delegate, size_t n)
2582+{
2583+ REPORT_FUNCTION()
2584+
2585+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2586+ if (d == NULL)
2587+ return NULL;
2588+
2589+ status_t ret = d->media_codec->getOutputBuffers(&d->output_buffers);
2590+ if (ret != OK)
2591+ {
2592+ ALOGE("Failed to get output buffers");
2593+ return NULL;
2594+ }
2595+
2596+ if (n > d->output_buffers.size())
2597+ {
2598+ ALOGE("Failed to get %uth output buffer, n > total buffer size", n);
2599+ return NULL;
2600+ }
2601+
2602+ return d->output_buffers.itemAt(n).get()->data();
2603+}
2604+
2605+size_t media_codec_get_nth_output_buffer_capacity(MediaCodecDelegate delegate, size_t n)
2606+{
2607+ REPORT_FUNCTION()
2608+
2609+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2610+ if (d == NULL)
2611+ return BAD_VALUE;
2612+
2613+ status_t ret = d->media_codec->getOutputBuffers(&d->output_buffers);
2614+ if (ret != OK)
2615+ {
2616+ ALOGE("Failed to get output buffers");
2617+ return 0;
2618+ }
2619+
2620+ if (n > d->output_buffers.size())
2621+ {
2622+ ALOGE("Failed to get %uth output buffer capacity, n > total buffer size", n);
2623+ return 0;
2624+ }
2625+
2626+ return d->output_buffers[n].get()->capacity();
2627+}
2628+
2629+#define INFO_TRY_AGAIN_LATER -1
2630+#define INFO_OUTPUT_FORMAT_CHANGED -2
2631+#define INFO_OUTPUT_BUFFERS_CHANGED -4
2632+
2633+int media_codec_dequeue_output_buffer(MediaCodecDelegate delegate, MediaCodecBufferInfo *info, int64_t timeout_us)
2634+{
2635+ REPORT_FUNCTION()
2636+
2637+ if (info == NULL)
2638+ {
2639+ ALOGE("info must not be NULL");
2640+ return BAD_VALUE;
2641+ }
2642+
2643+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2644+ if (d == NULL)
2645+ return BAD_VALUE;
2646+
2647+ int ret = d->media_codec->dequeueOutputBuffer(&info->index, &info->offset, &info->size, &info->presentation_time_us, &info->flags, timeout_us);
2648+ ALOGD("dequeueOutputBuffer() ret: %d", ret);
2649+ info->render_retries = 0;
2650+
2651+ if (ret == -EAGAIN)
2652+ {
2653+ ALOGD("dequeueOutputBuffer returned %d", ret);
2654+ return INFO_TRY_AGAIN_LATER;
2655+ }
2656+ else if (ret & ~INFO_OUTPUT_BUFFERS_CHANGED)
2657+ {
2658+ ALOGD("Output buffers changed (ret: %d)", ret);
2659+ return INFO_OUTPUT_BUFFERS_CHANGED + 1;
2660+ }
2661+ // FIXME: Get rid of the hardcoded -10 and replace with more elegant solution
2662+ else if (ret & ~(INFO_FORMAT_CHANGED - 10))
2663+ {
2664+ ALOGD("Output buffer format changed (ret: %d)", ret);
2665+ d->output_format_changed = true;
2666+ return -2;
2667+ }
2668+
2669+ ALOGD("Dequeued output buffer:\n-----------------------");
2670+ ALOGD("index: %u", info->index);
2671+ ALOGD("offset: %d", info->offset);
2672+ ALOGD("size: %d", info->size);
2673+ ALOGD("presentation_time_us: %lld", info->presentation_time_us);
2674+ ALOGD("flags: %d", info->flags);
2675+
2676+ // Keep track of the used output buffer info
2677+ d->available_output_buffer_infos.push_back(*info);
2678+
2679+ return OK;
2680+}
2681+
2682+int media_codec_queue_input_buffer(MediaCodecDelegate delegate, const MediaCodecBufferInfo *info)
2683+{
2684+ REPORT_FUNCTION()
2685+
2686+ if (info == NULL)
2687+ {
2688+ ALOGE("info must not be NULL");
2689+ return BAD_VALUE;
2690+ }
2691+
2692+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2693+ if (d == NULL)
2694+ return BAD_VALUE;
2695+
2696+ // Make sure that there is at least one dequeued input buffer available
2697+ if (d->available_input_buffer_indices.empty())
2698+ {
2699+ ALOGE("Input buffer index %d has not been dequeued, cannot queue input buffer", info->index);
2700+ return BAD_VALUE;
2701+ }
2702+
2703+ const size_t index = *d->available_input_buffer_indices.begin();
2704+ d->available_input_buffer_indices.erase(d->available_input_buffer_indices.begin());
2705+
2706+ ALOGD("info->index: %d", index);
2707+ ALOGD("info->offset: %d", info->offset);
2708+ ALOGD("info->size: %d", info->size);
2709+ ALOGD("info->presentation_time_us: %lld", info->presentation_time_us);
2710+ ALOGD("info->flags: %d", info->flags);
2711+
2712+ AString err_msg;
2713+ status_t ret = d->media_codec->queueInputBuffer(index, info->offset, info->size,
2714+ info->presentation_time_us, info->flags, &err_msg);
2715+ if (ret != OK)
2716+ {
2717+ ALOGE("Failed to queue input buffer (err: %d, index: %d)", ret, index);
2718+ ALOGE("Detailed error message: %s", err_msg.c_str());
2719+ }
2720+
2721+ return ret;
2722+}
2723+
2724+int media_codec_dequeue_input_buffer(MediaCodecDelegate delegate, size_t *index, int64_t timeout_us)
2725+{
2726+ REPORT_FUNCTION()
2727+
2728+ if (index == NULL)
2729+ {
2730+ ALOGE("index must not be NULL");
2731+ return BAD_VALUE;
2732+ }
2733+
2734+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2735+ if (d == NULL)
2736+ return BAD_VALUE;
2737+
2738+ status_t ret = d->media_codec->dequeueInputBuffer(index, timeout_us);
2739+ if (ret == -EAGAIN)
2740+ {
2741+ ALOGD("dequeueInputBuffer returned %d, tried timeout: %d", ret, timeout_us);
2742+ return INFO_TRY_AGAIN_LATER;
2743+ }
2744+ else if (ret == OK)
2745+ {
2746+ ALOGD("Dequeued input buffer (index: %d)", *index);
2747+ d->available_input_buffer_indices.push_back(*index);
2748+ }
2749+ else
2750+ ALOGE("Failed to dequeue input buffer (err: %d, index: %d)", ret, *index);
2751+
2752+ return ret;
2753+}
2754+
2755+int media_codec_release_output_buffer(MediaCodecDelegate delegate, size_t index, uint8_t render)
2756+{
2757+ REPORT_FUNCTION()
2758+ ALOGV("Requesting to release output buffer index: %d, render: %d", index, render);
2759+
2760+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2761+ if (d == NULL)
2762+ return BAD_VALUE;
2763+
2764+ status_t ret = OK;
2765+
2766+ auto it = d->available_output_buffer_infos.begin();
2767+ while (it != d->available_output_buffer_infos.end())
2768+ {
2769+ MediaCodecBufferInfo *info = &*it;
2770+ ALOGD("info index: %d", info->index);
2771+ ALOGD("info render_retries: %u", info->render_retries);
2772+ if (info->render_retries == 1)
2773+ {
2774+ ALOGV("Rendering and releasing output buffer %d from the available indices list", info->index);
2775+ ret = d->media_codec->renderOutputBufferAndRelease(info->index);
2776+ if (ret != OK)
2777+ {
2778+ ALOGE("Failed to release output buffer (ret: %d, index: %d)", ret, info->index);
2779+ ++info->render_retries;
2780+ }
2781+ else
2782+ {
2783+ ALOGV("Successfully rendered output buffer %d on a second try.", info->index);
2784+ d->available_output_buffer_infos.erase(it);
2785+ }
2786+ }
2787+ else if (info->render_retries > 1)
2788+ {
2789+ ALOGV("Tried to render output buffer %d twice, dropping.", info->index);
2790+ ret = d->media_codec->releaseOutputBuffer(info->index);
2791+ d->available_output_buffer_infos.erase(d->available_output_buffer_infos.begin());
2792+ }
2793+
2794+ ++it;
2795+ }
2796+
2797+ MediaCodecBufferInfo *info = &*d->available_output_buffer_infos.begin();
2798+ // Either render and release the output buffer, or just release.
2799+ if (render)
2800+ {
2801+ ALOGV("Rendering and releasing output buffer %d from the available indices list", info->index);
2802+ ret = d->media_codec->renderOutputBufferAndRelease(info->index);
2803+ }
2804+ else
2805+ {
2806+ ALOGV("Releasing output buffer %d from the available indices list", info->index);
2807+ ret = d->media_codec->releaseOutputBuffer(info->index);
2808+ }
2809+ if (ret != OK)
2810+ {
2811+ ALOGE("Failed to release output buffer (ret: %d, index: %d)", ret, info->index);
2812+ ++info->render_retries;
2813+ } else {
2814+ ALOGV("Released output buffer %d from the available buffer infos list", info->index);
2815+ d->available_output_buffer_infos.erase(d->available_output_buffer_infos.begin());
2816+ }
2817+
2818+ return ret;
2819+}
2820+
2821+MediaFormat media_codec_get_output_format(MediaCodecDelegate delegate)
2822+{
2823+ REPORT_FUNCTION()
2824+
2825+ _MediaCodecDelegate *d = get_internal_delegate(delegate);
2826+ if (d == NULL)
2827+ return NULL;
2828+
2829+ _MediaFormat *f = new _MediaFormat();
2830+
2831+ sp<AMessage> msg_format;
2832+ status_t ret = d->media_codec->getOutputFormat(&msg_format);
2833+ if (ret != OK)
2834+ {
2835+ ALOGE("Failed to get the output format");
2836+ return NULL;
2837+ }
2838+
2839+ ALOGD("Output format: %s", msg_format->debugString().c_str());
2840+
2841+ CHECK(msg_format->findString("mime", &f->mime));
2842+ CHECK(msg_format->findInt32("width", &f->width));
2843+ CHECK(msg_format->findInt32("height", &f->height));
2844+ CHECK(msg_format->findInt32("stride", &f->stride));
2845+ CHECK(msg_format->findInt32("slice-height", &f->slice_height));
2846+ CHECK(msg_format->findInt32("color-format", &f->color_format));
2847+ Rect crop;
2848+ CHECK(msg_format->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom));
2849+
2850+ return f;
2851+}
2852--- /dev/null
2853+++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_codec_list.cpp
2854@@ -0,0 +1,228 @@
2855+/*
2856+ * Copyright (C) 2013 Canonical Ltd
2857+ *
2858+ * Licensed under the Apache License, Version 2.0 (the "License");
2859+ * you may not use this file except in compliance with the License.
2860+ * You may obtain a copy of the License at
2861+ *
2862+ * http://www.apache.org/licenses/LICENSE-2.0
2863+ *
2864+ * Unless required by applicable law or agreed to in writing, software
2865+ * distributed under the License is distributed on an "AS IS" BASIS,
2866+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2867+ * See the License for the specific language governing permissions and
2868+ * limitations under the License.
2869+ *
2870+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
2871+ */
2872+
2873+// Uncomment to enable verbose debug output
2874+#define LOG_NDEBUG 0
2875+
2876+#undef LOG_TAG
2877+#define LOG_TAG "MediaCodecList"
2878+
2879+#include <hybris/media/media_codec_list.h>
2880+
2881+#include <media/stagefright/foundation/AString.h>
2882+#include <media/stagefright/MediaCodecList.h>
2883+
2884+#include <utils/Log.h>
2885+#include <utils/Vector.h>
2886+
2887+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__);
2888+
2889+using namespace android;
2890+
2891+ssize_t media_codec_list_find_codec_by_type(const char *type, bool encoder, size_t startIndex)
2892+{
2893+ REPORT_FUNCTION()
2894+ return MediaCodecList::getInstance()->findCodecByType(type, encoder, startIndex);
2895+}
2896+
2897+ssize_t media_codec_list_find_codec_by_name(const char *name)
2898+{
2899+ REPORT_FUNCTION()
2900+ return MediaCodecList::getInstance()->findCodecByName(name);
2901+}
2902+
2903+size_t media_codec_list_count_codecs()
2904+{
2905+ REPORT_FUNCTION()
2906+ return MediaCodecList::getInstance()->countCodecs();
2907+}
2908+
2909+void media_codec_list_get_codec_info_at_id(size_t index)
2910+{
2911+ REPORT_FUNCTION()
2912+}
2913+
2914+const char *media_codec_list_get_codec_name(size_t index)
2915+{
2916+ REPORT_FUNCTION()
2917+ return MediaCodecList::getInstance()->getCodecName(index);
2918+}
2919+
2920+bool media_codec_list_is_encoder(size_t index)
2921+{
2922+ REPORT_FUNCTION()
2923+ return MediaCodecList::getInstance()->isEncoder(index);
2924+}
2925+
2926+size_t media_codec_list_get_num_supported_types(size_t index)
2927+{
2928+ REPORT_FUNCTION()
2929+
2930+ Vector<AString> types;
2931+ status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types);
2932+ if (err != OK)
2933+ {
2934+ ALOGE("Failed to get the number of supported codec types (err: %d)", err);
2935+ return 0;
2936+ }
2937+ ALOGD("Number of supported codec types: %d", types.size());
2938+
2939+ return types.size();
2940+}
2941+
2942+size_t media_codec_list_get_nth_supported_type_len(size_t index, size_t n)
2943+{
2944+ REPORT_FUNCTION()
2945+
2946+ Vector<AString> types;
2947+ status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types);
2948+
2949+ return types[n].size();
2950+}
2951+
2952+int media_codec_list_get_nth_supported_type(size_t index, char *type, size_t n)
2953+{
2954+ REPORT_FUNCTION()
2955+
2956+ if (type == NULL)
2957+ {
2958+ ALOGE("types must not be NULL");
2959+ return BAD_VALUE;
2960+ }
2961+
2962+ Vector<AString> types;
2963+ status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types);
2964+ for (size_t i=0; i<types[n].size(); ++i)
2965+ type[i] = types.itemAt(n).c_str()[i];
2966+
2967+ return err;
2968+}
2969+
2970+static void media_codec_list_get_num_codec_capabilities(size_t index, const char *type, size_t *num_profile_levels, size_t *num_color_formats)
2971+{
2972+ REPORT_FUNCTION()
2973+
2974+ Vector<MediaCodecList::ProfileLevel> profile_levels;
2975+ Vector<uint32_t> color_formats;
2976+ ALOGD("index: %d, type: '%s'", index, type);
2977+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
2978+ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &color_formats);
2979+#else
2980+ uint32_t flags;
2981+ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &color_formats, &flags);
2982+#endif
2983+ if (err != OK)
2984+ {
2985+ ALOGE("Failed to get the number of supported codec capabilities (err: %d)", err);
2986+ return;
2987+ }
2988+
2989+ if (num_profile_levels != NULL)
2990+ {
2991+ ALOGD("Number of codec profile levels: %d", profile_levels.size());
2992+ *num_profile_levels = profile_levels.size();
2993+ }
2994+ if (num_color_formats != NULL)
2995+ {
2996+ ALOGD("Number of codec color formats: %d", color_formats.size());
2997+ *num_color_formats = color_formats.size();
2998+ }
2999+}
3000+
3001+size_t media_codec_list_get_num_profile_levels(size_t index, const char *type)
3002+{
3003+ REPORT_FUNCTION()
3004+
3005+ size_t num = 0;
3006+ media_codec_list_get_num_codec_capabilities(index, type, &num, NULL);
3007+
3008+ return num;
3009+}
3010+
3011+size_t media_codec_list_get_num_color_formats(size_t index, const char *type)
3012+{
3013+ REPORT_FUNCTION()
3014+
3015+ size_t num = 0;
3016+ media_codec_list_get_num_codec_capabilities(index, type, NULL, &num);
3017+
3018+ return num;
3019+}
3020+
3021+int media_codec_list_get_nth_codec_profile_level(size_t index, const char *type, profile_level *pro_level, size_t n)
3022+{
3023+ REPORT_FUNCTION()
3024+
3025+ if (type == NULL)
3026+ {
3027+ ALOGE("types must not be NULL");
3028+ return BAD_VALUE;
3029+ }
3030+
3031+ if (pro_level == NULL)
3032+ {
3033+ ALOGE("pro_level must not be NULL");
3034+ return BAD_VALUE;
3035+ }
3036+
3037+ Vector<MediaCodecList::ProfileLevel> profile_levels;
3038+ Vector<uint32_t> formats;
3039+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
3040+ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats);
3041+#else
3042+ uint32_t flags;
3043+ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats, &flags);
3044+#endif
3045+ if (err != OK)
3046+ {
3047+ ALOGE("Failed to get the nth codec profile level (err: %d)", err);
3048+ return 0;
3049+ }
3050+
3051+ pro_level->profile = profile_levels[n].mProfile;
3052+ pro_level->level = profile_levels[n].mLevel;
3053+
3054+ return err;
3055+}
3056+
3057+int media_codec_list_get_codec_color_formats(size_t index, const char *type, uint32_t *color_formats)
3058+{
3059+ REPORT_FUNCTION()
3060+
3061+ Vector<MediaCodecList::ProfileLevel> profile_levels;
3062+ Vector<uint32_t> formats;
3063+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
3064+ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats);
3065+#else
3066+ uint32_t flags;
3067+ status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats, &flags);
3068+#endif
3069+ if (err != OK)
3070+ {
3071+ ALOGE("Failed to get the number of supported codec types (err: %d)", err);
3072+ return 0;
3073+ }
3074+
3075+ for (size_t i=0; i<formats.size(); ++i)
3076+ {
3077+ color_formats[i] = formats[i];
3078+ ALOGD("Color format [%d]: %d", i, formats[i]);
3079+ }
3080+
3081+ return OK;
3082+}
3083--- /dev/null
3084+++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_compatibility_layer.cpp
3085@@ -0,0 +1,660 @@
3086+/*
3087+ * Copyright (C) 2013 Canonical Ltd
3088+ *
3089+ * Licensed under the Apache License, Version 2.0 (the "License");
3090+ * you may not use this file except in compliance with the License.
3091+ * You may obtain a copy of the License at
3092+ *
3093+ * http://www.apache.org/licenses/LICENSE-2.0
3094+ *
3095+ * Unless required by applicable law or agreed to in writing, software
3096+ * distributed under the License is distributed on an "AS IS" BASIS,
3097+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3098+ * See the License for the specific language governing permissions and
3099+ * limitations under the License.
3100+ *
3101+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
3102+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
3103+ */
3104+
3105+// Uncomment to enable verbose debug output
3106+#define LOG_NDEBUG 0
3107+
3108+#undef LOG_TAG
3109+#define LOG_TAG "MediaCompatibilityLayer"
3110+
3111+#include <hybris/media/media_compatibility_layer.h>
3112+
3113+#include <fcntl.h>
3114+#include <sys/stat.h>
3115+
3116+#include <media/mediaplayer.h>
3117+
3118+#include <binder/ProcessState.h>
3119+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3120+#include <gui/SurfaceTexture.h>
3121+#else
3122+#include <gui/GLConsumer.h>
3123+#endif
3124+
3125+#include <GLES2/gl2.h>
3126+#include <GLES2/gl2ext.h>
3127+
3128+#include <ui/GraphicBuffer.h>
3129+
3130+#include <utils/Log.h>
3131+
3132+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
3133+
3134+namespace android
3135+{
3136+NativeBufferAlloc::NativeBufferAlloc() {
3137+}
3138+
3139+NativeBufferAlloc::~NativeBufferAlloc() {
3140+}
3141+
3142+sp<GraphicBuffer> NativeBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
3143+ PixelFormat format, uint32_t usage, status_t* error) {
3144+ sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
3145+ status_t err = graphicBuffer->initCheck();
3146+ *error = err;
3147+ if (err != 0 || graphicBuffer->handle == 0) {
3148+ if (err == NO_MEMORY) {
3149+ GraphicBuffer::dumpAllocationsToSystemLog();
3150+ }
3151+ ALOGI("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
3152+ "failed (%s), handle=%p",
3153+ w, h, strerror(-err), graphicBuffer->handle);
3154+ return 0;
3155+ }
3156+ return graphicBuffer;
3157+}
3158+}
3159+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3160+struct FrameAvailableListener : public android::SurfaceTexture::FrameAvailableListener
3161+#else
3162+struct FrameAvailableListener : public android::GLConsumer::FrameAvailableListener
3163+#endif
3164+{
3165+ public:
3166+ FrameAvailableListener()
3167+ : set_video_texture_needs_update_cb(NULL),
3168+ video_texture_needs_update_context(NULL)
3169+ {
3170+ }
3171+
3172+ // From android::GLConsumer/SurfaceTexture::FrameAvailableListener
3173+ void onFrameAvailable()
3174+ {
3175+ if (set_video_texture_needs_update_cb != NULL)
3176+ set_video_texture_needs_update_cb(video_texture_needs_update_context);
3177+ }
3178+
3179+ void setVideoTextureNeedsUpdateCb(on_video_texture_needs_update cb, void *context)
3180+ {
3181+ set_video_texture_needs_update_cb = cb;
3182+ video_texture_needs_update_context = context;
3183+ }
3184+
3185+ private:
3186+ on_video_texture_needs_update set_video_texture_needs_update_cb;
3187+ void *video_texture_needs_update_context;
3188+};
3189+
3190+class MediaPlayerListenerWrapper : public android::MediaPlayerListener
3191+{
3192+ public:
3193+ MediaPlayerListenerWrapper()
3194+ : set_video_size_cb(NULL),
3195+ video_size_context(NULL),
3196+ error_cb(NULL),
3197+ error_context(NULL),
3198+ playback_complete_cb(NULL),
3199+ playback_complete_context(NULL),
3200+ media_prepared_cb(NULL),
3201+ media_prepared_context(NULL)
3202+ {
3203+ }
3204+
3205+ void notify(int msg, int ext1, int ext2, const android::Parcel *obj)
3206+ {
3207+ ALOGV("\tmsg: %d, ext1: %d, ext2: %d \n", msg, ext1, ext2);
3208+
3209+ switch (msg) {
3210+ case android::MEDIA_PREPARED:
3211+ ALOGV("\tMEDIA_PREPARED msg\n");
3212+ if (media_prepared_cb != NULL)
3213+ media_prepared_cb(media_prepared_context);
3214+ else
3215+ ALOGW("Failed to signal media prepared, callback not set.");
3216+ break;
3217+ case android::MEDIA_PLAYBACK_COMPLETE:
3218+ ALOGV("\tMEDIA_PLAYBACK_COMPLETE msg\n");
3219+ if (playback_complete_cb != NULL)
3220+ playback_complete_cb(playback_complete_context);
3221+ else
3222+ ALOGW("Failed to signal end of playback, callback not set.");
3223+ break;
3224+ case android::MEDIA_BUFFERING_UPDATE:
3225+ ALOGV("\tMEDIA_BUFFERING_UPDATE msg\n");
3226+ break;
3227+ case android::MEDIA_SEEK_COMPLETE:
3228+ ALOGV("\tMEDIA_SEEK_COMPLETE msg\n");
3229+ break;
3230+ case android::MEDIA_SET_VIDEO_SIZE:
3231+ ALOGV("\tMEDIA_SET_VIDEO_SIZE msg\n");
3232+ if (set_video_size_cb != NULL)
3233+ set_video_size_cb(ext2, ext1, video_size_context);
3234+ else
3235+ ALOGE("Failed to set video size. set_video_size_cb is NULL.");
3236+ break;
3237+ case android::MEDIA_TIMED_TEXT:
3238+ ALOGV("\tMEDIA_TIMED_TEXT msg\n");
3239+ break;
3240+ case android::MEDIA_ERROR:
3241+ ALOGV("\tMEDIA_ERROR msg\n");
3242+ // TODO: Extend this cb to include the error message
3243+ if (error_cb != NULL)
3244+ error_cb(error_context);
3245+ else
3246+ ALOGE("Failed to signal error to app layer, callback not set.");
3247+ break;
3248+ case android::MEDIA_INFO:
3249+ ALOGV("\tMEDIA_INFO msg\n");
3250+ break;
3251+ default:
3252+ ALOGV("\tUnknown media msg\n");
3253+ }
3254+ }
3255+
3256+ void setVideoSizeCb(on_msg_set_video_size cb, void *context)
3257+ {
3258+ REPORT_FUNCTION();
3259+
3260+ set_video_size_cb = cb;
3261+ video_size_context = context;
3262+ }
3263+
3264+ void setErrorCb(on_msg_error cb, void *context)
3265+ {
3266+ REPORT_FUNCTION();
3267+
3268+ error_cb = cb;
3269+ error_context = context;
3270+ }
3271+
3272+ void setPlaybackCompleteCb(on_playback_complete cb, void *context)
3273+ {
3274+ REPORT_FUNCTION();
3275+
3276+ playback_complete_cb = cb;
3277+ playback_complete_context = context;
3278+ }
3279+
3280+ void setMediaPreparedCb(on_media_prepared cb, void *context)
3281+ {
3282+ REPORT_FUNCTION();
3283+
3284+ media_prepared_cb = cb;
3285+ media_prepared_context = context;
3286+ }
3287+
3288+ private:
3289+ on_msg_set_video_size set_video_size_cb;
3290+ void *video_size_context;
3291+ on_msg_error error_cb;
3292+ void *error_context;
3293+ on_playback_complete playback_complete_cb;
3294+ void *playback_complete_context;
3295+ on_media_prepared media_prepared_cb;
3296+ void *media_prepared_context;
3297+};
3298+
3299+// ----- MediaPlayer Wrapper ----- //
3300+
3301+struct MediaPlayerWrapper : public android::MediaPlayer
3302+{
3303+ public:
3304+ MediaPlayerWrapper()
3305+ : MediaPlayer(),
3306+ texture(NULL),
3307+ media_player_listener(new MediaPlayerListenerWrapper()),
3308+ frame_listener(new FrameAvailableListener),
3309+ left_volume(1), // Set vol to 100% for this track by default
3310+ right_volume(1),
3311+ source_fd(-1)
3312+ {
3313+ setListener(media_player_listener);
3314+ // Update the live volume with the cached values
3315+ MediaPlayer::setVolume(left_volume, right_volume);
3316+ }
3317+
3318+ ~MediaPlayerWrapper()
3319+ {
3320+ reset();
3321+ source_fd = -1;
3322+ }
3323+
3324+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3325+ android::status_t setVideoSurfaceTexture(const android::sp<android::SurfaceTexture> &surfaceTexture)
3326+#else
3327+ android::status_t setVideoSurfaceTexture(android::sp<android::BufferQueue> bq, const android::sp<android::GLConsumer> &surfaceTexture)
3328+#endif
3329+ {
3330+ REPORT_FUNCTION();
3331+
3332+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3333+ surfaceTexture->getBufferQueue()->setBufferCount(5);
3334+#else
3335+ bq->setBufferCount(5);
3336+#endif
3337+ texture = surfaceTexture;
3338+ texture->setFrameAvailableListener(frame_listener);
3339+
3340+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3341+ return MediaPlayer::setVideoSurfaceTexture(surfaceTexture->getBufferQueue());
3342+#else
3343+ return MediaPlayer::setVideoSurfaceTexture(bq);
3344+#endif
3345+ }
3346+
3347+ void updateGLConsumer()
3348+ {
3349+ assert(texture != NULL);
3350+ texture->updateTexImage();
3351+ }
3352+
3353+ void get_transformation_matrix_for_surface_texture(GLfloat* matrix)
3354+ {
3355+ assert(texture != NULL);
3356+ texture->getTransformMatrix(matrix);
3357+ }
3358+
3359+ void setVideoSizeCb(on_msg_set_video_size cb, void *context)
3360+ {
3361+ REPORT_FUNCTION();
3362+
3363+ assert(media_player_listener != NULL);
3364+ media_player_listener->setVideoSizeCb(cb, context);
3365+ }
3366+
3367+ void setVideoTextureNeedsUpdateCb(on_video_texture_needs_update cb, void *context)
3368+ {
3369+ REPORT_FUNCTION();
3370+
3371+ assert(frame_listener != NULL);
3372+ frame_listener->setVideoTextureNeedsUpdateCb(cb, context);
3373+ }
3374+
3375+ void setErrorCb(on_msg_error cb, void *context)
3376+ {
3377+ REPORT_FUNCTION();
3378+
3379+ assert(media_player_listener != NULL);
3380+ media_player_listener->setErrorCb(cb, context);
3381+ }
3382+
3383+ void setPlaybackCompleteCb(on_playback_complete cb, void *context)
3384+ {
3385+ REPORT_FUNCTION();
3386+
3387+ assert(media_player_listener != NULL);
3388+ media_player_listener->setPlaybackCompleteCb(cb, context);
3389+ }
3390+
3391+ void setMediaPreparedCb(on_media_prepared cb, void *context)
3392+ {
3393+ REPORT_FUNCTION();
3394+
3395+ assert(media_player_listener != NULL);
3396+ media_player_listener->setMediaPreparedCb(cb, context);
3397+ }
3398+
3399+ void getVolume(float *leftVolume, float *rightVolume)
3400+ {
3401+ *leftVolume = left_volume;
3402+ *rightVolume = right_volume;
3403+ }
3404+
3405+ android::status_t setVolume(float leftVolume, float rightVolume)
3406+ {
3407+ REPORT_FUNCTION();
3408+
3409+ left_volume = leftVolume;
3410+ right_volume = rightVolume;
3411+ return MediaPlayer::setVolume(leftVolume, rightVolume);
3412+ }
3413+
3414+ int getSourceFd() const { return source_fd; }
3415+ void setSourceFd(int fd) { source_fd = fd; }
3416+
3417+ private:
3418+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3419+ android::sp<android::SurfaceTexture> texture;
3420+#else
3421+ android::sp<android::GLConsumer> texture;
3422+#endif
3423+ android::sp<MediaPlayerListenerWrapper> media_player_listener;
3424+ android::sp<FrameAvailableListener> frame_listener;
3425+ float left_volume;
3426+ float right_volume;
3427+ int source_fd;
3428+}; // MediaPlayerWrapper
3429+
3430+using namespace android;
3431+
3432+// ----- Media Player C API Implementation ----- //
3433+
3434+void android_media_set_video_size_cb(MediaPlayerWrapper *mp, on_msg_set_video_size cb, void *context)
3435+{
3436+ REPORT_FUNCTION();
3437+
3438+ if (mp == NULL) {
3439+ ALOGE("mp must not be NULL");
3440+ return;
3441+ }
3442+
3443+ mp->setVideoSizeCb(cb, context);
3444+}
3445+
3446+void android_media_set_video_texture_needs_update_cb(MediaPlayerWrapper *mp, on_video_texture_needs_update cb, void *context)
3447+{
3448+ REPORT_FUNCTION();
3449+
3450+ if (mp == NULL) {
3451+ ALOGE("mp must not be NULL");
3452+ return;
3453+ }
3454+
3455+ mp->setVideoTextureNeedsUpdateCb(cb, context);
3456+}
3457+
3458+void android_media_set_error_cb(MediaPlayerWrapper *mp, on_msg_error cb, void *context)
3459+{
3460+ REPORT_FUNCTION();
3461+
3462+ if (mp == NULL) {
3463+ ALOGE("mp must not be NULL");
3464+ return;
3465+ }
3466+
3467+ mp->setErrorCb(cb, context);
3468+}
3469+
3470+void android_media_set_playback_complete_cb(MediaPlayerWrapper *mp, on_playback_complete cb, void *context)
3471+{
3472+ REPORT_FUNCTION();
3473+
3474+ if (mp == NULL) {
3475+ ALOGE("mp must not be NULL");
3476+ return;
3477+ }
3478+
3479+ mp->setPlaybackCompleteCb(cb, context);
3480+}
3481+
3482+void android_media_set_media_prepared_cb(MediaPlayerWrapper *mp, on_media_prepared cb, void *context)
3483+{
3484+ REPORT_FUNCTION();
3485+
3486+ if (mp == NULL) {
3487+ ALOGE("mp must not be NULL");
3488+ return;
3489+ }
3490+
3491+ mp->setMediaPreparedCb(cb, context);
3492+}
3493+
3494+MediaPlayerWrapper *android_media_new_player()
3495+{
3496+ REPORT_FUNCTION();
3497+
3498+ MediaPlayerWrapper *mp = new MediaPlayerWrapper();
3499+ if (mp == NULL) {
3500+ ALOGE("Failed to create new MediaPlayerWrapper instance.");
3501+ return NULL;
3502+ }
3503+
3504+ // Required for internal player state processing. Without this, prepare() and start() hang.
3505+ ProcessState::self()->startThreadPool();
3506+
3507+ return mp;
3508+}
3509+
3510+int android_media_set_data_source(MediaPlayerWrapper *mp, const char* url)
3511+{
3512+ REPORT_FUNCTION();
3513+
3514+ if (mp == NULL) {
3515+ ALOGE("mp must not be NULL");
3516+ return BAD_VALUE;
3517+ }
3518+
3519+ if (url == NULL) {
3520+ ALOGE("url must not be NULL");
3521+ return BAD_VALUE;
3522+ }
3523+
3524+ ALOGD("url: %s", url);
3525+
3526+ String16 src(url);
3527+ if (src.startsWith(String16("http://")) == true) {
3528+ ALOGD("HTTP source URL detected");
3529+ mp->setDataSource(url, NULL);
3530+ } else {
3531+ ALOGD("File source URL detected");
3532+ int fd = open(url, O_RDONLY);
3533+ if (fd < 0)
3534+ {
3535+ ALOGE("Failed to open source data at: %s\n", url);
3536+ return BAD_VALUE;
3537+ }
3538+
3539+ mp->setSourceFd(fd);
3540+
3541+ struct stat st;
3542+ stat(url, &st);
3543+
3544+ ALOGD("source file length: %lld\n", st.st_size);
3545+
3546+ mp->setDataSource(fd, 0, st.st_size);
3547+ }
3548+ mp->prepare();
3549+
3550+ return OK;
3551+}
3552+
3553+int android_media_set_preview_texture(MediaPlayerWrapper *mp, int texture_id)
3554+{
3555+ REPORT_FUNCTION();
3556+
3557+ if (mp == NULL) {
3558+ ALOGE("mp must not be NULL");
3559+ return BAD_VALUE;
3560+ }
3561+
3562+ android::sp<android::NativeBufferAlloc> native_alloc(
3563+ new android::NativeBufferAlloc()
3564+ );
3565+
3566+ android::sp<android::BufferQueue> buffer_queue(
3567+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
3568+ new android::BufferQueue(false, NULL, native_alloc)
3569+#else
3570+ new android::BufferQueue(NULL, native_alloc)
3571+#endif
3572+ );
3573+
3574+ static const bool allow_synchronous_mode = true;
3575+ // Create a new GLConsumer/SurfaceTexture from the texture_id in synchronous mode (don't wait on all data in the buffer)
3576+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
3577+ mp->setVideoSurfaceTexture(android::sp<android::SurfaceTexture>(
3578+ new android::SurfaceTexture(
3579+#else
3580+ mp->setVideoSurfaceTexture(buffer_queue, android::sp<android::GLConsumer>(
3581+ new android::GLConsumer(
3582+#endif
3583+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
3584+ texture_id,
3585+ allow_synchronous_mode,
3586+ GL_TEXTURE_EXTERNAL_OES,
3587+ true,
3588+ buffer_queue)));
3589+#else
3590+ buffer_queue,
3591+ texture_id,
3592+ GL_TEXTURE_EXTERNAL_OES,
3593+ true,
3594+ false)));
3595+#endif
3596+
3597+ return OK;
3598+}
3599+
3600+void android_media_update_surface_texture(MediaPlayerWrapper *mp)
3601+{
3602+ if (mp == NULL) {
3603+ ALOGE("mp must not be NULL");
3604+ return;
3605+ }
3606+
3607+ mp->updateGLConsumer();
3608+}
3609+
3610+void android_media_surface_texture_get_transformation_matrix(MediaPlayerWrapper *mp, GLfloat* matrix)
3611+{
3612+ if (mp == NULL) {
3613+ ALOGE("mp must not be NULL");
3614+ return;
3615+ }
3616+
3617+ mp->get_transformation_matrix_for_surface_texture(matrix);
3618+}
3619+
3620+int android_media_play(MediaPlayerWrapper *mp)
3621+{
3622+ REPORT_FUNCTION();
3623+
3624+ if (mp == NULL) {
3625+ ALOGE("mp must not be NULL");
3626+ return BAD_VALUE;
3627+ }
3628+
3629+ mp->start();
3630+ const char *tmp = mp->isPlaying() ? "yes" : "no";
3631+ ALOGV("Is playing?: %s\n", tmp);
3632+
3633+ return OK;
3634+}
3635+
3636+int android_media_pause(MediaPlayerWrapper *mp)
3637+{
3638+ REPORT_FUNCTION();
3639+
3640+ if (mp == NULL) {
3641+ ALOGE("mp must not be NULL");
3642+ return BAD_VALUE;
3643+ }
3644+
3645+ mp->pause();
3646+
3647+ return OK;
3648+}
3649+
3650+int android_media_stop(MediaPlayerWrapper *mp)
3651+{
3652+ REPORT_FUNCTION();
3653+
3654+ if (mp == NULL) {
3655+ ALOGE("mp must not be NULL");
3656+ return BAD_VALUE;
3657+ }
3658+
3659+ mp->stop();
3660+
3661+ int fd = mp->getSourceFd();
3662+ if (fd > -1)
3663+ close(fd);
3664+
3665+ return OK;
3666+}
3667+
3668+bool android_media_is_playing(MediaPlayerWrapper *mp)
3669+{
3670+ if (mp != NULL) {
3671+ if (mp->isPlaying())
3672+ return true;
3673+ }
3674+
3675+ return false;
3676+}
3677+
3678+int android_media_seek_to(MediaPlayerWrapper *mp, int msec)
3679+{
3680+ REPORT_FUNCTION();
3681+
3682+ if (mp == NULL) {
3683+ ALOGE("mp must not be NULL");
3684+ return BAD_VALUE;
3685+ }
3686+
3687+ return mp->seekTo(msec);
3688+}
3689+
3690+int android_media_get_current_position(MediaPlayerWrapper *mp, int *msec)
3691+{
3692+ if (mp == NULL) {
3693+ ALOGE("mp must not be NULL");
3694+ return BAD_VALUE;
3695+ }
3696+
3697+ return mp->getCurrentPosition(msec);
3698+}
3699+
3700+int android_media_get_duration(MediaPlayerWrapper *mp, int *msec)
3701+{
3702+ REPORT_FUNCTION();
3703+
3704+ if (mp == NULL) {
3705+ ALOGE("mp must not be NULL");
3706+ return BAD_VALUE;
3707+ }
3708+
3709+ return mp->getDuration(msec);
3710+}
3711+
3712+int android_media_get_volume(MediaPlayerWrapper *mp, int *volume)
3713+{
3714+ REPORT_FUNCTION();
3715+
3716+ if (volume == NULL) {
3717+ ALOGE("volume must not be NULL");
3718+ return BAD_VALUE;
3719+ }
3720+
3721+ if (mp == NULL) {
3722+ ALOGE("mp must not be NULL");
3723+ return BAD_VALUE;
3724+ }
3725+
3726+ float left_volume = 0, right_volume = 0;
3727+ mp->getVolume(&left_volume, &right_volume);
3728+ *volume = left_volume * 100;
3729+
3730+ return OK;
3731+}
3732+
3733+int android_media_set_volume(MediaPlayerWrapper *mp, int volume)
3734+{
3735+ REPORT_FUNCTION();
3736+
3737+ if (mp == NULL) {
3738+ ALOGE("mp must not be NULL");
3739+ return BAD_VALUE;
3740+ }
3741+
3742+ float left_volume = float(volume / 100);
3743+ float right_volume = float(volume / 100);
3744+ return mp->setVolume(left_volume, right_volume);
3745+}
3746--- /dev/null
3747+++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_format_layer.cpp
3748@@ -0,0 +1,245 @@
3749+/*
3750+ * Copyright (C) 2013 Canonical Ltd
3751+ *
3752+ * Licensed under the Apache License, Version 2.0 (the "License");
3753+ * you may not use this file except in compliance with the License.
3754+ * You may obtain a copy of the License at
3755+ *
3756+ * http://www.apache.org/licenses/LICENSE-2.0
3757+ *
3758+ * Unless required by applicable law or agreed to in writing, software
3759+ * distributed under the License is distributed on an "AS IS" BASIS,
3760+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3761+ * See the License for the specific language governing permissions and
3762+ * limitations under the License.
3763+ *
3764+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
3765+ */
3766+
3767+// Uncomment to enable verbose debug output
3768+#define LOG_NDEBUG 0
3769+
3770+#undef LOG_TAG
3771+#define LOG_TAG "MediaFormatLayer"
3772+
3773+#include <hybris/media/media_format_layer.h>
3774+#include "media_format_layer_priv.h"
3775+
3776+#include <assert.h>
3777+
3778+#include <utils/Log.h>
3779+
3780+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__);
3781+
3782+using namespace android;
3783+
3784+static inline _MediaFormat *get_internal_format(MediaFormat format)
3785+{
3786+ if (format == NULL)
3787+ {
3788+ ALOGE("format must not be NULL");
3789+ return NULL;
3790+ }
3791+
3792+ _MediaFormat *mf = static_cast<_MediaFormat*>(format);
3793+ assert(mf->refcount >= 1);
3794+
3795+ return mf;
3796+}
3797+
3798+MediaFormat media_format_create_video_format(const char *mime, int32_t width, int32_t height, int64_t duration_us, int32_t max_input_size)
3799+{
3800+ REPORT_FUNCTION()
3801+
3802+ _MediaFormat *format = new _MediaFormat();
3803+ format->mime = AString(mime);
3804+ format->width = width;
3805+ format->height = height;
3806+ format->duration_us = duration_us;
3807+ format->max_input_size = max_input_size;
3808+
3809+ return format;
3810+}
3811+
3812+void media_format_destroy(MediaFormat format)
3813+{
3814+ REPORT_FUNCTION()
3815+
3816+ _MediaFormat *mf = get_internal_format(format);
3817+ if (mf == NULL)
3818+ return;
3819+
3820+ if (mf->refcount)
3821+ return;
3822+
3823+ delete mf;
3824+}
3825+
3826+void media_format_ref(MediaFormat format)
3827+{
3828+ REPORT_FUNCTION()
3829+
3830+ _MediaFormat *mf = get_internal_format(format);
3831+ if (mf == NULL)
3832+ return;
3833+
3834+ mf->refcount++;
3835+}
3836+
3837+void media_format_unref(MediaFormat format)
3838+{
3839+ REPORT_FUNCTION()
3840+
3841+ _MediaFormat *mf = get_internal_format(format);
3842+ if (mf == NULL)
3843+ return;
3844+
3845+ if (mf->refcount)
3846+ mf->refcount--;
3847+}
3848+
3849+void media_format_set_byte_buffer(MediaFormat format, const char *key, uint8_t *data, size_t size)
3850+{
3851+ REPORT_FUNCTION()
3852+
3853+ _MediaFormat *mf = get_internal_format(format);
3854+ if (mf == NULL)
3855+ return;
3856+ if (key == NULL || data == NULL || size == 0)
3857+ return;
3858+
3859+ mf->csd_key_name = AString(key);
3860+ mf->csd = sp<ABuffer>(new ABuffer(data, size));
3861+}
3862+
3863+const char* media_format_get_mime(MediaFormat format)
3864+{
3865+ REPORT_FUNCTION()
3866+
3867+ _MediaFormat *mf = get_internal_format(format);
3868+ if (mf == NULL)
3869+ return NULL;
3870+
3871+ return mf->mime.c_str();
3872+}
3873+
3874+int64_t media_format_get_duration_us(MediaFormat format)
3875+{
3876+ REPORT_FUNCTION()
3877+
3878+ _MediaFormat *mf = get_internal_format(format);
3879+ if (mf == NULL)
3880+ return 0;
3881+
3882+ return mf->duration_us;
3883+}
3884+
3885+int32_t media_format_get_width(MediaFormat format)
3886+{
3887+ REPORT_FUNCTION()
3888+
3889+ _MediaFormat *mf = get_internal_format(format);
3890+ if (mf == NULL)
3891+ return 0;
3892+
3893+ return mf->width;
3894+}
3895+
3896+int32_t media_format_get_height(MediaFormat format)
3897+{
3898+ REPORT_FUNCTION()
3899+
3900+ _MediaFormat *mf = get_internal_format(format);
3901+ if (mf == NULL)
3902+ return 0;
3903+
3904+ return mf->height;
3905+}
3906+
3907+int32_t media_format_get_max_input_size(MediaFormat format)
3908+{
3909+ REPORT_FUNCTION()
3910+
3911+ _MediaFormat *mf = get_internal_format(format);
3912+ if (mf == NULL)
3913+ return 0;
3914+
3915+ return mf->max_input_size;
3916+}
3917+
3918+int32_t media_format_get_stride(MediaFormat format)
3919+{
3920+ REPORT_FUNCTION()
3921+
3922+ _MediaFormat *mf = get_internal_format(format);
3923+ if (mf == NULL)
3924+ return 0;
3925+
3926+ return mf->stride;
3927+}
3928+
3929+int32_t media_format_get_slice_height(MediaFormat format)
3930+{
3931+ REPORT_FUNCTION()
3932+
3933+ _MediaFormat *mf = get_internal_format(format);
3934+ if (mf == NULL)
3935+ return 0;
3936+
3937+ return mf->height;
3938+}
3939+
3940+int32_t media_format_get_color_format(MediaFormat format)
3941+{
3942+ REPORT_FUNCTION()
3943+
3944+ _MediaFormat *mf = get_internal_format(format);
3945+ if (mf == NULL)
3946+ return 0;
3947+
3948+ return mf->color_format;
3949+}
3950+
3951+int32_t media_format_get_crop_left(MediaFormat format)
3952+{
3953+ REPORT_FUNCTION()
3954+
3955+ _MediaFormat *mf = get_internal_format(format);
3956+ if (mf == NULL)
3957+ return 0;
3958+
3959+ return mf->crop_left;
3960+}
3961+
3962+int32_t media_format_get_crop_right(MediaFormat format)
3963+{
3964+ REPORT_FUNCTION()
3965+
3966+ _MediaFormat *mf = get_internal_format(format);
3967+ if (mf == NULL)
3968+ return 0;
3969+
3970+ return mf->crop_right;
3971+}
3972+
3973+int32_t media_format_get_crop_top(MediaFormat format)
3974+{
3975+ REPORT_FUNCTION()
3976+
3977+ _MediaFormat *mf = get_internal_format(format);
3978+ if (mf == NULL)
3979+ return 0;
3980+
3981+ return mf->crop_top;
3982+}
3983+
3984+int32_t media_format_get_crop_bottom(MediaFormat format)
3985+{
3986+ REPORT_FUNCTION()
3987+
3988+ _MediaFormat *mf = get_internal_format(format);
3989+ if (mf == NULL)
3990+ return 0;
3991+
3992+ return mf->crop_bottom;
3993+}
3994--- /dev/null
3995+++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_format_layer_priv.cpp
3996@@ -0,0 +1,50 @@
3997+/*
3998+ * Copyright (C) 2013 Canonical Ltd
3999+ *
4000+ * Licensed under the Apache License, Version 2.0 (the "License");
4001+ * you may not use this file except in compliance with the License.
4002+ * You may obtain a copy of the License at
4003+ *
4004+ * http://www.apache.org/licenses/LICENSE-2.0
4005+ *
4006+ * Unless required by applicable law or agreed to in writing, software
4007+ * distributed under the License is distributed on an "AS IS" BASIS,
4008+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4009+ * See the License for the specific language governing permissions and
4010+ * limitations under the License.
4011+ *
4012+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4013+ */
4014+
4015+#include <stddef.h>
4016+#include <unistd.h>
4017+
4018+#include <media/stagefright/foundation/AString.h>
4019+
4020+#include <utils/RefBase.h>
4021+
4022+#ifdef __cplusplus
4023+extern "C" {
4024+#endif
4025+
4026+struct _MediaFormat : public RefBase
4027+{
4028+ _MediaFormat()
4029+ : refcount(1)
4030+ {
4031+ }
4032+
4033+ AString mime;
4034+ int64_t duration_us;
4035+ int32_t width;
4036+ int32_t height;
4037+ int32_t max_input_size;
4038+
4039+ unsigned int refcount;
4040+};
4041+
4042+#ifdef __cplusplus
4043+}
4044+#endif
4045+
4046+#endif
4047--- /dev/null
4048+++ libhybris-0.1.0+git20131207+e452e83/compat/media/media_format_layer_priv.h
4049@@ -0,0 +1,68 @@
4050+/*
4051+ * Copyright (C) 2013 Canonical Ltd
4052+ *
4053+ * Licensed under the Apache License, Version 2.0 (the "License");
4054+ * you may not use this file except in compliance with the License.
4055+ * You may obtain a copy of the License at
4056+ *
4057+ * http://www.apache.org/licenses/LICENSE-2.0
4058+ *
4059+ * Unless required by applicable law or agreed to in writing, software
4060+ * distributed under the License is distributed on an "AS IS" BASIS,
4061+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4062+ * See the License for the specific language governing permissions and
4063+ * limitations under the License.
4064+ *
4065+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4066+ */
4067+
4068+#ifndef MEDIA_FORMAT_LAYER_PRIV_H_
4069+#define MEDIA_FORMAT_LAYER_PRIV_H_
4070+
4071+#include <stddef.h>
4072+#include <unistd.h>
4073+
4074+#include <media/stagefright/foundation/AString.h>
4075+#include <media/stagefright/foundation/ABuffer.h>
4076+
4077+#include <utils/RefBase.h>
4078+
4079+struct _MediaFormat : public android::RefBase
4080+{
4081+ _MediaFormat()
4082+ : duration_us(0),
4083+ width(0),
4084+ height(0),
4085+ max_input_size(0),
4086+ csd(NULL),
4087+ stride(0),
4088+ slice_height(0),
4089+ color_format(0),
4090+ crop_left(0),
4091+ crop_right(0),
4092+ crop_top(0),
4093+ crop_bottom(0),
4094+ refcount(1)
4095+ {
4096+ }
4097+
4098+ android::AString mime;
4099+ int64_t duration_us;
4100+ int32_t width;
4101+ int32_t height;
4102+ int32_t max_input_size;
4103+ android::AString csd_key_name;
4104+ android::sp<android::ABuffer> csd;
4105+
4106+ int32_t stride;
4107+ int32_t slice_height;
4108+ int32_t color_format;
4109+ int32_t crop_left;
4110+ int32_t crop_right;
4111+ int32_t crop_top;
4112+ int32_t crop_bottom;
4113+
4114+ unsigned int refcount;
4115+};
4116+
4117+#endif // MEDIA_FORMAT_LAYER_PRIV_H_
4118--- /dev/null
4119+++ libhybris-0.1.0+git20131207+e452e83/compat/media/recorder_compatibility_layer.cpp
4120@@ -0,0 +1,457 @@
4121+/*
4122+ * Copyright (C) 2013 Canonical Ltd
4123+ *
4124+ * Licensed under the Apache License, Version 2.0 (the "License");
4125+ * you may not use this file except in compliance with the License.
4126+ * You may obtain a copy of the License at
4127+ *
4128+ * http://www.apache.org/licenses/LICENSE-2.0
4129+ *
4130+ * Unless required by applicable law or agreed to in writing, software
4131+ * distributed under the License is distributed on an "AS IS" BASIS,
4132+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4133+ * See the License for the specific language governing permissions and
4134+ * limitations under the License.
4135+ *
4136+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4137+ * Guenter Schwann <guenter.schwann@canonical.com>
4138+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
4139+ */
4140+
4141+#include <hybris/internal/camera_control.h>
4142+#include <hybris/media/recorder_compatibility_layer.h>
4143+
4144+#include <camera/Camera.h>
4145+#include <camera/ICamera.h>
4146+#include <media/mediarecorder.h>
4147+
4148+//#define LOG_NDEBUG 0
4149+#undef LOG_TAG
4150+#define LOG_TAG "MediaRecorderCompatibilityLayer"
4151+#include <utils/KeyedVector.h>
4152+#include <utils/Log.h>
4153+
4154+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
4155+
4156+/*!
4157+ * \brief The MediaRecorderListenerWrapper class is used to listen to events
4158+ * from the MediaRecorder
4159+ */
4160+class MediaRecorderListenerWrapper : public android::MediaRecorderListener
4161+{
4162+ public:
4163+ MediaRecorderListenerWrapper()
4164+ : error_cb(NULL),
4165+ error_context(NULL)
4166+ {
4167+ }
4168+
4169+ void notify(int msg, int ext1, int ext2)
4170+ {
4171+ ALOGV("\tmsg: %d, ext1: %d, ext2: %d \n", msg, ext1, ext2);
4172+
4173+ switch (msg) {
4174+ case android::MEDIA_RECORDER_EVENT_ERROR:
4175+ ALOGV("\tMEDIA_RECORDER_EVENT_ERROR msg\n");
4176+ // TODO: Extend this cb to include the error message
4177+ if (error_cb != NULL)
4178+ error_cb(error_context);
4179+ else
4180+ ALOGE("Failed to signal error to app layer, callback not set.");
4181+ break;
4182+ default:
4183+ ALOGV("\tUnknown notification\n");
4184+ }
4185+ }
4186+
4187+ void setErrorCb(on_recorder_msg_error cb, void *context)
4188+ {
4189+ REPORT_FUNCTION();
4190+ error_cb = cb;
4191+ error_context = context;
4192+ }
4193+
4194+ private:
4195+ on_recorder_msg_error error_cb;
4196+ void *error_context;
4197+};
4198+
4199+/*!
4200+ * \brief The MediaRecorderWrapper struct wraps the MediaRecorder class
4201+ */
4202+struct MediaRecorderWrapper : public android::MediaRecorder
4203+{
4204+ public:
4205+ MediaRecorderWrapper()
4206+ : MediaRecorder(),
4207+ media_recorder_listener(new MediaRecorderListenerWrapper())
4208+ {
4209+ setListener(media_recorder_listener);
4210+ }
4211+
4212+ ~MediaRecorderWrapper()
4213+ {
4214+ reset();
4215+ }
4216+
4217+ void setErrorCb(on_recorder_msg_error cb, void *context)
4218+ {
4219+ REPORT_FUNCTION();
4220+
4221+ assert(media_recorder_listener != NULL);
4222+ media_recorder_listener->setErrorCb(cb, context);
4223+ }
4224+
4225+ private:
4226+ android::sp<MediaRecorderListenerWrapper> media_recorder_listener;
4227+};
4228+
4229+
4230+using namespace android;
4231+
4232+/*!
4233+ * \brief android_recorder_set_error_cb
4234+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4235+ * \param cb The callback function to be called when a recording error occurs
4236+ * \param context
4237+ */
4238+void android_recorder_set_error_cb(MediaRecorderWrapper *mr, on_recorder_msg_error cb,
4239+ void *context)
4240+{
4241+ REPORT_FUNCTION();
4242+
4243+ if (mr == NULL) {
4244+ ALOGE("mr must not be NULL");
4245+ return;
4246+ }
4247+
4248+ mr->setErrorCb(cb, context);
4249+}
4250+
4251+/*!
4252+ * \brief android_media_new_recorder creates a new MediaRecorder
4253+ * \return New MediaRecorder object, or NULL if the object could not be created.
4254+ */
4255+MediaRecorderWrapper *android_media_new_recorder()
4256+{
4257+ REPORT_FUNCTION();
4258+
4259+ MediaRecorderWrapper *mr = new MediaRecorderWrapper;
4260+ if (mr == NULL) {
4261+ ALOGE("Failed to create new MediaRecorderWrapper instance.");
4262+ return NULL;
4263+ }
4264+
4265+ return mr;
4266+}
4267+
4268+/*!
4269+ * \brief android_recorder_initCheck
4270+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4271+ * \return negative value if an error occured
4272+ */
4273+int android_recorder_initCheck(MediaRecorderWrapper *mr)
4274+{
4275+ REPORT_FUNCTION();
4276+
4277+ if (mr == NULL) {
4278+ ALOGE("mr must not be NULL");
4279+ return BAD_VALUE;
4280+ }
4281+
4282+ return mr->initCheck();
4283+}
4284+
4285+/*!
4286+ * \brief android_recorder_setCamera sets the camera object for recording videos
4287+ * from the camera
4288+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4289+ * \param control Wrapper for the camera (see camera in hybris)
4290+ * \return negative value if an error occured
4291+ */
4292+int android_recorder_setCamera(MediaRecorderWrapper *mr, CameraControl* control)
4293+{
4294+ REPORT_FUNCTION();
4295+
4296+ if (mr == NULL) {
4297+ ALOGE("mr must not be NULL");
4298+ return BAD_VALUE;
4299+ }
4300+ if (control == NULL) {
4301+ ALOGE("control must not be NULL");
4302+ return BAD_VALUE;
4303+ }
4304+
4305+ return mr->setCamera(control->camera->remote(), control->camera->getRecordingProxy());
4306+}
4307+
4308+/*!
4309+ * \brief android_recorder_setVideoSource sets the video source.
4310+ * If no video source is set, only audio is recorded.
4311+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4312+ * \param vs The video source. It's either the camera of gralloc buffer
4313+ * \return negative value if an error occured
4314+ */
4315+int android_recorder_setVideoSource(MediaRecorderWrapper *mr, VideoSource vs)
4316+{
4317+ REPORT_FUNCTION();
4318+
4319+ if (mr == NULL) {
4320+ ALOGE("mr must not be NULL");
4321+ return BAD_VALUE;
4322+ }
4323+
4324+ return mr->setVideoSource(static_cast<int>(vs));
4325+}
4326+
4327+/*!
4328+ * \brief android_recorder_setAudioSource
4329+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4330+ * \param as The audio source.
4331+ * \return negative value if an error occured
4332+ */
4333+int android_recorder_setAudioSource(MediaRecorderWrapper *mr, AudioSource as)
4334+{
4335+ REPORT_FUNCTION();
4336+
4337+ if (mr == NULL) {
4338+ ALOGE("mr must not be NULL");
4339+ return BAD_VALUE;
4340+ }
4341+
4342+ return mr->setAudioSource(static_cast<int>(as));
4343+}
4344+
4345+/*!
4346+ * \brief android_recorder_setOutputFormat
4347+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4348+ * \param of The output file format
4349+ * \return negative value if an error occured
4350+ */
4351+int android_recorder_setOutputFormat(MediaRecorderWrapper *mr, OutputFormat of)
4352+{
4353+ REPORT_FUNCTION();
4354+
4355+ if (mr == NULL) {
4356+ ALOGE("mr must not be NULL");
4357+ return BAD_VALUE;
4358+ }
4359+
4360+ return mr->setOutputFormat(static_cast<int>(of));
4361+}
4362+
4363+/*!
4364+ * \brief android_recorder_setVideoEncoder
4365+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4366+ * \param ve The video encoder sets the codec for the video
4367+ * \return negative value if an error occured
4368+ */
4369+int android_recorder_setVideoEncoder(MediaRecorderWrapper *mr, VideoEncoder ve)
4370+{
4371+ REPORT_FUNCTION();
4372+
4373+ if (mr == NULL) {
4374+ ALOGE("mr must not be NULL");
4375+ return BAD_VALUE;
4376+ }
4377+
4378+ return mr->setVideoEncoder(static_cast<int>(ve));
4379+}
4380+
4381+/*!
4382+ * \brief android_recorder_setAudioEncoder
4383+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4384+ * \param ae The audio encoder sets the codec for the audio
4385+ * \return negative value if an error occured
4386+ */
4387+int android_recorder_setAudioEncoder(MediaRecorderWrapper *mr, AudioEncoder ae)
4388+{
4389+ REPORT_FUNCTION();
4390+
4391+ if (mr == NULL) {
4392+ ALOGE("mr must not be NULL");
4393+ return BAD_VALUE;
4394+ }
4395+
4396+ return mr->setAudioEncoder(static_cast<int>(ae));
4397+}
4398+
4399+/*!
4400+ * \brief android_recorder_setOutputFile sets the output file to the given file descriptor
4401+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4402+ * \param fd File descriptor of an open file, that the stream can be written to
4403+ * \return negative value if an error occured
4404+ */
4405+int android_recorder_setOutputFile(MediaRecorderWrapper *mr, int fd)
4406+{
4407+ REPORT_FUNCTION();
4408+
4409+ if (mr == NULL) {
4410+ ALOGE("mr must not be NULL");
4411+ return BAD_VALUE;
4412+ }
4413+
4414+ return mr->setOutputFile(fd, 0, 0);
4415+}
4416+
4417+/*!
4418+ * \brief android_recorder_setVideoSize
4419+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4420+ * \param width width for the video to record
4421+ * \param height height for the video to record
4422+ * \return negative value if an error occured
4423+ */
4424+int android_recorder_setVideoSize(MediaRecorderWrapper *mr, int width, int height)
4425+{
4426+ REPORT_FUNCTION();
4427+
4428+ if (mr == NULL) {
4429+ ALOGE("mr must not be NULL");
4430+ return BAD_VALUE;
4431+ }
4432+
4433+ return mr->setVideoSize(width, height);
4434+}
4435+
4436+/*!
4437+ * \brief android_recorder_setVideoFrameRate
4438+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4439+ * \param frames_per_second Frames per second has typical values for a movie clip in 720p is 30
4440+ * \return negative value if an error occured
4441+ */
4442+int android_recorder_setVideoFrameRate(MediaRecorderWrapper *mr, int frames_per_second)
4443+{
4444+ REPORT_FUNCTION();
4445+
4446+ if (mr == NULL) {
4447+ ALOGE("mr must not be NULL");
4448+ return BAD_VALUE;
4449+ }
4450+
4451+ return mr->setVideoFrameRate(frames_per_second);
4452+}
4453+
4454+/*!
4455+ * \brief android_recorder_setParameters sets a parameter. Even those without
4456+ * explicit function.
4457+ * For possible parameters look for example in StagefrightRecorder::setParameter()
4458+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4459+ * \param parameters list of parameters. format is "parameter1=value;parameter2=value"
4460+ * \return negative value if an error occured
4461+ */
4462+int android_recorder_setParameters(MediaRecorderWrapper *mr, const char* parameters)
4463+{
4464+ REPORT_FUNCTION();
4465+
4466+ if (mr == NULL) {
4467+ ALOGE("mr must not be NULL");
4468+ return BAD_VALUE;
4469+ }
4470+
4471+ String8 params(parameters);
4472+ return mr->setParameters(params);
4473+}
4474+
4475+/*!
4476+ * \brief android_recorder_start starts the recording.
4477+ * The MediaRecorder has to be in state "prepared"
4478+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4479+ * \return negative value if an error occured
4480+ */
4481+int android_recorder_start(MediaRecorderWrapper *mr)
4482+{
4483+ REPORT_FUNCTION();
4484+
4485+ if (mr == NULL) {
4486+ ALOGE("mr must not be NULL");
4487+ return BAD_VALUE;
4488+ }
4489+
4490+ return mr->start();
4491+}
4492+
4493+/*!
4494+ * \brief android_recorder_stop Stops a running recording.
4495+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4496+ * \return negative value if an error occured
4497+ */
4498+int android_recorder_stop(MediaRecorderWrapper *mr)
4499+{
4500+ REPORT_FUNCTION();
4501+
4502+ if (mr == NULL) {
4503+ ALOGE("mr must not be NULL");
4504+ return BAD_VALUE;
4505+ }
4506+
4507+ return mr->stop();
4508+}
4509+
4510+/*!
4511+ * \brief android_recorder_prepare put the MediaRecorder into state "prepare"
4512+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4513+ * \return negative value if an error occured
4514+ */
4515+int android_recorder_prepare(MediaRecorderWrapper *mr)
4516+{
4517+ REPORT_FUNCTION();
4518+
4519+ if (mr == NULL) {
4520+ ALOGE("mr must not be NULL");
4521+ return BAD_VALUE;
4522+ }
4523+
4524+ return mr->prepare();
4525+}
4526+
4527+/*!
4528+ * \brief android_recorder_reset resets the MediaRecorder
4529+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4530+ * \return negative value if an error occured
4531+ */
4532+int android_recorder_reset(MediaRecorderWrapper *mr)
4533+{
4534+ REPORT_FUNCTION();
4535+
4536+ if (mr == NULL) {
4537+ ALOGE("mr must not be NULL");
4538+ return BAD_VALUE;
4539+ }
4540+
4541+ return mr->reset();
4542+}
4543+
4544+/*!
4545+ * \brief android_recorder_close closes the MediaRecorder
4546+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4547+ * \return negative value if an error occured
4548+ */
4549+int android_recorder_close(MediaRecorderWrapper *mr)
4550+{
4551+ REPORT_FUNCTION();
4552+
4553+ if (mr == NULL) {
4554+ ALOGE("mr must not be NULL");
4555+ return BAD_VALUE;
4556+ }
4557+
4558+ return mr->close();
4559+}
4560+
4561+/*!
4562+ * \brief android_recorder_release releases the MediaRecorder resources
4563+ * This deletes the object. So don't use it after calling this function.
4564+ * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder()
4565+ * \return negative value if an error occured
4566+ */
4567+int android_recorder_release(MediaRecorderWrapper *mr)
4568+{
4569+ REPORT_FUNCTION();
4570+
4571+ if (mr == NULL) {
4572+ ALOGE("mr must not be NULL");
4573+ return BAD_VALUE;
4574+ }
4575+
4576+ return mr->release();
4577+}
4578--- /dev/null
4579+++ libhybris-0.1.0+git20131207+e452e83/compat/media/surface_texture_client_hybris.cpp
4580@@ -0,0 +1,333 @@
4581+/*
4582+ * Copyright (C) 2013 Canonical Ltd
4583+ *
4584+ * Licensed under the Apache License, Version 2.0 (the "License");
4585+ * you may not use this file except in compliance with the License.
4586+ * You may obtain a copy of the License at
4587+ *
4588+ * http://www.apache.org/licenses/LICENSE-2.0
4589+ *
4590+ * Unless required by applicable law or agreed to in writing, software
4591+ * distributed under the License is distributed on an "AS IS" BASIS,
4592+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4593+ * See the License for the specific language governing permissions and
4594+ * limitations under the License.
4595+ *
4596+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4597+ */
4598+
4599+// Uncomment to enable verbose debug output
4600+#define LOG_NDEBUG 0
4601+
4602+#undef LOG_TAG
4603+#define LOG_TAG "SurfaceTextureClientHybris"
4604+
4605+#include <hybris/media/surface_texture_client_hybris.h>
4606+#include "surface_texture_client_hybris_priv.h"
4607+
4608+#include <ui/GraphicBuffer.h>
4609+#include <utils/Log.h>
4610+#include <ui/Region.h>
4611+#include <gui/Surface.h>
4612+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4613+#include <gui/SurfaceTextureClient.h>
4614+#endif
4615+
4616+#include <GLES2/gl2.h>
4617+#include <GLES2/gl2ext.h>
4618+
4619+#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__);
4620+
4621+using namespace android;
4622+
4623+// ----- Begin _SurfaceTextureClientHybris API ----- //
4624+
4625+static inline _SurfaceTextureClientHybris *get_internal_stch(SurfaceTextureClientHybris stc, const char * func)
4626+{
4627+ if (stc == NULL)
4628+ {
4629+ ALOGE("stc must not be NULL (%s)", func);
4630+ return NULL;
4631+ }
4632+
4633+ _SurfaceTextureClientHybris *s = static_cast<_SurfaceTextureClientHybris*>(stc);
4634+ assert(s->refcount >= 1);
4635+
4636+ return s;
4637+}
4638+
4639+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4640+_SurfaceTextureClientHybris::_SurfaceTextureClientHybris()
4641+ : refcount(1),
4642+ ready(false)
4643+{
4644+ REPORT_FUNCTION()
4645+}
4646+#endif
4647+
4648+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=4
4649+_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp<BufferQueue> &bq)
4650+ : Surface::Surface(bq, true),
4651+ refcount(1),
4652+ ready(false)
4653+{
4654+ REPORT_FUNCTION()
4655+}
4656+#endif
4657+
4658+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4659+_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const _SurfaceTextureClientHybris &stch)
4660+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4661+ : SurfaceTextureClient::SurfaceTextureClient(),
4662+#else
4663+ : Surface::Surface(new BufferQueue(), true),
4664+#endif
4665+ refcount(stch.refcount),
4666+ ready(false)
4667+{
4668+ REPORT_FUNCTION()
4669+}
4670+
4671+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4672+_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp<ISurfaceTexture> &st)
4673+ : SurfaceTextureClient::SurfaceTextureClient(st),
4674+#else
4675+_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp<IGraphicBufferProducer> &st)
4676+ : Surface::Surface(st, true),
4677+#endif
4678+ refcount(1),
4679+ ready(false)
4680+{
4681+ REPORT_FUNCTION()
4682+}
4683+#endif
4684+
4685+_SurfaceTextureClientHybris::~_SurfaceTextureClientHybris()
4686+{
4687+ REPORT_FUNCTION()
4688+
4689+ ready = false;
4690+}
4691+
4692+bool _SurfaceTextureClientHybris::isReady() const
4693+{
4694+ return ready;
4695+}
4696+
4697+int _SurfaceTextureClientHybris::dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd)
4698+{
4699+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4700+ return SurfaceTextureClient::dequeueBuffer(buffer, fenceFd);
4701+#else
4702+ return Surface::dequeueBuffer(buffer, fenceFd);
4703+#endif
4704+}
4705+
4706+int _SurfaceTextureClientHybris::queueBuffer(ANativeWindowBuffer* buffer, int fenceFd)
4707+{
4708+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4709+ return SurfaceTextureClient::queueBuffer(buffer, fenceFd);
4710+#else
4711+ return Surface::queueBuffer(buffer, fenceFd);
4712+#endif
4713+}
4714+
4715+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4716+void _SurfaceTextureClientHybris::setISurfaceTexture(const sp<ISurfaceTexture>& surface_texture)
4717+{
4718+ SurfaceTextureClient::setISurfaceTexture(surface_texture);
4719+#else
4720+void _SurfaceTextureClientHybris::setISurfaceTexture(const sp<IGraphicBufferProducer>& surface_texture)
4721+{
4722+ // We don't need to set up the IGraphicBufferProducer as stc needs it when created
4723+#endif
4724+
4725+ // Ready for rendering
4726+ ready = true;
4727+}
4728+
4729+void _SurfaceTextureClientHybris::setHardwareRendering(bool do_hardware_rendering)
4730+{
4731+ hardware_rendering = do_hardware_rendering;
4732+}
4733+
4734+bool _SurfaceTextureClientHybris::hardwareRendering()
4735+{
4736+ return hardware_rendering;
4737+}
4738+
4739+// ----- End _SurfaceTextureClientHybris API ----- //
4740+
4741+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4742+static inline void set_surface(_SurfaceTextureClientHybris *stch, const sp<SurfaceTexture> &surface_texture)
4743+#else
4744+static inline void set_surface(_SurfaceTextureClientHybris *stch, const sp<GLConsumer> &surface_texture)
4745+#endif
4746+{
4747+ REPORT_FUNCTION()
4748+
4749+ if (stch == NULL)
4750+ return;
4751+
4752+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4753+ stch->setISurfaceTexture(surface_texture->getBufferQueue());
4754+#else
4755+ stch->setISurfaceTexture(stch->getIGraphicBufferProducer());
4756+#endif
4757+}
4758+
4759+SurfaceTextureClientHybris surface_texture_client_create_by_id(unsigned int texture_id)
4760+{
4761+ REPORT_FUNCTION()
4762+
4763+ if (texture_id == 0)
4764+ {
4765+ ALOGE("Cannot create new SurfaceTextureClientHybris, texture id must be > 0.");
4766+ return NULL;
4767+ }
4768+
4769+ // Use a new native buffer allocator vs the default one, which means it'll use the proper one
4770+ // that will allow rendering to work with Mir
4771+ sp<NativeBufferAlloc> native_alloc(new NativeBufferAlloc());
4772+
4773+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
4774+ sp<BufferQueue> buffer_queue(new BufferQueue(false, NULL, native_alloc));
4775+ _SurfaceTextureClientHybris *stch(new _SurfaceTextureClientHybris);
4776+#else
4777+ sp<BufferQueue> buffer_queue(new BufferQueue(NULL, native_alloc));
4778+ _SurfaceTextureClientHybris *stch(new _SurfaceTextureClientHybris(buffer_queue));
4779+#endif
4780+
4781+ ALOGD("stch: %p (%s)", stch, __PRETTY_FUNCTION__);
4782+
4783+ if (stch->surface_texture != NULL)
4784+ stch->surface_texture.clear();
4785+
4786+ const bool allow_synchronous_mode = true;
4787+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4788+ stch->surface_texture = new SurfaceTexture(texture_id, allow_synchronous_mode, GL_TEXTURE_EXTERNAL_OES, true, buffer_queue);
4789+ set_surface(stch, stch->surface_texture);
4790+#else
4791+ stch->surface_texture = new GLConsumer(buffer_queue, texture_id, GL_TEXTURE_EXTERNAL_OES, true, true);
4792+#endif
4793+ set_surface(stch, stch->surface_texture);
4794+
4795+ return stch;
4796+}
4797+
4798+uint8_t surface_texture_client_is_ready_for_rendering(SurfaceTextureClientHybris stc)
4799+{
4800+ REPORT_FUNCTION()
4801+
4802+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4803+ if (s == NULL)
4804+ return false;
4805+
4806+ return static_cast<uint8_t>(s->isReady());
4807+}
4808+
4809+uint8_t surface_texture_client_hardware_rendering(SurfaceTextureClientHybris stc)
4810+{
4811+ REPORT_FUNCTION()
4812+
4813+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4814+ if (s == NULL)
4815+ return false;
4816+
4817+ return s->hardwareRendering();
4818+}
4819+
4820+void surface_texture_client_set_hardware_rendering(SurfaceTextureClientHybris stc, uint8_t hardware_rendering)
4821+{
4822+ REPORT_FUNCTION()
4823+
4824+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4825+ if (s == NULL)
4826+ return;
4827+
4828+ s->setHardwareRendering(static_cast<bool>(hardware_rendering));
4829+}
4830+
4831+void surface_texture_client_get_transformation_matrix(SurfaceTextureClientHybris stc, float *matrix)
4832+{
4833+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4834+ if (s == NULL)
4835+ return;
4836+
4837+ s->surface_texture->getTransformMatrix(static_cast<GLfloat*>(matrix));
4838+}
4839+
4840+void surface_texture_client_update_texture(SurfaceTextureClientHybris stc)
4841+{
4842+ REPORT_FUNCTION()
4843+
4844+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4845+ if (s == NULL)
4846+ return;
4847+
4848+ s->surface_texture->updateTexImage();
4849+}
4850+
4851+void surface_texture_client_destroy(SurfaceTextureClientHybris stc)
4852+{
4853+ REPORT_FUNCTION()
4854+
4855+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4856+ if (s == NULL)
4857+ {
4858+ ALOGE("s == NULL, cannot destroy SurfaceTextureClientHybris instance");
4859+ return;
4860+ }
4861+
4862+ s->refcount = 0;
4863+
4864+ delete s;
4865+}
4866+
4867+void surface_texture_client_ref(SurfaceTextureClientHybris stc)
4868+{
4869+ REPORT_FUNCTION()
4870+
4871+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4872+ if (s == NULL)
4873+ return;
4874+
4875+ s->refcount++;
4876+}
4877+
4878+void surface_texture_client_unref(SurfaceTextureClientHybris stc)
4879+{
4880+ REPORT_FUNCTION()
4881+
4882+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4883+ if (s == NULL)
4884+ {
4885+ ALOGE("s == NULL, cannot unref SurfaceTextureClientHybris instance");
4886+ return;
4887+ }
4888+
4889+ if (s->refcount > 1)
4890+ s->refcount--;
4891+ else
4892+ surface_texture_client_destroy (stc);
4893+}
4894+
4895+void surface_texture_client_set_surface_texture(SurfaceTextureClientHybris stc, EGLNativeWindowType native_window)
4896+{
4897+ _SurfaceTextureClientHybris *s = get_internal_stch(stc, __PRETTY_FUNCTION__);
4898+ if (s == NULL)
4899+ return;
4900+
4901+ if (native_window == NULL)
4902+ {
4903+ ALOGE("native_window must not be NULL");
4904+ return;
4905+ }
4906+
4907+ sp<Surface> surface = static_cast<Surface*>(native_window);
4908+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4909+ s->setISurfaceTexture(surface->getSurfaceTexture());
4910+#else
4911+ s->setISurfaceTexture(surface->getIGraphicBufferProducer());
4912+#endif
4913+}
4914--- /dev/null
4915+++ libhybris-0.1.0+git20131207+e452e83/compat/media/surface_texture_client_hybris_priv.h
4916@@ -0,0 +1,68 @@
4917+/*
4918+ * Copyright (C) 2013 Canonical Ltd
4919+ *
4920+ * Licensed under the Apache License, Version 2.0 (the "License");
4921+ * you may not use this file except in compliance with the License.
4922+ * You may obtain a copy of the License at
4923+ *
4924+ * http://www.apache.org/licenses/LICENSE-2.0
4925+ *
4926+ * Unless required by applicable law or agreed to in writing, software
4927+ * distributed under the License is distributed on an "AS IS" BASIS,
4928+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4929+ * See the License for the specific language governing permissions and
4930+ * limitations under the License.
4931+ *
4932+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
4933+ */
4934+
4935+#include <gui/Surface.h>
4936+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4937+#include <gui/SurfaceTextureClient.h>
4938+#else
4939+#include <gui/GLConsumer.h>
4940+#endif
4941+
4942+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4943+struct _SurfaceTextureClientHybris : public android::SurfaceTextureClient
4944+#else
4945+struct _SurfaceTextureClientHybris : public android::Surface
4946+#endif
4947+{
4948+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4949+ _SurfaceTextureClientHybris();
4950+#endif
4951+ _SurfaceTextureClientHybris(const _SurfaceTextureClientHybris &stch);
4952+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4953+ _SurfaceTextureClientHybris(const android::sp<android::ISurfaceTexture> &st);
4954+#else
4955+ _SurfaceTextureClientHybris(const android::sp<android::BufferQueue> &bq);
4956+#endif
4957+ ~_SurfaceTextureClientHybris();
4958+
4959+ /** Has a texture id or EGLNativeWindowType been passed in, meaning rendering will function? **/
4960+ bool isReady() const;
4961+
4962+public:
4963+ int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
4964+ int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd);
4965+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4966+ void setISurfaceTexture(const android::sp<android::ISurfaceTexture>& surface_texture);
4967+#else
4968+ void setISurfaceTexture(const android::sp<android::IGraphicBufferProducer>& surface_texture);
4969+#endif
4970+ void setHardwareRendering(bool do_hardware_rendering);
4971+ bool hardwareRendering();
4972+
4973+ unsigned int refcount;
4974+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
4975+ android::sp<android::SurfaceTexture> surface_texture;
4976+#else
4977+ android::sp<android::GLConsumer> surface_texture;
4978+#endif
4979+
4980+private:
4981+ bool ready;
4982+ bool hardware_rendering;
4983+};
4984+
4985--- libhybris-0.1.0+git20131207+e452e83.orig/compat/ui/Android.mk
4986+++ libhybris-0.1.0+git20131207+e452e83/compat/ui/Android.mk
4987@@ -1,5 +1,6 @@
4988 LOCAL_PATH:= $(call my-dir)
4989 include $(CLEAR_VARS)
4990+include $(LOCAL_PATH)/../Android.common.mk
4991
4992 HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
4993
4994--- libhybris-0.1.0+git20131207+e452e83.orig/compat/ui/ui_compatibility_layer.cpp
4995+++ libhybris-0.1.0+git20131207+e452e83/compat/ui/ui_compatibility_layer.cpp
4996@@ -126,6 +126,7 @@ void* graphic_buffer_get_native_buffer(s
4997 return buffer->self->getNativeBuffer();
4998 }
4999
5000+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
5001 void graphic_buffer_set_index(struct graphic_buffer *buffer, int index)
5002 {
5003 return buffer->self->setIndex(index);
5004@@ -135,6 +136,7 @@ int graphic_buffer_get_index(struct grap
5005 {
5006 return buffer->self->getIndex();
5007 }
5008+#endif
5009
5010 int graphic_buffer_init_check(struct graphic_buffer *buffer)
5011 {
5012--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/Makefile.am
5013+++ libhybris-0.1.0+git20131207+e452e83/hybris/Makefile.am
5014@@ -4,7 +4,7 @@ if HAS_ANDROID_4_2_0
5015 SUBDIRS += libsync
5016 endif
5017
5018-SUBDIRS += egl glesv1 glesv2 ui sf input camera
5019+SUBDIRS += egl glesv1 glesv2 ui sf input camera media
5020 if HAS_LIBNFC_NXP_HEADERS
5021 SUBDIRS += libnfc_nxp libnfc_ndef_nxp
5022 endif
5023--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/hooks.c
5024+++ libhybris-0.1.0+git20131207+e452e83/hybris/common/hooks.c
5025@@ -27,6 +27,7 @@
5026 #include <stdio_ext.h>
5027 #include <stddef.h>
5028 #include <stdlib.h>
5029+#include <limits.h>
5030 #include <malloc.h>
5031 #include <string.h>
5032 #include <strings.h>
5033@@ -42,6 +43,10 @@
5034 #include <sys/ipc.h>
5035 #include <sys/shm.h>
5036
5037+#include <linux/futex.h>
5038+#include <sys/syscall.h>
5039+#include <sys/time.h>
5040+
5041 #include <netdb.h>
5042 #include <unistd.h>
5043 #include <syslog.h>
5044@@ -64,8 +69,12 @@ static int locale_inited = 0;
5045
5046 #define ANDROID_MUTEX_SHARED_MASK 0x2000
5047 #define ANDROID_COND_SHARED_MASK 0x0001
5048+#define ANDROID_COND_COUNTER_INCREMENT 0x0002
5049+#define ANDROID_COND_COUNTER_MASK (~ANDROID_COND_SHARED_MASK)
5050 #define ANDROID_RWLOCKATTR_SHARED_MASK 0x0010
5051
5052+#define ANDROID_COND_IS_SHARED(c) (((c)->value & ANDROID_COND_SHARED_MASK) != 0)
5053+
5054 /* For the static initializer types */
5055 #define ANDROID_PTHREAD_MUTEX_INITIALIZER 0
5056 #define ANDROID_PTHREAD_RECURSIVE_MUTEX_INITIALIZER 0x4000
5057@@ -87,6 +96,11 @@ struct _hook {
5058 void *func;
5059 };
5060
5061+/* pthread cond struct as done in Android */
5062+typedef struct {
5063+ int volatile value;
5064+} android_cond_t;
5065+
5066 /* Helpers */
5067 static int hybris_check_android_shared_mutex(unsigned int mutex_addr)
5068 {
5069@@ -109,9 +123,59 @@ static int hybris_check_android_shared_c
5070 (cond_addr & ANDROID_COND_SHARED_MASK))
5071 return 1;
5072
5073+ /* In case android is setting up cond_addr with a negative value,
5074+ * used for error control */
5075+ if (cond_addr > HYBRIS_SHM_MASK_TOP)
5076+ return 1;
5077+
5078+ return 0;
5079+}
5080+
5081+/* Based on Android's Bionic pthread implementation.
5082+ * This is just needed when we have a shared cond with Android */
5083+static int __android_pthread_cond_pulse(android_cond_t *cond, int counter)
5084+{
5085+ long flags;
5086+ int fret;
5087+
5088+ if (cond == NULL)
5089+ return EINVAL;
5090+
5091+ flags = (cond->value & ~ANDROID_COND_COUNTER_MASK);
5092+ for (;;) {
5093+ long oldval = cond->value;
5094+ long newval = 0;
5095+ /* In our case all we need to do is make sure the negative value
5096+ * is under our range, which is the last 0xF from SHM_MASK */
5097+ if (oldval < -12)
5098+ newval = ((oldval + ANDROID_COND_COUNTER_INCREMENT) &
5099+ ANDROID_COND_COUNTER_MASK) | flags;
5100+ else
5101+ newval = ((oldval - ANDROID_COND_COUNTER_INCREMENT) &
5102+ ANDROID_COND_COUNTER_MASK) | flags;
5103+ if (__sync_bool_compare_and_swap(&cond->value, oldval, newval))
5104+ break;
5105+ }
5106+
5107+ int pshared = cond->value & ANDROID_COND_SHARED_MASK;
5108+ fret = syscall(SYS_futex , &cond->value,
5109+ pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, counter,
5110+ NULL, NULL, NULL);
5111+ LOGD("futex based pthread_cond_*, value %d, counter %d, ret %d",
5112+ cond->value, counter, fret);
5113 return 0;
5114 }
5115
5116+int android_pthread_cond_broadcast(android_cond_t *cond)
5117+{
5118+ return __android_pthread_cond_pulse(cond, INT_MAX);
5119+}
5120+
5121+int android_pthread_cond_signal(android_cond_t *cond)
5122+{
5123+ return __android_pthread_cond_pulse(cond, 1);
5124+}
5125+
5126 static void hybris_set_mutex_attr(unsigned int android_value, pthread_mutexattr_t *attr)
5127 {
5128 /* Init already sets as PTHREAD_MUTEX_NORMAL */
5129@@ -577,8 +641,8 @@ static int my_pthread_cond_broadcast(pth
5130 {
5131 unsigned int value = (*(unsigned int *) cond);
5132 if (hybris_check_android_shared_cond(value)) {
5133- LOGD("shared condition with Android, not broadcasting.");
5134- return 0;
5135+ LOGD("Shared condition with Android, broadcasting with futex.");
5136+ return android_pthread_cond_broadcast((android_cond_t *) cond);
5137 }
5138
5139 pthread_cond_t *realcond = (pthread_cond_t *) value;
5140@@ -598,8 +662,8 @@ static int my_pthread_cond_signal(pthrea
5141 unsigned int value = (*(unsigned int *) cond);
5142
5143 if (hybris_check_android_shared_cond(value)) {
5144- LOGD("Shared condition with Android, not signaling.");
5145- return 0;
5146+ LOGD("Shared condition with Android, broadcasting with futex.");
5147+ return android_pthread_cond_signal((android_cond_t *) cond);
5148 }
5149
5150 pthread_cond_t *realcond = (pthread_cond_t *) value;
5151@@ -1217,6 +1281,56 @@ FP_ATTRIB static double my_strtod(const
5152 return strtod_l(nptr, endptr, hybris_locale);
5153 }
5154
5155+static int __my_system_property_read(const void *pi, char *name, char *value)
5156+{
5157+ return property_get(name, value, NULL);
5158+}
5159+
5160+static int __my_system_property_get(const char *name, char *value)
5161+{
5162+ return property_get(name, value, NULL);
5163+}
5164+
5165+static int __my_system_property_foreach(void (*propfn)(const void *pi, void *cookie), void *cookie)
5166+{
5167+ return 0;
5168+}
5169+
5170+static const void *__my_system_property_find(const char *name)
5171+{
5172+ return NULL;
5173+}
5174+
5175+static unsigned int __my_system_property_serial(const void *pi)
5176+{
5177+ return 0;
5178+}
5179+
5180+static int __my_system_property_wait(const void *pi)
5181+{
5182+ return 0;
5183+}
5184+
5185+static int __my_system_property_update(void *pi, const char *value, unsigned int len)
5186+{
5187+ return 0;
5188+}
5189+
5190+static int __my_system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen)
5191+{
5192+ return 0;
5193+}
5194+
5195+static unsigned int __my_system_property_wait_any(unsigned int serial)
5196+{
5197+ return 0;
5198+}
5199+
5200+static const void *__my_system_property_find_nth(unsigned n)
5201+{
5202+ return NULL;
5203+}
5204+
5205 extern int __cxa_atexit(void (*)(void*), void*, void*);
5206
5207 static struct _hook hooks[] = {
5208@@ -1449,6 +1563,17 @@ static struct _hook hooks[] = {
5209 /* grp.h */
5210 {"getgrgid", getgrgid},
5211 {"__cxa_atexit", __cxa_atexit},
5212+ {"__system_property_read", __my_system_property_read},
5213+ {"__system_property_get", __my_system_property_get},
5214+ {"__system_property_set", property_set},
5215+ {"__system_property_foreach", __my_system_property_foreach},
5216+ {"__system_property_find", __my_system_property_find},
5217+ {"__system_property_serial", __my_system_property_serial},
5218+ {"__system_property_wait", __my_system_property_wait},
5219+ {"__system_property_update", __my_system_property_update},
5220+ {"__system_property_add", __my_system_property_add},
5221+ {"__system_property_wait_any", __my_system_property_wait_any},
5222+ {"__system_property_find_nth", __my_system_property_find_nth},
5223 {NULL, NULL},
5224 };
5225
5226--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/hooks_shm.c
5227+++ libhybris-0.1.0+git20131207+e452e83/hybris/common/hooks_shm.c
5228@@ -123,7 +123,9 @@ static void _hybris_shm_init()
5229 else {
5230 LOGD("Creating a new shared memory segment.");
5231
5232- _hybris_shm_fd = shm_open(HYBRIS_SHM_PATH, O_RDWR | O_CREAT, 0660);
5233+ mode_t pumask = umask(0);
5234+ _hybris_shm_fd = shm_open(HYBRIS_SHM_PATH, O_RDWR | O_CREAT, 0666);
5235+ umask(pumask);
5236 if (_hybris_shm_fd >= 0) {
5237 ftruncate( _hybris_shm_fd, size_to_map );
5238 /* Map the memory object */
5239@@ -171,11 +173,12 @@ static void _hybris_shm_extend_region()
5240
5241 /*
5242 * Determine if the pointer that has been extracted by hybris is
5243- * pointing to an address in the shared memory
5244+ * pointing to an address in the shared memory.
5245 */
5246 int hybris_is_pointer_in_shm(void *ptr)
5247 {
5248- if ((unsigned int)ptr >= HYBRIS_SHM_MASK)
5249+ if (((unsigned int) ptr >= HYBRIS_SHM_MASK) &&
5250+ ((unsigned int) ptr <= HYBRIS_SHM_MASK_TOP))
5251 return 1;
5252
5253 return 0;
5254--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/hooks_shm.h
5255+++ libhybris-0.1.0+git20131207+e452e83/hybris/common/hooks_shm.h
5256@@ -20,6 +20,9 @@
5257
5258 #include <stddef.h>
5259
5260+/* Leave space to workaround the issue that Android might pass negative int values */
5261+#define HYBRIS_SHM_MASK_TOP 0xFFFFFFF0UL
5262+
5263 typedef unsigned int hybris_shm_pointer_t;
5264
5265 /*
5266--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/dlfcn.c
5267+++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/dlfcn.c
5268@@ -78,7 +78,7 @@ const char *android_dlerror(void)
5269 void *android_dlsym(void *handle, const char *symbol)
5270 {
5271 soinfo *found;
5272- Elf32_Sym *sym;
5273+ Elf_Sym *sym;
5274 unsigned bind;
5275
5276 pthread_mutex_lock(&dl_lock);
5277@@ -142,7 +142,7 @@ int android_dladdr(const void *addr, Dl_
5278 info->dli_fbase = (void*)si->base;
5279
5280 /* Determine if any symbol in the library contains the specified address */
5281- Elf32_Sym *sym = find_containing_symbol(addr, si);
5282+ Elf_Sym *sym = find_containing_symbol(addr, si);
5283
5284 if(sym != NULL) {
5285 info->dli_sname = si->strtab + sym->st_name;
5286@@ -192,7 +192,7 @@ int android_dl_iterate_phdr(int (*cb)(st
5287 #endif
5288
5289
5290-static Elf32_Sym libdl_symtab[] = {
5291+static Elf_Sym libdl_symtab[] = {
5292 // total length of libdl_info.strtab, including trailing 0
5293 // This is actually the the STH_UNDEF entry. Technically, it's
5294 // supposed to have st_name == 0, but instead, it points to an index
5295@@ -200,45 +200,45 @@ static Elf32_Sym libdl_symtab[] = {
5296 { st_name: sizeof(ANDROID_LIBDL_STRTAB) - 1,
5297 },
5298 { st_name: 0, // starting index of the name in libdl_info.strtab
5299- st_value: (Elf32_Addr) &android_dlopen,
5300+ st_value: (Elf_Addr) &android_dlopen,
5301 st_info: STB_GLOBAL << 4,
5302 st_shndx: 1,
5303 },
5304 { st_name: 7,
5305- st_value: (Elf32_Addr) &android_dlclose,
5306+ st_value: (Elf_Addr) &android_dlclose,
5307 st_info: STB_GLOBAL << 4,
5308 st_shndx: 1,
5309 },
5310 { st_name: 15,
5311- st_value: (Elf32_Addr) &android_dlsym,
5312+ st_value: (Elf_Addr) &android_dlsym,
5313 st_info: STB_GLOBAL << 4,
5314 st_shndx: 1,
5315 },
5316 { st_name: 21,
5317- st_value: (Elf32_Addr) &android_dlerror,
5318+ st_value: (Elf_Addr) &android_dlerror,
5319 st_info: STB_GLOBAL << 4,
5320 st_shndx: 1,
5321 },
5322 { st_name: 29,
5323- st_value: (Elf32_Addr) &android_dladdr,
5324+ st_value: (Elf_Addr) &android_dladdr,
5325 st_info: STB_GLOBAL << 4,
5326 st_shndx: 1,
5327 },
5328 #ifdef ANDROID_ARM_LINKER
5329 { st_name: 36,
5330- st_value: (Elf32_Addr) &android_dl_unwind_find_exidx,
5331+ st_value: (Elf_Addr) &android_dl_unwind_find_exidx,
5332 st_info: STB_GLOBAL << 4,
5333 st_shndx: 1,
5334 },
5335 #elif defined(ANDROID_X86_LINKER)
5336 { st_name: 36,
5337- st_value: (Elf32_Addr) &android_dl_iterate_phdr,
5338+ st_value: (Elf_Addr) &android_dl_iterate_phdr,
5339 st_info: STB_GLOBAL << 4,
5340 st_shndx: 1,
5341 },
5342 #elif defined(ANDROID_SH_LINKER)
5343 { st_name: 36,
5344- st_value: (Elf32_Addr) &android_dl_iterate_phdr,
5345+ st_value: (Elf_Addr) &android_dl_iterate_phdr,
5346 st_info: STB_GLOBAL << 4,
5347 st_shndx: 1,
5348 },
5349--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/linker.c
5350+++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/linker.c
5351@@ -381,10 +381,10 @@ android_dl_iterate_phdr(int (*cb)(struct
5352 }
5353 #endif
5354
5355-static Elf32_Sym *_elf_lookup(soinfo *si, unsigned hash, const char *name)
5356+static Elf_Sym *_elf_lookup(soinfo *si, unsigned hash, const char *name)
5357 {
5358- Elf32_Sym *s;
5359- Elf32_Sym *symtab = si->symtab;
5360+ Elf_Sym *s;
5361+ Elf_Sym *symtab = si->symtab;
5362 const char *strtab = si->strtab;
5363 unsigned n;
5364
5365@@ -426,11 +426,11 @@ static unsigned elfhash(const char *_nam
5366 return h;
5367 }
5368
5369-static Elf32_Sym *
5370+static Elf_Sym *
5371 _do_lookup(soinfo *si, const char *name, unsigned *base)
5372 {
5373 unsigned elf_hash = elfhash(name);
5374- Elf32_Sym *s;
5375+ Elf_Sym *s;
5376 unsigned *d;
5377 soinfo *lsi = si;
5378 int i;
5379@@ -502,17 +502,17 @@ done:
5380 /* This is used by dl_sym(). It performs symbol lookup only within the
5381 specified soinfo object and not in any of its dependencies.
5382 */
5383-Elf32_Sym *lookup_in_library(soinfo *si, const char *name)
5384+Elf_Sym *lookup_in_library(soinfo *si, const char *name)
5385 {
5386 return _elf_lookup(si, elfhash(name), name);
5387 }
5388
5389 /* This is used by dl_sym(). It performs a global symbol lookup.
5390 */
5391-Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start)
5392+Elf_Sym *lookup(const char *name, soinfo **found, soinfo *start)
5393 {
5394 unsigned elf_hash = elfhash(name);
5395- Elf32_Sym *s = NULL;
5396+ Elf_Sym *s = NULL;
5397 soinfo *si;
5398
5399 if(start == NULL) {
5400@@ -553,7 +553,7 @@ soinfo *find_containing_library(const vo
5401 return NULL;
5402 }
5403
5404-Elf32_Sym *find_containing_symbol(const void *addr, soinfo *si)
5405+Elf_Sym *find_containing_symbol(const void *addr, soinfo *si)
5406 {
5407 unsigned int i;
5408 unsigned soaddr = (unsigned)addr - si->base;
5409@@ -561,7 +561,7 @@ Elf32_Sym *find_containing_symbol(const
5410 /* Search the library's symbol table for any defined symbol which
5411 * contains this address */
5412 for(i=0; i<si->nchain; i++) {
5413- Elf32_Sym *sym = &si->symtab[i];
5414+ Elf_Sym *sym = &si->symtab[i];
5415
5416 if(sym->st_shndx != SHN_UNDEF &&
5417 soaddr >= sym->st_value &&
5418@@ -576,7 +576,7 @@ Elf32_Sym *find_containing_symbol(const
5419 #if 0
5420 static void dump(soinfo *si)
5421 {
5422- Elf32_Sym *s = si->symtab;
5423+ Elf_Sym *s = si->symtab;
5424 unsigned n;
5425
5426 for(n = 0; n < si->nchain; n++) {
5427@@ -705,7 +705,7 @@ is_prelinked(int fd, const char *name)
5428 static int
5429 verify_elf_object(void *base, const char *name)
5430 {
5431- Elf32_Ehdr *hdr = (Elf32_Ehdr *) base;
5432+ Elf_Ehdr *hdr = (Elf_Ehdr *) base;
5433
5434 if (hdr->e_ident[EI_MAG0] != ELFMAG0) return -1;
5435 if (hdr->e_ident[EI_MAG1] != ELFMAG1) return -1;
5436@@ -750,8 +750,8 @@ get_lib_extents(int fd, const char *name
5437 unsigned min_vaddr = 0xffffffff;
5438 unsigned max_vaddr = 0;
5439 unsigned char *_hdr = (unsigned char *)__hdr;
5440- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)_hdr;
5441- Elf32_Phdr *phdr;
5442+ Elf_Ehdr *ehdr = (Elf_Ehdr *)_hdr;
5443+ Elf_Phdr *phdr;
5444 int cnt;
5445
5446 TRACE("[ %5d Computing extents for '%s'. ]\n", pid, name);
5447@@ -770,7 +770,7 @@ get_lib_extents(int fd, const char *name
5448 TRACE("[ %5d - Non-prelinked library '%s' found. ]\n", pid, name);
5449 }
5450
5451- phdr = (Elf32_Phdr *)(_hdr + ehdr->e_phoff);
5452+ phdr = (Elf_Phdr *)(_hdr + ehdr->e_phoff);
5453
5454 /* find the min/max p_vaddrs from all the PT_LOAD segments so we can
5455 * get the range. */
5456@@ -885,12 +885,12 @@ err:
5457 static int
5458 load_segments(int fd, void *header, soinfo *si)
5459 {
5460- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)header;
5461- Elf32_Phdr *phdr = (Elf32_Phdr *)((unsigned char *)header + ehdr->e_phoff);
5462- Elf32_Addr base = (Elf32_Addr) si->base;
5463+ Elf_Ehdr *ehdr = (Elf_Ehdr *)header;
5464+ Elf_Phdr *phdr = (Elf_Phdr *)((unsigned char *)header + ehdr->e_phoff);
5465+ Elf_Addr base = (Elf_Addr) si->base;
5466 int cnt;
5467 unsigned len;
5468- Elf32_Addr tmp;
5469+ Elf_Addr tmp;
5470 unsigned char *pbase;
5471 unsigned char *extra_base;
5472 unsigned extra_len;
5473@@ -956,7 +956,7 @@ load_segments(int fd, void *header, soin
5474 * | |
5475 * _+---------------------+ page boundary
5476 */
5477- tmp = (Elf32_Addr)(((unsigned)pbase + len + PAGE_SIZE - 1) &
5478+ tmp = (Elf_Addr)(((unsigned)pbase + len + PAGE_SIZE - 1) &
5479 (~PAGE_MASK));
5480 if (tmp < (base + phdr->p_vaddr + phdr->p_memsz)) {
5481 extra_len = base + phdr->p_vaddr + phdr->p_memsz - tmp;
5482@@ -1020,7 +1020,7 @@ load_segments(int fd, void *header, soin
5483 phdr->p_vaddr, phdr->p_memsz);
5484 goto fail;
5485 }
5486- si->gnu_relro_start = (Elf32_Addr) (base + phdr->p_vaddr);
5487+ si->gnu_relro_start = (Elf_Addr) (base + phdr->p_vaddr);
5488 si->gnu_relro_len = (unsigned) phdr->p_memsz;
5489 } else {
5490 #ifdef ANDROID_ARM_LINKER
5491@@ -1067,11 +1067,11 @@ fail:
5492 */
5493 #if 0
5494 static unsigned
5495-get_wr_offset(int fd, const char *name, Elf32_Ehdr *ehdr)
5496+get_wr_offset(int fd, const char *name, Elf_Ehdr *ehdr)
5497 {
5498- Elf32_Shdr *shdr_start;
5499- Elf32_Shdr *shdr;
5500- int shdr_sz = ehdr->e_shnum * sizeof(Elf32_Shdr);
5501+ Elf_Shdr *shdr_start;
5502+ Elf_Shdr *shdr;
5503+ int shdr_sz = ehdr->e_shnum * sizeof(Elf_Shdr);
5504 int cnt;
5505 unsigned wr_offset = 0xffffffff;
5506
5507@@ -1104,7 +1104,7 @@ load_library(const char *name)
5508 unsigned req_base;
5509 const char *bname;
5510 soinfo *si = NULL;
5511- Elf32_Ehdr *hdr;
5512+ Elf_Ehdr *hdr;
5513
5514 if(fd == -1) {
5515 DL_ERR("Library '%s' not found", name);
5516@@ -1161,8 +1161,8 @@ load_library(const char *name)
5517
5518 /* this might not be right. Technically, we don't even need this info
5519 * once we go through 'load_segments'. */
5520- hdr = (Elf32_Ehdr *)si->base;
5521- si->phdr = (Elf32_Phdr *)((unsigned char *)si->base + hdr->e_phoff);
5522+ hdr = (Elf_Ehdr *)si->base;
5523+ si->phdr = (Elf_Phdr *)((unsigned char *)si->base + hdr->e_phoff);
5524 si->phnum = hdr->e_phnum;
5525 /**/
5526
5527@@ -1261,7 +1261,7 @@ unsigned unload_library(soinfo *si)
5528 * in link_image. This is needed to undo the DT_NEEDED hack below.
5529 */
5530 if ((si->gnu_relro_start != 0) && (si->gnu_relro_len != 0)) {
5531- Elf32_Addr start = (si->gnu_relro_start & ~PAGE_MASK);
5532+ Elf_Addr start = (si->gnu_relro_start & ~PAGE_MASK);
5533 unsigned len = (si->gnu_relro_start - start) + si->gnu_relro_len;
5534 if (mprotect((void *) start, len, PROT_READ | PROT_WRITE) < 0)
5535 DL_ERR("%5d %s: could not undo GNU_RELRO protections. "
5536@@ -1304,16 +1304,16 @@ unsigned unload_library(soinfo *si)
5537 }
5538
5539 /* TODO: don't use unsigned for addrs below. It works, but is not
5540- * ideal. They should probably be either uint32_t, Elf32_Addr, or unsigned
5541+ * ideal. They should probably be either uint32_t, Elf_Addr, or unsigned
5542 * long.
5543 */
5544-static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
5545+static int reloc_library(soinfo *si, Elf_Rel *rel, unsigned count)
5546 {
5547- Elf32_Sym *symtab = si->symtab;
5548+ Elf_Sym *symtab = si->symtab;
5549 const char *strtab = si->strtab;
5550- Elf32_Sym *s;
5551+ Elf_Sym *s;
5552 unsigned base;
5553- Elf32_Rel *start = rel;
5554+ Elf_Rel *start = rel;
5555 unsigned idx;
5556
5557 for (idx = 0; idx < count; ++idx) {
5558@@ -1712,7 +1712,7 @@ static int nullify_closed_stdio (void)
5559 static int link_image(soinfo *si, unsigned wr_offset)
5560 {
5561 unsigned *d;
5562- Elf32_Phdr *phdr = si->phdr;
5563+ Elf_Phdr *phdr = si->phdr;
5564 int phnum = si->phnum;
5565
5566 INFO("[ %5d linking %s ]\n", pid, si->name);
5567@@ -1795,7 +1795,7 @@ static int link_image(soinfo *si, unsign
5568 phdr->p_vaddr, phdr->p_memsz);
5569 goto fail;
5570 }
5571- si->gnu_relro_start = (Elf32_Addr) (si->base + phdr->p_vaddr);
5572+ si->gnu_relro_start = (Elf_Addr) (si->base + phdr->p_vaddr);
5573 si->gnu_relro_len = (unsigned) phdr->p_memsz;
5574 }
5575 }
5576@@ -1822,7 +1822,7 @@ static int link_image(soinfo *si, unsign
5577 si->strtab = (const char *) (si->base + *d);
5578 break;
5579 case DT_SYMTAB:
5580- si->symtab = (Elf32_Sym *) (si->base + *d);
5581+ si->symtab = (Elf_Sym *) (si->base + *d);
5582 break;
5583 case DT_PLTREL:
5584 if(*d != DT_REL) {
5585@@ -1831,13 +1831,13 @@ static int link_image(soinfo *si, unsign
5586 }
5587 break;
5588 case DT_JMPREL:
5589- si->plt_rel = (Elf32_Rel*) (si->base + *d);
5590+ si->plt_rel = (Elf_Rel*) (si->base + *d);
5591 break;
5592 case DT_PLTRELSZ:
5593 si->plt_rel_count = *d / 8;
5594 break;
5595 case DT_REL:
5596- si->rel = (Elf32_Rel*) (si->base + *d);
5597+ si->rel = (Elf_Rel*) (si->base + *d);
5598 break;
5599 case DT_RELSZ:
5600 si->rel_count = *d / 8;
5601@@ -1869,7 +1869,7 @@ static int link_image(soinfo *si, unsign
5602 pid, si->name, si->init_array);
5603 break;
5604 case DT_INIT_ARRAYSZ:
5605- si->init_array_count = ((unsigned)*d) / sizeof(Elf32_Addr);
5606+ si->init_array_count = ((unsigned)*d) / sizeof(Elf_Addr);
5607 break;
5608 case DT_FINI_ARRAY:
5609 si->fini_array = (unsigned *)(si->base + *d);
5610@@ -1877,7 +1877,7 @@ static int link_image(soinfo *si, unsign
5611 pid, si->name, si->fini_array);
5612 break;
5613 case DT_FINI_ARRAYSZ:
5614- si->fini_array_count = ((unsigned)*d) / sizeof(Elf32_Addr);
5615+ si->fini_array_count = ((unsigned)*d) / sizeof(Elf_Addr);
5616 break;
5617 case DT_PREINIT_ARRAY:
5618 si->preinit_array = (unsigned *)(si->base + *d);
5619@@ -1885,7 +1885,7 @@ static int link_image(soinfo *si, unsign
5620 pid, si->name, si->preinit_array);
5621 break;
5622 case DT_PREINIT_ARRAYSZ:
5623- si->preinit_array_count = ((unsigned)*d) / sizeof(Elf32_Addr);
5624+ si->preinit_array_count = ((unsigned)*d) / sizeof(Elf_Addr);
5625 break;
5626 case DT_TEXTREL:
5627 /* TODO: make use of this. */
5628@@ -1987,7 +1987,7 @@ static int link_image(soinfo *si, unsign
5629 #endif
5630
5631 if (si->gnu_relro_start != 0 && si->gnu_relro_len != 0) {
5632- Elf32_Addr start = (si->gnu_relro_start & ~PAGE_MASK);
5633+ Elf_Addr start = (si->gnu_relro_start & ~PAGE_MASK);
5634 unsigned len = (si->gnu_relro_start - start) + si->gnu_relro_len;
5635 if (mprotect((void *) start, len, PROT_READ) < 0) {
5636 DL_ERR("%5d GNU_RELRO mprotect of library '%s' failed: %d (%s)\n",
5637@@ -2170,7 +2170,7 @@ sanitize:
5638 while(vecs[0] != 0){
5639 switch(vecs[0]){
5640 case AT_PHDR:
5641- si->phdr = (Elf32_Phdr*) vecs[1];
5642+ si->phdr = (Elf_Phdr*) vecs[1];
5643 break;
5644 case AT_PHNUM:
5645 si->phnum = (int) vecs[1];
5646@@ -2190,7 +2190,7 @@ sanitize:
5647 si->base = 0;
5648 for ( nn = 0; nn < si->phnum; nn++ ) {
5649 if (si->phdr[nn].p_type == PT_PHDR) {
5650- si->base = (Elf32_Addr) si->phdr - si->phdr[nn].p_vaddr;
5651+ si->base = (Elf_Addr) si->phdr - si->phdr[nn].p_vaddr;
5652 break;
5653 }
5654 }
5655@@ -2303,9 +2303,9 @@ static unsigned find_linker_base(unsigne
5656 */
5657 unsigned __linker_init(unsigned **elfdata) {
5658 unsigned linker_addr = find_linker_base(elfdata);
5659- Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) linker_addr;
5660- Elf32_Phdr *phdr =
5661- (Elf32_Phdr *)((unsigned char *) linker_addr + elf_hdr->e_phoff);
5662+ Elf_Ehdr *elf_hdr = (Elf_Ehdr *) linker_addr;
5663+ Elf_Phdr *phdr =
5664+ (Elf_Phdr *)((unsigned char *) linker_addr + elf_hdr->e_phoff);
5665
5666 soinfo linker_so;
5667 memset(&linker_so, 0, sizeof(soinfo));
5668--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/linker.h
5669+++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/linker.h
5670@@ -38,6 +38,26 @@
5671 #define PAGE_SIZE 4096
5672 #define PAGE_MASK 4095
5673
5674+#if defined(__x86_64__)
5675+typedef Elf64_Ehdr Elf_Ehdr;
5676+typedef Elf64_Shdr Elf_Shdr;
5677+typedef Elf64_Sym Elf_Sym;
5678+typedef Elf64_Addr Elf_Addr;
5679+typedef Elf64_Phdr Elf_Phdr;
5680+typedef Elf64_Half Elf_Half;
5681+typedef Elf64_Rel Elf_Rel;
5682+typedef Elf64_Rela Elf_Rela;
5683+#else
5684+typedef Elf32_Ehdr Elf_Ehdr;
5685+typedef Elf32_Shdr Elf_Shdr;
5686+typedef Elf32_Sym Elf_Sym;
5687+typedef Elf32_Addr Elf_Addr;
5688+typedef Elf32_Phdr Elf_Phdr;
5689+typedef Elf32_Half Elf_Half;
5690+typedef Elf32_Rel Elf_Rel;
5691+typedef Elf32_Rela Elf_Rela;
5692+#endif
5693+
5694 void debugger_init();
5695 const char *addr_to_name(unsigned addr);
5696
5697@@ -55,10 +75,10 @@ struct link_map
5698 /* needed for dl_iterate_phdr to be passed to the callbacks provided */
5699 struct dl_phdr_info
5700 {
5701- Elf32_Addr dlpi_addr;
5702+ Elf_Addr dlpi_addr;
5703 const char *dlpi_name;
5704- const Elf32_Phdr *dlpi_phdr;
5705- Elf32_Half dlpi_phnum;
5706+ const Elf_Phdr *dlpi_phdr;
5707+ Elf_Half dlpi_phnum;
5708 };
5709
5710
5711@@ -90,7 +110,7 @@ typedef struct soinfo soinfo;
5712 struct soinfo
5713 {
5714 const char name[SOINFO_NAME_LEN];
5715- Elf32_Phdr *phdr;
5716+ Elf_Phdr *phdr;
5717 int phnum;
5718 unsigned entry;
5719 unsigned base;
5720@@ -107,7 +127,7 @@ struct soinfo
5721 unsigned flags;
5722
5723 const char *strtab;
5724- Elf32_Sym *symtab;
5725+ Elf_Sym *symtab;
5726
5727 unsigned nbucket;
5728 unsigned nchain;
5729@@ -116,10 +136,10 @@ struct soinfo
5730
5731 unsigned *plt_got;
5732
5733- Elf32_Rel *plt_rel;
5734+ Elf_Rel *plt_rel;
5735 unsigned plt_rel_count;
5736
5737- Elf32_Rel *rel;
5738+ Elf_Rel *rel;
5739 unsigned rel_count;
5740
5741 unsigned *preinit_array;
5742@@ -144,7 +164,7 @@ struct soinfo
5743
5744 int constructors_called;
5745
5746- Elf32_Addr gnu_relro_start;
5747+ Elf_Addr gnu_relro_start;
5748 unsigned gnu_relro_len;
5749
5750 };
5751@@ -202,10 +222,10 @@ extern soinfo libdl_info;
5752
5753 soinfo *find_library(const char *name);
5754 unsigned unload_library(soinfo *si);
5755-Elf32_Sym *lookup_in_library(soinfo *si, const char *name);
5756-Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start);
5757+Elf_Sym *lookup_in_library(soinfo *si, const char *name);
5758+Elf_Sym *lookup(const char *name, soinfo **found, soinfo *start);
5759 soinfo *find_containing_library(const void *addr);
5760-Elf32_Sym *find_containing_symbol(const void *addr, soinfo *si);
5761+Elf_Sym *find_containing_symbol(const void *addr, soinfo *si);
5762 const char *linker_get_error(void);
5763 void call_constructors_recursive(soinfo *si);
5764
5765--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/common/jb/linker_format.c
5766+++ libhybris-0.1.0+git20131207+e452e83/hybris/common/jb/linker_format.c
5767@@ -268,7 +268,7 @@ static int log_vprint(int prio, const ch
5768 result = vformat_buffer(buf, sizeof buf, fmt, args);
5769
5770 if (log_fd < 0) {
5771- log_fd = open("/dev/log/main", O_WRONLY);
5772+ log_fd = open("/dev/alog/main", O_WRONLY);
5773 if (log_fd < 0) {
5774 log_fd = fileno(stdout); // kernel doesn't have android log
5775 return result;
5776--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/configure.ac
5777+++ libhybris-0.1.0+git20131207+e452e83/hybris/configure.ac
5778@@ -184,6 +184,8 @@ AC_CONFIG_FILES([
5779 input/libis.pc
5780 camera/Makefile
5781 camera/libcamera.pc
5782+ media/Makefile
5783+ media/libmedia.pc
5784 include/Makefile
5785 utils/Makefile
5786 tests/Makefile
5787--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/hardware/hardware.c
5788+++ libhybris-0.1.0+git20131207+e452e83/hybris/hardware/hardware.c
5789@@ -17,6 +17,7 @@
5790
5791 #include <dlfcn.h>
5792 #include <stddef.h>
5793+#include <errno.h>
5794 #include <android/hardware/hardware.h>
5795 #include <hybris/internal/binding.h>
5796
5797@@ -26,15 +27,20 @@ static int (*_hw_get_module)(const char
5798
5799 static int (*_hw_get_module_by_class)(const char *class_id, const char *inst, const struct hw_module_t **module) = NULL;
5800
5801-#define HARDWARE_DLSYM(fptr, sym) do { if (_libhardware == NULL) { _init_lib_hardware(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libhardware, sym); } } while (0)
5802+#define HARDWARE_DLSYM(fptr, sym) do { if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libhardware, sym); } } while (0)
5803
5804-static void _init_lib_hardware()
5805+static void *_init_lib_hardware()
5806 {
5807- _libhardware = (void *) android_dlopen("/system/lib/libhardware.so", RTLD_LAZY);
5808+ if (!_libhardware)
5809+ _libhardware = (void *) android_dlopen("/system/lib/libhardware.so", RTLD_LAZY);
5810+ return _libhardware;
5811 }
5812
5813 int hw_get_module(const char *id, const struct hw_module_t **module)
5814 {
5815+ if (!_init_lib_hardware())
5816+ return -EINVAL;
5817+
5818 HARDWARE_DLSYM(&_hw_get_module, "hw_get_module");
5819 return (*_hw_get_module)(id, module);
5820 }
5821@@ -42,6 +48,9 @@ int hw_get_module(const char *id, const
5822 int hw_get_module_by_class(const char *class_id, const char *inst,
5823 const struct hw_module_t **module)
5824 {
5825+ if (!_init_lib_hardware())
5826+ return -EINVAL;
5827+
5828 HARDWARE_DLSYM(&_hw_get_module_by_class, "hw_get_module_by_class");
5829 return (*_hw_get_module_by_class)(class_id, inst, module);
5830 }
5831--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/Makefile.am
5832+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/Makefile.am
5833@@ -65,6 +65,15 @@ propertiesincludedir = $(includedir)/hyb
5834 propertiesinclude_HEADERS = \
5835 hybris/properties/properties.h
5836
5837+mediaincludedir = $(includedir)/hybris/media
5838+mediainclude_HEADERS = \
5839+ hybris/media/media_compatibility_layer.h \
5840+ hybris/media/media_codec_layer.h \
5841+ hybris/media/media_codec_list.h \
5842+ hybris/media/media_format_layer.h \
5843+ hybris/media/surface_texture_client_hybris.h \
5844+ hybris/media/recorder_compatibility_layer.h
5845+
5846 dlfcnincludedir = $(includedir)/hybris/dlfcn
5847 dlfcninclude_HEADERS = \
5848 hybris/dlfcn/dlfcn.h
5849--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/input/input_stack_compatibility_layer.h
5850+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/input/input_stack_compatibility_layer.h
5851@@ -109,6 +109,7 @@ extern "C" {
5852 int input_area_height;
5853 };
5854
5855+ int android_input_check_availability();
5856 void android_input_stack_initialize(
5857 struct AndroidEventListener* listener,
5858 struct InputStackConfiguration* input_stack_configuration);
5859--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/internal/camera_control.h
5860+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/internal/camera_control.h
5861@@ -19,7 +19,11 @@
5862
5863 #include <camera/Camera.h>
5864 #include <camera/CameraParameters.h>
5865+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
5866 #include <gui/SurfaceTexture.h>
5867+#else
5868+#include <gui/GLConsumer.h>
5869+#endif
5870
5871 #include <stdint.h>
5872 #include <unistd.h>
5873@@ -31,15 +35,22 @@ extern "C" {
5874 struct CameraControlListener;
5875
5876 struct CameraControl : public android::CameraListener,
5877+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
5878 public android::SurfaceTexture::FrameAvailableListener
5879+#else
5880+ public android::GLConsumer::FrameAvailableListener
5881+#endif
5882 {
5883 android::Mutex guard;
5884 CameraControlListener* listener;
5885 android::sp<android::Camera> camera;
5886 android::CameraParameters camera_parameters;
5887+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
5888 android::sp<android::SurfaceTexture> preview_texture;
5889-
5890- // From android::SurfaceTexture::FrameAvailableListener
5891+#else
5892+ android::sp<android::GLConsumer> preview_texture;
5893+#endif
5894+ // From android::SurfaceTexture/GLConsumer::FrameAvailableListener
5895 void onFrameAvailable();
5896
5897 // From android::CameraListener
5898--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/internal/surface_flinger_compatibility_layer_internal.h
5899+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/internal/surface_flinger_compatibility_layer_internal.h
5900@@ -25,6 +25,7 @@
5901
5902 #include <utils/misc.h>
5903
5904+#include <gui/Surface.h>
5905 #include <gui/SurfaceComposerClient.h>
5906 #include <ui/PixelFormat.h>
5907 #include <ui/Region.h>
5908--- /dev/null
5909+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_codec_layer.h
5910@@ -0,0 +1,93 @@
5911+/*
5912+ * Copyright (C) 2013 Canonical Ltd
5913+ *
5914+ * Licensed under the Apache License, Version 2.0 (the "License");
5915+ * you may not use this file except in compliance with the License.
5916+ * You may obtain a copy of the License at
5917+ *
5918+ * http://www.apache.org/licenses/LICENSE-2.0
5919+ *
5920+ * Unless required by applicable law or agreed to in writing, software
5921+ * distributed under the License is distributed on an "AS IS" BASIS,
5922+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5923+ * See the License for the specific language governing permissions and
5924+ * limitations under the License.
5925+ *
5926+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
5927+ */
5928+
5929+#ifndef MEDIA_CODEC_LAYER_H_
5930+#define MEDIA_CODEC_LAYER_H_
5931+
5932+#include <stdint.h>
5933+#include <unistd.h>
5934+
5935+#ifdef SIMPLE_PLAYER
5936+#include <media/stagefright/MediaCodec.h>
5937+#endif
5938+
5939+#include <hybris/media/media_format_layer.h>
5940+#include <hybris/media/surface_texture_client_hybris.h>
5941+
5942+#ifdef __cplusplus
5943+extern "C" {
5944+#endif
5945+
5946+ typedef void* MediaCodecDelegate;
5947+
5948+ typedef void (*on_texture_needs_update)(void *context);
5949+ void media_codec_set_texture_needs_update_cb(MediaCodecDelegate delegate, on_texture_needs_update cb, void *context);
5950+
5951+ MediaCodecDelegate media_codec_create_by_codec_name(const char *name);
5952+ MediaCodecDelegate media_codec_create_by_codec_type(const char *type);
5953+
5954+#ifdef SIMPLE_PLAYER
5955+ android::MediaCodec* media_codec_get(MediaCodecDelegate delegate);
5956+#endif
5957+
5958+ void media_codec_delegate_destroy(MediaCodecDelegate delegate);
5959+ void media_codec_delegate_ref(MediaCodecDelegate delegate);
5960+ void media_codec_delegate_unref(MediaCodecDelegate delegate);
5961+
5962+#ifdef SIMPLE_PLAYER
5963+ int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, void *nativeWindow, uint32_t flags);
5964+#else
5965+ int media_codec_configure(MediaCodecDelegate delegate, MediaFormat format, SurfaceTextureClientHybris stc, uint32_t flags);
5966+#endif
5967+ int media_codec_set_surface_texture_client(MediaCodecDelegate delegate, SurfaceTextureClientHybris stc);
5968+
5969+ int media_codec_queue_csd(MediaCodecDelegate delegate, MediaFormat format);
5970+ int media_codec_start(MediaCodecDelegate delegate);
5971+ int media_codec_stop(MediaCodecDelegate delegate);
5972+ int media_codec_release(MediaCodecDelegate delegate);
5973+ int media_codec_flush(MediaCodecDelegate delegate);
5974+ size_t media_codec_get_input_buffers_size(MediaCodecDelegate delegate);
5975+ uint8_t *media_codec_get_nth_input_buffer(MediaCodecDelegate delegate, size_t n);
5976+ size_t media_codec_get_nth_input_buffer_capacity(MediaCodecDelegate delegate, size_t n);
5977+ size_t media_codec_get_output_buffers_size(MediaCodecDelegate delegate);
5978+ uint8_t *media_codec_get_nth_output_buffer(MediaCodecDelegate delegate, size_t n);
5979+ size_t media_codec_get_nth_output_buffer_capacity(MediaCodecDelegate delegate, size_t n);
5980+
5981+ struct _MediaCodecBufferInfo
5982+ {
5983+ size_t index;
5984+ size_t offset;
5985+ size_t size;
5986+ int64_t presentation_time_us;
5987+ uint32_t flags;
5988+ uint8_t render_retries;
5989+ };
5990+ typedef struct _MediaCodecBufferInfo MediaCodecBufferInfo;
5991+
5992+ int media_codec_dequeue_output_buffer(MediaCodecDelegate delegate, MediaCodecBufferInfo *info, int64_t timeout_us);
5993+ int media_codec_queue_input_buffer(MediaCodecDelegate delegate, const MediaCodecBufferInfo *info);
5994+ int media_codec_dequeue_input_buffer(MediaCodecDelegate delegate, size_t *index, int64_t timeout_us);
5995+ int media_codec_release_output_buffer(MediaCodecDelegate delegate, size_t index, uint8_t render);
5996+
5997+ MediaFormat media_codec_get_output_format(MediaCodecDelegate delegate);
5998+
5999+#ifdef __cplusplus
6000+}
6001+#endif
6002+
6003+#endif // MEDIA_CODEC_LAYER_H_
6004--- /dev/null
6005+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_codec_list.h
6006@@ -0,0 +1,56 @@
6007+/*
6008+ * Copyright (C) 2013 Canonical Ltd
6009+ *
6010+ * Licensed under the Apache License, Version 2.0 (the "License");
6011+ * you may not use this file except in compliance with the License.
6012+ * You may obtain a copy of the License at
6013+ *
6014+ * http://www.apache.org/licenses/LICENSE-2.0
6015+ *
6016+ * Unless required by applicable law or agreed to in writing, software
6017+ * distributed under the License is distributed on an "AS IS" BASIS,
6018+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6019+ * See the License for the specific language governing permissions and
6020+ * limitations under the License.
6021+ *
6022+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
6023+ */
6024+
6025+#ifndef MEDIA_CODEC_LIST_PRIV_H_
6026+#define MEDIA_CODEC_LIST_PRIV_H_
6027+
6028+#include <stddef.h>
6029+#include <stdbool.h>
6030+#include <unistd.h>
6031+
6032+#ifdef __cplusplus
6033+extern "C" {
6034+#endif
6035+
6036+ ssize_t media_codec_list_find_codec_by_type(const char *type, bool encoder, size_t startIndex);
6037+ ssize_t media_codec_list_find_codec_by_name(const char *name);
6038+ size_t media_codec_list_count_codecs();
6039+ void media_codec_list_get_codec_info_at_id(size_t index);
6040+ const char *media_codec_list_get_codec_name(size_t index);
6041+ bool media_codec_list_is_encoder(size_t index);
6042+ size_t media_codec_list_get_num_supported_types(size_t index);
6043+ size_t media_codec_list_get_nth_supported_type_len(size_t index, size_t n);
6044+ int media_codec_list_get_nth_supported_type(size_t index, char *type, size_t n);
6045+
6046+ struct _profile_level
6047+ {
6048+ uint32_t profile;
6049+ uint32_t level;
6050+ };
6051+ typedef struct _profile_level profile_level;
6052+
6053+ size_t media_codec_list_get_num_profile_levels(size_t index, const char*);
6054+ size_t media_codec_list_get_num_color_formats(size_t index, const char*);
6055+ int media_codec_list_get_nth_codec_profile_level(size_t index, const char *type, profile_level *pro_level, size_t n);
6056+ int media_codec_list_get_codec_color_formats(size_t index, const char *type, uint32_t *color_formats);
6057+
6058+#ifdef __cplusplus
6059+}
6060+#endif
6061+
6062+#endif // MEDIA_CODEC_LIST_PRIV_H_
6063--- /dev/null
6064+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_compatibility_layer.h
6065@@ -0,0 +1,75 @@
6066+/*
6067+ * Copyright (C) 2013 Canonical Ltd
6068+ *
6069+ * Licensed under the Apache License, Version 2.0 (the "License");
6070+ * you may not use this file except in compliance with the License.
6071+ * You may obtain a copy of the License at
6072+ *
6073+ * http://www.apache.org/licenses/LICENSE-2.0
6074+ *
6075+ * Unless required by applicable law or agreed to in writing, software
6076+ * distributed under the License is distributed on an "AS IS" BASIS,
6077+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6078+ * See the License for the specific language governing permissions and
6079+ * limitations under the License.
6080+ *
6081+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
6082+ */
6083+
6084+#ifndef MEDIA_COMPATIBILITY_LAYER_H_
6085+#define MEDIA_COMPATIBILITY_LAYER_H_
6086+
6087+#include <stdint.h>
6088+#include <unistd.h>
6089+#include <stdbool.h>
6090+
6091+#include <GLES2/gl2.h>
6092+
6093+#ifdef __cplusplus
6094+extern "C" {
6095+#endif
6096+
6097+ // Common compat calls
6098+ int media_compat_check_availability();
6099+
6100+ // Callback types
6101+ typedef void (*on_msg_set_video_size)(int height, int width, void *context);
6102+ typedef void (*on_video_texture_needs_update)(void *context);
6103+ typedef void (*on_msg_error)(void *context);
6104+ typedef void (*on_playback_complete)(void *context);
6105+ typedef void (*on_media_prepared)(void *context);
6106+
6107+ struct MediaPlayerWrapper;
6108+
6109+ // ----- Start of C API ----- //
6110+
6111+ // Callback setters
6112+ void android_media_set_video_size_cb(struct MediaPlayerWrapper *mp, on_msg_set_video_size cb, void *context);
6113+ void android_media_set_video_texture_needs_update_cb(struct MediaPlayerWrapper *mp, on_video_texture_needs_update cb, void *context);
6114+ void android_media_set_error_cb(struct MediaPlayerWrapper *mp, on_msg_error cb, void *context);
6115+ void android_media_set_playback_complete_cb(struct MediaPlayerWrapper *mp, on_playback_complete cb, void *context);
6116+ void android_media_set_media_prepared_cb(struct MediaPlayerWrapper *mp, on_media_prepared cb, void *context);
6117+
6118+ // Main player control API
6119+ struct MediaPlayerWrapper *android_media_new_player();
6120+ int android_media_set_data_source(struct MediaPlayerWrapper *mp, const char* url);
6121+ int android_media_set_preview_texture(struct MediaPlayerWrapper *mp, int texture_id);
6122+ void android_media_update_surface_texture(struct MediaPlayerWrapper *mp);
6123+ void android_media_surface_texture_get_transformation_matrix(struct MediaPlayerWrapper *mp, GLfloat*matrix);
6124+ int android_media_play(struct MediaPlayerWrapper *mp);
6125+ int android_media_pause(struct MediaPlayerWrapper *mp);
6126+ int android_media_stop(struct MediaPlayerWrapper *mp);
6127+ bool android_media_is_playing(struct MediaPlayerWrapper *mp);
6128+
6129+ int android_media_seek_to(struct MediaPlayerWrapper *mp, int msec);
6130+ int android_media_get_current_position(struct MediaPlayerWrapper *mp, int *msec);
6131+ int android_media_get_duration(struct MediaPlayerWrapper *mp, int *msec);
6132+
6133+ int android_media_get_volume(struct MediaPlayerWrapper *mp, int *volume);
6134+ int android_media_set_volume(struct MediaPlayerWrapper *mp, int volume);
6135+
6136+#ifdef __cplusplus
6137+}
6138+#endif
6139+
6140+#endif // MEDIA_COMPATIBILITY_LAYER_H_
6141--- /dev/null
6142+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/media_format_layer.h
6143@@ -0,0 +1,58 @@
6144+/*
6145+ * Copyright (C) 2013 Canonical Ltd
6146+ *
6147+ * Licensed under the Apache License, Version 2.0 (the "License");
6148+ * you may not use this file except in compliance with the License.
6149+ * You may obtain a copy of the License at
6150+ *
6151+ * http://www.apache.org/licenses/LICENSE-2.0
6152+ *
6153+ * Unless required by applicable law or agreed to in writing, software
6154+ * distributed under the License is distributed on an "AS IS" BASIS,
6155+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6156+ * See the License for the specific language governing permissions and
6157+ * limitations under the License.
6158+ *
6159+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
6160+ */
6161+
6162+#ifndef MEDIA_FORMAT_LAYER_H_
6163+#define MEDIA_FORMAT_LAYER_H_
6164+
6165+#include <stddef.h>
6166+#include <unistd.h>
6167+
6168+#ifdef __cplusplus
6169+extern "C" {
6170+#endif
6171+
6172+ typedef void* MediaFormat;
6173+
6174+ MediaFormat media_format_create_video_format(const char *mime, int32_t width, int32_t height, int64_t duration_us, int32_t max_input_size);
6175+
6176+ void media_format_destroy(MediaFormat format);
6177+ void media_format_ref(MediaFormat format);
6178+ void media_format_unref(MediaFormat format);
6179+
6180+ void media_format_set_byte_buffer(MediaFormat format, const char *key, uint8_t *data, size_t size);
6181+
6182+ const char* media_format_get_mime(MediaFormat format);
6183+ int64_t media_format_get_duration_us(MediaFormat format);
6184+ int32_t media_format_get_width(MediaFormat format);
6185+ int32_t media_format_get_height(MediaFormat format);
6186+ int32_t media_format_get_max_input_size(MediaFormat format);
6187+ int32_t media_format_get_stride(MediaFormat format);
6188+ int32_t media_format_get_slice_height(MediaFormat format);
6189+ int32_t media_format_get_color_format(MediaFormat format);
6190+ int32_t media_format_get_crop_left(MediaFormat format);
6191+ int32_t media_format_get_crop_right(MediaFormat format);
6192+ int32_t media_format_get_crop_top(MediaFormat format);
6193+ int32_t media_format_get_crop_bottom(MediaFormat format);
6194+
6195+ // TODO: Add getter for CSD buffer
6196+
6197+#ifdef __cplusplus
6198+}
6199+#endif
6200+
6201+#endif // MEDIA_FORMAT_LAYER_H_
6202--- /dev/null
6203+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/recorder_compatibility_layer.h
6204@@ -0,0 +1,126 @@
6205+/*
6206+ * Copyright (C) 2013 Canonical Ltd
6207+ *
6208+ * Licensed under the Apache License, Version 2.0 (the "License");
6209+ * you may not use this file except in compliance with the License.
6210+ * You may obtain a copy of the License at
6211+ *
6212+ * http://www.apache.org/licenses/LICENSE-2.0
6213+ *
6214+ * Unless required by applicable law or agreed to in writing, software
6215+ * distributed under the License is distributed on an "AS IS" BASIS,
6216+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6217+ * See the License for the specific language governing permissions and
6218+ * limitations under the License.
6219+ */
6220+
6221+#ifndef RECORDER_COMPATIBILITY_LAYER_H_
6222+#define RECORDER_COMPATIBILITY_LAYER_H_
6223+
6224+#include <stdint.h>
6225+#include <unistd.h>
6226+#include <stdint.h>
6227+#include <stdbool.h>
6228+
6229+#ifdef __cplusplus
6230+extern "C" {
6231+#endif
6232+
6233+ struct MediaRecorderWrapper;
6234+ struct CameraControl;
6235+
6236+ // values are from andoid /frameworks/av/include/media/mediarecorder.h
6237+ typedef enum
6238+ {
6239+ ANDROID_VIDEO_SOURCE_DEFAULT = 0,
6240+ ANDROID_VIDEO_SOURCE_CAMERA = 1,
6241+ ANDROID_VIDEO_SOURCE_GRALLOC_BUFFER = 2
6242+ } VideoSource;
6243+
6244+ // values are from andoid /system/core/include/system/audio.h
6245+ typedef enum
6246+ {
6247+ ANDROID_AUDIO_SOURCE_DEFAULT = 0,
6248+ ANDROID_AUDIO_SOURCE_MIC = 1,
6249+ ANDROID_AUDIO_SOURCE_VOICE_UPLINK = 2,
6250+ ANDROID_AUDIO_SOURCE_VOICE_DOWNLINK = 3,
6251+ ANDROID_AUDIO_SOURCE_VOICE_CALL = 4,
6252+ ANDROID_AUDIO_SOURCE_CAMCORDER = 5,
6253+ ANDROID_AUDIO_SOURCE_VOICE_RECOGNITION = 6,
6254+ ANDROID_AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
6255+ ANDROID_AUDIO_SOURCE_REMOTE_SUBMIX = 8,
6256+ ANDROID_AUDIO_SOURCE_CNT,
6257+ ANDROID_AUDIO_SOURCE_MAX = ANDROID_AUDIO_SOURCE_CNT - 1
6258+ } AudioSource;
6259+
6260+ // values are from andoid /frameworks/av/include/media/mediarecorder.h
6261+ typedef enum
6262+ {
6263+ ANDROID_OUTPUT_FORMAT_DEFAULT = 0,
6264+ ANDROID_OUTPUT_FORMAT_THREE_GPP = 1,
6265+ ANDROID_OUTPUT_FORMAT_MPEG_4 = 2,
6266+ ANDROID_OUTPUT_FORMAT_AUDIO_ONLY_START = 3,
6267+ /* These are audio only file formats */
6268+ ANDROID_OUTPUT_FORMAT_RAW_AMR = 3, //to be backward compatible
6269+ ANDROID_OUTPUT_FORMAT_AMR_NB = 3,
6270+ ANDROID_OUTPUT_FORMAT_AMR_WB = 4,
6271+ ANDROID_OUTPUT_FORMAT_AAC_ADIF = 5,
6272+ ANDROID_OUTPUT_FORMAT_AAC_ADTS = 6,
6273+ /* Stream over a socket, limited to a single stream */
6274+ ANDROID_OUTPUT_FORMAT_RTP_AVP = 7,
6275+ /* H.264/AAC data encapsulated in MPEG2/TS */
6276+ ANDROID_OUTPUT_FORMAT_MPEG2TS = 8
6277+ } OutputFormat;
6278+
6279+ // values are from andoid /frameworks/av/include/media/mediarecorder.h
6280+ typedef enum
6281+ {
6282+ ANDROID_VIDEO_ENCODER_DEFAULT = 0,
6283+ ANDROID_VIDEO_ENCODER_H263 = 1,
6284+ ANDROID_VIDEO_ENCODER_H264 = 2,
6285+ ANDROID_VIDEO_ENCODER_MPEG_4_SP = 3
6286+ } VideoEncoder;
6287+
6288+ // values are from andoid /frameworks/av/include/media/mediarecorder.h
6289+ typedef enum
6290+ {
6291+ ANDROID_AUDIO_ENCODER_DEFAULT = 0,
6292+ ANDROID_AUDIO_ENCODER_AMR_NB = 1,
6293+ ANDROID_AUDIO_ENCODER_AMR_WB = 2,
6294+ ANDROID_AUDIO_ENCODER_AAC = 3,
6295+ ANDROID_AUDIO_ENCODER_HE_AAC = 4,
6296+ ANDROID_AUDIO_ENCODER_AAC_ELD = 5
6297+ } AudioEncoder;
6298+
6299+ // Callback types
6300+ typedef void (*on_recorder_msg_error)(void *context);
6301+
6302+ // Callback setters
6303+ void android_recorder_set_error_cb(struct MediaRecorderWrapper *mr, on_recorder_msg_error cb,
6304+ void *context);
6305+
6306+ // Main recorder control API
6307+ struct MediaRecorderWrapper *android_media_new_recorder();
6308+ int android_recorder_initCheck(struct MediaRecorderWrapper *mr);
6309+ int android_recorder_setCamera(struct MediaRecorderWrapper *mr, struct CameraControl* control);
6310+ int android_recorder_setVideoSource(struct MediaRecorderWrapper *mr, VideoSource vs);
6311+ int android_recorder_setAudioSource(struct MediaRecorderWrapper *mr, AudioSource as);
6312+ int android_recorder_setOutputFormat(struct MediaRecorderWrapper *mr, OutputFormat of);
6313+ int android_recorder_setVideoEncoder(struct MediaRecorderWrapper *mr, VideoEncoder ve);
6314+ int android_recorder_setAudioEncoder(struct MediaRecorderWrapper *mr, AudioEncoder ae);
6315+ int android_recorder_setOutputFile(struct MediaRecorderWrapper *mr, int fd);
6316+ int android_recorder_setVideoSize(struct MediaRecorderWrapper *mr, int width, int height);
6317+ int android_recorder_setVideoFrameRate(struct MediaRecorderWrapper *mr, int frames_per_second);
6318+ int android_recorder_setParameters(struct MediaRecorderWrapper *mr, const char* parameters);
6319+ int android_recorder_start(struct MediaRecorderWrapper *mr);
6320+ int android_recorder_stop(struct MediaRecorderWrapper *mr);
6321+ int android_recorder_prepare(struct MediaRecorderWrapper *mr);
6322+ int android_recorder_reset(struct MediaRecorderWrapper *mr);
6323+ int android_recorder_close(struct MediaRecorderWrapper *mr);
6324+ int android_recorder_release(struct MediaRecorderWrapper *mr);
6325+
6326+#ifdef __cplusplus
6327+}
6328+#endif
6329+
6330+#endif
6331--- /dev/null
6332+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/media/surface_texture_client_hybris.h
6333@@ -0,0 +1,63 @@
6334+/*
6335+ * Copyright (C) 2013 Canonical Ltd
6336+ *
6337+ * Licensed under the Apache License, Version 2.0 (the "License");
6338+ * you may not use this file except in compliance with the License.
6339+ * You may obtain a copy of the License at
6340+ *
6341+ * http://www.apache.org/licenses/LICENSE-2.0
6342+ *
6343+ * Unless required by applicable law or agreed to in writing, software
6344+ * distributed under the License is distributed on an "AS IS" BASIS,
6345+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6346+ * See the License for the specific language governing permissions and
6347+ * limitations under the License.
6348+ *
6349+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
6350+ */
6351+
6352+#ifndef SURFACE_TEXTURE_CLIENT_HYBRIS_H_
6353+#define SURFACE_TEXTURE_CLIENT_HYBRIS_H_
6354+
6355+#include <stdint.h>
6356+#include <unistd.h>
6357+
6358+#include <EGL/egl.h>
6359+
6360+#ifdef __ARM_PCS_VFP
6361+#define FP_ATTRIB __attribute__((pcs("aapcs")))
6362+#else
6363+#define FP_ATTRIB
6364+#endif
6365+
6366+#ifdef __cplusplus
6367+extern "C" {
6368+#endif
6369+
6370+ // Taken from native_window.h
6371+ enum {
6372+ WINDOW_FORMAT_RGBA_8888 = 1,
6373+ WINDOW_FORMAT_RGBX_8888 = 2,
6374+ WINDOW_FORMAT_RGB_565 = 4,
6375+ };
6376+
6377+ typedef void* SurfaceTextureClientHybris;
6378+
6379+ //SurfaceTextureClientHybris surface_texture_client_get_instance();
6380+ SurfaceTextureClientHybris surface_texture_client_create(EGLNativeWindowType native_window);
6381+ SurfaceTextureClientHybris surface_texture_client_create_by_id(unsigned int texture_id);
6382+ uint8_t surface_texture_client_is_ready_for_rendering(SurfaceTextureClientHybris stc);
6383+ uint8_t surface_texture_client_hardware_rendering(SurfaceTextureClientHybris stc);
6384+ void surface_texture_client_set_hardware_rendering(SurfaceTextureClientHybris stc, uint8_t hardware_rendering);
6385+ void surface_texture_client_get_transformation_matrix(SurfaceTextureClientHybris stc, float *matrix) FP_ATTRIB;
6386+ void surface_texture_client_update_texture(SurfaceTextureClientHybris stc);
6387+ void surface_texture_client_destroy(SurfaceTextureClientHybris stc);
6388+ void surface_texture_client_ref(SurfaceTextureClientHybris stc);
6389+ void surface_texture_client_unref(SurfaceTextureClientHybris stc);
6390+ void surface_texture_client_set_surface_texture(SurfaceTextureClientHybris stc, EGLNativeWindowType native_window);
6391+
6392+#ifdef __cplusplus
6393+}
6394+#endif
6395+
6396+#endif // SURFACE_TEXTURE_CLIENT_HYBRIS_H_
6397--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/include/hybris/ui/ui_compatibility_layer.h
6398+++ libhybris-0.1.0+git20131207+e452e83/hybris/include/hybris/ui/ui_compatibility_layer.h
6399@@ -50,8 +50,10 @@ extern "C" {
6400
6401 void* graphic_buffer_get_native_buffer(struct graphic_buffer *buffer);
6402
6403+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
6404 void graphic_buffer_set_index(struct graphic_buffer *buffer, int index);
6405 int graphic_buffer_get_index(struct graphic_buffer *buffer);
6406+#endif
6407
6408 int graphic_buffer_init_check(struct graphic_buffer *buffer);
6409
6410--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/input/is.c
6411+++ libhybris-0.1.0+git20131207+e452e83/hybris/input/is.c
6412@@ -28,6 +28,14 @@
6413
6414 HYBRIS_LIBRARY_INITIALIZE(is, COMPAT_LIBRARY_PATH);
6415
6416+int android_input_check_availability()
6417+{
6418+ /* Both are defined via HYBRIS_LIBRARY_INITIALIZE */
6419+ if (!is_handle)
6420+ hybris_is_initialize();
6421+ return is_handle ? 1 : 0;
6422+}
6423+
6424 HYBRIS_IMPLEMENT_VOID_FUNCTION2(is, android_input_stack_initialize,
6425 struct AndroidEventListener*, struct InputStackConfiguration*);
6426 HYBRIS_IMPLEMENT_VOID_FUNCTION0(is, android_input_stack_start);
6427--- /dev/null
6428+++ libhybris-0.1.0+git20131207+e452e83/hybris/media/Makefile.am
6429@@ -0,0 +1,17 @@
6430+lib_LTLIBRARIES = \
6431+ libmedia.la
6432+
6433+libmedia_la_SOURCES = media.c
6434+libmedia_la_CFLAGS = -I$(top_srcdir)/include
6435+if WANT_TRACE
6436+libmedia_la_CFLAGS += -DDEBUG
6437+endif
6438+if WANT_DEBUG
6439+libmedia_la_CFLAGS += -ggdb -O0
6440+endif
6441+libmedia_la_LDFLAGS = \
6442+ $(top_builddir)/common/libhybris-common.la \
6443+ -version-info "1":"0":"0"
6444+
6445+pkgconfigdir = $(libdir)/pkgconfig
6446+pkgconfig_DATA = libmedia.pc
6447--- /dev/null
6448+++ libhybris-0.1.0+git20131207+e452e83/hybris/media/libmedia.pc.in
6449@@ -0,0 +1,10 @@
6450+prefix=@prefix@
6451+exec_prefix=${prefix}
6452+libdir=@libdir@
6453+includedir=@includedir@
6454+
6455+Name: hybris-media
6456+Description: libhybris media library
6457+Version: @VERSION@
6458+Libs: -L${libdir} -lhybris-common -lmedia
6459+Cflags: -I${includedir}
6460--- /dev/null
6461+++ libhybris-0.1.0+git20131207+e452e83/hybris/media/media.c
6462@@ -0,0 +1,272 @@
6463+/*
6464+ * Copyright (C) 2013 Canonical Ltd
6465+ *
6466+ * Licensed under the Apache License, Version 2.0 (the "License");
6467+ * you may not use this file except in compliance with the License.
6468+ * You may obtain a copy of the License at
6469+ *
6470+ * http://www.apache.org/licenses/LICENSE-2.0
6471+ *
6472+ * Unless required by applicable law or agreed to in writing, software
6473+ * distributed under the License is distributed on an "AS IS" BASIS,
6474+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6475+ * See the License for the specific language governing permissions and
6476+ * limitations under the License.
6477+ *
6478+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
6479+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
6480+ */
6481+
6482+#include <assert.h>
6483+#include <dlfcn.h>
6484+#include <stddef.h>
6485+#include <stdbool.h>
6486+
6487+#include <hybris/internal/binding.h>
6488+#include <hybris/media/media_compatibility_layer.h>
6489+#include <hybris/media/recorder_compatibility_layer.h>
6490+#include <hybris/media/media_codec_layer.h>
6491+#include <hybris/media/media_codec_list.h>
6492+#include <hybris/media/media_format_layer.h>
6493+#include <hybris/media/surface_texture_client_hybris.h>
6494+
6495+#define COMPAT_LIBRARY_PATH "/system/lib/libmedia_compat_layer.so"
6496+
6497+#ifdef __ARM_PCS_VFP
6498+#define FP_ATTRIB __attribute__((pcs("aapcs")))
6499+#else
6500+#define FP_ATTRIB
6501+#endif
6502+
6503+HYBRIS_LIBRARY_INITIALIZE(media, COMPAT_LIBRARY_PATH);
6504+
6505+int media_compat_check_availability()
6506+{
6507+ /* Both are defined via HYBRIS_LIBRARY_INITIALIZE */
6508+ hybris_media_initialize();
6509+ return media_handle ? 1 : 0;
6510+}
6511+
6512+HYBRIS_IMPLEMENT_FUNCTION0(media, struct MediaPlayerWrapper*,
6513+ android_media_new_player);
6514+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, android_media_update_surface_texture,
6515+ struct MediaPlayerWrapper*);
6516+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_media_play,
6517+ struct MediaPlayerWrapper*);
6518+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_media_pause,
6519+ struct MediaPlayerWrapper*);
6520+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_media_stop,
6521+ struct MediaPlayerWrapper*);
6522+HYBRIS_IMPLEMENT_FUNCTION1(media, bool, android_media_is_playing,
6523+ struct MediaPlayerWrapper*);
6524+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_seek_to,
6525+ struct MediaPlayerWrapper*, int);
6526+
6527+// Setters
6528+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_set_data_source,
6529+ struct MediaPlayerWrapper*, const char*);
6530+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_set_preview_texture,
6531+ struct MediaPlayerWrapper*, int);
6532+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_set_volume,
6533+ struct MediaPlayerWrapper*, int);
6534+
6535+// Getters
6536+HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, android_media_surface_texture_get_transformation_matrix,
6537+ struct MediaPlayerWrapper*, float*);
6538+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_get_current_position,
6539+ struct MediaPlayerWrapper*, int*);
6540+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_get_duration,
6541+ struct MediaPlayerWrapper*, int*);
6542+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_media_get_volume,
6543+ struct MediaPlayerWrapper*, int*);
6544+
6545+// Callbacks
6546+HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_video_size_cb,
6547+ struct MediaPlayerWrapper*, on_msg_set_video_size, void*);
6548+HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_video_texture_needs_update_cb,
6549+ struct MediaPlayerWrapper*, on_video_texture_needs_update, void*);
6550+HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_error_cb,
6551+ struct MediaPlayerWrapper*, on_msg_error, void*);
6552+HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_playback_complete_cb,
6553+ struct MediaPlayerWrapper*, on_playback_complete, void*);
6554+HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_media_set_media_prepared_cb,
6555+ struct MediaPlayerWrapper*, on_media_prepared, void*);
6556+
6557+// Media Codecs
6558+HYBRIS_IMPLEMENT_FUNCTION1(media, MediaCodecDelegate,
6559+ media_codec_create_by_codec_name, const char*);
6560+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_delegate_destroy,
6561+ MediaCodecDelegate);
6562+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_delegate_ref,
6563+ MediaCodecDelegate);
6564+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_delegate_unref,
6565+ MediaCodecDelegate);
6566+
6567+#ifdef SIMPLE_PLAYER
6568+HYBRIS_IMPLEMENT_FUNCTION4(media, int, media_codec_configure,
6569+ MediaCodecDelegate, MediaFormat, void*, uint32_t);
6570+#else
6571+HYBRIS_IMPLEMENT_FUNCTION4(media, int, media_codec_configure,
6572+ MediaCodecDelegate, MediaFormat, SurfaceTextureClientHybris, uint32_t);
6573+#endif
6574+HYBRIS_IMPLEMENT_FUNCTION2(media, int, media_codec_set_surface_texture_client,
6575+ MediaCodecDelegate, SurfaceTextureClientHybris);
6576+HYBRIS_IMPLEMENT_FUNCTION2(media, int, media_codec_queue_csd,
6577+ MediaCodecDelegate, MediaFormat);
6578+HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_start,
6579+ MediaCodecDelegate);
6580+HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_stop,
6581+ MediaCodecDelegate);
6582+HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_release,
6583+ MediaCodecDelegate);
6584+HYBRIS_IMPLEMENT_FUNCTION1(media, int, media_codec_flush,
6585+ MediaCodecDelegate);
6586+HYBRIS_IMPLEMENT_FUNCTION1(media, size_t, media_codec_get_input_buffers_size,
6587+ MediaCodecDelegate);
6588+HYBRIS_IMPLEMENT_FUNCTION2(media, uint8_t*, media_codec_get_nth_input_buffer,
6589+ MediaCodecDelegate, size_t);
6590+HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_get_nth_input_buffer_capacity,
6591+ MediaCodecDelegate, size_t);
6592+HYBRIS_IMPLEMENT_FUNCTION1(media, size_t, media_codec_get_output_buffers_size,
6593+ MediaCodecDelegate);
6594+HYBRIS_IMPLEMENT_FUNCTION2(media, uint8_t*, media_codec_get_nth_output_buffer,
6595+ MediaCodecDelegate, size_t);
6596+HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_get_nth_output_buffer_capacity,
6597+ MediaCodecDelegate, size_t);
6598+HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_dequeue_output_buffer,
6599+ MediaCodecDelegate, MediaCodecBufferInfo*, int64_t);
6600+HYBRIS_IMPLEMENT_FUNCTION2(media, int, media_codec_queue_input_buffer,
6601+ MediaCodecDelegate, const MediaCodecBufferInfo*);
6602+HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_dequeue_input_buffer,
6603+ MediaCodecDelegate, size_t*, int64_t);
6604+HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_release_output_buffer,
6605+ MediaCodecDelegate, size_t, uint8_t);
6606+HYBRIS_IMPLEMENT_FUNCTION1(media, MediaFormat, media_codec_get_output_format,
6607+ MediaCodecDelegate);
6608+
6609+HYBRIS_IMPLEMENT_FUNCTION3(media, ssize_t, media_codec_list_find_codec_by_type,
6610+ const char*, bool, size_t);
6611+HYBRIS_IMPLEMENT_FUNCTION1(media, ssize_t, media_codec_list_find_codec_by_name,
6612+ const char *);
6613+HYBRIS_IMPLEMENT_FUNCTION0(media, size_t, media_codec_list_count_codecs);
6614+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_codec_list_get_codec_info_at_id,
6615+ size_t);
6616+HYBRIS_IMPLEMENT_FUNCTION1(media, const char*, media_codec_list_get_codec_name,
6617+ size_t);
6618+HYBRIS_IMPLEMENT_FUNCTION1(media, bool, media_codec_list_is_encoder,
6619+ size_t);
6620+HYBRIS_IMPLEMENT_FUNCTION1(media, size_t, media_codec_list_get_num_supported_types,
6621+ size_t);
6622+HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_list_get_nth_supported_type_len,
6623+ size_t, size_t);
6624+HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_list_get_nth_supported_type,
6625+ size_t, char *, size_t);
6626+HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_list_get_num_profile_levels,
6627+ size_t, const char*);
6628+HYBRIS_IMPLEMENT_FUNCTION2(media, size_t, media_codec_list_get_num_color_formats,
6629+ size_t, const char*);
6630+HYBRIS_IMPLEMENT_FUNCTION4(media, int, media_codec_list_get_nth_codec_profile_level,
6631+ size_t, const char*, profile_level*, size_t);
6632+HYBRIS_IMPLEMENT_FUNCTION3(media, int, media_codec_list_get_codec_color_formats,
6633+ size_t, const char*, uint32_t*);
6634+
6635+HYBRIS_IMPLEMENT_FUNCTION5(media, MediaFormat, media_format_create_video_format,
6636+ const char*, int32_t, int32_t, int64_t, int32_t);
6637+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_format_destroy,
6638+ MediaFormat);
6639+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_format_ref,
6640+ MediaFormat);
6641+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, media_format_unref,
6642+ MediaFormat);
6643+HYBRIS_IMPLEMENT_VOID_FUNCTION4(media, media_format_set_byte_buffer,
6644+ MediaFormat, const char*, uint8_t*, size_t);
6645+HYBRIS_IMPLEMENT_FUNCTION1(media, const char*, media_format_get_mime,
6646+ MediaFormat);
6647+HYBRIS_IMPLEMENT_FUNCTION1(media, int64_t, media_format_get_duration_us,
6648+ MediaFormat);
6649+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_width,
6650+ MediaFormat);
6651+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_height,
6652+ MediaFormat);
6653+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_max_input_size,
6654+ MediaFormat);
6655+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_stride,
6656+ MediaFormat);
6657+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_slice_height,
6658+ MediaFormat);
6659+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_color_format,
6660+ MediaFormat);
6661+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_left,
6662+ MediaFormat);
6663+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_right,
6664+ MediaFormat);
6665+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_top,
6666+ MediaFormat);
6667+HYBRIS_IMPLEMENT_FUNCTION1(media, int32_t, media_format_get_crop_bottom,
6668+ MediaFormat);
6669+
6670+// SurfaceTextureClientHybris
6671+HYBRIS_IMPLEMENT_FUNCTION1(media, SurfaceTextureClientHybris,
6672+ surface_texture_client_create, EGLNativeWindowType);
6673+HYBRIS_IMPLEMENT_FUNCTION1(media, SurfaceTextureClientHybris,
6674+ surface_texture_client_create_by_id, unsigned int);
6675+HYBRIS_IMPLEMENT_FUNCTION1(media, uint8_t,
6676+ surface_texture_client_is_ready_for_rendering, SurfaceTextureClientHybris);
6677+HYBRIS_IMPLEMENT_FUNCTION1(media, uint8_t,
6678+ surface_texture_client_hardware_rendering, SurfaceTextureClientHybris);
6679+HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, surface_texture_client_set_hardware_rendering,
6680+ SurfaceTextureClientHybris, uint8_t);
6681+HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, surface_texture_client_get_transformation_matrix,
6682+ SurfaceTextureClientHybris, GLfloat*);
6683+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_update_texture,
6684+ SurfaceTextureClientHybris);
6685+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_destroy,
6686+ SurfaceTextureClientHybris);
6687+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_ref,
6688+ SurfaceTextureClientHybris);
6689+HYBRIS_IMPLEMENT_VOID_FUNCTION1(media, surface_texture_client_unref,
6690+ SurfaceTextureClientHybris);
6691+HYBRIS_IMPLEMENT_VOID_FUNCTION2(media, surface_texture_client_set_surface_texture,
6692+ SurfaceTextureClientHybris, EGLNativeWindowType);
6693+
6694+// Recorder
6695+HYBRIS_IMPLEMENT_FUNCTION0(media, struct MediaRecorderWrapper*,
6696+ android_media_new_recorder);
6697+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_initCheck,
6698+ struct MediaRecorderWrapper*);
6699+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setCamera,
6700+ struct MediaRecorderWrapper*, struct CameraControl*);
6701+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setVideoSource,
6702+ struct MediaRecorderWrapper*, VideoSource);
6703+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setAudioSource,
6704+ struct MediaRecorderWrapper*, AudioSource);
6705+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setOutputFormat,
6706+ struct MediaRecorderWrapper*, OutputFormat);
6707+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setVideoEncoder,
6708+ struct MediaRecorderWrapper*, VideoEncoder);
6709+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setAudioEncoder,
6710+ struct MediaRecorderWrapper*, AudioEncoder);
6711+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setOutputFile,
6712+ struct MediaRecorderWrapper*, int);
6713+HYBRIS_IMPLEMENT_FUNCTION3(media, int, android_recorder_setVideoSize,
6714+ struct MediaRecorderWrapper*, int, int);
6715+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setVideoFrameRate,
6716+ struct MediaRecorderWrapper*, int);
6717+HYBRIS_IMPLEMENT_FUNCTION2(media, int, android_recorder_setParameters,
6718+ struct MediaRecorderWrapper*, const char*);
6719+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_start,
6720+ struct MediaRecorderWrapper*);
6721+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_stop,
6722+ struct MediaRecorderWrapper*);
6723+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_prepare,
6724+ struct MediaRecorderWrapper*);
6725+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_reset,
6726+ struct MediaRecorderWrapper*);
6727+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_close,
6728+ struct MediaRecorderWrapper*);
6729+HYBRIS_IMPLEMENT_FUNCTION1(media, int, android_recorder_release,
6730+ struct MediaRecorderWrapper*);
6731+
6732+// Recorder Callbacks
6733+HYBRIS_IMPLEMENT_VOID_FUNCTION3(media, android_recorder_set_error_cb,
6734+ struct MediaRecorderWrapper *, on_recorder_msg_error, void*);
6735--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/tests/Makefile.am
6736+++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/Makefile.am
6737@@ -7,6 +7,8 @@ bin_PROGRAMS = \
6738 test_sensors \
6739 test_input \
6740 test_camera \
6741+ test_media \
6742+ test_recorder \
6743 test_gps
6744
6745 if HAS_ANDROID_4_2_0
6746@@ -140,6 +142,28 @@ test_camera_LDADD = \
6747 $(top_builddir)/camera/libcamera.la \
6748 $(top_builddir)/input/libis.la
6749
6750+test_media_SOURCES = test_media.c
6751+test_media_CFLAGS = \
6752+ -I$(top_srcdir)/include
6753+test_media_LDADD = \
6754+ $(top_builddir)/common/libhybris-common.la \
6755+ $(top_builddir)/egl/libEGL.la \
6756+ $(top_builddir)/glesv2/libGLESv2.la \
6757+ $(top_builddir)/media/libmedia.la \
6758+ $(top_builddir)/sf/libsf.la
6759+
6760+test_recorder_SOURCES = test_recorder.c
6761+test_recorder_CFLAGS = \
6762+ -I$(top_srcdir)/include
6763+test_recorder_LDADD = \
6764+ $(top_builddir)/common/libhybris-common.la \
6765+ $(top_builddir)/egl/libEGL.la \
6766+ $(top_builddir)/glesv2/libGLESv2.la \
6767+ $(top_builddir)/media/libmedia.la \
6768+ $(top_builddir)/camera/libcamera.la \
6769+ $(top_builddir)/input/libis.la \
6770+ $(top_builddir)/sf/libsf.la
6771+
6772 test_gps_SOURCES = test_gps.c
6773 test_gps_CFLAGS = -pthread \
6774 -I$(top_srcdir)/include \
6775--- /dev/null
6776+++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/test_media.c
6777@@ -0,0 +1,373 @@
6778+/*
6779+ * Copyright (C) 2013 Canonical Ltd
6780+ *
6781+ * Licensed under the Apache License, Version 2.0 (the "License");
6782+ * you may not use this file except in compliance with the License.
6783+ * You may obtain a copy of the License at
6784+ *
6785+ * http://www.apache.org/licenses/LICENSE-2.0
6786+ *
6787+ * Unless required by applicable law or agreed to in writing, software
6788+ * distributed under the License is distributed on an "AS IS" BASIS,
6789+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6790+ * See the License for the specific language governing permissions and
6791+ * limitations under the License.
6792+ *
6793+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
6794+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
6795+ */
6796+
6797+#include <hybris/media/media_compatibility_layer.h>
6798+#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
6799+
6800+#include <EGL/egl.h>
6801+#include <GLES2/gl2.h>
6802+#include <GLES2/gl2ext.h>
6803+
6804+#include <assert.h>
6805+#include <stdlib.h>
6806+#include <stdio.h>
6807+#include <string.h>
6808+#include <stdbool.h>
6809+#include <limits.h>
6810+#include <fcntl.h>
6811+#include <unistd.h>
6812+#include <sys/stat.h>
6813+#include <sys/types.h>
6814+
6815+enum {
6816+ OK = 0,
6817+ NO_ERROR = 0,
6818+};
6819+
6820+static float DestWidth = 0.0, DestHeight = 0.0;
6821+// Actual video dimmensions
6822+static int Width = 0, Height = 0;
6823+
6824+static GLuint gProgram;
6825+static GLuint gaPositionHandle, gaTexHandle, gsTextureHandle, gmTexMatrix;
6826+
6827+static GLfloat positionCoordinates[8];
6828+
6829+struct MediaPlayerWrapper *player = NULL;
6830+
6831+void calculate_position_coordinates()
6832+{
6833+ // Assuming cropping output for now
6834+ float x = 1, y = 1;
6835+
6836+ // Black borders
6837+ x = (float) (Width / DestWidth);
6838+ y = (float) (Height / DestHeight);
6839+
6840+ // Make the larger side be 1
6841+ if (x > y) {
6842+ y /= x;
6843+ x = 1;
6844+ } else {
6845+ x /= y;
6846+ y = 1;
6847+ }
6848+
6849+ positionCoordinates[0] = -x;
6850+ positionCoordinates[1] = y;
6851+ positionCoordinates[2] = -x;
6852+ positionCoordinates[3] = -y;
6853+ positionCoordinates[4] = x;
6854+ positionCoordinates[5] = -y;
6855+ positionCoordinates[6] = x;
6856+ positionCoordinates[7] = y;
6857+}
6858+
6859+struct ClientWithSurface
6860+{
6861+ struct SfClient* client;
6862+ struct SfSurface* surface;
6863+};
6864+
6865+struct ClientWithSurface client_with_surface(bool setup_surface_with_egl)
6866+{
6867+ struct ClientWithSurface cs;
6868+
6869+ cs.client = sf_client_create();
6870+
6871+ if (!cs.client) {
6872+ printf("Problem creating client ... aborting now.");
6873+ return cs;
6874+ }
6875+
6876+ static const size_t primary_display = 0;
6877+
6878+ DestWidth = sf_get_display_width(primary_display);
6879+ DestHeight = sf_get_display_height(primary_display);
6880+ printf("Primary display width: %f, height: %f\n", DestWidth, DestHeight);
6881+
6882+ SfSurfaceCreationParameters params = {
6883+ 0,
6884+ 0,
6885+ DestWidth,
6886+ DestHeight,
6887+ -1, //PIXEL_FORMAT_RGBA_8888,
6888+ 15000,
6889+ 0.5f,
6890+ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL
6891+ "MediaCompatLayerTestSurface"
6892+ };
6893+
6894+ cs.surface = sf_surface_create(cs.client, &params);
6895+
6896+ if (!cs.surface) {
6897+ printf("Problem creating surface ... aborting now.");
6898+ return cs;
6899+ }
6900+
6901+ sf_surface_make_current(cs.surface);
6902+
6903+ return cs;
6904+}
6905+
6906+static const char *vertex_shader()
6907+{
6908+ return
6909+ "attribute vec4 a_position; \n"
6910+ "attribute vec2 a_texCoord; \n"
6911+ "uniform mat4 m_texMatrix; \n"
6912+ "varying vec2 v_texCoord; \n"
6913+ "varying float topDown; \n"
6914+ "void main() \n"
6915+ "{ \n"
6916+ " gl_Position = a_position; \n"
6917+ " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
6918+ "} \n";
6919+}
6920+
6921+static const char *fragment_shader()
6922+{
6923+ return
6924+ "#extension GL_OES_EGL_image_external : require \n"
6925+ "precision mediump float; \n"
6926+ "varying vec2 v_texCoord; \n"
6927+ "uniform samplerExternalOES s_texture; \n"
6928+ "void main() \n"
6929+ "{ \n"
6930+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
6931+ "} \n";
6932+}
6933+
6934+static GLuint loadShader(GLenum shaderType, const char* pSource)
6935+{
6936+ GLuint shader = glCreateShader(shaderType);
6937+
6938+ if (shader) {
6939+ glShaderSource(shader, 1, &pSource, NULL);
6940+ glCompileShader(shader);
6941+ GLint compiled = 0;
6942+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
6943+
6944+ if (!compiled) {
6945+ GLint infoLen = 0;
6946+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
6947+ if (infoLen) {
6948+ char* buf = (char*) malloc(infoLen);
6949+ if (buf) {
6950+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
6951+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
6952+ shaderType, buf);
6953+ free(buf);
6954+ }
6955+ glDeleteShader(shader);
6956+ shader = 0;
6957+ }
6958+ }
6959+ } else {
6960+ printf("Error, during shader creation: %i\n", glGetError());
6961+ }
6962+
6963+ return shader;
6964+}
6965+
6966+static GLuint create_program(const char* pVertexSource, const char* pFragmentSource)
6967+{
6968+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
6969+ if (!vertexShader) {
6970+ printf("vertex shader not compiled\n");
6971+ return 0;
6972+ }
6973+
6974+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
6975+ if (!pixelShader) {
6976+ printf("frag shader not compiled\n");
6977+ return 0;
6978+ }
6979+
6980+ GLuint program = glCreateProgram();
6981+ if (program) {
6982+ glAttachShader(program, vertexShader);
6983+ glAttachShader(program, pixelShader);
6984+ glLinkProgram(program);
6985+ GLint linkStatus = GL_FALSE;
6986+
6987+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
6988+ if (linkStatus != GL_TRUE) {
6989+ GLint bufLength = 0;
6990+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
6991+ if (bufLength) {
6992+ char* buf = (char*) malloc(bufLength);
6993+ if (buf) {
6994+ glGetProgramInfoLog(program, bufLength, NULL, buf);
6995+ fprintf(stderr, "Could not link program:\n%s\n", buf);
6996+ free(buf);
6997+ }
6998+ }
6999+ glDeleteProgram(program);
7000+ program = 0;
7001+ }
7002+ }
7003+
7004+ return program;
7005+}
7006+
7007+static int setup_video_texture(struct ClientWithSurface *cs, GLuint *preview_texture_id)
7008+{
7009+ assert(cs != NULL);
7010+ assert(preview_texture_id != NULL);
7011+
7012+ sf_surface_make_current(cs->surface);
7013+
7014+ glGenTextures(1, preview_texture_id);
7015+ glClearColor(0, 0, 0, 0);
7016+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7017+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7018+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7019+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7020+
7021+ android_media_set_preview_texture(player, *preview_texture_id);
7022+
7023+ return 0;
7024+}
7025+
7026+void set_video_size_cb(int height, int width, void *context)
7027+{
7028+ printf("Video height: %d, width: %d\n", height, width);
7029+ printf("Video dest height: %f, width: %f\n", DestHeight, DestWidth);
7030+
7031+ Height = height;
7032+ Width = width;
7033+}
7034+
7035+void media_prepared_cb(void *context)
7036+{
7037+ printf("Media is prepared for playback.\n");
7038+}
7039+
7040+int main(int argc, char **argv)
7041+{
7042+ if (argc < 2) {
7043+ printf("Usage: test_media <video_to_play>\n");
7044+ return EXIT_FAILURE;
7045+ }
7046+
7047+ player = android_media_new_player();
7048+ if (player == NULL) {
7049+ printf("Problem creating new media player.\n");
7050+ return EXIT_FAILURE;
7051+ }
7052+
7053+ // Set player event cb for when the video size is known:
7054+ android_media_set_video_size_cb(player, set_video_size_cb, NULL);
7055+ android_media_set_media_prepared_cb(player, media_prepared_cb, NULL);
7056+
7057+ printf("Setting data source to: %s.\n", argv[1]);
7058+
7059+ if (android_media_set_data_source(player, argv[1]) != OK) {
7060+ printf("Failed to set data source: %s\n", argv[1]);
7061+ return EXIT_FAILURE;
7062+ }
7063+
7064+ printf("Creating EGL surface.\n");
7065+ struct ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */);
7066+ if (!cs.surface) {
7067+ printf("Problem acquiring surface for preview");
7068+ return EXIT_FAILURE;
7069+ }
7070+
7071+ printf("Creating GL texture.\n");
7072+
7073+ GLuint preview_texture_id;
7074+ EGLDisplay disp = sf_client_get_egl_display(cs.client);
7075+ EGLSurface surface = sf_surface_get_egl_surface(cs.surface);
7076+
7077+ sf_surface_make_current(cs.surface);
7078+
7079+ if (setup_video_texture(&cs, &preview_texture_id) != OK) {
7080+ printf("Problem setting up GL texture for video surface.\n");
7081+ return EXIT_FAILURE;
7082+ }
7083+
7084+ printf("Starting video playback.\n");
7085+ android_media_play(player);
7086+
7087+ while (android_media_is_playing(player)) {
7088+ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
7089+
7090+ const GLfloat textureCoordinates[] = {
7091+ 1.0f, 1.0f,
7092+ 0.0f, 1.0f,
7093+ 0.0f, 0.0f,
7094+ 1.0f, 0.0f
7095+ };
7096+
7097+ android_media_update_surface_texture(player);
7098+
7099+ calculate_position_coordinates();
7100+
7101+ gProgram = create_program(vertex_shader(), fragment_shader());
7102+ gaPositionHandle = glGetAttribLocation(gProgram, "a_position");
7103+ gaTexHandle = glGetAttribLocation(gProgram, "a_texCoord");
7104+ gsTextureHandle = glGetUniformLocation(gProgram, "s_texture");
7105+ gmTexMatrix = glGetUniformLocation(gProgram, "m_texMatrix");
7106+
7107+ glClear(GL_COLOR_BUFFER_BIT);
7108+
7109+ // Use the program object
7110+ glUseProgram(gProgram);
7111+ // Enable attributes
7112+ glEnableVertexAttribArray(gaPositionHandle);
7113+ glEnableVertexAttribArray(gaTexHandle);
7114+ // Load the vertex position
7115+ glVertexAttribPointer(gaPositionHandle,
7116+ 2,
7117+ GL_FLOAT,
7118+ GL_FALSE,
7119+ 0,
7120+ positionCoordinates);
7121+ // Load the texture coordinate
7122+ glVertexAttribPointer(gaTexHandle,
7123+ 2,
7124+ GL_FLOAT,
7125+ GL_FALSE,
7126+ 0,
7127+ textureCoordinates);
7128+
7129+ GLfloat matrix[16];
7130+ android_media_surface_texture_get_transformation_matrix(player, matrix);
7131+
7132+ glUniformMatrix4fv(gmTexMatrix, 1, GL_FALSE, matrix);
7133+
7134+ glActiveTexture(GL_TEXTURE0);
7135+ // Set the sampler texture unit to 0
7136+ glUniform1i(gsTextureHandle, 0);
7137+ glUniform1i(gmTexMatrix, 0);
7138+ android_media_update_surface_texture(player);
7139+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
7140+ //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
7141+ glDisableVertexAttribArray(gaPositionHandle);
7142+ glDisableVertexAttribArray(gaTexHandle);
7143+
7144+ eglSwapBuffers(disp, surface);
7145+ }
7146+
7147+ android_media_stop(player);
7148+
7149+ return EXIT_SUCCESS;
7150+}
7151--- /dev/null
7152+++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/test_recorder.c
7153@@ -0,0 +1,490 @@
7154+/*
7155+ * Copyright (C) 2013 Canonical Ltd
7156+ *
7157+ * Licensed under the Apache License, Version 2.0 (the "License");
7158+ * you may not use this file except in compliance with the License.
7159+ * You may obtain a copy of the License at
7160+ *
7161+ * http://www.apache.org/licenses/LICENSE-2.0
7162+ *
7163+ * Unless required by applicable law or agreed to in writing, software
7164+ * distributed under the License is distributed on an "AS IS" BASIS,
7165+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7166+ * See the License for the specific language governing permissions and
7167+ * limitations under the License.
7168+ *
7169+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
7170+ * Guenter Schwann <guenter.schwann@canonical.com>
7171+ * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
7172+ */
7173+
7174+#include <hybris/camera/camera_compatibility_layer.h>
7175+#include <hybris/camera/camera_compatibility_layer_capabilities.h>
7176+
7177+#include <hybris/media/recorder_compatibility_layer.h>
7178+
7179+#include <hybris/input/input_stack_compatibility_layer.h>
7180+#include <hybris/input/input_stack_compatibility_layer_codes_key.h>
7181+#include <hybris/input/input_stack_compatibility_layer_flags_key.h>
7182+
7183+#include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
7184+
7185+#include <EGL/egl.h>
7186+#include <GLES2/gl2.h>
7187+#include <GLES2/gl2ext.h>
7188+
7189+#include <assert.h>
7190+#include <stdlib.h>
7191+#include <stdio.h>
7192+#include <string.h>
7193+#include <stdbool.h>
7194+#include <limits.h>
7195+#include <fcntl.h>
7196+#include <unistd.h>
7197+#include <sys/stat.h>
7198+#include <sys/types.h>
7199+
7200+int shot_counter = 1;
7201+int32_t current_zoom_level = 1;
7202+bool new_camera_frame_available = true;
7203+struct MediaRecorderWrapper *mr = 0;
7204+GLuint preview_texture_id = 0;
7205+
7206+static GLuint gProgram;
7207+static GLuint gaPositionHandle, gaTexHandle, gsTextureHandle, gmTexMatrix;
7208+
7209+void error_msg_cb(void* context)
7210+{
7211+ printf("%s \n", __PRETTY_FUNCTION__);
7212+}
7213+
7214+void shutter_msg_cb(void* context)
7215+{
7216+ printf("%s \n", __PRETTY_FUNCTION__);
7217+}
7218+
7219+void zoom_msg_cb(void* context, int32_t new_zoom_level)
7220+{
7221+ printf("%s \n", __PRETTY_FUNCTION__);
7222+
7223+ struct CameraControl* cc = (struct CameraControl*) context;
7224+ static int zoom;
7225+ current_zoom_level = new_zoom_level;
7226+}
7227+
7228+void autofocus_msg_cb(void* context)
7229+{
7230+ printf("%s \n", __PRETTY_FUNCTION__);
7231+}
7232+
7233+void raw_data_cb(void* data, uint32_t data_size, void* context)
7234+{
7235+ printf("%s: %d \n", __PRETTY_FUNCTION__, data_size);
7236+}
7237+
7238+void jpeg_data_cb(void* data, uint32_t data_size, void* context)
7239+{
7240+ printf("%s: %d \n", __PRETTY_FUNCTION__, data_size);
7241+ struct CameraControl* cc = (struct CameraControl*) context;
7242+ android_camera_start_preview(cc);
7243+}
7244+
7245+void size_cb(void* ctx, int width, int height)
7246+{
7247+ printf("Supported size: [%d,%d]\n", width, height);
7248+}
7249+
7250+void preview_texture_needs_update_cb(void* ctx)
7251+{
7252+ new_camera_frame_available = true;
7253+}
7254+
7255+void on_new_input_event(struct Event* event, void* context)
7256+{
7257+ assert(context);
7258+
7259+ if (event->type == KEY_EVENT_TYPE && event->action == ISCL_KEY_EVENT_ACTION_UP) {
7260+ printf("We have got a key event: %d \n", event->details.key.key_code);
7261+
7262+ struct CameraControl* cc = (struct CameraControl*) context;
7263+
7264+ int ret;
7265+ switch (event->details.key.key_code) {
7266+ case ISCL_KEYCODE_VOLUME_UP:
7267+ printf("Starting video recording\n");
7268+
7269+ android_camera_unlock(cc);
7270+
7271+ ret = android_recorder_setCamera(mr, cc);
7272+ if (ret < 0) {
7273+ printf("android_recorder_setCamera() failed\n");
7274+ return;
7275+ }
7276+ //state initial / idle
7277+ ret = android_recorder_setAudioSource(mr, ANDROID_AUDIO_SOURCE_CAMCORDER);
7278+ if (ret < 0) {
7279+ printf("android_recorder_setAudioSource() failed\n");
7280+ return;
7281+ }
7282+ ret = android_recorder_setVideoSource(mr, ANDROID_VIDEO_SOURCE_CAMERA);
7283+ if (ret < 0) {
7284+ printf("android_recorder_setVideoSource() failed\n");
7285+ return;
7286+ }
7287+ //state initialized
7288+ ret = android_recorder_setOutputFormat(mr, ANDROID_OUTPUT_FORMAT_MPEG_4);
7289+ if (ret < 0) {
7290+ printf("android_recorder_setOutputFormat() failed\n");
7291+ return;
7292+ }
7293+ //state DataSourceConfigured
7294+ ret = android_recorder_setAudioEncoder(mr, ANDROID_AUDIO_ENCODER_AAC);
7295+ if (ret < 0) {
7296+ printf("android_recorder_setAudioEncoder() failed\n");
7297+ return;
7298+ }
7299+ ret = android_recorder_setVideoEncoder(mr, ANDROID_VIDEO_ENCODER_H264);
7300+ if (ret < 0) {
7301+ printf("android_recorder_setVideoEncoder() failed\n");
7302+ return;
7303+ }
7304+
7305+ int fd;
7306+ fd = open("/tmp/test_video_recorder.avi", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
7307+ if (fd < 0) {
7308+ printf("Could not open file for video recording\n");
7309+ printf("FD: %i\n", fd);
7310+ return;
7311+ }
7312+ ret = android_recorder_setOutputFile(mr, fd);
7313+ if (ret < 0) {
7314+ printf("android_recorder_setOutputFile() failed\n");
7315+ return;
7316+ }
7317+
7318+ ret = android_recorder_setVideoSize(mr, 1280, 720);
7319+ if (ret < 0) {
7320+ printf("android_recorder_setVideoSize() failed\n");
7321+ return;
7322+ }
7323+ ret = android_recorder_setVideoFrameRate(mr, 30);
7324+ if (ret < 0) {
7325+ printf("android_recorder_setVideoFrameRate() failed\n");
7326+ return;
7327+ }
7328+
7329+ ret = android_recorder_prepare(mr);
7330+ if (ret < 0) {
7331+ printf("android_recorder_prepare() failed\n");
7332+ return;
7333+ }
7334+ //state prepared
7335+ ret = android_recorder_start(mr);
7336+ if (ret < 0) {
7337+ printf("android_recorder_start() failed\n");
7338+ return;
7339+ }
7340+ break;
7341+ case ISCL_KEYCODE_VOLUME_DOWN:
7342+ printf("Stoping video recording\n");
7343+ ret = android_recorder_stop(mr);
7344+
7345+ printf("Stoping video recording returned\n");
7346+ if (ret < 0) {
7347+ printf("android_recorder_stop() failed\n");
7348+ return;
7349+ }
7350+ printf("Stopped video recording\n");
7351+ ret = android_recorder_reset(mr);
7352+ if (ret < 0) {
7353+ printf("android_recorder_reset() failed\n");
7354+ return;
7355+ }
7356+ printf("Reset video recorder\n");
7357+ break;
7358+ }
7359+ }
7360+}
7361+
7362+struct ClientWithSurface
7363+{
7364+ struct SfClient* client;
7365+ struct SfSurface* surface;
7366+};
7367+
7368+struct ClientWithSurface client_with_surface(bool setup_surface_with_egl)
7369+{
7370+ struct ClientWithSurface cs;
7371+
7372+ cs.client = sf_client_create();
7373+
7374+ if (!cs.client) {
7375+ printf("Problem creating client ... aborting now.");
7376+ return cs;
7377+ }
7378+
7379+ static const size_t primary_display = 0;
7380+
7381+ SfSurfaceCreationParameters params = {
7382+ 0,
7383+ 0,
7384+ sf_get_display_width(primary_display),
7385+ sf_get_display_height(primary_display),
7386+ -1, //PIXEL_FORMAT_RGBA_8888,
7387+ 15000,
7388+ 0.5f,
7389+ setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL
7390+ "CameraCompatLayerTestSurface"
7391+ };
7392+
7393+ cs.surface = sf_surface_create(cs.client, &params);
7394+
7395+ if (!cs.surface) {
7396+ printf("Problem creating surface ... aborting now.");
7397+ return cs;
7398+ }
7399+
7400+ sf_surface_make_current(cs.surface);
7401+
7402+ return cs;
7403+}
7404+
7405+static const char* vertex_shader()
7406+{
7407+ return
7408+ "#extension GL_OES_EGL_image_external : require \n"
7409+ "attribute vec4 a_position; \n"
7410+ "attribute vec2 a_texCoord; \n"
7411+ "uniform mat4 m_texMatrix; \n"
7412+ "varying vec2 v_texCoord; \n"
7413+ "varying float topDown; \n"
7414+ "void main() \n"
7415+ "{ \n"
7416+ " gl_Position = a_position; \n"
7417+ " v_texCoord = a_texCoord; \n"
7418+ // " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
7419+ //" topDown = v_texCoord.y; \n"
7420+ "} \n";
7421+}
7422+
7423+static const char* fragment_shader()
7424+{
7425+ return
7426+ "#extension GL_OES_EGL_image_external : require \n"
7427+ "precision mediump float; \n"
7428+ "varying vec2 v_texCoord; \n"
7429+ "uniform samplerExternalOES s_texture; \n"
7430+ "void main() \n"
7431+ "{ \n"
7432+ " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
7433+ "} \n";
7434+}
7435+
7436+static GLuint loadShader(GLenum shaderType, const char* pSource) {
7437+ GLuint shader = glCreateShader(shaderType);
7438+
7439+ if (shader) {
7440+ glShaderSource(shader, 1, &pSource, NULL);
7441+ glCompileShader(shader);
7442+ GLint compiled = 0;
7443+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
7444+
7445+ if (!compiled) {
7446+ GLint infoLen = 0;
7447+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
7448+ if (infoLen) {
7449+ char* buf = (char*) malloc(infoLen);
7450+ if (buf) {
7451+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
7452+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
7453+ shaderType, buf);
7454+ free(buf);
7455+ }
7456+ glDeleteShader(shader);
7457+ shader = 0;
7458+ }
7459+ }
7460+ } else {
7461+ printf("Error, during shader creation: %i\n", glGetError());
7462+ }
7463+
7464+ return shader;
7465+}
7466+
7467+static GLuint create_program(const char* pVertexSource, const char* pFragmentSource) {
7468+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
7469+ if (!vertexShader) {
7470+ printf("vertex shader not compiled\n");
7471+ return 0;
7472+ }
7473+
7474+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
7475+ if (!pixelShader) {
7476+ printf("frag shader not compiled\n");
7477+ return 0;
7478+ }
7479+
7480+ GLuint program = glCreateProgram();
7481+ if (program) {
7482+ glAttachShader(program, vertexShader);
7483+ glAttachShader(program, pixelShader);
7484+ glLinkProgram(program);
7485+ GLint linkStatus = GL_FALSE;
7486+
7487+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
7488+ if (linkStatus != GL_TRUE) {
7489+ GLint bufLength = 0;
7490+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
7491+ if (bufLength) {
7492+ char* buf = (char*) malloc(bufLength);
7493+ if (buf) {
7494+ glGetProgramInfoLog(program, bufLength, NULL, buf);
7495+ fprintf(stderr, "Could not link program:\n%s\n", buf);
7496+ free(buf);
7497+ }
7498+ }
7499+ glDeleteProgram(program);
7500+ program = 0;
7501+ }
7502+ }
7503+
7504+ return program;
7505+}
7506+
7507+int main(int argc, char** argv)
7508+{
7509+ printf("Test application for video recording using the camera\n");
7510+ printf("Recording start with volume up button. And stops with volume down.\n");
7511+ printf("The result is stored to /root/test_video.avi\n\n");
7512+
7513+ struct CameraControlListener listener;
7514+ memset(&listener, 0, sizeof(listener));
7515+ listener.on_msg_error_cb = error_msg_cb;
7516+ listener.on_msg_shutter_cb = shutter_msg_cb;
7517+ listener.on_msg_focus_cb = autofocus_msg_cb;
7518+ listener.on_msg_zoom_cb = zoom_msg_cb;
7519+
7520+ listener.on_data_raw_image_cb = raw_data_cb;
7521+ listener.on_data_compressed_image_cb = jpeg_data_cb;
7522+ listener.on_preview_texture_needs_update_cb = preview_texture_needs_update_cb;
7523+ struct CameraControl* cc = android_camera_connect_to(BACK_FACING_CAMERA_TYPE,
7524+ &listener);
7525+ if (cc == NULL) {
7526+ printf("Problem connecting to camera");
7527+ return 1;
7528+ }
7529+
7530+ listener.context = cc;
7531+
7532+ mr = android_media_new_recorder();
7533+
7534+ struct AndroidEventListener event_listener;
7535+ event_listener.on_new_event = on_new_input_event;
7536+ event_listener.context = cc;
7537+
7538+ struct InputStackConfiguration input_configuration = { false, 25000 };
7539+
7540+ android_input_stack_initialize(&event_listener, &input_configuration);
7541+ android_input_stack_start();
7542+
7543+ android_camera_dump_parameters(cc);
7544+
7545+ printf("Supported video sizes:\n");
7546+ android_camera_enumerate_supported_video_sizes(cc, size_cb, NULL);
7547+
7548+ int min_fps, max_fps, current_fps;
7549+
7550+ android_camera_set_preview_size(cc, 1280, 720);
7551+
7552+ int width, height;
7553+ android_camera_get_video_size(cc, &width, &height);
7554+ printf("Current video size: [%d,%d]\n", width, height);
7555+
7556+ struct ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */);
7557+
7558+ if (!cs.surface) {
7559+ printf("Problem acquiring surface for preview");
7560+ return 1;
7561+ }
7562+
7563+ EGLDisplay disp = sf_client_get_egl_display(cs.client);
7564+ EGLSurface surface = sf_surface_get_egl_surface(cs.surface);
7565+
7566+ sf_surface_make_current(cs.surface);
7567+
7568+ gProgram = create_program(vertex_shader(), fragment_shader());
7569+ gaPositionHandle = glGetAttribLocation(gProgram, "a_position");
7570+ gaTexHandle = glGetAttribLocation(gProgram, "a_texCoord");
7571+ gsTextureHandle = glGetUniformLocation(gProgram, "s_texture");
7572+ gmTexMatrix = glGetUniformLocation(gProgram, "m_texMatrix");
7573+
7574+ glGenTextures(1, &preview_texture_id);
7575+ glClearColor(1.0, 0., 0.5, 1.);
7576+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7577+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7578+ glTexParameteri(
7579+ GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7580+ glTexParameteri(
7581+ GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7582+ android_camera_set_preview_texture(cc, preview_texture_id);
7583+ android_camera_start_preview(cc);
7584+
7585+ GLfloat transformation_matrix[16];
7586+ android_camera_get_preview_texture_transformation(cc, transformation_matrix);
7587+ glUniformMatrix4fv(gmTexMatrix, 1, GL_FALSE, transformation_matrix);
7588+
7589+ printf("Started camera preview.\n");
7590+
7591+ while (true) {
7592+ /*if (new_camera_frame_available)
7593+ {
7594+ printf("Updating texture");
7595+ new_camera_frame_available = false;
7596+ }*/
7597+ static GLfloat vVertices[] = { 0.0f, 0.0f, 0.0f, // Position 0
7598+ 0.0f, 0.0f, // TexCoord 0
7599+ 0.0f, 1.0f, 0.0f, // Position 1
7600+ 0.0f, 1.0f, // TexCoord 1
7601+ 1.0f, 1.0f, 0.0f, // Position 2
7602+ 1.0f, 1.0f, // TexCoord 2
7603+ 1.0f, 0.0f, 0.0f, // Position 3
7604+ 1.0f, 0.0f // TexCoord 3
7605+ };
7606+
7607+ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
7608+
7609+ // Set the viewport
7610+ // Clear the color buffer
7611+ glClear(GL_COLOR_BUFFER_BIT);
7612+ // Use the program object
7613+ glUseProgram(gProgram);
7614+ // Enable attributes
7615+ glEnableVertexAttribArray(gaPositionHandle);
7616+ glEnableVertexAttribArray(gaTexHandle);
7617+ // Load the vertex position
7618+ glVertexAttribPointer(gaPositionHandle,
7619+ 3,
7620+ GL_FLOAT,
7621+ GL_FALSE,
7622+ 5 * sizeof(GLfloat),
7623+ vVertices);
7624+ // Load the texture coordinate
7625+ glVertexAttribPointer(gaTexHandle,
7626+ 2,
7627+ GL_FLOAT,
7628+ GL_FALSE,
7629+ 5 * sizeof(GLfloat),
7630+ vVertices+3);
7631+
7632+ glActiveTexture(GL_TEXTURE0);
7633+ // Set the sampler texture unit to 0
7634+ glUniform1i(gsTextureHandle, 0);
7635+ glUniform1i(gmTexMatrix, 0);
7636+ android_camera_update_preview_texture(cc);
7637+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
7638+ glDisableVertexAttribArray(gaPositionHandle);
7639+ glDisableVertexAttribArray(gaTexHandle);
7640+
7641+ eglSwapBuffers(disp, surface);
7642+ }
7643+}
7644--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/tests/test_ui.c
7645+++ libhybris-0.1.0+git20131207+e452e83/hybris/tests/test_ui.c
7646@@ -52,8 +52,10 @@ int main(int argc, char **argv)
7647 graphic_buffer_lock(buffer, GRALLOC_USAGE_HW_RENDER, &vaddr);
7648 graphic_buffer_unlock(buffer);
7649
7650+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
7651 graphic_buffer_set_index(buffer, 11);
7652 assert(graphic_buffer_get_index(buffer) == 11);
7653+#endif
7654
7655 graphic_buffer_free(buffer);
7656
7657--- libhybris-0.1.0+git20131207+e452e83.orig/hybris/ui/ui.c
7658+++ libhybris-0.1.0+git20131207+e452e83/hybris/ui/ui.c
7659@@ -48,9 +48,11 @@ HYBRIS_IMPLEMENT_FUNCTION1(ui, uint32_t,
7660 struct graphic_buffer*);
7661 HYBRIS_IMPLEMENT_FUNCTION1(ui, void*, graphic_buffer_get_native_buffer,
7662 struct graphic_buffer*);
7663+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
7664 HYBRIS_IMPLEMENT_VOID_FUNCTION2(ui, graphic_buffer_set_index,
7665 struct graphic_buffer*, int);
7666 HYBRIS_IMPLEMENT_FUNCTION1(ui, int, graphic_buffer_get_index,
7667 struct graphic_buffer*);
7668+#endif
7669 HYBRIS_IMPLEMENT_FUNCTION1(ui, int, graphic_buffer_init_check,
7670 struct graphic_buffer*);