android_media_ImageReader.cpp revision 252f3b20bb158ddde6ffa687eff9c4d070919091
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> 34212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 35212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <jni.h> 36212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <JNIHelp.h> 37212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 385096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <stdint.h> 395096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <inttypes.h> 405096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 41212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" 42ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mNativeBuffer" 43212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" 44212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 45212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 46212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 47212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heusing namespace android; 48212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 49212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 50e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinenum { 51e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_SUCCESS = 0, 52e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_NO_BUFFERS = 1, 53e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_MAX_IMAGES = 2, 54e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin}; 55e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin 56ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 57ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mNativeContext; 58ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jmethodID postEventFromNative; 59ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gImageReaderClassInfo; 60ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown 61ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 62ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jfieldID mNativeBuffer; 63ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mTimestamp; 640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jfieldID mPlanes; 65ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfaceImageClassInfo; 66212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 67ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 68212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz; 69212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jmethodID ctor; 70ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfacePlaneClassInfo; 71212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 72ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala// Get an ID that's unique within this process. 73ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvalastatic int32_t createProcessUniqueId() { 74ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala static volatile int32_t globalCounter = 0; 75ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala return android_atomic_inc(&globalCounter); 76ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala} 77ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala 78212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 79212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 80ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Heclass JNIImageReaderContext : public ConsumerBase::FrameAvailableListener 81212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 82212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hepublic: 83212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext(JNIEnv* env, jobject weakThiz, jclass clazz, int maxImages); 84212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 85212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He virtual ~JNIImageReaderContext(); 86212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 872c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stoza virtual void onFrameAvailable(const BufferItem& item); 88212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* getBufferItem(); 900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void returnBufferItem(BufferItem* buffer); 91ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 92212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void setBufferConsumer(const sp<BufferItemConsumer>& consumer) { mConsumer = consumer; } 940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* getBufferConsumer() { return mConsumer.get(); } 95ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 965b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; } 975b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* getProducer() { return mProducer.get(); } 98212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 99212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferFormat(int format) { mFormat = format; } 100212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferFormat() { return mFormat; } 101212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 102805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala void setBufferDataspace(android_dataspace dataSpace) { mDataSpace = dataSpace; } 103805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace getBufferDataspace() { return mDataSpace; } 104805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala 105212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferWidth(int width) { mWidth = width; } 106212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferWidth() { return mWidth; } 107212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 108212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferHeight(int height) { mHeight = height; } 109212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferHeight() { return mHeight; } 110212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 111212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heprivate: 112212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static JNIEnv* getJNIEnv(bool* needsDetach); 113212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static void detachJNI(); 114212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He List<BufferItem*> mBuffers; 1160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<BufferItemConsumer> mConsumer; 1175b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<IGraphicBufferProducer> mProducer; 118212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject mWeakThiz; 119212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass mClazz; 120212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mFormat; 121805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace mDataSpace; 122212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mWidth; 123212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mHeight; 124212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 125212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 126212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::JNIImageReaderContext(JNIEnv* env, 127212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject weakThiz, jclass clazz, int maxImages) : 128212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mWeakThiz(env->NewGlobalRef(weakThiz)), 1290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mClazz((jclass)env->NewGlobalRef(clazz)), 1300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mFormat(0), 1310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mDataSpace(HAL_DATASPACE_UNKNOWN), 1320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mWidth(-1), 1330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He mHeight(-1) { 134212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (int i = 0; i < maxImages; i++) { 1350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = new BufferItem; 136212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 137212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 138212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 139212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 140212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) { 141212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!"); 142212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = false; 143212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = AndroidRuntime::getJNIEnv(); 144212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env == NULL) { 145212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; 146212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 147212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->AttachCurrentThread(&env, (void*) &args); 148212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 149212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread attach failed: %#x", result); 150212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 151212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 152212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = true; 153212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 154212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return env; 155212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 156212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 157212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hevoid JNIImageReaderContext::detachJNI() { 158212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 159212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->DetachCurrentThread(); 160212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 161212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread detach failed: %#x", result); 162212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 163212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 164212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1650ab416269a866c8afa8f65d9351afa2407abee4cZhijun HeBufferItem* JNIImageReaderContext::getBufferItem() { 166212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (mBuffers.empty()) { 167212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 168212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return a BufferItem pointer and remove it from the list 1700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He List<BufferItem*>::iterator it = mBuffers.begin(); 1710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = *it; 172212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.erase(it); 173212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return buffer; 174212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 175212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1760ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hevoid JNIImageReaderContext::returnBufferItem(BufferItem* buffer) { 177212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 178212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 179212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 180212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::~JNIImageReaderContext() { 181212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 182212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 183212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 184212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mWeakThiz); 185212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mClazz); 186212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 187212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("leaking JNI object references"); 188212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 189212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 190212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 191212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 192212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Delete buffer items. 1940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He for (List<BufferItem *>::iterator it = mBuffers.begin(); 195212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He it != mBuffers.end(); it++) { 196212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He delete *it; 197212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 198ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 199ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (mConsumer != 0) { 200ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mConsumer.clear(); 201ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 202212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 203212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2042c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stozavoid JNIImageReaderContext::onFrameAvailable(const BufferItem& /*item*/) 205212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 206212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: frame available", __FUNCTION__); 207212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 208212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 209212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 210ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz); 211212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 212212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("onFrameAvailable event will not posted"); 213212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 214212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 215212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 216212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 217212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 218212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 219212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 220212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 221212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heextern "C" { 222212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 223212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz) 224212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 225212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext *ctx; 226212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx = reinterpret_cast<JNIImageReaderContext *> 227ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext)); 228212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx; 229212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 230212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2315b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stozastatic IGraphicBufferProducer* ImageReader_getProducer(JNIEnv* env, jobject thiz) 23252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{ 23352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian ALOGV("%s:", __FUNCTION__); 23452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 23552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian if (ctx == NULL) { 23652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 23752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return NULL; 23852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian } 239ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2405b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return ctx->getProducer(); 24152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian} 24252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian 243212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_setNativeContext(JNIEnv* env, 244212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject thiz, sp<JNIImageReaderContext> ctx) 245212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 246212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 247212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const p = ImageReader_getContext(env, thiz); 248212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx != 0) { 249212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->incStrong((void*)ImageReader_setNativeContext); 250212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 251212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (p) { 252212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He p->decStrong((void*)ImageReader_setNativeContext); 253212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 254ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext, 255ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown reinterpret_cast<jlong>(ctx.get())); 256212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 257212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2580ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic BufferItemConsumer* ImageReader_getBufferConsumer(JNIEnv* env, jobject thiz) 259ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 260ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGV("%s:", __FUNCTION__); 261ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 262ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx == NULL) { 263ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 264ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 265ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 266ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return ctx->getBufferConsumer(); 2680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 269ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2700ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_setBufferItem(JNIEnv* env, jobject thiz, 2710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He const BufferItem* buffer) 2720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He{ 2730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer, reinterpret_cast<jlong>(buffer)); 274ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 275ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2760ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic BufferItem* Image_getBufferItem(JNIEnv* env, jobject image) 277ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 278ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return reinterpret_cast<BufferItem*>( 279ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->GetLongField(image, gSurfaceImageClassInfo.mNativeBuffer)); 280ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 281ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 282ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 283212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 284212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 285212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_classInit(JNIEnv* env, jclass clazz) 286212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 287212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 288212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 289212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage"); 290212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(imageClazz == NULL, 291212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader$SurfaceImage"); 292ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He gSurfaceImageClassInfo.mNativeBuffer = env->GetFieldID( 293ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J"); 294ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mNativeBuffer == NULL, 295212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 296212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID); 297212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 298ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mTimestamp = env->GetFieldID( 299ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J"); 300ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL, 301212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 302212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); 303212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 3040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He gSurfaceImageClassInfo.mPlanes = env->GetFieldID( 3050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He imageClazz, "mPlanes", "[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;"); 3060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mPlanes == NULL, 3070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "can't find android/media/ImageReader$ReaderSurfaceImage.mPlanes"); 3080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 309ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.mNativeContext = env->GetFieldID( 310ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J"); 311ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL, 312212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 313212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID); 314212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 315ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID( 316ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, "postEventFromNative", "(Ljava/lang/Object;)V"); 317ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL, 318212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.postEventFromNative"); 319212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 320212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane"); 321212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class"); 322212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // FindClass only gives a local reference of jclass object. 323ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); 324ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>", 3250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "(Landroid/media/ImageReader$SurfaceImage;IILjava/nio/ByteBuffer;)V"); 326ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, 327ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "Can not find SurfacePlane constructor"); 328212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 329212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 330212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, 331212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jint width, jint height, jint format, jint maxImages) 332212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 333212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res; 334212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int nativeFormat; 335805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace nativeDataspace; 336212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 337212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d", 338212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He __FUNCTION__, width, height, format, maxImages); 339212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 340805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala PublicFormat publicFormat = static_cast<PublicFormat>(format); 341805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeFormat = android_view_Surface_mapPublicFormatToHalFormat( 342805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 343805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeDataspace = android_view_Surface_mapPublicFormatToHalDataspace( 344805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 345212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 346212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz = env->GetObjectClass(thiz); 347212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (clazz == NULL) { 348212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader"); 349212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 350212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 351212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages)); 352ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 353ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferProducer> gbProducer; 354ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferConsumer> gbConsumer; 355ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 3560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<BufferItemConsumer> bufferConsumer; 357ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d", 358ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala width, height, format, maxImages, getpid(), 359ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala createProcessUniqueId()); 3600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t consumerUsage = GRALLOC_USAGE_SW_READ_OFTEN; 3610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 362ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(nativeFormat)) { 363ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Use the SW_READ_NEVER usage to tell producer that this format is not for preview or video 364ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // encoding. The only possibility will be ZSL output. 3650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He consumerUsage = GRALLOC_USAGE_SW_READ_NEVER; 366ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 3670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer = new BufferItemConsumer(gbConsumer, consumerUsage, maxImages, 3680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /*controlledByApp*/true); 3690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (bufferConsumer == nullptr) { 3700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/RuntimeException", 3710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to allocate native buffer consumer for format 0x%x", nativeFormat); 3720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 3730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 3740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->setBufferConsumer(bufferConsumer); 3750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->setName(consumerName); 376ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 3775b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza ctx->setProducer(gbProducer); 3780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->setFrameAvailableListener(ctx); 379212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, ctx); 380212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferFormat(nativeFormat); 381805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala ctx->setBufferDataspace(nativeDataspace); 382212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferWidth(width); 383212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferHeight(height); 384212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 3850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Set the width/height/format/dataspace to the bufferConsumer. 3860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferSize(width, height); 3870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 3880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 3890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default size (%dx%d) for format 0x%x", 3900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He width, height, nativeFormat); 3910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 3920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 3930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferFormat(nativeFormat); 3940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 3950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 3960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default format 0x%x", nativeFormat); 3970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 3980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->setDefaultBufferDataSpace(nativeDataspace); 3990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 4010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to set buffer consumer default dataSpace 0x%x", nativeDataspace); 402805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala } 403212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 404212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 405212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_close(JNIEnv* env, jobject thiz) 406212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 407212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 408212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 409212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 410212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 411212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // ImageReader is already closed. 412212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 413212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 414212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* consumer = NULL; 4160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He consumer = ImageReader_getBufferConsumer(env, thiz); 417ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 418212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer != NULL) { 419212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->abandon(); 420212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(NULL); 421212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 422212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, NULL); 423212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 424212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4250ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic sp<Fence> Image_unlockIfLocked(JNIEnv* env, jobject image) { 4260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 4270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 4280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) { 4290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 4300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image is not initialized"); 4310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 4340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Is locked? 4350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bool wasBufferLocked = false; 4360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject planes = NULL; 4370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!isFormatOpaque(buffer->mGraphicBuffer->getPixelFormat())) { 4380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He planes = env->GetObjectField(image, gSurfaceImageClassInfo.mPlanes); 4390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He wasBufferLocked = (planes != NULL); 4410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (wasBufferLocked) { 4420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = OK; 4430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int fenceFd = -1; 4440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (wasBufferLocked) { 4450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = buffer->mGraphicBuffer->unlockAsync(&fenceFd); 4460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 4470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "unlock buffer failed"); 4480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<Fence> releaseFence = new Fence(fenceFd); 4520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return releaseFence; 4530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("Successfully unlocked the image"); 4540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 4550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return Fence::NO_FENCE; 4560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 4570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 458212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image) 459212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 460212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 461212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 462212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 463212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("ImageReader#close called before Image#close, consider calling Image#close first"); 464212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 465212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 466212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 4680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 4690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == nullptr) { 4700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Release an already closed image is harmless. 4710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 472212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 4730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 4740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He sp<Fence> releaseFence = Image_unlockIfLocked(env, image); 4750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->releaseBuffer(*buffer, releaseFence); 4760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_setBufferItem(env, image, NULL); 4770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 4780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Image (format: 0x%x) has been released", __FUNCTION__, ctx->getBufferFormat()); 479212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 480212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4810ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) { 482212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 4830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 4840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (ctx == NULL) { 4850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 4860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "ImageReader is not initialized or was already closed"); 487e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 488212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 489212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 4910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = ctx->getBufferItem(); 492ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (buffer == NULL) { 493ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGW("Unable to acquire a buffer item, very likely client tried to acquire more than" 494ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He " maxImages buffers"); 495ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ACQUIRE_MAX_IMAGES; 496ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 497ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 4980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = bufferConsumer->acquireBuffer(buffer, 0); 499ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 5000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 5010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != BufferQueue::NO_BUFFER_AVAILABLE) { 5020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res == INVALID_OPERATION) { 5030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Max number of images were already acquired. 5040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: Max number of buffers allowed are already acquired : %s (%d)", 5050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, strerror(-res), res); 506e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 507dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } else { 5080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: Acquire image failed with some unknown error: %s (%d)", 5090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, strerror(-res), res); 5100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 5110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Unknown error (%d) when we tried to acquire an image.", 5120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res); 5130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return ACQUIRE_NO_BUFFERS; 514dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } 515f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown } 5160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // This isn't really an error case, as the application may acquire buffer at any time. 517e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_NO_BUFFERS; 518212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 519212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Add some extra checks for non-opaque formats. 5210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!isFormatOpaque(ctx->getBufferFormat())) { 5220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Check if the left-top corner of the crop rect is origin, we currently assume this point is 5230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // zero, will revisit this once this assumption turns out problematic. 5240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Point lt = buffer->mCrop.leftTop(); 5250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (lt.x != 0 || lt.y != 0) { 5260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 5270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 5280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return -1; 5290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5304eda9f5359347c11914e47f477535c9533674d32Zhijun He 5310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Check if the producer buffer configurations match what ImageReader configured. 5320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int outputWidth = getBufferWidth(buffer); 5330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int outputHeight = getBufferHeight(buffer); 5340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imgReaderFmt = ctx->getBufferFormat(); 5360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imageReaderWidth = ctx->getBufferWidth(); 5370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int imageReaderHeight = ctx->getBufferHeight(); 5380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int bufferFormat = buffer->mGraphicBuffer->getPixelFormat(); 5390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if ((bufferFormat != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) && 5400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) { 5410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", 5420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); 5430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (imgReaderFmt != bufferFormat) { 5450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && 5460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He isPossiblyYUV(bufferFormat)) { 5470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Treat formats that are compatible with flexible YUV 5480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // (HAL_PIXEL_FORMAT_YCbCr_420_888) as HAL_PIXEL_FORMAT_YCbCr_420_888. 5490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCbCr_420_888", 5500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, bufferFormat); 5510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && 5520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) { 5530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Using HAL_PIXEL_FORMAT_RGBA_8888 Gralloc buffers containing JPEGs to get around 5540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // SW write limitations for (b/17379185). 5550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.", __FUNCTION__); 5560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else { 5570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return the buffer to the queue. No need to provide fence, as this buffer wasn't 5580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // used anywhere yet. 5590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferConsumer->releaseBuffer(*buffer); 5600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ctx->returnBufferItem(buffer); 5610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Throw exception 5630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 5640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat, ctx->getBufferFormat()); 5650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He String8 msg; 5660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.appendFormat("The producer output buffer format 0x%x doesn't " 5670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "match the ImageReader's configured buffer format 0x%x.", 5680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bufferFormat, ctx->getBufferFormat()); 5690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 5700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.string()); 5710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return -1; 5720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 574212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 575212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 576212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 577212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set SurfaceImage instance member variables 5780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_setBufferItem(env, image, buffer); 579ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 5800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He static_cast<jlong>(buffer->mTimestamp)); 581212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 582e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_SUCCESS; 583212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 584212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 585ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint ImageReader_detachImage(JNIEnv* env, jobject thiz, jobject image) { 586f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He ALOGV("%s:", __FUNCTION__); 587f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 588f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (ctx == NULL) { 589f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed"); 590ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 591f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 592f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 5930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 5940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, image); 5950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!buffer) { 596ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGE( 5970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image already released and can not be detached from ImageReader!!!"); 598ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 5990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image detach from ImageReader failed: buffer was already released"); 600ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 601ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 602ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 6030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = OK; 6040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_unlockIfLocked(env, image); 6050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = bufferConsumer->detachBuffer(buffer->mSlot); 606ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 6070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Image detach failed: %s (%d)!!!", strerror(-res), res); 608ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, 6090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "nativeDetachImage failed for image!!!"); 610ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return res; 611ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 612ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return OK; 613f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He} 614f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 6152e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvalastatic void ImageReader_discardFreeBuffers(JNIEnv* env, jobject thiz) { 6162e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala ALOGV("%s:", __FUNCTION__); 6172e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 6182e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala if (ctx == NULL) { 6192e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed"); 6202e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala return; 6212e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala } 6222e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala 6232e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala BufferItemConsumer* bufferConsumer = ctx->getBufferConsumer(); 6242e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala status_t res = bufferConsumer->discardFreeBuffers(); 6252e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala if (res != OK) { 6262e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala ALOGE("Buffer discard failed: %s (%d)", strerror(-res), res); 6272e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala jniThrowRuntimeException(env, 6282e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala "nativeDicardFreebuffers failed"); 6292e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala } 6302e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala} 6312e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala 632212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) 633212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 634212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: ", __FUNCTION__); 635212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6365b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* gbp = ImageReader_getProducer(env, thiz); 6375b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza if (gbp == NULL) { 6380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "Buffer consumer is uninitialized"); 639212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 640212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 641212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 642212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Wrap the IGBP in a Java-language Surface. 6435b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return android_view_Surface_createFromIGraphicBufferProducer(env, gbp); 644212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 645212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6460ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) { 6470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 6480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 6490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) { 650ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 6510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Image is not initialized"); 6520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 653ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 654212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = lockImageFromBuffer(buffer, 6560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He GRALLOC_USAGE_SW_READ_OFTEN, buffer->mFence->dup(), image); 6570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 6580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/RuntimeException", 6590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "lock buffer failed for format 0x%x", 6600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->mGraphicBuffer->getPixelFormat()); 6610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return; 662212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 6630fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 6640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Carry over some fields from BufferItem. 6650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->crop = buffer->mCrop; 6660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->transform = buffer->mTransform; 6670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->scalingMode = buffer->mScalingMode; 6680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->timestamp = buffer->mTimestamp; 6690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->dataSpace = buffer->mDataSpace; 6700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He image->frameNumber = buffer->mFrameNumber; 6710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Successfully locked the image", __FUNCTION__); 6730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // crop, transform, scalingMode, timestamp, and frameNumber should be set by producer, 6740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // and we don't set them here. 6750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 676212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6770ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic void Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx, 6780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t writerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) { 6790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 680212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = getLockedImageInfo(buffer, idx, writerFormat, base, size, 6820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pixelStride, rowStride); 6830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 6840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 6850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Pixel format: 0x%x is unsupported", buffer->flexFormat); 6860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 687212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 688212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6890ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, 6900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int numPlanes, int readerFormat) 691212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 6920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes); 6930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int rowStride = 0; 6940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int pixelStride = 0; 6950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t *pData = NULL; 6960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t dataSize = 0; 6970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject byteBuffer = NULL; 698212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He PublicFormat publicReaderFormat = static_cast<PublicFormat>(readerFormat); 7000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int halReaderFormat = android_view_Surface_mapPublicFormatToHalFormat( 7010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He publicReaderFormat); 702212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(halReaderFormat) && numPlanes > 0) { 7040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He String8 msg; 7050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)" 7060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He " must be 0", halReaderFormat, numPlanes); 7070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalArgumentException", msg.string()); 708ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 709ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 710ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 7110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobjectArray surfacePlanes = env->NewObjectArray(numPlanes, gSurfacePlaneClassInfo.clazz, 7120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /*initial_element*/NULL); 7130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (surfacePlanes == NULL) { 7140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowRuntimeException(env, "Failed to create SurfacePlane arrays," 7150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He " probably out of memory"); 7165096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return NULL; 7175096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 7180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(halReaderFormat)) { 7190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Return 0 element surface array. 7200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return surfacePlanes; 7210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 7220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LockedImage lockedImg = LockedImage(); 7240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_getLockedImage(env, thiz, &lockedImg); 725252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih if (env->ExceptionCheck()) { 726252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih return NULL; 727252f3b20bb158ddde6ffa687eff9c4d070919091Robert Shih } 7280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Create all SurfacePlanes 7290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He for (int i = 0; i < numPlanes; i++) { 7300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He Image_getLockedImageInfo(env, &lockedImg, i, halReaderFormat, 7310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He &pData, &dataSize, &pixelStride, &rowStride); 7320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He byteBuffer = env->NewDirectByteBuffer(pData, dataSize); 7330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { 7340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jniThrowException(env, "java/lang/IllegalStateException", 7350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Failed to allocate ByteBuffer"); 7360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return NULL; 7370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 7385096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 7390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Finally, create this SurfacePlane. 7400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He jobject surfacePlane = env->NewObject(gSurfacePlaneClassInfo.clazz, 7410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He gSurfacePlaneClassInfo.ctor, thiz, rowStride, pixelStride, byteBuffer); 7420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He env->SetObjectArrayElement(surfacePlanes, i, surfacePlane); 743212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 744212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return surfacePlanes; 746212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 747212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7480ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint Image_getWidth(JNIEnv* env, jobject thiz) 749f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 7500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return getBufferWidth(buffer); 752f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 753f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 7540ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatic jint Image_getHeight(JNIEnv* env, jobject thiz) 755f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 7560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return getBufferHeight(buffer); 758f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 759f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 7607c3997d96a2571295a97457264832d54b05ee966Zhijun Hestatic jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat) 7617c3997d96a2571295a97457264832d54b05ee966Zhijun He{ 7627c3997d96a2571295a97457264832d54b05ee966Zhijun He if (isFormatOpaque(readerFormat)) { 7637c3997d96a2571295a97457264832d54b05ee966Zhijun He // Assuming opaque reader produce opaque images. 7647c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(PublicFormat::PRIVATE); 7657c3997d96a2571295a97457264832d54b05ee966Zhijun He } else { 7660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He BufferItem* buffer = Image_getBufferItem(env, thiz); 7670782aab077b32613c6715190135008dbf3dc5d6dChien-Yu Chen int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat( 7680782aab077b32613c6715190135008dbf3dc5d6dChien-Yu Chen static_cast<PublicFormat>(readerFormat)); 7690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t fmt = applyFormatOverrides( 7700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->mGraphicBuffer->getPixelFormat(), readerHalFormat); 7719cc3f881df13583c93ca08668281413be6412414Zhijun He // Override the image format to HAL_PIXEL_FORMAT_YCbCr_420_888 if the actual format is 7729cc3f881df13583c93ca08668281413be6412414Zhijun He // NV21 or YV12. This could only happen when the Gralloc HAL version is v0.1 thus doesn't 7739cc3f881df13583c93ca08668281413be6412414Zhijun He // support lockycbcr(), the CpuConsumer need to use the lock() method in the 7749cc3f881df13583c93ca08668281413be6412414Zhijun He // lockNextBuffer() call. For Gralloc HAL v0.2 or newer, this format should already be 7759cc3f881df13583c93ca08668281413be6412414Zhijun He // overridden to HAL_PIXEL_FORMAT_YCbCr_420_888 for the flexible YUV compatible formats. 7760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isPossiblyYUV(fmt)) { 7779cc3f881df13583c93ca08668281413be6412414Zhijun He fmt = HAL_PIXEL_FORMAT_YCbCr_420_888; 7789cc3f881df13583c93ca08668281413be6412414Zhijun He } 7797c3997d96a2571295a97457264832d54b05ee966Zhijun He PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat( 7800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He fmt, buffer->mDataSpace); 7817c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(publicFmt); 7827c3997d96a2571295a97457264832d54b05ee966Zhijun He } 7837c3997d96a2571295a97457264832d54b05ee966Zhijun He} 7847c3997d96a2571295a97457264832d54b05ee966Zhijun He 785212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} // extern "C" 786212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 787212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 788212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 78976f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gImageReaderMethods[] = { 790212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClassInit", "()V", (void*)ImageReader_classInit }, 791212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeInit", "(Ljava/lang/Object;IIII)V", (void*)ImageReader_init }, 792212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClose", "()V", (void*)ImageReader_close }, 793212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, 794f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup }, 795212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, 796ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He {"nativeDetachImage", "(Landroid/media/Image;)I", (void*)ImageReader_detachImage }, 7972e2aaf6e0497302bc03c218949d29b01f469316eEino-Ville Talvala {"nativeDiscardFreeBuffers", "()V", (void*)ImageReader_discardFreeBuffers } 798212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 799212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 80076f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gImageMethods[] = { 8010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He {"nativeCreatePlanes", "(II)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", 8020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (void*)Image_createSurfacePlanes }, 8030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He {"nativeGetWidth", "()I", (void*)Image_getWidth }, 8040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He {"nativeGetHeight", "()I", (void*)Image_getHeight }, 8057c3997d96a2571295a97457264832d54b05ee966Zhijun He {"nativeGetFormat", "(I)I", (void*)Image_getFormat }, 806212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 807212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 808212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heint register_android_media_ImageReader(JNIEnv *env) { 809212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 810212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret1 = AndroidRuntime::registerNativeMethods(env, 811212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods)); 812212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 813212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret2 = AndroidRuntime::registerNativeMethods(env, 814212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods)); 815212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 816212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return (ret1 || ret2); 817212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 818