1212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He/* 2212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * Copyright 2013 The Android Open Source Project 3212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * 4212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * Licensed under the Apache License, Version 2.0 (the "License"); 5212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * you may not use this file except in compliance with the License. 6212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * You may obtain a copy of the License at 7212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * 8212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * http://www.apache.org/licenses/LICENSE-2.0 9212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * 10212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * Unless required by applicable law or agreed to in writing, software 11212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * distributed under the License is distributed on an "AS IS" BASIS, 12212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * See the License for the specific language governing permissions and 14212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He * limitations under the License. 15212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He */ 16212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 17212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He//#define LOG_NDEBUG 0 18212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define LOG_TAG "ImageReader_JNI" 190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He#include "android_media_Utils.h" 20df7707cb4f34138b423dde493fccfa4e7fb50c20Mathias Agopian#include <cutils/atomic.h> 21212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <utils/Log.h> 22212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <utils/misc.h> 23212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <utils/List.h> 24ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown#include <utils/String8.h> 25212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 26212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <cstdio> 27212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 28ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He#include <gui/BufferItemConsumer.h> 29212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <gui/Surface.h> 30212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 31212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/AndroidRuntime.h> 32212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/android_view_Surface.h> 33916d8ac650865cd05808d48bad68b69bebbc95abZhijun He#include <android_runtime/android_hardware_HardwareBuffer.h> 34916d8ac650865cd05808d48bad68b69bebbc95abZhijun He#include <grallocusage/GrallocUsageConversion.h> 35212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 363e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian#include <private/android/AHardwareBufferHelpers.h> 373e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian 38212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <jni.h> 392279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h> 40212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 415096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <stdint.h> 425096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <inttypes.h> 433e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian#include <android/hardware_buffer_jni.h> 445096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 45212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" 46ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mNativeBuffer" 47212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" 48450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev#define ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID "mTransform" 49750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev#define ANDROID_MEDIA_SURFACEIMAGE_SM_JNI_ID "mScalingMode" 50212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 51916d8ac650865cd05808d48bad68b69bebbc95abZhijun He#define CONSUMER_BUFFER_USAGE_UNKNOWN 0; 52212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 53212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 54212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heusing namespace android; 55212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 56212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 57e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinenum { 58e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_SUCCESS = 0, 59e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_NO_BUFFERS = 1, 60e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_MAX_IMAGES = 2, 61e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin}; 62e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin 63ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 64ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mNativeContext; 65ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jmethodID postEventFromNative; 66ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gImageReaderClassInfo; 67ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown 68ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 69ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jfieldID mNativeBuffer; 70ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mTimestamp; 71450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev jfieldID mTransform; 72750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev jfieldID mScalingMode; 730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jfieldID mPlanes; 74ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfaceImageClassInfo; 75212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 76ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 77212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz; 78212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jmethodID ctor; 79ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfacePlaneClassInfo; 80212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 81ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala// Get an ID that's unique within this process. 82ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvalastatic int32_t createProcessUniqueId() { 83ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala static volatile int32_t globalCounter = 0; 84ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala return android_atomic_inc(&globalCounter); 85ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala} 86ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala 87212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 88212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 89ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Heclass JNIImageReaderContext : public ConsumerBase::FrameAvailableListener 90212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 91212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hepublic: 92212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext(JNIEnv* env, jobject weakThiz, jclass clazz, int maxImages); 93212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 94212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He virtual ~JNIImageReaderContext(); 95212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 962c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stoza virtual void onFrameAvailable(const BufferItem& item); 97212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* getBufferItem(); 990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void returnBufferItem(BufferItem* buffer); 100ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 101212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void setBufferConsumer(const sp<BufferItemConsumer>& consumer) { mConsumer = consumer; } 1030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* getBufferConsumer() { return mConsumer.get(); } 104ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 1055b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; } 1065b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* getProducer() { return mProducer.get(); } 107212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 108212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferFormat(int format) { mFormat = format; } 109212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferFormat() { return mFormat; } 110212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 111805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala void setBufferDataspace(android_dataspace dataSpace) { mDataSpace = dataSpace; } 112805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace getBufferDataspace() { return mDataSpace; } 113805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala 114212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferWidth(int width) { mWidth = width; } 115212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferWidth() { return mWidth; } 116212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 117212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferHeight(int height) { mHeight = height; } 118212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferHeight() { return mHeight; } 119212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 120212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heprivate: 121212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static JNIEnv* getJNIEnv(bool* needsDetach); 122212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static void detachJNI(); 123212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He List<BufferItem*> mBuffers; 1250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<BufferItemConsumer> mConsumer; 1265b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<IGraphicBufferProducer> mProducer; 127212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject mWeakThiz; 128212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass mClazz; 129212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mFormat; 130805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace mDataSpace; 131212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mWidth; 132212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mHeight; 133212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 134212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 135212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::JNIImageReaderContext(JNIEnv* env, 136212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject weakThiz, jclass clazz, int maxImages) : 137212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mWeakThiz(env->NewGlobalRef(weakThiz)), 1380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mClazz((jclass)env->NewGlobalRef(clazz)), 1390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mFormat(0), 1400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mDataSpace(HAL_DATASPACE_UNKNOWN), 1410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mWidth(-1), 1420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mHeight(-1) { 143212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (int i = 0; i < maxImages; i++) { 1440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = new BufferItem; 145212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 146212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 147212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 148212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 149212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) { 150212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!"); 151212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = false; 152212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = AndroidRuntime::getJNIEnv(); 153212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env == NULL) { 154212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; 155212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 156212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->AttachCurrentThread(&env, (void*) &args); 157212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 158212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread attach failed: %#x", result); 159212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 160212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 161212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = true; 162212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 163212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return env; 164212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 165212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 166212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hevoid JNIImageReaderContext::detachJNI() { 167212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 168212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->DetachCurrentThread(); 169212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 170212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread detach failed: %#x", result); 171212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 172212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 173212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1740ab416269a866c8afa8f65d9351afa2407abee4cZhijun HeBufferItem* JNIImageReaderContext::getBufferItem() { 175212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (mBuffers.empty()) { 176212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 177212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return a BufferItem pointer and remove it from the list 1790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He List<BufferItem*>::iterator it = mBuffers.begin(); 1800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = *it; 181212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.erase(it); 182212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return buffer; 183212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 184212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1850ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hevoid JNIImageReaderContext::returnBufferItem(BufferItem* buffer) { 1860af9435572aa4ef66c61a62605f6eb3f8d218d8bEino-Ville Talvala buffer->mGraphicBuffer = nullptr; 187212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 188212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 189212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 190212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::~JNIImageReaderContext() { 191212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 192212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 193212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 194212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mWeakThiz); 195212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mClazz); 196212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 197212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("leaking JNI object references"); 198212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 199212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 200212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 201212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 202212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Delete buffer items. 2040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He for (List<BufferItem *>::iterator it = mBuffers.begin(); 205212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He it != mBuffers.end(); it++) { 206212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He delete *it; 207212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 208ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 209ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (mConsumer != 0) { 210ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mConsumer.clear(); 211ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 212212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 213212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2142c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stozavoid JNIImageReaderContext::onFrameAvailable(const BufferItem& /*item*/) 215212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 216212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: frame available", __FUNCTION__); 217212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 218212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 219212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 220ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz); 221212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 222212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("onFrameAvailable event will not posted"); 223212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 224212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 225212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 226212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 227212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 228212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 229212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 230212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 231212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heextern "C" { 232212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 233212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz) 234212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 235212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext *ctx; 236212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx = reinterpret_cast<JNIImageReaderContext *> 237ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext)); 238212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx; 239212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 240212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2415b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stozastatic IGraphicBufferProducer* ImageReader_getProducer(JNIEnv* env, jobject thiz) 24252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{ 24352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian ALOGV("%s:", __FUNCTION__); 24452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 24552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian if (ctx == NULL) { 24652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 24752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return NULL; 24852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian } 249ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2505b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return ctx->getProducer(); 25152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian} 25252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian 253212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_setNativeContext(JNIEnv* env, 254212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject thiz, sp<JNIImageReaderContext> ctx) 255212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 256212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 257212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const p = ImageReader_getContext(env, thiz); 258212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx != 0) { 259212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->incStrong((void*)ImageReader_setNativeContext); 260212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 261212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (p) { 262212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He p->decStrong((void*)ImageReader_setNativeContext); 263212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 264ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext, 265ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown reinterpret_cast<jlong>(ctx.get())); 266212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 267212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2680ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic BufferItemConsumer* ImageReader_getBufferConsumer(JNIEnv* env, jobject thiz) 269ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 270ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGV("%s:", __FUNCTION__); 271ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 272ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx == NULL) { 273ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 274ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 275ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 276ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return ctx->getBufferConsumer(); 2780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 279ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2800ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_setBufferItem(JNIEnv* env, jobject thiz, 2810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He const BufferItem* buffer) 2820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He{ 2830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer, reinterpret_cast<jlong>(buffer)); 284ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 285ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2860ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic BufferItem* Image_getBufferItem(JNIEnv* env, jobject image) 287ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 288ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return reinterpret_cast<BufferItem*>( 289ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->GetLongField(image, gSurfaceImageClassInfo.mNativeBuffer)); 290ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 291ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 292ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 293212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 294212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 295212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_classInit(JNIEnv* env, jclass clazz) 296212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 297212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 298212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 299212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage"); 300212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(imageClazz == NULL, 301212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader$SurfaceImage"); 302ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He gSurfaceImageClassInfo.mNativeBuffer = env->GetFieldID( 303ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J"); 304ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mNativeBuffer == NULL, 305212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 306212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID); 307212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 308ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mTimestamp = env->GetFieldID( 309ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J"); 310ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL, 311212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 312212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); 313212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 314450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev gSurfaceImageClassInfo.mTransform = env->GetFieldID( 315450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID, "I"); 316450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTransform == NULL, 317450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev "can't find android/graphics/ImageReader.%s", 318450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID); 319450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev 320750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev gSurfaceImageClassInfo.mScalingMode = env->GetFieldID( 321750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev imageClazz, ANDROID_MEDIA_SURFACEIMAGE_SM_JNI_ID, "I"); 322750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mScalingMode == NULL, 323750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev "can't find android/graphics/ImageReader.%s", 324750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev ANDROID_MEDIA_SURFACEIMAGE_SM_JNI_ID); 325750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev 3260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He gSurfaceImageClassInfo.mPlanes = env->GetFieldID( 3270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He imageClazz, "mPlanes", "[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;"); 3280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mPlanes == NULL, 3290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "can't find android/media/ImageReader$ReaderSurfaceImage.mPlanes"); 3300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 331ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.mNativeContext = env->GetFieldID( 332ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J"); 333ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL, 334212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 335212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID); 336212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 337ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID( 338ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, "postEventFromNative", "(Ljava/lang/Object;)V"); 339ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL, 340212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.postEventFromNative"); 341212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 342212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane"); 343212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class"); 344212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // FindClass only gives a local reference of jclass object. 345ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); 346ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>", 3470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "(Landroid/media/ImageReader$SurfaceImage;IILjava/nio/ByteBuffer;)V"); 348ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, 349ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "Can not find SurfacePlane constructor"); 350212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 351212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 352916d8ac650865cd05808d48bad68b69bebbc95abZhijun Hestatic void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint width, jint height, 353916d8ac650865cd05808d48bad68b69bebbc95abZhijun He jint format, jint maxImages, jlong ndkUsage) 354212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 355212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res; 356212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int nativeFormat; 357805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace nativeDataspace; 358212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 359212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d", 360212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He __FUNCTION__, width, height, format, maxImages); 361212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 362805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala PublicFormat publicFormat = static_cast<PublicFormat>(format); 363805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeFormat = android_view_Surface_mapPublicFormatToHalFormat( 364805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 365805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeDataspace = android_view_Surface_mapPublicFormatToHalDataspace( 366805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 367212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 368212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz = env->GetObjectClass(thiz); 369212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (clazz == NULL) { 370212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader"); 371212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 372212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 373212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages)); 374ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 375ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferProducer> gbProducer; 376ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferConsumer> gbConsumer; 377ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 3780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<BufferItemConsumer> bufferConsumer; 379ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d", 380ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala width, height, format, maxImages, getpid(), 381ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala createProcessUniqueId()); 3820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t consumerUsage = GRALLOC_USAGE_SW_READ_OFTEN; 383916d8ac650865cd05808d48bad68b69bebbc95abZhijun He bool needUsageOverride = ndkUsage != CONSUMER_BUFFER_USAGE_UNKNOWN; 384916d8ac650865cd05808d48bad68b69bebbc95abZhijun He uint64_t outProducerUsage = 0; 385916d8ac650865cd05808d48bad68b69bebbc95abZhijun He uint64_t outConsumerUsage = 0; 386916d8ac650865cd05808d48bad68b69bebbc95abZhijun He android_hardware_HardwareBuffer_convertToGrallocUsageBits(&outProducerUsage, &outConsumerUsage, 387916d8ac650865cd05808d48bad68b69bebbc95abZhijun He ndkUsage, 0); 3880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 389ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(nativeFormat)) { 390ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Use the SW_READ_NEVER usage to tell producer that this format is not for preview or video 391ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // encoding. The only possibility will be ZSL output. 3920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He consumerUsage = GRALLOC_USAGE_SW_READ_NEVER; 393916d8ac650865cd05808d48bad68b69bebbc95abZhijun He if (needUsageOverride) { 394916d8ac650865cd05808d48bad68b69bebbc95abZhijun He consumerUsage = android_convertGralloc1To0Usage(0, outConsumerUsage); 395916d8ac650865cd05808d48bad68b69bebbc95abZhijun He } 396916d8ac650865cd05808d48bad68b69bebbc95abZhijun He } else if (needUsageOverride) { 397916d8ac650865cd05808d48bad68b69bebbc95abZhijun He ALOGW("Consumer usage override for non-opaque format is not implemented yet, " 398916d8ac650865cd05808d48bad68b69bebbc95abZhijun He "ignore the provided usage from the application"); 399ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 4000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer = new BufferItemConsumer(gbConsumer, consumerUsage, maxImages, 4010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /*controlledByApp*/true); 4020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (bufferConsumer == nullptr) { 4030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/RuntimeException", 404916d8ac650865cd05808d48bad68b69bebbc95abZhijun He "Failed to allocate native buffer consumer for format 0x%x and usage 0x%x", 405916d8ac650865cd05808d48bad68b69bebbc95abZhijun He nativeFormat, consumerUsage); 4060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 4070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->setBufferConsumer(bufferConsumer); 4090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->setName(consumerName); 410ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 4115b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza ctx->setProducer(gbProducer); 4120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->setFrameAvailableListener(ctx); 413212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, ctx); 414212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferFormat(nativeFormat); 415805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala ctx->setBufferDataspace(nativeDataspace); 416212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferWidth(width); 417212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferHeight(height); 418212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Set the width/height/format/dataspace to the bufferConsumer. 4200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferSize(width, height); 4210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 4230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default size (%dx%d) for format 0x%x", 4240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He width, height, nativeFormat); 4250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 4260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferFormat(nativeFormat); 4280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 4300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default format 0x%x", nativeFormat); 4310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferDataSpace(nativeDataspace); 4330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 4350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default dataSpace 0x%x", nativeDataspace); 436805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala } 437212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 438212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 439212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_close(JNIEnv* env, jobject thiz) 440212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 441212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 442212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 443212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 444212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 445212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // ImageReader is already closed. 446212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 447212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 448212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* consumer = NULL; 4500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He consumer = ImageReader_getBufferConsumer(env, thiz); 451ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 452212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer != NULL) { 453212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->abandon(); 454212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(NULL); 455212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 456212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, NULL); 457212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 458212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4590ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic sp<Fence> Image_unlockIfLocked(JNIEnv* env, jobject image) { 4600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 4610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 4620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) { 4630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 4640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image is not initialized"); 4650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 4680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Is locked? 4690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bool wasBufferLocked = false; 4700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject planes = NULL; 4710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!isFormatOpaque(buffer->mGraphicBuffer->getPixelFormat())) { 4720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He planes = env->GetObjectField(image, gSurfaceImageClassInfo.mPlanes); 4730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He wasBufferLocked = (planes != NULL); 4750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (wasBufferLocked) { 4760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = OK; 4770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int fenceFd = -1; 4780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (wasBufferLocked) { 4790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = buffer->mGraphicBuffer->unlockAsync(&fenceFd); 4800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "unlock buffer failed"); 4820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<Fence> releaseFence = new Fence(fenceFd); 4860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return releaseFence; 4870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("Successfully unlocked the image"); 4880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 4910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 492212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image) 493212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 494212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 495212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 496212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 497212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("ImageReader#close called before Image#close, consider calling Image#close first"); 498212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 499212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 500212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 5020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 5030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == nullptr) { 5040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Release an already closed image is harmless. 5050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 506212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 5070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<Fence> releaseFence = Image_unlockIfLocked(env, image); 5090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->releaseBuffer(*buffer, releaseFence); 5100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_setBufferItem(env, image, NULL); 5110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 5120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Image (format: 0x%x) has been released", __FUNCTION__, ctx->getBufferFormat()); 513212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 514212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5150ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) { 516212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 5170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 5180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (ctx == NULL) { 5190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 5200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "ImageReader is not initialized or was already closed"); 521e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 522212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 523212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 5250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = ctx->getBufferItem(); 526ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (buffer == NULL) { 527ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGW("Unable to acquire a buffer item, very likely client tried to acquire more than" 528ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He " maxImages buffers"); 529ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ACQUIRE_MAX_IMAGES; 530ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 531ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 5320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = bufferConsumer->acquireBuffer(buffer, 0); 533ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 5340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 5350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != BufferQueue::NO_BUFFER_AVAILABLE) { 5360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res == INVALID_OPERATION) { 5370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Max number of images were already acquired. 5380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: Max number of buffers allowed are already acquired : %s (%d)", 5390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, strerror(-res), res); 540e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 541dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } else { 5420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: Acquire image failed with some unknown error: %s (%d)", 5430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, strerror(-res), res); 5440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 5450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Unknown error (%d) when we tried to acquire an image.", 5460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res); 5470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return ACQUIRE_NO_BUFFERS; 548dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } 549f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown } 5500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // This isn't really an error case, as the application may acquire buffer at any time. 551e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_NO_BUFFERS; 552212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 553212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Add some extra checks for non-opaque formats. 5550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!isFormatOpaque(ctx->getBufferFormat())) { 5560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Check if the left-top corner of the crop rect is origin, we currently assume this point is 5570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // zero, will revisit this once this assumption turns out problematic. 5580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Point lt = buffer->mCrop.leftTop(); 5590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (lt.x != 0 || lt.y != 0) { 5600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 5610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 5620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return -1; 5630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5644eda9f5359347c11914e47f477535c9533674d32Zhijun He 5650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Check if the producer buffer configurations match what ImageReader configured. 5660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int outputWidth = getBufferWidth(buffer); 5670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int outputHeight = getBufferHeight(buffer); 5680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imgReaderFmt = ctx->getBufferFormat(); 5700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imageReaderWidth = ctx->getBufferWidth(); 5710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imageReaderHeight = ctx->getBufferHeight(); 5720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int bufferFormat = buffer->mGraphicBuffer->getPixelFormat(); 5730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if ((bufferFormat != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) && 5740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) { 5750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", 5760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); 5770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (imgReaderFmt != bufferFormat) { 5790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && 5800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He isPossiblyYUV(bufferFormat)) { 5810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Treat formats that are compatible with flexible YUV 5820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // (HAL_PIXEL_FORMAT_YCbCr_420_888) as HAL_PIXEL_FORMAT_YCbCr_420_888. 5830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCbCr_420_888", 5840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, bufferFormat); 5850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && 5860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) { 5870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Using HAL_PIXEL_FORMAT_RGBA_8888 Gralloc buffers containing JPEGs to get around 5880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // SW write limitations for (b/17379185). 5890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.", __FUNCTION__); 5900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else { 5910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return the buffer to the queue. No need to provide fence, as this buffer wasn't 5920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // used anywhere yet. 5930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->releaseBuffer(*buffer); 5940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 5950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Throw exception 5970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 5980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat, ctx->getBufferFormat()); 5990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He String8 msg; 6000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.appendFormat("The producer output buffer format 0x%x doesn't " 6010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "match the ImageReader's configured buffer format 0x%x.", 6020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat, ctx->getBufferFormat()); 6030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 6040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.string()); 6050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return -1; 6060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 608212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 609212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 610212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 611212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set SurfaceImage instance member variables 6120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_setBufferItem(env, image, buffer); 613ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 6140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He static_cast<jlong>(buffer->mTimestamp)); 615450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev env->SetIntField(image, gSurfaceImageClassInfo.mTransform, 616450a5ffdfd6e4dffbacda25b6d93abd2b93355f7Emilian Peev static_cast<jint>(buffer->mTransform)); 617750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev env->SetIntField(image, gSurfaceImageClassInfo.mScalingMode, 618750aec6f3bf8353fb619773862f3181b5766d42eEmilian Peev static_cast<jint>(buffer->mScalingMode)); 619212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 620e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_SUCCESS; 621212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 622212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 623ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint ImageReader_detachImage(JNIEnv* env, jobject thiz, jobject image) { 624f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He ALOGV("%s:", __FUNCTION__); 625f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 626f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (ctx == NULL) { 627f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed"); 628ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 629f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 630f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 6310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 6320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 6330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!buffer) { 634ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGE( 6350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image already released and can not be detached from ImageReader!!!"); 636ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 6370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image detach from ImageReader failed: buffer was already released"); 638ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 639ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 640ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 6410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = OK; 6420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_unlockIfLocked(env, image); 6430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->detachBuffer(buffer->mSlot); 644ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 6450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Image detach failed: %s (%d)!!!", strerror(-res), res); 646ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, 6470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "nativeDetachImage failed for image!!!"); 648ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return res; 649ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 650ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return OK; 651f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He} 652f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 6532e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvalastatic void ImageReader_discardFreeBuffers(JNIEnv* env, jobject thiz) { 6542e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala ALOGV("%s:", __FUNCTION__); 6552e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 6562e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala if (ctx == NULL) { 6572e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed"); 6582e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala return; 6592e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala } 6602e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala 6612e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 6622e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala status_t res = bufferConsumer->discardFreeBuffers(); 6632e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala if (res != OK) { 6642e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala ALOGE("Buffer discard failed: %s (%d)", strerror(-res), res); 6652e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala jniThrowRuntimeException(env, 6662e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala "nativeDicardFreebuffers failed"); 6672e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala } 6682e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala} 6692e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala 670212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) 671212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 672212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: ", __FUNCTION__); 673212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6745b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* gbp = ImageReader_getProducer(env, thiz); 6755b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza if (gbp == NULL) { 6760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "Buffer consumer is uninitialized"); 677212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 678212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 679212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 680212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Wrap the IGBP in a Java-language Surface. 6815b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return android_view_Surface_createFromIGraphicBufferProducer(env, gbp); 682212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 683212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6840ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) { 6850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 6860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 6870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) { 688ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 6890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image is not initialized"); 6900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 691ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 692212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = lockImageFromBuffer(buffer, 6940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He GRALLOC_USAGE_SW_READ_OFTEN, buffer->mFence->dup(), image); 6950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 6960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/RuntimeException", 6970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "lock buffer failed for format 0x%x", 6980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->mGraphicBuffer->getPixelFormat()); 6990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 700212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 7010fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 7020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Carry over some fields from BufferItem. 7030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->crop = buffer->mCrop; 7040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->transform = buffer->mTransform; 7050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->scalingMode = buffer->mScalingMode; 7060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->timestamp = buffer->mTimestamp; 7070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->dataSpace = buffer->mDataSpace; 7080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->frameNumber = buffer->mFrameNumber; 7090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Successfully locked the image", __FUNCTION__); 7110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // crop, transform, scalingMode, timestamp, and frameNumber should be set by producer, 7120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // and we don't set them here. 7130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 714212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7150ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx, 7160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t writerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) { 7170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 718212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = getLockedImageInfo(buffer, idx, writerFormat, base, size, 7200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pixelStride, rowStride); 7210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 7220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 7230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Pixel format: 0x%x is unsupported", buffer->flexFormat); 7240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 725212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 726212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7270ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, 7280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int numPlanes, int readerFormat) 729212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 7300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes); 7310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int rowStride = 0; 7320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int pixelStride = 0; 7330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t *pData = NULL; 7340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t dataSize = 0; 7350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject byteBuffer = NULL; 736212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He PublicFormat publicReaderFormat = static_cast<PublicFormat>(readerFormat); 7380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int halReaderFormat = android_view_Surface_mapPublicFormatToHalFormat( 7390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He publicReaderFormat); 740212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(halReaderFormat) && numPlanes > 0) { 7420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He String8 msg; 7430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)" 7440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He " must be 0", halReaderFormat, numPlanes); 7450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalArgumentException", msg.string()); 746ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 747ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 748ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 7490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobjectArray surfacePlanes = env->NewObjectArray(numPlanes, gSurfacePlaneClassInfo.clazz, 7500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /*initial_element*/NULL); 7510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (surfacePlanes == NULL) { 7520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "Failed to create SurfacePlane arrays," 7530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He " probably out of memory"); 7545096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return NULL; 7555096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 7560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(halReaderFormat)) { 7570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return 0 element surface array. 7580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return surfacePlanes; 7590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 7600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LockedImage lockedImg = LockedImage(); 7620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_getLockedImage(env, thiz, &lockedImg); 763252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih if (env->ExceptionCheck()) { 764252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih return NULL; 765252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih } 7660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Create all SurfacePlanes 7670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He for (int i = 0; i < numPlanes; i++) { 7680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_getLockedImageInfo(env, &lockedImg, i, halReaderFormat, 7690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He &pData, &dataSize, &pixelStride, &rowStride); 7700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He byteBuffer = env->NewDirectByteBuffer(pData, dataSize); 7710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { 7720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 7730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to allocate ByteBuffer"); 7740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return NULL; 7750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 7765096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 7770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Finally, create this SurfacePlane. 7780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject surfacePlane = env->NewObject(gSurfacePlaneClassInfo.clazz, 7790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He gSurfacePlaneClassInfo.ctor, thiz, rowStride, pixelStride, byteBuffer); 7800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He env->SetObjectArrayElement(surfacePlanes, i, surfacePlane); 781212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 782212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return surfacePlanes; 784212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 785212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7860ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint Image_getWidth(JNIEnv* env, jobject thiz) 787f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 7880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return getBufferWidth(buffer); 790f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 791f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 7920ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint Image_getHeight(JNIEnv* env, jobject thiz) 793f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 7940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return getBufferHeight(buffer); 796f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 797f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 7987c3997d96a2571295a97457264832d54b05ee966Zhijun Hestatic jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat) 7997c3997d96a2571295a97457264832d54b05ee966Zhijun He{ 8007c3997d96a2571295a97457264832d54b05ee966Zhijun He if (isFormatOpaque(readerFormat)) { 8017c3997d96a2571295a97457264832d54b05ee966Zhijun He // Assuming opaque reader produce opaque images. 8027c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(PublicFormat::PRIVATE); 8037c3997d96a2571295a97457264832d54b05ee966Zhijun He } else { 8040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 8050782aab077b32613c6715190135008dbf3dc5d6dChien-Yu Chen int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat( 8060782aab077b32613c6715190135008dbf3dc5d6dChien-Yu Chen static_cast<PublicFormat>(readerFormat)); 8070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t fmt = applyFormatOverrides( 8080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->mGraphicBuffer->getPixelFormat(), readerHalFormat); 8099cc3f881df13583c93ca08668281413be6412414Zhijun He // Override the image format to HAL_PIXEL_FORMAT_YCbCr_420_888 if the actual format is 8109cc3f881df13583c93ca08668281413be6412414Zhijun He // NV21 or YV12. This could only happen when the Gralloc HAL version is v0.1 thus doesn't 8119cc3f881df13583c93ca08668281413be6412414Zhijun He // support lockycbcr(), the CpuConsumer need to use the lock() method in the 8129cc3f881df13583c93ca08668281413be6412414Zhijun He // lockNextBuffer() call. For Gralloc HAL v0.2 or newer, this format should already be 8139cc3f881df13583c93ca08668281413be6412414Zhijun He // overridden to HAL_PIXEL_FORMAT_YCbCr_420_888 for the flexible YUV compatible formats. 8140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isPossiblyYUV(fmt)) { 8159cc3f881df13583c93ca08668281413be6412414Zhijun He fmt = HAL_PIXEL_FORMAT_YCbCr_420_888; 8169cc3f881df13583c93ca08668281413be6412414Zhijun He } 8177c3997d96a2571295a97457264832d54b05ee966Zhijun He PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat( 8180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He fmt, buffer->mDataSpace); 8197c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(publicFmt); 8207c3997d96a2571295a97457264832d54b05ee966Zhijun He } 8217c3997d96a2571295a97457264832d54b05ee966Zhijun He} 8227c3997d96a2571295a97457264832d54b05ee966Zhijun He 8233e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopianstatic jobject Image_getHardwareBuffer(JNIEnv* env, jobject thiz) { 8243e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian BufferItem* buffer = Image_getBufferItem(env, thiz); 8253e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian AHardwareBuffer* b = AHardwareBuffer_from_GraphicBuffer(buffer->mGraphicBuffer.get()); 8263e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian // don't user the public AHardwareBuffer_toHardwareBuffer() because this would force us 8273e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian // to link against libandroid.so 8283e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian return android_hardware_HardwareBuffer_createFromAHardwareBuffer(env, b); 8293e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian} 8303e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian 831212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} // extern "C" 832212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 833212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 834212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 83576f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gImageReaderMethods[] = { 836212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClassInit", "()V", (void*)ImageReader_classInit }, 837916d8ac650865cd05808d48bad68b69bebbc95abZhijun He {"nativeInit", "(Ljava/lang/Object;IIIIJ)V", (void*)ImageReader_init }, 838212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClose", "()V", (void*)ImageReader_close }, 839212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, 840f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup }, 841212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, 842ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He {"nativeDetachImage", "(Landroid/media/Image;)I", (void*)ImageReader_detachImage }, 8432e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala {"nativeDiscardFreeBuffers", "()V", (void*)ImageReader_discardFreeBuffers } 844212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 845212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 84676f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gImageMethods[] = { 8470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He {"nativeCreatePlanes", "(II)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", 8483e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian (void*)Image_createSurfacePlanes }, 8493e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian {"nativeGetWidth", "()I", (void*)Image_getWidth }, 8503e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian {"nativeGetHeight", "()I", (void*)Image_getHeight }, 8513e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian {"nativeGetFormat", "(I)I", (void*)Image_getFormat }, 8523e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian {"nativeGetHardwareBuffer", "()Landroid/hardware/HardwareBuffer;", 8533e88ed82e58acd93419f6dc844b8139208cc5f1eMathias Agopian (void*)Image_getHardwareBuffer }, 854212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 855212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 856212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heint register_android_media_ImageReader(JNIEnv *env) { 857212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 858212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret1 = AndroidRuntime::registerNativeMethods(env, 859212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods)); 860212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 861212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret2 = AndroidRuntime::registerNativeMethods(env, 862212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods)); 863212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 864212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return (ret1 || ret2); 865212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 866