android_media_ImageReader.cpp revision 4eda9f5359347c11914e47f477535c9533674d32
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> 27212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <gui/Surface.h> 28534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He#include <camera3.h> 29212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 30212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/AndroidRuntime.h> 31212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <android_runtime/android_view_Surface.h> 32212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 33212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <jni.h> 34212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#include <JNIHelp.h> 35212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 36212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 37212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 38212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" 39212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mLockedBuffer" 40212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" 41212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 42212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 43212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 44212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heusing namespace android; 45212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 46212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heenum { 47212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He IMAGE_READER_MAX_NUM_PLANES = 3, 48212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 49212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 50e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinenum { 51e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_SUCCESS = 0, 52e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_NO_BUFFERS = 1, 53e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_MAX_IMAGES = 2, 54e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin}; 55e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin 56ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 57ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mNativeContext; 58ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jmethodID postEventFromNative; 59ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gImageReaderClassInfo; 60ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown 61ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 62ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mLockedBuffer; 63ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mTimestamp; 64ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfaceImageClassInfo; 65212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 66ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 67212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz; 68212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jmethodID ctor; 69ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfacePlaneClassInfo; 70212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 71212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 72212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 73212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heclass JNIImageReaderContext : public CpuConsumer::FrameAvailableListener 74212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 75212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hepublic: 76212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext(JNIEnv* env, jobject weakThiz, jclass clazz, int maxImages); 77212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 78212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He virtual ~JNIImageReaderContext(); 79212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 80212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He virtual void onFrameAvailable(); 81212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 82212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* getLockedBuffer(); 83212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 84212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void returnLockedBuffer(CpuConsumer::LockedBuffer* buffer); 85212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 8652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian void setCpuConsumer(const sp<CpuConsumer>& consumer) { mConsumer = consumer; } 87212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* getCpuConsumer() { return mConsumer.get(); } 88212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 8952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian void setBufferQueue(const sp<BufferQueue>& bq) { mBufferQueue = bq; } 9052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian BufferQueue* getBufferQueue() { return mBufferQueue.get(); } 91212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 92212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferFormat(int format) { mFormat = format; } 93212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferFormat() { return mFormat; } 94212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 95212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferWidth(int width) { mWidth = width; } 96212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferWidth() { return mWidth; } 97212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 98212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferHeight(int height) { mHeight = height; } 99212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferHeight() { return mHeight; } 100212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 101212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heprivate: 102212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static JNIEnv* getJNIEnv(bool* needsDetach); 103212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static void detachJNI(); 104212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 105212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He List<CpuConsumer::LockedBuffer*> mBuffers; 106212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<CpuConsumer> mConsumer; 10752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian sp<BufferQueue> mBufferQueue; 108212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject mWeakThiz; 109212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass mClazz; 110212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mFormat; 111212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mWidth; 112212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mHeight; 113212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 114212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 115212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::JNIImageReaderContext(JNIEnv* env, 116212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject weakThiz, jclass clazz, int maxImages) : 117212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mWeakThiz(env->NewGlobalRef(weakThiz)), 118212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mClazz((jclass)env->NewGlobalRef(clazz)) { 119212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (int i = 0; i < maxImages; i++) { 120212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer *buffer = new CpuConsumer::LockedBuffer; 121212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 122212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 123212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 124212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 125212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) { 126212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!"); 127212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = false; 128212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = AndroidRuntime::getJNIEnv(); 129212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env == NULL) { 130212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; 131212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 132212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->AttachCurrentThread(&env, (void*) &args); 133212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 134212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread attach failed: %#x", result); 135212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 136212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 137212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = true; 138212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 139212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return env; 140212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 141212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 142212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hevoid JNIImageReaderContext::detachJNI() { 143212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 144212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->DetachCurrentThread(); 145212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 146212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread detach failed: %#x", result); 147212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 148212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 149212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 150212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeCpuConsumer::LockedBuffer* JNIImageReaderContext::getLockedBuffer() { 151212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (mBuffers.empty()) { 152212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 153212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 154212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Return a LockedBuffer pointer and remove it from the list 155212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He List<CpuConsumer::LockedBuffer*>::iterator it = mBuffers.begin(); 156212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = *it; 157212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.erase(it); 158212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return buffer; 159212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 160212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 161d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkinvoid JNIImageReaderContext::returnLockedBuffer(CpuConsumer::LockedBuffer* buffer) { 162212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 163212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 164212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 165212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::~JNIImageReaderContext() { 166212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 167212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 168212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 169212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mWeakThiz); 170212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mClazz); 171212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 172212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("leaking JNI object references"); 173212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 174212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 175212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 176212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 177212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 178212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Delete LockedBuffers 179212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (List<CpuConsumer::LockedBuffer *>::iterator it = mBuffers.begin(); 180212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He it != mBuffers.end(); it++) { 181212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He delete *it; 182212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 183212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.clear(); 184212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mConsumer.clear(); 185212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 186212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 187212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hevoid JNIImageReaderContext::onFrameAvailable() 188212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 189212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: frame available", __FUNCTION__); 190212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 191212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 192212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 193ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz); 194212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 195212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("onFrameAvailable event will not posted"); 196212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 197212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 198212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 199212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 200212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 201212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 202212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 203212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 204212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heextern "C" { 205212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 206212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz) 207212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 208212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext *ctx; 209212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx = reinterpret_cast<JNIImageReaderContext *> 210ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext)); 211212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx; 212212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 213212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 214212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic CpuConsumer* ImageReader_getCpuConsumer(JNIEnv* env, jobject thiz) 215212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 216212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 217212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 218212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 219212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 220212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 221212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 222212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx->getCpuConsumer(); 223212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 224212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 22552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopianstatic BufferQueue* ImageReader_getBufferQueue(JNIEnv* env, jobject thiz) 22652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{ 22752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian ALOGV("%s:", __FUNCTION__); 22852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 22952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian if (ctx == NULL) { 23052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 23152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return NULL; 23252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian } 23352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return ctx->getBufferQueue(); 23452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian} 23552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian 236212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_setNativeContext(JNIEnv* env, 237212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject thiz, sp<JNIImageReaderContext> ctx) 238212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 239212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 240212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const p = ImageReader_getContext(env, thiz); 241212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx != 0) { 242212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->incStrong((void*)ImageReader_setNativeContext); 243212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 244212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (p) { 245212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He p->decStrong((void*)ImageReader_setNativeContext); 246212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 247ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext, 248ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown reinterpret_cast<jlong>(ctx.get())); 249212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 250212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 251212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic CpuConsumer::LockedBuffer* Image_getLockedBuffer(JNIEnv* env, jobject image) 252212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 253ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown return reinterpret_cast<CpuConsumer::LockedBuffer*>( 254ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->GetLongField(image, gSurfaceImageClassInfo.mLockedBuffer)); 255212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 256212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 257212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void Image_setBuffer(JNIEnv* env, jobject thiz, 258212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He const CpuConsumer::LockedBuffer* buffer) 259212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 260ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gSurfaceImageClassInfo.mLockedBuffer, reinterpret_cast<jlong>(buffer)); 261212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 262212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 263212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// Some formats like JPEG defined with different values between android.graphics.ImageFormat and 264212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// graphics.h, need convert to the one defined in graphics.h here. 265212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic int Image_getPixelFormat(JNIEnv* env, int format) 266212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 267212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int jpegFormat, rawSensorFormat; 268212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jfieldID fid; 269212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 270212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: format = 0x%x", __FUNCTION__, format); 271212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 272212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat"); 273212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(imageFormatClazz != NULL); 274212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 275212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He fid = env->GetStaticFieldID(imageFormatClazz, "JPEG", "I"); 276212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jpegFormat = env->GetStaticIntField(imageFormatClazz, fid); 277212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He fid = env->GetStaticFieldID(imageFormatClazz, "RAW_SENSOR", "I"); 278212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rawSensorFormat = env->GetStaticIntField(imageFormatClazz, fid); 279212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 280212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Translate the JPEG to BLOB for camera purpose, an add more if more mismatch is found. 281212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (format == jpegFormat) { 282212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He format = HAL_PIXEL_FORMAT_BLOB; 283212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 284212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Same thing for RAW_SENSOR format 285212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (format == rawSensorFormat) { 286212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He format = HAL_PIXEL_FORMAT_RAW_SENSOR; 287212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 288212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 289212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return format; 290212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 291212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 292534046d2b12fd13776ad782b982649cb0bea9b79Zhijun Hestatic uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer) 293534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He{ 294534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 295534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint32_t size = 0; 296534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint32_t width = buffer->width; 297534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint8_t* jpegBuffer = buffer->data; 298534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 299534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He // First check for JPEG transport header at the end of the buffer 300534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob)); 301534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header); 302534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) { 303534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He size = blob->jpeg_size; 304534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He ALOGV("%s: Jpeg size = %d", __FUNCTION__, size); 305534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He } 306534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 307534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He // failed to find size, default to whole buffer 308534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He if (size == 0) { 309534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He size = width; 310534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He } 311534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 312534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He return size; 313534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He} 314534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 315212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 316212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t **base, uint32_t *size) 317212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 318212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 319212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(base != NULL, "base is NULL!!!"); 320212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(size != NULL, "size is NULL!!!"); 321212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 322212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 3237f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He ALOGV("%s: buffer: %p", __FUNCTION__, buffer); 324212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 325212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint32_t dataSize, ySize, cSize, cStride; 326212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *cb, *cr; 327212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *pData = NULL; 328708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He int bytesPerPixel = 0; 329212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 330212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = ySize = cSize = cStride = 0; 331212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int32_t fmt = buffer->format; 332212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 333212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 334212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 335212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 336212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 337212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 338212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->dataCb : 339212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->dataCr; 340212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (idx == 0) { 341212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = buffer->stride * buffer->height; 342212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 343212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = buffer->chromaStride * buffer->height / 2; 344212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 345212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 346212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // NV21 347212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 348212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr = buffer->data + (buffer->stride * buffer->height); 349212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb = cr + 1; 350212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ySize = buffer->width * buffer->height; 351212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cSize = buffer->width * buffer->height / 2; 352212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 353212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 354212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 355212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 356212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 357212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb: 358212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr; 359212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 360212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = (idx == 0) ? ySize : cSize; 361212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 362212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 363212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Y and C stride need to be 16 pixel aligned. 364212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 365212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 366212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 367212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ySize = buffer->stride * buffer->height; 368212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cStride = ALIGN(buffer->stride / 2, 16); 369212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr = buffer->data + ySize; 370212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cSize = cStride * buffer->height / 2; 371212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb = cr + cSize; 372212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 373212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 374212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 375212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 376212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 377212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb : 378212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr; 379212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = (idx == 0) ? ySize : cSize; 380212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 381212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 382212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane, 8bpp. 383212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 384212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 385212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 386212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = buffer->stride * buffer->height; 387212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 388212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 389212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane, 16bpp, strides are specified in pixels, not in bytes 390212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 391212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 392212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 393212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = buffer->stride * buffer->height * 2; 394212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 395212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 396212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Used for JPEG data, height must be 1, width == size, single plane. 397212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 398212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height); 399212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 400212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 401534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He dataSize = Image_getJpegSize(buffer); 402212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 403212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_RAW_SENSOR: 404212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp bayer data. 405212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 406212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 407212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = buffer->width * 2 * buffer->height; 408212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 409708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 410708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 411708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 32bpp. 412708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 4; 413708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 414708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 415708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 416708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 417708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 418708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 16bpp. 419708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 2; 420708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 421708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 422708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 423708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 424708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 425708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 426708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 3; 427708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 428708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 429708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 430708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 431212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 432212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 433212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Pixel format: 0x%x is unsupported", fmt); 434212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 435212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 436212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 437212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *base = pData; 438212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *size = dataSize; 439212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 440212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 441212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx) 442212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 443212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 444212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx); 445212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 446212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int pixelStride = 0; 447212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 448212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 449212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int32_t fmt = buffer->format; 450212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 451212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 452212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = (idx == 0) ? 1 : buffer->chromaStep; 453212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 454212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 455212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = (idx == 0) ? 1 : 2; 456212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 457212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 458212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 8bpp data. 459212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 460212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride; 461212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 462212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 463212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 1; 464212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 465212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 466212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Used for JPEG data, single plane, row and pixel strides are 0 467212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 468212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 0; 469212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 470212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 471212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_RAW_SENSOR: 472708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 473212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp data. 474212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 475212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 2; 476212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 477708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 478708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 479708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 480708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pixelStride = 4; 481708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 482708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 483708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 484708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 485708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pixelStride = 3; 486708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 487212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 488212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 489212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Pixel format: 0x%x is unsupported", fmt); 490212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 491212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 492212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 493212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return pixelStride; 494212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 495212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 496212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx) 497212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 498212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 499212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 500212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 501212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int rowStride = 0; 502212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 503212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 504212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int32_t fmt = buffer->format; 505212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 506212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 507212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 508212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = (idx == 0) ? buffer->stride : buffer->chromaStride; 509212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 510212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 511212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->width; 512212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 513212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 514212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 515212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 516212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16); 517212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 518212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 519212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Used for JPEG data, single plane, row and pixel strides are 0 520212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 521212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = 0; 522212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 523212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 524212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 525212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 526212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 527212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->stride; 528212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 529212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 530212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_RAW_SENSOR: 531212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // In native side, strides are specified in pixels, not in bytes. 532212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp bayer data. even width/height, 533212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // row stride multiple of 16 pixels (32 bytes) 534212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 535212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 536212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 537212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->stride * 2; 538212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 539708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 540708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 541708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 2; 542708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 543708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 544708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 545708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 546708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 4; 547708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 548708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 549708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 550708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 551708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 3; 552708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 553212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 554212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt); 555212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 556212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "unsupported buffer format"); 557212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 558212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 559212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 560212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return rowStride; 561212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 562212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 563212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 564212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 565212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_classInit(JNIEnv* env, jclass clazz) 566212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 567212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 568212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 569212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage"); 570212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(imageClazz == NULL, 571212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader$SurfaceImage"); 572ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mLockedBuffer = env->GetFieldID( 573ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J"); 574ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mLockedBuffer == NULL, 575212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 576212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID); 577212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 578ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mTimestamp = env->GetFieldID( 579ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J"); 580ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL, 581212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 582212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); 583212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 584ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.mNativeContext = env->GetFieldID( 585ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J"); 586ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL, 587212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 588212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID); 589212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 590ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID( 591ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, "postEventFromNative", "(Ljava/lang/Object;)V"); 592ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL, 593212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.postEventFromNative"); 594212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 595212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane"); 596212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class"); 597212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // FindClass only gives a local reference of jclass object. 598ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); 599ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>", 600ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "(Landroid/media/ImageReader$SurfaceImage;III)V"); 601ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, 602ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "Can not find SurfacePlane constructor"); 603212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 604212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 605212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, 606212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jint width, jint height, jint format, jint maxImages) 607212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 608212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res; 609212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int nativeFormat; 610212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 611212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d", 612212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He __FUNCTION__, width, height, format, maxImages); 613212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 614212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He nativeFormat = Image_getPixelFormat(env, format); 615212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 616b550929b7a4b0d5f9645a7a1ebf287d3f13cf1afMathias Agopian sp<BufferQueue> bq = new BufferQueue(); 617dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin sp<CpuConsumer> consumer = new CpuConsumer(bq, maxImages, 618dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin /*controlledByApp*/true); 619212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // TODO: throw dvm exOutOfMemoryError? 620212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer == NULL) { 621212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer"); 622212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 623212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 624212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 625212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz = env->GetObjectClass(thiz); 626212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (clazz == NULL) { 627212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader"); 628212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 629212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 630212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages)); 631212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setCpuConsumer(consumer); 63252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian ctx->setBufferQueue(bq); 633212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(ctx); 634212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, ctx); 635212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferFormat(nativeFormat); 636212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferWidth(width); 637212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferHeight(height); 638212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 639212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set the width/height/format to the CpuConsumer 640212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He res = consumer->setDefaultBufferSize(width, height); 641212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (res != OK) { 642212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 643212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Failed to set CpuConsumer buffer size"); 644212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 645212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 646212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He res = consumer->setDefaultBufferFormat(nativeFormat); 647212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (res != OK) { 648212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 649212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Failed to set CpuConsumer buffer format"); 650212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 651212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 652212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 653212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_close(JNIEnv* env, jobject thiz) 654212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 655212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 656212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 657212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 658212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 659212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // ImageReader is already closed. 660212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 661212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 662212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 663212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* consumer = ImageReader_getCpuConsumer(env, thiz); 664212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer != NULL) { 665212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->abandon(); 666212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(NULL); 667212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 668212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, NULL); 669212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 670212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 671212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image) 672212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 673212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 674212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 675212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 676212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("ImageReader#close called before Image#close, consider calling Image#close first"); 677212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 678212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 679212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 680212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* consumer = ctx->getCpuConsumer(); 681212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, image); 682212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (!buffer) { 683212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("Image already released!!!"); 684212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 685212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 686212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->unlockBuffer(*buffer); 687212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Image_setBuffer(env, image, NULL); 688212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->returnLockedBuffer(buffer); 689212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 690212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 691e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinstatic jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, 692212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject image) 693212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 694212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 695212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 696212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 697212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 698e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 699212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 700212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 701212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* consumer = ctx->getCpuConsumer(); 702212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = ctx->getLockedBuffer(); 703212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 704d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkin ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than" 705d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkin " maxImages buffers"); 706e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 707212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 708212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res = consumer->lockNextBuffer(buffer); 709212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (res != NO_ERROR) { 710f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown if (res != BAD_VALUE /*no buffers*/) { 711dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin if (res == NOT_ENOUGH_DATA) { 712e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 713dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } else { 714dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin ALOGE("%s Fail to lockNextBuffer with error: %d ", 715dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin __FUNCTION__, res); 716e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin jniThrowExceptionFmt(env, "java/lang/AssertionError", 717dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin "Unknown error (%d) when we tried to lock buffer.", 718dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin res); 719dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } 720f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown } 721e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_NO_BUFFERS; 722212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 723212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 7244eda9f5359347c11914e47f477535c9533674d32Zhijun He if (buffer->format == HAL_PIXEL_FORMAT_YCrCb_420_SP) { 7254eda9f5359347c11914e47f477535c9533674d32Zhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 7264eda9f5359347c11914e47f477535c9533674d32Zhijun He "NV21 format is not supported by ImageReader"); 7274eda9f5359347c11914e47f477535c9533674d32Zhijun He return -1; 7284eda9f5359347c11914e47f477535c9533674d32Zhijun He } 7294eda9f5359347c11914e47f477535c9533674d32Zhijun He 730212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Check if the left-top corner of the crop rect is origin, we currently assume this point is 731212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // zero, will revist this once this assumption turns out problematic. 732212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Point lt = buffer->crop.leftTop(); 733212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (lt.x != 0 || lt.y != 0) { 7344eda9f5359347c11914e47f477535c9533674d32Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 7354eda9f5359347c11914e47f477535c9533674d32Zhijun He "crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 736e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 737212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 738212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 739212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Check if the producer buffer configurations match what ImageReader configured. 740212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // We want to fail for the very first image because this case is too bad. 741534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He int outputWidth = buffer->width; 742534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He int outputHeight = buffer->height; 743534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 74437682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He // Correct width/height when crop is set. 7459e6d073a999d7934aa3f22a5877c6e8e2ce15766Zhijun He if (!buffer->crop.isEmpty()) { 746cfa553369fd8ef68db751fe1052cd17fd5763965Zhijun He outputWidth = buffer->crop.getWidth(); 747cfa553369fd8ef68db751fe1052cd17fd5763965Zhijun He outputHeight = buffer->crop.getHeight(); 748534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He } 749534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 750212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int imageReaderWidth = ctx->getBufferWidth(); 751212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int imageReaderHeight = ctx->getBufferHeight(); 75237682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && 75337682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He (imageReaderWidth != outputWidth || imageReaderHeight > outputHeight)) { 75437682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He /** 75537682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He * For video decoder, the buffer height is actually the vertical stride, 75637682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He * which is always >= actual image height. For future, decoder need provide 75737682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He * right crop rectangle to CpuConsumer to indicate the actual image height, 75837682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He * see bug 9563986. After this bug is fixed, we can enforce the height equal 75937682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He * check. Right now, only make sure buffer height is no less than ImageReader 76037682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He * height. 76137682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He */ 76237682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 76337682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He "Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", 76437682135da2fd90e7bc6a89a418862d1f4ca15fdZhijun He outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); 765e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 766212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 767212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 768212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx->getBufferFormat() != buffer->format) { 769212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Return the buffer to the queue. 770212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->unlockBuffer(*buffer); 771212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->returnLockedBuffer(buffer); 772212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 773212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Throw exception 774212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 775212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->format, ctx->getBufferFormat()); 776ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown String8 msg; 777ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown msg.appendFormat("The producer output buffer format 0x%x doesn't " 778ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "match the ImageReader's configured buffer format 0x%x.", 779ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown buffer->format, ctx->getBufferFormat()); 780212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 781ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown msg.string()); 782e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 783212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 784212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set SurfaceImage instance member variables 785212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Image_setBuffer(env, image, buffer); 786ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 787ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown static_cast<jlong>(buffer->timestamp)); 788212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 789e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_SUCCESS; 790212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 791212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 792212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) 793212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 794212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: ", __FUNCTION__); 795212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 79652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian BufferQueue* bq = ImageReader_getBufferQueue(env, thiz); 79752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian if (bq == NULL) { 798212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "CpuConsumer is uninitialized"); 799212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 800212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 801212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 802212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Wrap the IGBP in a Java-language Surface. 80352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return android_view_Surface_createFromIGraphicBufferProducer(env, bq); 804212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 805212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 806212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx) 807212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 808212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int rowStride, pixelStride; 809212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 810212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 811212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 812212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 813212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL); 814212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 815212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 816212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 817212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = Image_imageGetRowStride(env, buffer, idx); 818212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = Image_imageGetPixelStride(env, buffer, idx); 819212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 820ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz, 821ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride); 822212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 823212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return surfPlaneObj; 824212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 825212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 826212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx) 827212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 828212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *base = NULL; 829212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint32_t size = 0; 830212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject byteBuffer; 831212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 832212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 833212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 834212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 835212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 836212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 837212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 838212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 839212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 840212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Create byteBuffer from native buffer 841212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Image_getLockedBufferInfo(env, buffer, idx, &base, &size); 842212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He byteBuffer = env->NewDirectByteBuffer(base, size); 843212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // TODO: throw dvm exOutOfMemoryError? 844212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { 845212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Failed to allocate ByteBuffer"); 846212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 847212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 848212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return byteBuffer; 849212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 850212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 851212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} // extern "C" 852212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 853212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 854212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 855212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNINativeMethod gImageReaderMethods[] = { 856212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClassInit", "()V", (void*)ImageReader_classInit }, 857212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeInit", "(Ljava/lang/Object;IIII)V", (void*)ImageReader_init }, 858212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClose", "()V", (void*)ImageReader_close }, 859212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, 860e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup }, 861212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, 862212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 863212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 864212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNINativeMethod gImageMethods[] = { 865212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeImageGetBuffer", "(I)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer }, 866212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeCreatePlane", "(I)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", 867212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (void*)Image_createSurfacePlane }, 868212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 869212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 870212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heint register_android_media_ImageReader(JNIEnv *env) { 871212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 872212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret1 = AndroidRuntime::registerNativeMethods(env, 873212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods)); 874212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 875212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret2 = AndroidRuntime::registerNativeMethods(env, 876212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods)); 877212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 878212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return (ret1 || ret2); 879212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 880