Imported Debian patch 0.1.0+git20131207+e452e83-0ubuntu12
[deb_libhybris.git] / debian / patches / debian-changes
1 Subject: Collected Debian patches for libhybris
2 Author: Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
3
4 The libhybris package is maintained in Git rather than maintaining
5 patches as separate files, and separating the patches doesn't seem to
6 be worth the effort. They are therefore all included in this single
7 Debian patch.
8
9 For full commit history and separated commits, see the packaging Git
10 repository.
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*);