android_media_ImageReader.cpp revision 916d8ac650865cd05808d48bad68b69bebbc95ab
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> 30534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He#include <camera3.h> 31212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 32212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/AndroidRuntime.h> 33212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/android_view_Surface.h> 34916d8ac650865cd05808d48bad68b69bebbc95abZhijun He#include <android_runtime/android_hardware_HardwareBuffer.h> 35916d8ac650865cd05808d48bad68b69bebbc95abZhijun He#include <grallocusage/GrallocUsageConversion.h> 36212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 37212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <jni.h> 38212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <JNIHelp.h> 39212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 405096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <stdint.h> 415096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <inttypes.h> 425096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 43212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" 44ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mNativeBuffer" 45212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" 46212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 47916d8ac650865cd05808d48bad68b69bebbc95abZhijun He#define CONSUMER_BUFFER_USAGE_UNKNOWN 0; 48212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 49212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 50212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heusing namespace android; 51212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 52212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 53e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinenum { 54e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_SUCCESS = 0, 55e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_NO_BUFFERS = 1, 56e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_MAX_IMAGES = 2, 57e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin}; 58e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin 59ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 60ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mNativeContext; 61ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jmethodID postEventFromNative; 62ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gImageReaderClassInfo; 63ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown 64ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 65ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jfieldID mNativeBuffer; 66ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mTimestamp; 670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jfieldID mPlanes; 68ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfaceImageClassInfo; 69212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 70ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 71212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz; 72212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jmethodID ctor; 73ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfacePlaneClassInfo; 74212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 75ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala// Get an ID that's unique within this process. 76ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvalastatic int32_t createProcessUniqueId() { 77ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala static volatile int32_t globalCounter = 0; 78ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala return android_atomic_inc(&globalCounter); 79ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala} 80ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala 81212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 82212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 83ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Heclass JNIImageReaderContext : public ConsumerBase::FrameAvailableListener 84212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 85212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hepublic: 86212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext(JNIEnv* env, jobject weakThiz, jclass clazz, int maxImages); 87212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 88212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He virtual ~JNIImageReaderContext(); 89212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 902c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stoza virtual void onFrameAvailable(const BufferItem& item); 91212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* getBufferItem(); 930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void returnBufferItem(BufferItem* buffer); 94ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 95212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void setBufferConsumer(const sp<BufferItemConsumer>& consumer) { mConsumer = consumer; } 970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* getBufferConsumer() { return mConsumer.get(); } 98ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 995b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; } 1005b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* getProducer() { return mProducer.get(); } 101212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 102212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferFormat(int format) { mFormat = format; } 103212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferFormat() { return mFormat; } 104212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 105805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala void setBufferDataspace(android_dataspace dataSpace) { mDataSpace = dataSpace; } 106805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace getBufferDataspace() { return mDataSpace; } 107805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala 108212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferWidth(int width) { mWidth = width; } 109212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferWidth() { return mWidth; } 110212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 111212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferHeight(int height) { mHeight = height; } 112212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferHeight() { return mHeight; } 113212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 114212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heprivate: 115212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static JNIEnv* getJNIEnv(bool* needsDetach); 116212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static void detachJNI(); 117212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He List<BufferItem*> mBuffers; 1190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<BufferItemConsumer> mConsumer; 1205b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<IGraphicBufferProducer> mProducer; 121212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject mWeakThiz; 122212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass mClazz; 123212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mFormat; 124805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace mDataSpace; 125212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mWidth; 126212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mHeight; 127212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 128212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 129212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::JNIImageReaderContext(JNIEnv* env, 130212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject weakThiz, jclass clazz, int maxImages) : 131212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mWeakThiz(env->NewGlobalRef(weakThiz)), 1320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mClazz((jclass)env->NewGlobalRef(clazz)), 1330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mFormat(0), 1340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mDataSpace(HAL_DATASPACE_UNKNOWN), 1350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mWidth(-1), 1360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mHeight(-1) { 137212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (int i = 0; i < maxImages; i++) { 1380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = new BufferItem; 139212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 140212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 141212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 142212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 143212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) { 144212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!"); 145212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = false; 146212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = AndroidRuntime::getJNIEnv(); 147212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env == NULL) { 148212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; 149212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 150212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->AttachCurrentThread(&env, (void*) &args); 151212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 152212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread attach failed: %#x", result); 153212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 154212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 155212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = true; 156212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 157212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return env; 158212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 159212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 160212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hevoid JNIImageReaderContext::detachJNI() { 161212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 162212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->DetachCurrentThread(); 163212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 164212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread detach failed: %#x", result); 165212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 166212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 167212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1680ab416269a866c8afa8f65d9351afa2407abee4cZhijun HeBufferItem* JNIImageReaderContext::getBufferItem() { 169212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (mBuffers.empty()) { 170212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 171212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return a BufferItem pointer and remove it from the list 1730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He List<BufferItem*>::iterator it = mBuffers.begin(); 1740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = *it; 175212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.erase(it); 176212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return buffer; 177212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 178212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1790ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hevoid JNIImageReaderContext::returnBufferItem(BufferItem* buffer) { 180212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 181212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 182212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 183212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::~JNIImageReaderContext() { 184212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 185212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 186212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 187212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mWeakThiz); 188212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mClazz); 189212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 190212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("leaking JNI object references"); 191212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 192212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 193212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 194212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 195212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Delete buffer items. 1970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He for (List<BufferItem *>::iterator it = mBuffers.begin(); 198212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He it != mBuffers.end(); it++) { 199212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He delete *it; 200212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 201ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 202ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (mConsumer != 0) { 203ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mConsumer.clear(); 204ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 205212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 206212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2072c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stozavoid JNIImageReaderContext::onFrameAvailable(const BufferItem& /*item*/) 208212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 209212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: frame available", __FUNCTION__); 210212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 211212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 212212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 213ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz); 214212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 215212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("onFrameAvailable event will not posted"); 216212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 217212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 218212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 219212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 220212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 221212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 222212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 223212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 224212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heextern "C" { 225212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 226212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz) 227212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 228212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext *ctx; 229212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx = reinterpret_cast<JNIImageReaderContext *> 230ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext)); 231212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx; 232212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 233212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2345b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stozastatic IGraphicBufferProducer* ImageReader_getProducer(JNIEnv* env, jobject thiz) 23552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{ 23652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian ALOGV("%s:", __FUNCTION__); 23752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 23852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian if (ctx == NULL) { 23952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 24052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return NULL; 24152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian } 242ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2435b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return ctx->getProducer(); 24452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian} 24552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian 246212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_setNativeContext(JNIEnv* env, 247212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject thiz, sp<JNIImageReaderContext> ctx) 248212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 249212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 250212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const p = ImageReader_getContext(env, thiz); 251212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx != 0) { 252212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->incStrong((void*)ImageReader_setNativeContext); 253212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 254212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (p) { 255212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He p->decStrong((void*)ImageReader_setNativeContext); 256212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 257ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext, 258ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown reinterpret_cast<jlong>(ctx.get())); 259212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 260212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2610ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic BufferItemConsumer* ImageReader_getBufferConsumer(JNIEnv* env, jobject thiz) 262ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 263ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGV("%s:", __FUNCTION__); 264ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 265ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx == NULL) { 266ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 267ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 268ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 269ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return ctx->getBufferConsumer(); 2710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 272ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2730ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_setBufferItem(JNIEnv* env, jobject thiz, 2740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He const BufferItem* buffer) 2750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He{ 2760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer, reinterpret_cast<jlong>(buffer)); 277ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 278ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2790ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic BufferItem* Image_getBufferItem(JNIEnv* env, jobject image) 280ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 281ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return reinterpret_cast<BufferItem*>( 282ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->GetLongField(image, gSurfaceImageClassInfo.mNativeBuffer)); 283ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 284ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 285ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 286212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 287212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 288212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_classInit(JNIEnv* env, jclass clazz) 289212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 290212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 291212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 292212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage"); 293212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(imageClazz == NULL, 294212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader$SurfaceImage"); 295ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He gSurfaceImageClassInfo.mNativeBuffer = env->GetFieldID( 296ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J"); 297ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mNativeBuffer == NULL, 298212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 299212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID); 300212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 301ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mTimestamp = env->GetFieldID( 302ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J"); 303ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL, 304212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 305212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); 306212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 3070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He gSurfaceImageClassInfo.mPlanes = env->GetFieldID( 3080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He imageClazz, "mPlanes", "[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;"); 3090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mPlanes == NULL, 3100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "can't find android/media/ImageReader$ReaderSurfaceImage.mPlanes"); 3110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 312ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.mNativeContext = env->GetFieldID( 313ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J"); 314ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL, 315212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 316212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID); 317212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 318ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID( 319ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, "postEventFromNative", "(Ljava/lang/Object;)V"); 320ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL, 321212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.postEventFromNative"); 322212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 323212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane"); 324212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class"); 325212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // FindClass only gives a local reference of jclass object. 326ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); 327ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>", 3280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "(Landroid/media/ImageReader$SurfaceImage;IILjava/nio/ByteBuffer;)V"); 329ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, 330ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "Can not find SurfacePlane constructor"); 331212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 332212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 333916d8ac650865cd05808d48bad68b69bebbc95abZhijun Hestatic void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint width, jint height, 334916d8ac650865cd05808d48bad68b69bebbc95abZhijun He jint format, jint maxImages, jlong ndkUsage) 335212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 336212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res; 337212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int nativeFormat; 338805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace nativeDataspace; 339212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 340212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d", 341212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He __FUNCTION__, width, height, format, maxImages); 342212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 343805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala PublicFormat publicFormat = static_cast<PublicFormat>(format); 344805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeFormat = android_view_Surface_mapPublicFormatToHalFormat( 345805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 346805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeDataspace = android_view_Surface_mapPublicFormatToHalDataspace( 347805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 348212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 349212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz = env->GetObjectClass(thiz); 350212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (clazz == NULL) { 351212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader"); 352212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 353212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 354212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages)); 355ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 356ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferProducer> gbProducer; 357ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferConsumer> gbConsumer; 358ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 3590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<BufferItemConsumer> bufferConsumer; 360ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d", 361ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala width, height, format, maxImages, getpid(), 362ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala createProcessUniqueId()); 3630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t consumerUsage = GRALLOC_USAGE_SW_READ_OFTEN; 364916d8ac650865cd05808d48bad68b69bebbc95abZhijun He bool needUsageOverride = ndkUsage != CONSUMER_BUFFER_USAGE_UNKNOWN; 365916d8ac650865cd05808d48bad68b69bebbc95abZhijun He uint64_t outProducerUsage = 0; 366916d8ac650865cd05808d48bad68b69bebbc95abZhijun He uint64_t outConsumerUsage = 0; 367916d8ac650865cd05808d48bad68b69bebbc95abZhijun He android_hardware_HardwareBuffer_convertToGrallocUsageBits(&outProducerUsage, &outConsumerUsage, 368916d8ac650865cd05808d48bad68b69bebbc95abZhijun He ndkUsage, 0); 3690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 370ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(nativeFormat)) { 371ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Use the SW_READ_NEVER usage to tell producer that this format is not for preview or video 372ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // encoding. The only possibility will be ZSL output. 3730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He consumerUsage = GRALLOC_USAGE_SW_READ_NEVER; 374916d8ac650865cd05808d48bad68b69bebbc95abZhijun He if (needUsageOverride) { 375916d8ac650865cd05808d48bad68b69bebbc95abZhijun He consumerUsage = android_convertGralloc1To0Usage(0, outConsumerUsage); 376916d8ac650865cd05808d48bad68b69bebbc95abZhijun He } 377916d8ac650865cd05808d48bad68b69bebbc95abZhijun He } else if (needUsageOverride) { 378916d8ac650865cd05808d48bad68b69bebbc95abZhijun He ALOGW("Consumer usage override for non-opaque format is not implemented yet, " 379916d8ac650865cd05808d48bad68b69bebbc95abZhijun He "ignore the provided usage from the application"); 380ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 3810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer = new BufferItemConsumer(gbConsumer, consumerUsage, maxImages, 3820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /*controlledByApp*/true); 3830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (bufferConsumer == nullptr) { 3840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/RuntimeException", 385916d8ac650865cd05808d48bad68b69bebbc95abZhijun He "Failed to allocate native buffer consumer for format 0x%x and usage 0x%x", 386916d8ac650865cd05808d48bad68b69bebbc95abZhijun He nativeFormat, consumerUsage); 3870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 3880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 3890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->setBufferConsumer(bufferConsumer); 3900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->setName(consumerName); 391ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 3925b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza ctx->setProducer(gbProducer); 3930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->setFrameAvailableListener(ctx); 394212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, ctx); 395212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferFormat(nativeFormat); 396805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala ctx->setBufferDataspace(nativeDataspace); 397212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferWidth(width); 398212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferHeight(height); 399212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Set the width/height/format/dataspace to the bufferConsumer. 4010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferSize(width, height); 4020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 4040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default size (%dx%d) for format 0x%x", 4050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He width, height, nativeFormat); 4060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 4070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferFormat(nativeFormat); 4090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 4110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default format 0x%x", nativeFormat); 4120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferDataSpace(nativeDataspace); 4140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 4160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default dataSpace 0x%x", nativeDataspace); 417805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala } 418212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 419212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 420212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_close(JNIEnv* env, jobject thiz) 421212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 422212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 423212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 424212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 425212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 426212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // ImageReader is already closed. 427212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 428212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 429212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* consumer = NULL; 4310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He consumer = ImageReader_getBufferConsumer(env, thiz); 432ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 433212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer != NULL) { 434212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->abandon(); 435212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(NULL); 436212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 437212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, NULL); 438212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 439212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4400ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic sp<Fence> Image_unlockIfLocked(JNIEnv* env, jobject image) { 4410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 4420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 4430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) { 4440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 4450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image is not initialized"); 4460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 4490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Is locked? 4500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bool wasBufferLocked = false; 4510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject planes = NULL; 4520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!isFormatOpaque(buffer->mGraphicBuffer->getPixelFormat())) { 4530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He planes = env->GetObjectField(image, gSurfaceImageClassInfo.mPlanes); 4540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He wasBufferLocked = (planes != NULL); 4560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (wasBufferLocked) { 4570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = OK; 4580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int fenceFd = -1; 4590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (wasBufferLocked) { 4600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = buffer->mGraphicBuffer->unlockAsync(&fenceFd); 4610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "unlock buffer failed"); 4630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<Fence> releaseFence = new Fence(fenceFd); 4670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return releaseFence; 4680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("Successfully unlocked the image"); 4690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 4720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 473212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image) 474212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 475212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 476212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 477212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 478212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("ImageReader#close called before Image#close, consider calling Image#close first"); 479212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 480212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 481212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 4830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 4840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == nullptr) { 4850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Release an already closed image is harmless. 4860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 487212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 4880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 4890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<Fence> releaseFence = Image_unlockIfLocked(env, image); 4900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->releaseBuffer(*buffer, releaseFence); 4910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_setBufferItem(env, image, NULL); 4920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 4930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Image (format: 0x%x) has been released", __FUNCTION__, ctx->getBufferFormat()); 494212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 495212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4960ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) { 497212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 4980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 4990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (ctx == NULL) { 5000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 5010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "ImageReader is not initialized or was already closed"); 502e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 503212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 504212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 5060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = ctx->getBufferItem(); 507ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (buffer == NULL) { 508ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGW("Unable to acquire a buffer item, very likely client tried to acquire more than" 509ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He " maxImages buffers"); 510ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ACQUIRE_MAX_IMAGES; 511ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 512ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 5130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = bufferConsumer->acquireBuffer(buffer, 0); 514ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 5150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 5160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != BufferQueue::NO_BUFFER_AVAILABLE) { 5170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res == INVALID_OPERATION) { 5180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Max number of images were already acquired. 5190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: Max number of buffers allowed are already acquired : %s (%d)", 5200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, strerror(-res), res); 521e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 522dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } else { 5230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: Acquire image failed with some unknown error: %s (%d)", 5240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, strerror(-res), res); 5250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 5260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Unknown error (%d) when we tried to acquire an image.", 5270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res); 5280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return ACQUIRE_NO_BUFFERS; 529dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } 530f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown } 5310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // This isn't really an error case, as the application may acquire buffer at any time. 532e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_NO_BUFFERS; 533212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 534212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Add some extra checks for non-opaque formats. 5360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!isFormatOpaque(ctx->getBufferFormat())) { 5370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Check if the left-top corner of the crop rect is origin, we currently assume this point is 5380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // zero, will revisit this once this assumption turns out problematic. 5390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Point lt = buffer->mCrop.leftTop(); 5400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (lt.x != 0 || lt.y != 0) { 5410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 5420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 5430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return -1; 5440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5454eda9f5359347c11914e47f477535c9533674d32Zhijun He 5460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Check if the producer buffer configurations match what ImageReader configured. 5470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int outputWidth = getBufferWidth(buffer); 5480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int outputHeight = getBufferHeight(buffer); 5490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imgReaderFmt = ctx->getBufferFormat(); 5510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imageReaderWidth = ctx->getBufferWidth(); 5520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imageReaderHeight = ctx->getBufferHeight(); 5530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int bufferFormat = buffer->mGraphicBuffer->getPixelFormat(); 5540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if ((bufferFormat != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) && 5550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) { 5560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", 5570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); 5580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (imgReaderFmt != bufferFormat) { 5600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && 5610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He isPossiblyYUV(bufferFormat)) { 5620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Treat formats that are compatible with flexible YUV 5630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // (HAL_PIXEL_FORMAT_YCbCr_420_888) as HAL_PIXEL_FORMAT_YCbCr_420_888. 5640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCbCr_420_888", 5650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, bufferFormat); 5660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && 5670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) { 5680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Using HAL_PIXEL_FORMAT_RGBA_8888 Gralloc buffers containing JPEGs to get around 5690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // SW write limitations for (b/17379185). 5700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.", __FUNCTION__); 5710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else { 5720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return the buffer to the queue. No need to provide fence, as this buffer wasn't 5730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // used anywhere yet. 5740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->releaseBuffer(*buffer); 5750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 5760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Throw exception 5780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 5790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat, ctx->getBufferFormat()); 5800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He String8 msg; 5810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.appendFormat("The producer output buffer format 0x%x doesn't " 5820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "match the ImageReader's configured buffer format 0x%x.", 5830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat, ctx->getBufferFormat()); 5840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 5850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.string()); 5860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return -1; 5870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 589212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 590212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 591212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 592212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set SurfaceImage instance member variables 5930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_setBufferItem(env, image, buffer); 594ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 5950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He static_cast<jlong>(buffer->mTimestamp)); 596212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 597e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_SUCCESS; 598212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 599212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 600ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint ImageReader_detachImage(JNIEnv* env, jobject thiz, jobject image) { 601f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He ALOGV("%s:", __FUNCTION__); 602f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 603f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (ctx == NULL) { 604f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed"); 605ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 606f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 607f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 6080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 6090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 6100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!buffer) { 611ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGE( 6120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image already released and can not be detached from ImageReader!!!"); 613ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 6140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image detach from ImageReader failed: buffer was already released"); 615ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 616ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 617ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 6180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = OK; 6190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_unlockIfLocked(env, image); 6200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->detachBuffer(buffer->mSlot); 621ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 6220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Image detach failed: %s (%d)!!!", strerror(-res), res); 623ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, 6240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "nativeDetachImage failed for image!!!"); 625ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return res; 626ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 627ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return OK; 628f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He} 629f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 6302e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvalastatic void ImageReader_discardFreeBuffers(JNIEnv* env, jobject thiz) { 6312e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala ALOGV("%s:", __FUNCTION__); 6322e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 6332e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala if (ctx == NULL) { 6342e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed"); 6352e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala return; 6362e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala } 6372e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala 6382e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 6392e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala status_t res = bufferConsumer->discardFreeBuffers(); 6402e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala if (res != OK) { 6412e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala ALOGE("Buffer discard failed: %s (%d)", strerror(-res), res); 6422e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala jniThrowRuntimeException(env, 6432e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala "nativeDicardFreebuffers failed"); 6442e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala } 6452e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala} 6462e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala 647212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) 648212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 649212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: ", __FUNCTION__); 650212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6515b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* gbp = ImageReader_getProducer(env, thiz); 6525b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza if (gbp == NULL) { 6530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "Buffer consumer is uninitialized"); 654212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 655212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 656212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 657212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Wrap the IGBP in a Java-language Surface. 6585b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return android_view_Surface_createFromIGraphicBufferProducer(env, gbp); 659212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 660212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6610ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) { 6620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 6630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 6640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) { 665ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 6660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image is not initialized"); 6670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 668ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 669212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = lockImageFromBuffer(buffer, 6710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He GRALLOC_USAGE_SW_READ_OFTEN, buffer->mFence->dup(), image); 6720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 6730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/RuntimeException", 6740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "lock buffer failed for format 0x%x", 6750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->mGraphicBuffer->getPixelFormat()); 6760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 677212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 6780fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 6790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Carry over some fields from BufferItem. 6800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->crop = buffer->mCrop; 6810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->transform = buffer->mTransform; 6820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->scalingMode = buffer->mScalingMode; 6830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->timestamp = buffer->mTimestamp; 6840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->dataSpace = buffer->mDataSpace; 6850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->frameNumber = buffer->mFrameNumber; 6860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Successfully locked the image", __FUNCTION__); 6880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // crop, transform, scalingMode, timestamp, and frameNumber should be set by producer, 6890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // and we don't set them here. 6900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 691212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6920ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx, 6930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t writerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) { 6940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 695212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = getLockedImageInfo(buffer, idx, writerFormat, base, size, 6970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pixelStride, rowStride); 6980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 6990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 7000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Pixel format: 0x%x is unsupported", buffer->flexFormat); 7010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 702212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 703212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7040ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, 7050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int numPlanes, int readerFormat) 706212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 7070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes); 7080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int rowStride = 0; 7090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int pixelStride = 0; 7100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t *pData = NULL; 7110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t dataSize = 0; 7120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject byteBuffer = NULL; 713212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He PublicFormat publicReaderFormat = static_cast<PublicFormat>(readerFormat); 7150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int halReaderFormat = android_view_Surface_mapPublicFormatToHalFormat( 7160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He publicReaderFormat); 717212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(halReaderFormat) && numPlanes > 0) { 7190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He String8 msg; 7200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)" 7210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He " must be 0", halReaderFormat, numPlanes); 7220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalArgumentException", msg.string()); 723ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 724ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 725ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 7260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobjectArray surfacePlanes = env->NewObjectArray(numPlanes, gSurfacePlaneClassInfo.clazz, 7270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /*initial_element*/NULL); 7280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (surfacePlanes == NULL) { 7290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "Failed to create SurfacePlane arrays," 7300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He " probably out of memory"); 7315096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return NULL; 7325096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 7330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(halReaderFormat)) { 7340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return 0 element surface array. 7350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return surfacePlanes; 7360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 7370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LockedImage lockedImg = LockedImage(); 7390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_getLockedImage(env, thiz, &lockedImg); 740252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih if (env->ExceptionCheck()) { 741252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih return NULL; 742252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih } 7430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Create all SurfacePlanes 7440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He for (int i = 0; i < numPlanes; i++) { 7450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_getLockedImageInfo(env, &lockedImg, i, halReaderFormat, 7460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He &pData, &dataSize, &pixelStride, &rowStride); 7470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He byteBuffer = env->NewDirectByteBuffer(pData, dataSize); 7480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { 7490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 7500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to allocate ByteBuffer"); 7510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return NULL; 7520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 7535096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 7540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Finally, create this SurfacePlane. 7550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject surfacePlane = env->NewObject(gSurfacePlaneClassInfo.clazz, 7560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He gSurfacePlaneClassInfo.ctor, thiz, rowStride, pixelStride, byteBuffer); 7570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He env->SetObjectArrayElement(surfacePlanes, i, surfacePlane); 758212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 759212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return surfacePlanes; 761212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 762212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7630ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint Image_getWidth(JNIEnv* env, jobject thiz) 764f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 7650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return getBufferWidth(buffer); 767f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 768f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 7690ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint Image_getHeight(JNIEnv* env, jobject thiz) 770f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 7710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return getBufferHeight(buffer); 773f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 774f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 7757c3997d96a2571295a97457264832d54b05ee966Zhijun Hestatic jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat) 7767c3997d96a2571295a97457264832d54b05ee966Zhijun He{ 7777c3997d96a2571295a97457264832d54b05ee966Zhijun He if (isFormatOpaque(readerFormat)) { 7787c3997d96a2571295a97457264832d54b05ee966Zhijun He // Assuming opaque reader produce opaque images. 7797c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(PublicFormat::PRIVATE); 7807c3997d96a2571295a97457264832d54b05ee966Zhijun He } else { 7810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7820782aab077b32613c6715190135008dbf3dc5d6dChien-Yu Chen int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat( 7830782aab077b32613c6715190135008dbf3dc5d6dChien-Yu Chen static_cast<PublicFormat>(readerFormat)); 7840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t fmt = applyFormatOverrides( 7850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->mGraphicBuffer->getPixelFormat(), readerHalFormat); 7869cc3f881df13583c93ca08668281413be6412414Zhijun He // Override the image format to HAL_PIXEL_FORMAT_YCbCr_420_888 if the actual format is 7879cc3f881df13583c93ca08668281413be6412414Zhijun He // NV21 or YV12. This could only happen when the Gralloc HAL version is v0.1 thus doesn't 7889cc3f881df13583c93ca08668281413be6412414Zhijun He // support lockycbcr(), the CpuConsumer need to use the lock() method in the 7899cc3f881df13583c93ca08668281413be6412414Zhijun He // lockNextBuffer() call. For Gralloc HAL v0.2 or newer, this format should already be 7909cc3f881df13583c93ca08668281413be6412414Zhijun He // overridden to HAL_PIXEL_FORMAT_YCbCr_420_888 for the flexible YUV compatible formats. 7910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isPossiblyYUV(fmt)) { 7929cc3f881df13583c93ca08668281413be6412414Zhijun He fmt = HAL_PIXEL_FORMAT_YCbCr_420_888; 7939cc3f881df13583c93ca08668281413be6412414Zhijun He } 7947c3997d96a2571295a97457264832d54b05ee966Zhijun He PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat( 7950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He fmt, buffer->mDataSpace); 7967c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(publicFmt); 7977c3997d96a2571295a97457264832d54b05ee966Zhijun He } 7987c3997d96a2571295a97457264832d54b05ee966Zhijun He} 7997c3997d96a2571295a97457264832d54b05ee966Zhijun He 800212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} // extern "C" 801212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 802212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 803212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 80476f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gImageReaderMethods[] = { 805212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClassInit", "()V", (void*)ImageReader_classInit }, 806916d8ac650865cd05808d48bad68b69bebbc95abZhijun He {"nativeInit", "(Ljava/lang/Object;IIIIJ)V", (void*)ImageReader_init }, 807212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClose", "()V", (void*)ImageReader_close }, 808212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, 809f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup }, 810212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, 811ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He {"nativeDetachImage", "(Landroid/media/Image;)I", (void*)ImageReader_detachImage }, 8122e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala {"nativeDiscardFreeBuffers", "()V", (void*)ImageReader_discardFreeBuffers } 813212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 814212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 81576f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gImageMethods[] = { 8160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He {"nativeCreatePlanes", "(II)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", 8170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (void*)Image_createSurfacePlanes }, 8180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He {"nativeGetWidth", "()I", (void*)Image_getWidth }, 8190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He {"nativeGetHeight", "()I", (void*)Image_getHeight }, 8207c3997d96a2571295a97457264832d54b05ee966Zhijun He {"nativeGetFormat", "(I)I", (void*)Image_getFormat }, 821212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 822212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 823212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heint register_android_media_ImageReader(JNIEnv *env) { 824212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 825212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret1 = AndroidRuntime::registerNativeMethods(env, 826212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods)); 827212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 828212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret2 = AndroidRuntime::registerNativeMethods(env, 829212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods)); 830212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 831212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return (ret1 || ret2); 832212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 833