android_media_ImageReader.cpp revision ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbc
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" 19212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <utils/Log.h> 20212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <utils/misc.h> 21212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <utils/List.h> 22ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown#include <utils/String8.h> 23212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 24212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <cstdio> 25212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 26212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <gui/CpuConsumer.h> 27ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He#include <gui/BufferItemConsumer.h> 28212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <gui/Surface.h> 29534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He#include <camera3.h> 30212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 31212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/AndroidRuntime.h> 32212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/android_view_Surface.h> 33212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 34212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <jni.h> 35212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <JNIHelp.h> 36212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 375096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <stdint.h> 385096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <inttypes.h> 395096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 40212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 41212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 42212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" 43ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mNativeBuffer" 44212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" 45212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 46212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 47212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 48212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heusing namespace android; 49212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 50212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heenum { 51212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He IMAGE_READER_MAX_NUM_PLANES = 3, 52212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 53212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 54e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinenum { 55e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_SUCCESS = 0, 56e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_NO_BUFFERS = 1, 57e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_MAX_IMAGES = 2, 58e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin}; 59e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin 60ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 61ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mNativeContext; 62ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jmethodID postEventFromNative; 63ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gImageReaderClassInfo; 64ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown 65ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 66ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jfieldID mNativeBuffer; 67ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mTimestamp; 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 92212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* getLockedBuffer(); 93212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void returnLockedBuffer(CpuConsumer::LockedBuffer* buffer); 94212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 95ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* getOpaqueBuffer(); 96ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He void returnOpaqueBuffer(BufferItem* buffer); 97ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 9852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian void setCpuConsumer(const sp<CpuConsumer>& consumer) { mConsumer = consumer; } 99212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* getCpuConsumer() { return mConsumer.get(); } 100212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 101ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He void setOpaqueConsumer(const sp<BufferItemConsumer>& consumer) { mOpaqueConsumer = consumer; } 102ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItemConsumer* getOpaqueConsumer() { return mOpaqueConsumer.get(); } 103ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // This is the only opaque format exposed in the ImageFormat public API. 104ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He bool isOpaque() { return mFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; } 105ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 1065b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; } 1075b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* getProducer() { return mProducer.get(); } 108212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 109212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferFormat(int format) { mFormat = format; } 110212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferFormat() { return mFormat; } 111212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 112805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala void setBufferDataspace(android_dataspace dataSpace) { mDataSpace = dataSpace; } 113805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace getBufferDataspace() { return mDataSpace; } 114805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala 115212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferWidth(int width) { mWidth = width; } 116212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferWidth() { return mWidth; } 117212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 118212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferHeight(int height) { mHeight = height; } 119212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferHeight() { return mHeight; } 120212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 121212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heprivate: 122212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static JNIEnv* getJNIEnv(bool* needsDetach); 123212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static void detachJNI(); 124212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 125212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He List<CpuConsumer::LockedBuffer*> mBuffers; 126ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He List<BufferItem*> mOpaqueBuffers; 127212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<CpuConsumer> mConsumer; 128ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<BufferItemConsumer> mOpaqueConsumer; 1295b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<IGraphicBufferProducer> mProducer; 130212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject mWeakThiz; 131212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass mClazz; 132212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mFormat; 133805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace mDataSpace; 134212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mWidth; 135212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mHeight; 136212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 137212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 138212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::JNIImageReaderContext(JNIEnv* env, 139212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject weakThiz, jclass clazz, int maxImages) : 140212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mWeakThiz(env->NewGlobalRef(weakThiz)), 141212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mClazz((jclass)env->NewGlobalRef(clazz)) { 142212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (int i = 0; i < maxImages; i++) { 143212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer *buffer = new CpuConsumer::LockedBuffer; 144ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* opaqueBuffer = new BufferItem; 145212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 146ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mOpaqueBuffers.push_back(opaqueBuffer); 147212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 148212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 149212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 150212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) { 151212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!"); 152212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = false; 153212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = AndroidRuntime::getJNIEnv(); 154212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env == NULL) { 155212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; 156212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 157212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->AttachCurrentThread(&env, (void*) &args); 158212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 159212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread attach failed: %#x", result); 160212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 161212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 162212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = true; 163212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 164212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return env; 165212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 166212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 167212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hevoid JNIImageReaderContext::detachJNI() { 168212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 169212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->DetachCurrentThread(); 170212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 171212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread detach failed: %#x", result); 172212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 173212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 174212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 175212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeCpuConsumer::LockedBuffer* JNIImageReaderContext::getLockedBuffer() { 176212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (mBuffers.empty()) { 177212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 178212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 179212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Return a LockedBuffer pointer and remove it from the list 180212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He List<CpuConsumer::LockedBuffer*>::iterator it = mBuffers.begin(); 181212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = *it; 182212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.erase(it); 183212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return buffer; 184212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 185212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 186d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkinvoid JNIImageReaderContext::returnLockedBuffer(CpuConsumer::LockedBuffer* buffer) { 187212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 188212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 189212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 190ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun HeBufferItem* JNIImageReaderContext::getOpaqueBuffer() { 191ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (mOpaqueBuffers.empty()) { 192ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 193ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 194ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Return an opaque buffer pointer and remove it from the list 195ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He List<BufferItem*>::iterator it = mOpaqueBuffers.begin(); 196ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* buffer = *it; 197ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mOpaqueBuffers.erase(it); 198ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return buffer; 199ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 200ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 201ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hevoid JNIImageReaderContext::returnOpaqueBuffer(BufferItem* buffer) { 202ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mOpaqueBuffers.push_back(buffer); 203ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 204ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 205212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::~JNIImageReaderContext() { 206212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 207212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 208212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 209212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mWeakThiz); 210212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mClazz); 211212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 212212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("leaking JNI object references"); 213212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 214212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 215212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 216212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 217212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 218212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Delete LockedBuffers 219212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (List<CpuConsumer::LockedBuffer *>::iterator it = mBuffers.begin(); 220212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He it != mBuffers.end(); it++) { 221212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He delete *it; 222212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 223ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 224ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Delete opaque buffers 225ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He for (List<BufferItem *>::iterator it = mOpaqueBuffers.begin(); 226ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He it != mOpaqueBuffers.end(); it++) { 227ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He delete *it; 228ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 229ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 230212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.clear(); 231ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (mConsumer != 0) { 232ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mConsumer.clear(); 233ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 234ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (mOpaqueConsumer != 0) { 235ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He mOpaqueConsumer.clear(); 236ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 237212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 238212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2392c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stozavoid JNIImageReaderContext::onFrameAvailable(const BufferItem& /*item*/) 240212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 241212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: frame available", __FUNCTION__); 242212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 243212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 244212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 245ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz); 246212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 247212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("onFrameAvailable event will not posted"); 248212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 249212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 250212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 251212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 252212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 253212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 254212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 255212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 256212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heextern "C" { 257212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 258ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic bool isFormatOpaque(int format) { 259ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Only treat IMPLEMENTATION_DEFINED as an opaque format for now. 260ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 261ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 262ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 263212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz) 264212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 265212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext *ctx; 266212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx = reinterpret_cast<JNIImageReaderContext *> 267ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext)); 268212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx; 269212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 270212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 271212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic CpuConsumer* ImageReader_getCpuConsumer(JNIEnv* env, jobject thiz) 272212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 273212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 274212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 275212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 276212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 277212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 278212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 279ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 280ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx->isOpaque()) { 281ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 282ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Opaque ImageReader doesn't support this method"); 283ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 284ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 285ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 286212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx->getCpuConsumer(); 287212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 288212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2895b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stozastatic IGraphicBufferProducer* ImageReader_getProducer(JNIEnv* env, jobject thiz) 29052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{ 29152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian ALOGV("%s:", __FUNCTION__); 29252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 29352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian if (ctx == NULL) { 29452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 29552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return NULL; 29652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian } 297ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 2985b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return ctx->getProducer(); 29952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian} 30052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian 301212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_setNativeContext(JNIEnv* env, 302212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject thiz, sp<JNIImageReaderContext> ctx) 303212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 304212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 305212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const p = ImageReader_getContext(env, thiz); 306212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx != 0) { 307212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->incStrong((void*)ImageReader_setNativeContext); 308212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 309212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (p) { 310212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He p->decStrong((void*)ImageReader_setNativeContext); 311212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 312ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext, 313ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown reinterpret_cast<jlong>(ctx.get())); 314212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 315212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 316212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic CpuConsumer::LockedBuffer* Image_getLockedBuffer(JNIEnv* env, jobject image) 317212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 318ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown return reinterpret_cast<CpuConsumer::LockedBuffer*>( 319ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->GetLongField(image, gSurfaceImageClassInfo.mNativeBuffer)); 320212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 321212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 322212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void Image_setBuffer(JNIEnv* env, jobject thiz, 323212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He const CpuConsumer::LockedBuffer* buffer) 324212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 325ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer, reinterpret_cast<jlong>(buffer)); 326ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 327ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 328ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic void Image_setOpaqueBuffer(JNIEnv* env, jobject thiz, 329ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He const BufferItem* buffer) 330ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 331ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer, reinterpret_cast<jlong>(buffer)); 332212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 333212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 33431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer, bool usingRGBAOverride) 335534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He{ 336534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 337534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint32_t size = 0; 338534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint32_t width = buffer->width; 339534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint8_t* jpegBuffer = buffer->data; 340534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 34131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (usingRGBAOverride) { 3420c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4; 34331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 34431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 345534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He // First check for JPEG transport header at the end of the buffer 346534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob)); 347534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header); 348534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) { 349534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He size = blob->jpeg_size; 350534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He ALOGV("%s: Jpeg size = %d", __FUNCTION__, size); 351534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He } 352534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 353534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He // failed to find size, default to whole buffer 354534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He if (size == 0) { 3555096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin /* 3565096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * This is a problem because not including the JPEG header 3575096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * means that in certain rare situations a regular JPEG blob 3585096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * will be misidentified as having a header, in which case 3595096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * we will get a garbage size value. 3605096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin */ 3615096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGW("%s: No JPEG header detected, defaulting to size=width=%d", 3625096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin __FUNCTION__, width); 363534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He size = width; 364534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He } 365534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 366534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He return size; 367534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He} 368534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 36931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic bool usingRGBAToJpegOverride(int32_t bufferFormat, int32_t readerCtxFormat) { 37031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return readerCtxFormat == HAL_PIXEL_FORMAT_BLOB && bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888; 37131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk} 37231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 3730fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic int32_t applyFormatOverrides(int32_t bufferFormat, int32_t readerCtxFormat) 3740fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk{ 3750fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW 3760fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // write limitations for some platforms (b/17379185). 37731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (usingRGBAToJpegOverride(bufferFormat, readerCtxFormat)) { 3780fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return HAL_PIXEL_FORMAT_BLOB; 3790fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } 3800fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return bufferFormat; 3810fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk} 3820fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 383212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 3840fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk uint8_t **base, uint32_t *size, int32_t readerFormat) 385212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 386212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 387212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(base != NULL, "base is NULL!!!"); 388212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(size != NULL, "size is NULL!!!"); 389212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 390212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 3917f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He ALOGV("%s: buffer: %p", __FUNCTION__, buffer); 392212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 393212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint32_t dataSize, ySize, cSize, cStride; 394212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *cb, *cr; 395212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *pData = NULL; 396708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He int bytesPerPixel = 0; 397212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 398212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = ySize = cSize = cStride = 0; 3994fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar int32_t fmt = buffer->flexFormat; 4000fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 40131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk bool usingRGBAOverride = usingRGBAToJpegOverride(fmt, readerFormat); 4020fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk fmt = applyFormatOverrides(fmt, readerFormat); 403212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 404212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 405212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 406212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 407212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 408212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 409212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->dataCb : 410212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->dataCr; 4114fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar // only map until last pixel 412212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (idx == 0) { 4134fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar dataSize = buffer->stride * (buffer->height - 1) + buffer->width; 414212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 4154fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar dataSize = buffer->chromaStride * (buffer->height / 2 - 1) + 4164fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar buffer->chromaStep * (buffer->width / 2 - 1) + 1; 417212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 418212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 419212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // NV21 420212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 421212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr = buffer->data + (buffer->stride * buffer->height); 422212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb = cr + 1; 4234fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar // only map until last pixel 4244fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar ySize = buffer->width * (buffer->height - 1) + buffer->width; 4254fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar cSize = buffer->width * (buffer->height / 2 - 1) + buffer->width - 1; 426212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 427212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 428212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 429212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 430212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 431212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb: 432212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr; 433212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 434212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = (idx == 0) ? ySize : cSize; 435212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 436212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 437212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Y and C stride need to be 16 pixel aligned. 438212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 439212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 440212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 441212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ySize = buffer->stride * buffer->height; 442212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cStride = ALIGN(buffer->stride / 2, 16); 443212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr = buffer->data + ySize; 444212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cSize = cStride * buffer->height / 2; 445212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb = cr + cSize; 446212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 447212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 448212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 449212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 450212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 451212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb : 452212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr; 453212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = (idx == 0) ? ySize : cSize; 454212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 455212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 456212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane, 8bpp. 457212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 458212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 459212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 460212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = buffer->stride * buffer->height; 461212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 462212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 463977ad8d26e701ed3902247852986d474e0e07f4dZhijun He bytesPerPixel = 2; 464212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane, 16bpp, strides are specified in pixels, not in bytes 465212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 466212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 467212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 468977ad8d26e701ed3902247852986d474e0e07f4dZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 469212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 470212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 471212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Used for JPEG data, height must be 1, width == size, single plane. 472212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 473212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height); 474212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 475212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 47631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk dataSize = Image_getJpegSize(buffer, usingRGBAOverride); 477212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 47864cc1d03596bcda1f2d0bdc35d92546bb03eb406Eino-Ville Talvala case HAL_PIXEL_FORMAT_RAW16: 479212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp bayer data. 480977ad8d26e701ed3902247852986d474e0e07f4dZhijun He bytesPerPixel = 2; 481212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 482212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 483977ad8d26e701ed3902247852986d474e0e07f4dZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 484212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 485d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He case HAL_PIXEL_FORMAT_RAW10: 486d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He // Single plane 10bpp bayer data. 487d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 488d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He LOG_ALWAYS_FATAL_IF(buffer->width % 4, 489d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He "Width is not multiple of 4 %d", buffer->width); 490d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He LOG_ALWAYS_FATAL_IF(buffer->height % 2, 491d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He "Height is not even %d", buffer->height); 4924c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 10 / 8), 4934c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He "stride (%d) should be at least %d", 4944c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He buffer->stride, buffer->width * 10 / 8); 495d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He pData = buffer->data; 4964c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He dataSize = buffer->stride * buffer->height; 497d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He break; 49811d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh case HAL_PIXEL_FORMAT_RAW12: 49911d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh // Single plane 10bpp bayer data. 50011d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 50111d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh LOG_ALWAYS_FATAL_IF(buffer->width % 4, 50211d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh "Width is not multiple of 4 %d", buffer->width); 50311d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh LOG_ALWAYS_FATAL_IF(buffer->height % 2, 50411d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh "Height is not even %d", buffer->height); 50511d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 12 / 8), 50611d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh "stride (%d) should be at least %d", 50711d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh buffer->stride, buffer->width * 12 / 8); 50811d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh pData = buffer->data; 50911d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh dataSize = buffer->stride * buffer->height; 51011d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh break; 511708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 512708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 513708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 32bpp. 514708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 4; 515708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 516708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 517708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 518708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 519708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 520708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 16bpp. 521708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 2; 522708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 523708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 524708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 525708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 526708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 527708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 528708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 3; 529708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 530708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 531708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 532708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 533212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 534212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 535212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Pixel format: 0x%x is unsupported", fmt); 536212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 537212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 538212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 539212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *base = pData; 540212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *size = dataSize; 541212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 542212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5430fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 544805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala int32_t halReaderFormat) 545212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 546212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 547212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx); 548212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 549212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int pixelStride = 0; 550212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 551212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5524fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar int32_t fmt = buffer->flexFormat; 5530fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 554805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala fmt = applyFormatOverrides(fmt, halReaderFormat); 5550fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 556212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 557212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 558212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = (idx == 0) ? 1 : buffer->chromaStep; 559212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 560212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 561212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = (idx == 0) ? 1 : 2; 562212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 563212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 564212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 8bpp data. 565212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 566212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 567212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 568212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 1; 569212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 570212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 571d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He case HAL_PIXEL_FORMAT_RAW10: 57211d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh case HAL_PIXEL_FORMAT_RAW12: 57311d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh // Blob is used for JPEG data, RAW10 and RAW12 is used for 10-bit and 12-bit raw data, 57411d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh // those are single plane data with pixel stride 0 since they don't really have a 57511d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh // well defined pixel stride 576212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 577212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 0; 578212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 579212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 58064cc1d03596bcda1f2d0bdc35d92546bb03eb406Eino-Ville Talvala case HAL_PIXEL_FORMAT_RAW16: 581708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 582212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp data. 583212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 584212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 2; 585212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 586708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 587708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 588708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 589708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pixelStride = 4; 590708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 591708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 592708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 593708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 594708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pixelStride = 3; 595708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 596212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 597212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 598212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Pixel format: 0x%x is unsupported", fmt); 599212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 600212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 601212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 602212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return pixelStride; 603212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 604212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6050fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 606805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala int32_t halReaderFormat) 607212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 608212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 609212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 610212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 611212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int rowStride = 0; 612212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 613212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6144fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar int32_t fmt = buffer->flexFormat; 615212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 616805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala fmt = applyFormatOverrides(fmt, halReaderFormat); 6170fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 618212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 619212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 620212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = (idx == 0) ? buffer->stride : buffer->chromaStride; 621212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 622212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 623212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->width; 624212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 625212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 626212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 627212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 628212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16); 629212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 630212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 63111d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh // Blob is used for JPEG data. It is single plane and has 0 row stride and 63211d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh // 0 pixel stride 633212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 634212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = 0; 635212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 6364c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He case HAL_PIXEL_FORMAT_RAW10: 63711d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh case HAL_PIXEL_FORMAT_RAW12: 63811d444f0b789ead8b10506d24956d243274c724bYin-Chia Yeh // RAW10 and RAW12 are used for 10-bit and 12-bit raw data, they are single plane 6394c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 6404c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He rowStride = buffer->stride; 6414c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He break; 642212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 643212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 644212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 645212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 646212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->stride; 647212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 648212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 64964cc1d03596bcda1f2d0bdc35d92546bb03eb406Eino-Ville Talvala case HAL_PIXEL_FORMAT_RAW16: 650212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // In native side, strides are specified in pixels, not in bytes. 651212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp bayer data. even width/height, 652212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // row stride multiple of 16 pixels (32 bytes) 653212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 654212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 655212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 656212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->stride * 2; 657212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 658708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 659708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 660708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 2; 661708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 662708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 663708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 664708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 665708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 4; 666708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 667708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 668708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 669708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 670708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 3; 671708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 672212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 673212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt); 674212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 675212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "unsupported buffer format"); 676212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 677212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 678212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 679212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return rowStride; 680212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 681212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 682f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic int Image_getBufferWidth(CpuConsumer::LockedBuffer* buffer) { 683f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (buffer == NULL) return -1; 684f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 685f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (!buffer->crop.isEmpty()) { 686f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->crop.getWidth(); 687f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 688f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->width; 689f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 690f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 691f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic int Image_getBufferHeight(CpuConsumer::LockedBuffer* buffer) { 692f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (buffer == NULL) return -1; 693f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 694f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (!buffer->crop.isEmpty()) { 695f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->crop.getHeight(); 696f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 697f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->height; 698f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 699f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 700ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He// --------------------------Methods for opaque Image and ImageReader---------- 701ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 702ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic BufferItemConsumer* ImageReader_getOpaqueConsumer(JNIEnv* env, jobject thiz) 703ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 704ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGV("%s:", __FUNCTION__); 705ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 706ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx == NULL) { 707ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 708ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 709ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 710ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 711ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (!ctx->isOpaque()) { 712ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 713ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Non-opaque ImageReader doesn't support this method"); 714ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 715ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 716ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ctx->getOpaqueConsumer(); 717ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 718ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 719ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic BufferItem* Image_getOpaqueBuffer(JNIEnv* env, jobject image) 720ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He{ 721ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return reinterpret_cast<BufferItem*>( 722ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->GetLongField(image, gSurfaceImageClassInfo.mNativeBuffer)); 723ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 724ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 725ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic int Image_getOpaqueBufferWidth(BufferItem* buffer) { 726ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (buffer == NULL) return -1; 727ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 728ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (!buffer->mCrop.isEmpty()) { 729ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return buffer->mCrop.getWidth(); 730ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 731ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return buffer->mGraphicBuffer->getWidth(); 732ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 733ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 734ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic int Image_getOpaqueBufferHeight(BufferItem* buffer) { 735ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (buffer == NULL) return -1; 736ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 737ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (!buffer->mCrop.isEmpty()) { 738ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return buffer->mCrop.getHeight(); 739ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 740ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 741ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return buffer->mGraphicBuffer->getHeight(); 742ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 743ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 744ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 745ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 746212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 747212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 748212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_classInit(JNIEnv* env, jclass clazz) 749212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 750212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 751212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 752212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage"); 753212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(imageClazz == NULL, 754212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader$SurfaceImage"); 755ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He gSurfaceImageClassInfo.mNativeBuffer = env->GetFieldID( 756ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J"); 757ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mNativeBuffer == NULL, 758212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 759212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID); 760212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 761ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mTimestamp = env->GetFieldID( 762ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J"); 763ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL, 764212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 765212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); 766212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 767ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.mNativeContext = env->GetFieldID( 768ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J"); 769ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL, 770212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 771212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID); 772212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 773ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID( 774ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, "postEventFromNative", "(Ljava/lang/Object;)V"); 775ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL, 776212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.postEventFromNative"); 777212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 778212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane"); 779212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class"); 780212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // FindClass only gives a local reference of jclass object. 781ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); 782ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>", 783ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "(Landroid/media/ImageReader$SurfaceImage;III)V"); 784ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, 785ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "Can not find SurfacePlane constructor"); 786212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 787212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 788212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, 789212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jint width, jint height, jint format, jint maxImages) 790212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 791212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res; 792212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int nativeFormat; 793805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala android_dataspace nativeDataspace; 794212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 795212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d", 796212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He __FUNCTION__, width, height, format, maxImages); 797212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 798805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala PublicFormat publicFormat = static_cast<PublicFormat>(format); 799805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeFormat = android_view_Surface_mapPublicFormatToHalFormat( 800805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 801805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala nativeDataspace = android_view_Surface_mapPublicFormatToHalDataspace( 802805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala publicFormat); 803212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 804212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz = env->GetObjectClass(thiz); 805212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (clazz == NULL) { 806212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader"); 807212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 808212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 809212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages)); 810ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 811ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferProducer> gbProducer; 812ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<IGraphicBufferConsumer> gbConsumer; 813ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 814ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<ConsumerBase> consumer; 815ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<CpuConsumer> cpuConsumer; 816ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He sp<BufferItemConsumer> opaqueConsumer; 817ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d", 818ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala width, height, format, maxImages, getpid(), 819ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala createProcessUniqueId()); 820ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(nativeFormat)) { 821ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Use the SW_READ_NEVER usage to tell producer that this format is not for preview or video 822ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // encoding. The only possibility will be ZSL output. 823ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He opaqueConsumer = 824ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He new BufferItemConsumer(gbConsumer, GRALLOC_USAGE_SW_READ_NEVER, maxImages, 825ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He /*controlledByApp*/true); 826ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (opaqueConsumer == NULL) { 827ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, "Failed to allocate native opaque consumer"); 828ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return; 829ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 830ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ctx->setOpaqueConsumer(opaqueConsumer); 831ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala opaqueConsumer->setName(consumerName); 832ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He consumer = opaqueConsumer; 833ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 834ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He cpuConsumer = new CpuConsumer(gbConsumer, maxImages, /*controlledByApp*/true); 835ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // TODO: throw dvm exOutOfMemoryError? 836ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (cpuConsumer == NULL) { 837ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer"); 838ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return; 839ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 840ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ctx->setCpuConsumer(cpuConsumer); 841ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala cpuConsumer->setName(consumerName); 842ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He consumer = cpuConsumer; 843ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 844ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 8455b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza ctx->setProducer(gbProducer); 846212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(ctx); 847212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, ctx); 848212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferFormat(nativeFormat); 849805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala ctx->setBufferDataspace(nativeDataspace); 850212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferWidth(width); 851212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferHeight(height); 852212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 853805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala // Set the width/height/format/dataspace to the CpuConsumer 854ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // TODO: below code can be simplified once b/19977701 is fixed. 855ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(nativeFormat)) { 856ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He res = opaqueConsumer->setDefaultBufferSize(width, height); 857ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 858ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 859ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Failed to set opaque consumer buffer size"); 860ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return; 861ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 862ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He res = opaqueConsumer->setDefaultBufferFormat(nativeFormat); 863ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 864ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 865ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Failed to set opaque consumer buffer format"); 866ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 867ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He res = opaqueConsumer->setDefaultBufferDataSpace(nativeDataspace); 868ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 869ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 870ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Failed to set opaque consumer buffer dataSpace"); 871ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 872ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 873ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He res = cpuConsumer->setDefaultBufferSize(width, height); 874ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 875ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 876ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Failed to set CpuConsumer buffer size"); 877ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return; 878ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 879ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He res = cpuConsumer->setDefaultBufferFormat(nativeFormat); 880ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 881ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 882ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Failed to set CpuConsumer buffer format"); 883ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 884ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He res = cpuConsumer->setDefaultBufferDataSpace(nativeDataspace); 885ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 886ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 887ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Failed to set CpuConsumer buffer dataSpace"); 888ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 889805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala } 890212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 891212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 892212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_close(JNIEnv* env, jobject thiz) 893212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 894212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 895212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 896212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 897212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 898212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // ImageReader is already closed. 899212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 900212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 901212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 902ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ConsumerBase* consumer = NULL; 903ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx->isOpaque()) { 904ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He consumer = ImageReader_getOpaqueConsumer(env, thiz); 905ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 906ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He consumer = ImageReader_getCpuConsumer(env, thiz); 907ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 908ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 909212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer != NULL) { 910212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->abandon(); 911212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(NULL); 912212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 913212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, NULL); 914212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 915212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 916212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image) 917212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 918212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 919212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 920212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 921212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("ImageReader#close called before Image#close, consider calling Image#close first"); 922212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 923212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 924212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 925ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx->isOpaque()) { 926ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItemConsumer* opaqueConsumer = ctx->getOpaqueConsumer(); 927ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* opaqueBuffer = Image_getOpaqueBuffer(env, image); 928ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He opaqueConsumer->releaseBuffer(*opaqueBuffer); // Not using fence for now. 929ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He Image_setOpaqueBuffer(env, image, NULL); 930ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ctx->returnOpaqueBuffer(opaqueBuffer); 931ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGV("%s: Opaque Image has been released", __FUNCTION__); 932ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 933ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He CpuConsumer* consumer = ctx->getCpuConsumer(); 934ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, image); 935ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (!buffer) { 936ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGW("Image already released!!!"); 937ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return; 938ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 939ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He consumer->unlockBuffer(*buffer); 940ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He Image_setBuffer(env, image, NULL); 941ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ctx->returnLockedBuffer(buffer); 942ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGV("%s: Image (format: 0x%x) has been released", __FUNCTION__, ctx->getBufferFormat()); 943212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 944212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 945212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 946ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint ImageReader_opaqueImageSetup(JNIEnv* env, JNIImageReaderContext* ctx, jobject image) { 947212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 948ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx == NULL || !ctx->isOpaque()) { 949212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 950e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 951212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 952212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 953ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItemConsumer* opaqueConsumer = ctx->getOpaqueConsumer(); 954ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* buffer = ctx->getOpaqueBuffer(); 955ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (buffer == NULL) { 956ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGW("Unable to acquire a buffer item, very likely client tried to acquire more than" 957ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He " maxImages buffers"); 958ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ACQUIRE_MAX_IMAGES; 959ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 960ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 961ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He status_t res = opaqueConsumer->acquireBuffer(buffer, 0); 962ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 963ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ctx->returnOpaqueBuffer(buffer); 964ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res == INVALID_OPERATION) { 965ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Max number of images were already acquired. 966ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGE("%s: Max number of buffers allowed are already acquired : %s (%d)", 967ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He __FUNCTION__, strerror(-res), res); 968ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ACQUIRE_MAX_IMAGES; 969ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 970ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGE("%s: Acquire image failed with error: %s (%d)", 971ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He __FUNCTION__, strerror(-res), res); 972ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ACQUIRE_NO_BUFFERS; 973ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 974ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 975ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 976ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // Set SurfaceImage instance member variables 977ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He Image_setOpaqueBuffer(env, image, buffer); 978ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 979ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He static_cast<jlong>(buffer->mTimestamp)); 980ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 981ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ACQUIRE_SUCCESS; 982ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 983ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 984ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint ImageReader_lockedImageSetup(JNIEnv* env, JNIImageReaderContext* ctx, jobject image) { 985212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* consumer = ctx->getCpuConsumer(); 986212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = ctx->getLockedBuffer(); 987212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 988d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkin ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than" 989d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkin " maxImages buffers"); 990e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 991212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 992212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res = consumer->lockNextBuffer(buffer); 993212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (res != NO_ERROR) { 994334778981dc01b5f8f4e137eb3f78745e214cf4dlina.x.pi ctx->returnLockedBuffer(buffer); 995f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown if (res != BAD_VALUE /*no buffers*/) { 996dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin if (res == NOT_ENOUGH_DATA) { 997e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 998dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } else { 999dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin ALOGE("%s Fail to lockNextBuffer with error: %d ", 1000dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin __FUNCTION__, res); 1001e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin jniThrowExceptionFmt(env, "java/lang/AssertionError", 1002dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin "Unknown error (%d) when we tried to lock buffer.", 1003dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin res); 1004dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } 1005f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown } 1006e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_NO_BUFFERS; 1007212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1008212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 10094fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar if (buffer->flexFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) { 10104eda9f5359347c11914e47f477535c9533674d32Zhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 10114eda9f5359347c11914e47f477535c9533674d32Zhijun He "NV21 format is not supported by ImageReader"); 10124eda9f5359347c11914e47f477535c9533674d32Zhijun He return -1; 10134eda9f5359347c11914e47f477535c9533674d32Zhijun He } 10144eda9f5359347c11914e47f477535c9533674d32Zhijun He 1015212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Check if the left-top corner of the crop rect is origin, we currently assume this point is 1016212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // zero, will revist this once this assumption turns out problematic. 1017212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Point lt = buffer->crop.leftTop(); 1018212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (lt.x != 0 || lt.y != 0) { 10194eda9f5359347c11914e47f477535c9533674d32Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 10204eda9f5359347c11914e47f477535c9533674d32Zhijun He "crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 1021e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 1022212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1023212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1024212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Check if the producer buffer configurations match what ImageReader configured. 1025f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk int outputWidth = Image_getBufferWidth(buffer); 1026f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk int outputHeight = Image_getBufferHeight(buffer); 1027534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 10280fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk int imgReaderFmt = ctx->getBufferFormat(); 1029212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int imageReaderWidth = ctx->getBufferWidth(); 1030212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int imageReaderHeight = ctx->getBufferHeight(); 10310fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) && 1032f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) { 1033f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", 1034f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); 1035212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1036212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1037feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int bufFmt = buffer->format; 10384fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888) { 10394fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar bufFmt = buffer->flexFormat; 10404fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar } 1041feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (imgReaderFmt != bufFmt) { 104291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt == 104391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) { 10440fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // Special casing for when producer switches to a format compatible with flexible YUV 10450fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // (HAL_PIXEL_FORMAT_YCbCr_420_888). 104691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ctx->setBufferFormat(bufFmt); 10470fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGD("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt); 10480fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && bufFmt == HAL_PIXEL_FORMAT_RGBA_8888) { 10490fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW 10500fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // write limitations for (b/17379185). 10510fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGD("%s: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.", __FUNCTION__); 1052feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 1053feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Return the buffer to the queue. 1054feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk consumer->unlockBuffer(*buffer); 1055feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ctx->returnLockedBuffer(buffer); 1056feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 1057feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Throw exception 1058feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 1059feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk buffer->format, ctx->getBufferFormat()); 1060feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk String8 msg; 1061feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk msg.appendFormat("The producer output buffer format 0x%x doesn't " 1062feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "match the ImageReader's configured buffer format 0x%x.", 10634fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar bufFmt, ctx->getBufferFormat()); 1064feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowException(env, "java/lang/UnsupportedOperationException", 1065feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk msg.string()); 1066feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return -1; 1067feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 1068212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1069212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set SurfaceImage instance member variables 1070212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Image_setBuffer(env, image, buffer); 1071ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 1072ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown static_cast<jlong>(buffer->timestamp)); 1073212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1074e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_SUCCESS; 1075212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 1076212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1077ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) { 1078ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGV("%s:", __FUNCTION__); 1079ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 1080ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx == NULL) { 1081ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 1082ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 1083ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1084ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 1085ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (ctx->isOpaque()) { 1086ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ImageReader_opaqueImageSetup(env, ctx, image); 1087ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 1088ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return ImageReader_lockedImageSetup(env, ctx, image); 1089ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1090ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He} 1091ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 1092ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint ImageReader_detachImage(JNIEnv* env, jobject thiz, jobject image) { 1093f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He ALOGV("%s:", __FUNCTION__); 1094f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 1095f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (ctx == NULL) { 1096f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed"); 1097ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 1098f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 1099f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 1100ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He status_t res = OK; 1101ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (!ctx->isOpaque()) { 1102ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He // TODO: Non-Opaque format detach is not implemented yet. 1103ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, 1104ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "nativeDetachImage is not implemented yet for non-opaque format !!!"); 1105ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 1106f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 1107f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 1108ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItemConsumer* opaqueConsumer = ctx->getOpaqueConsumer(); 1109ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* opaqueBuffer = Image_getOpaqueBuffer(env, image); 1110ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (!opaqueBuffer) { 1111ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGE( 1112ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Opaque Image already released and can not be detached from ImageReader!!!"); 1113ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 1114ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Opaque Image detach from ImageReader failed: buffer was already released"); 1115ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return -1; 1116ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1117ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 1118ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He res = opaqueConsumer->detachBuffer(opaqueBuffer->mSlot); 1119ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (res != OK) { 1120ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He ALOGE("Opaque Image detach failed: %s (%d)!!!", strerror(-res), res); 1121ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowRuntimeException(env, 1122ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "nativeDetachImage failed for opaque image!!!"); 1123ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return res; 1124ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1125ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return OK; 1126f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He} 1127f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 1128212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) 1129212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 1130212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: ", __FUNCTION__); 1131212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 11325b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* gbp = ImageReader_getProducer(env, thiz); 11335b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza if (gbp == NULL) { 1134212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "CpuConsumer is uninitialized"); 1135212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 1136212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1137212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1138212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Wrap the IGBP in a Java-language Surface. 11395b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return android_view_Surface_createFromIGraphicBufferProducer(env, gbp); 1140212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 1141212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 11420fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx, int readerFormat) 1143212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 1144212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int rowStride, pixelStride; 1145805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala PublicFormat publicReaderFormat = static_cast<PublicFormat>(readerFormat); 1146ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He int halReaderFormat = android_view_Surface_mapPublicFormatToHalFormat( 1147ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He publicReaderFormat); 1148805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala 1149212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 1150ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(halReaderFormat)) { 1151ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 1152ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Opaque images from Opaque ImageReader do not have any planes"); 1153ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 1154ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1155212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1156212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 1157212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1158212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL); 1159212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 1160212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 1161212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 11620fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 1163805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala rowStride = Image_imageGetRowStride(env, buffer, idx, halReaderFormat); 1164805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala pixelStride = Image_imageGetPixelStride(env, buffer, idx, halReaderFormat); 1165212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1166ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz, 1167ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride); 1168212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1169212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return surfPlaneObj; 1170212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 1171212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 11720fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx, int readerFormat) 1173212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 1174212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *base = NULL; 1175212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint32_t size = 0; 1176212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject byteBuffer; 1177805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala PublicFormat readerPublicFormat = static_cast<PublicFormat>(readerFormat); 1178ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat( 1179ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He readerPublicFormat); 1180212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1181212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 1182212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1183ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(readerHalFormat)) { 1184ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 1185ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He "Opaque images from Opaque ImageReader do not have any plane"); 1186ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return NULL; 1187ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1188ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He 1189212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 1190212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1191212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 1192212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 1193212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1194212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1195212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Create byteBuffer from native buffer 1196805f3c9428f9ebd5080aec48d3d9d77dbf4b41a9Eino-Ville Talvala Image_getLockedBufferInfo(env, buffer, idx, &base, &size, readerHalFormat); 11975096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 11985096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (size > static_cast<uint32_t>(INT32_MAX)) { 11995096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin // Byte buffer have 'int capacity', so check the range 12005096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 120131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk "Size too large for bytebuffer capacity %" PRIu32, size); 12025096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return NULL; 12035096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 12045096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 1205212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He byteBuffer = env->NewDirectByteBuffer(base, size); 1206212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // TODO: throw dvm exOutOfMemoryError? 1207212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { 1208212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Failed to allocate ByteBuffer"); 1209212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 1210212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1211212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return byteBuffer; 1212212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 1213212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1214ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint Image_getWidth(JNIEnv* env, jobject thiz, jint format) 1215f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 1216ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(format)) { 1217ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* opaqueBuffer = Image_getOpaqueBuffer(env, thiz); 1218ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return Image_getOpaqueBufferWidth(opaqueBuffer); 1219ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 1220ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 1221ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return Image_getBufferWidth(buffer); 1222ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1223f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 1224f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 1225ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun Hestatic jint Image_getHeight(JNIEnv* env, jobject thiz, jint format) 1226f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 1227ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He if (isFormatOpaque(format)) { 1228ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He BufferItem* opaqueBuffer = Image_getOpaqueBuffer(env, thiz); 1229ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return Image_getOpaqueBufferHeight(opaqueBuffer); 1230ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } else { 1231ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 1232ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He return Image_getBufferHeight(buffer); 1233ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He } 1234f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 1235f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 12367c3997d96a2571295a97457264832d54b05ee966Zhijun Hestatic jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat) 12377c3997d96a2571295a97457264832d54b05ee966Zhijun He{ 12387c3997d96a2571295a97457264832d54b05ee966Zhijun He if (isFormatOpaque(readerFormat)) { 12397c3997d96a2571295a97457264832d54b05ee966Zhijun He // Assuming opaque reader produce opaque images. 12407c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(PublicFormat::PRIVATE); 12417c3997d96a2571295a97457264832d54b05ee966Zhijun He } else { 12427c3997d96a2571295a97457264832d54b05ee966Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 12437c3997d96a2571295a97457264832d54b05ee966Zhijun He PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat( 12447c3997d96a2571295a97457264832d54b05ee966Zhijun He buffer->flexFormat, buffer->dataSpace); 12457c3997d96a2571295a97457264832d54b05ee966Zhijun He return static_cast<jint>(publicFmt); 12467c3997d96a2571295a97457264832d54b05ee966Zhijun He } 12477c3997d96a2571295a97457264832d54b05ee966Zhijun He} 12487c3997d96a2571295a97457264832d54b05ee966Zhijun He 1249212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} // extern "C" 1250212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1251212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 1252212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1253212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNINativeMethod gImageReaderMethods[] = { 1254212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClassInit", "()V", (void*)ImageReader_classInit }, 1255212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeInit", "(Ljava/lang/Object;IIII)V", (void*)ImageReader_init }, 1256212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClose", "()V", (void*)ImageReader_close }, 1257212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, 1258f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup }, 1259212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, 1260ce9d6f9c75e2254f3704996e232e57e0c8f686d8Zhijun He {"nativeDetachImage", "(Landroid/media/Image;)I", (void*)ImageReader_detachImage }, 1261212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 1262212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1263212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNINativeMethod gImageMethods[] = { 12640fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk {"nativeImageGetBuffer", "(II)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer }, 12650fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk {"nativeCreatePlane", "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", 1266f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk (void*)Image_createSurfacePlane }, 12677c3997d96a2571295a97457264832d54b05ee966Zhijun He {"nativeGetWidth", "(I)I", (void*)Image_getWidth }, 12687c3997d96a2571295a97457264832d54b05ee966Zhijun He {"nativeGetHeight", "(I)I", (void*)Image_getHeight }, 12697c3997d96a2571295a97457264832d54b05ee966Zhijun He {"nativeGetFormat", "(I)I", (void*)Image_getFormat }, 1270212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 1271212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1272212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heint register_android_media_ImageReader(JNIEnv *env) { 1273212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1274212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret1 = AndroidRuntime::registerNativeMethods(env, 1275212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods)); 1276212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1277212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret2 = AndroidRuntime::registerNativeMethods(env, 1278212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods)); 1279212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1280212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return (ret1 || ret2); 1281212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 1282