android_media_ImageReader.cpp revision 4fb442617cdea52b11ed622b5cf0490337928ec1
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 365096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <stdint.h> 375096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <inttypes.h> 385096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 39212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 40212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 41212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" 42212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mLockedBuffer" 43212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" 44212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 45212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 46212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 47212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heusing namespace android; 48212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 49212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heenum { 50212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He IMAGE_READER_MAX_NUM_PLANES = 3, 51212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 52212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 53e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinenum { 54e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_SUCCESS = 0, 55e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_NO_BUFFERS = 1, 56e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin ACQUIRE_MAX_IMAGES = 2, 57e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin}; 58e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin 59ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 60ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mNativeContext; 61ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jmethodID postEventFromNative; 62ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gImageReaderClassInfo; 63ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown 64ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 65ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mLockedBuffer; 66ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jfieldID mTimestamp; 67ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfaceImageClassInfo; 68212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 69ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brownstatic struct { 70212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz; 71212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jmethodID ctor; 72ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown} gSurfacePlaneClassInfo; 73212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 74212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 75212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 76212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heclass JNIImageReaderContext : public CpuConsumer::FrameAvailableListener 77212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 78212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hepublic: 79212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext(JNIEnv* env, jobject weakThiz, jclass clazz, int maxImages); 80212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 81212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He virtual ~JNIImageReaderContext(); 82212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 832c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stoza virtual void onFrameAvailable(const BufferItem& item); 84212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 85212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* getLockedBuffer(); 86212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 87212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void returnLockedBuffer(CpuConsumer::LockedBuffer* buffer); 88212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 8952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian void setCpuConsumer(const sp<CpuConsumer>& consumer) { mConsumer = consumer; } 90212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* getCpuConsumer() { return mConsumer.get(); } 91212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 925b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; } 935b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* getProducer() { return mProducer.get(); } 94212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 95212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferFormat(int format) { mFormat = format; } 96212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferFormat() { return mFormat; } 97212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 98212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferWidth(int width) { mWidth = width; } 99212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferWidth() { return mWidth; } 100212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 101212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He void setBufferHeight(int height) { mHeight = height; } 102212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int getBufferHeight() { return mHeight; } 103212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 104212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heprivate: 105212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static JNIEnv* getJNIEnv(bool* needsDetach); 106212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He static void detachJNI(); 107212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 108212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He List<CpuConsumer::LockedBuffer*> mBuffers; 109212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<CpuConsumer> mConsumer; 1105b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<IGraphicBufferProducer> mProducer; 111212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject mWeakThiz; 112212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass mClazz; 113212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mFormat; 114212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mWidth; 115212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int mHeight; 116212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 117212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 118212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::JNIImageReaderContext(JNIEnv* env, 119212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject weakThiz, jclass clazz, int maxImages) : 120212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mWeakThiz(env->NewGlobalRef(weakThiz)), 121212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mClazz((jclass)env->NewGlobalRef(clazz)) { 122212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (int i = 0; i < maxImages; i++) { 123212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer *buffer = new CpuConsumer::LockedBuffer; 124212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 125212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 126212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 127212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 128212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) { 129212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!"); 130212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = false; 131212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = AndroidRuntime::getJNIEnv(); 132212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env == NULL) { 133212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; 134212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 135212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->AttachCurrentThread(&env, (void*) &args); 136212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 137212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread attach failed: %#x", result); 138212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 139212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 140212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *needsDetach = true; 141212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 142212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return env; 143212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 144212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 145212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hevoid JNIImageReaderContext::detachJNI() { 146212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JavaVM* vm = AndroidRuntime::getJavaVM(); 147212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int result = vm->DetachCurrentThread(); 148212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (result != JNI_OK) { 149212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("thread detach failed: %#x", result); 150212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 151212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 152212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 153212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeCpuConsumer::LockedBuffer* JNIImageReaderContext::getLockedBuffer() { 154212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (mBuffers.empty()) { 155212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 156212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 157212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Return a LockedBuffer pointer and remove it from the list 158212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He List<CpuConsumer::LockedBuffer*>::iterator it = mBuffers.begin(); 159212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = *it; 160212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.erase(it); 161212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return buffer; 162212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 163212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 164d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkinvoid JNIImageReaderContext::returnLockedBuffer(CpuConsumer::LockedBuffer* buffer) { 165212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.push_back(buffer); 166212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 167212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 168212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun HeJNIImageReaderContext::~JNIImageReaderContext() { 169212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 170212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 171212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 172212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mWeakThiz); 173212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He env->DeleteGlobalRef(mClazz); 174212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 175212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("leaking JNI object references"); 176212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 177212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 178212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 179212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 180212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 181212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Delete LockedBuffers 182212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He for (List<CpuConsumer::LockedBuffer *>::iterator it = mBuffers.begin(); 183212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He it != mBuffers.end(); it++) { 184212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He delete *it; 185212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 186212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mBuffers.clear(); 187212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He mConsumer.clear(); 188212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 189212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 1902c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stozavoid JNIImageReaderContext::onFrameAvailable(const BufferItem& /*item*/) 191212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 192212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: frame available", __FUNCTION__); 193212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He bool needsDetach = false; 194212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIEnv* env = getJNIEnv(&needsDetach); 195212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (env != NULL) { 196ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz); 197212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 198212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("onFrameAvailable event will not posted"); 199212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 200212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (needsDetach) { 201212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He detachJNI(); 202212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 203212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 204212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 205212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 206212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 207212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heextern "C" { 208212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 209212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz) 210212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 211212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext *ctx; 212212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx = reinterpret_cast<JNIImageReaderContext *> 213ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext)); 214212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx; 215212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 216212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 217212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic CpuConsumer* ImageReader_getCpuConsumer(JNIEnv* env, jobject thiz) 218212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 219212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 220212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 221212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 222212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 223212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 224212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 225212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return ctx->getCpuConsumer(); 226212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 227212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 2285b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stozastatic IGraphicBufferProducer* ImageReader_getProducer(JNIEnv* env, jobject thiz) 22952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{ 23052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian ALOGV("%s:", __FUNCTION__); 23152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 23252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian if (ctx == NULL) { 23352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 23452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian return NULL; 23552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian } 2365b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return ctx->getProducer(); 23752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian} 23852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian 239212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_setNativeContext(JNIEnv* env, 240212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject thiz, sp<JNIImageReaderContext> ctx) 241212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 242212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 243212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const p = ImageReader_getContext(env, thiz); 244212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx != 0) { 245212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->incStrong((void*)ImageReader_setNativeContext); 246212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 247212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (p) { 248212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He p->decStrong((void*)ImageReader_setNativeContext); 249212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 250ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext, 251ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown reinterpret_cast<jlong>(ctx.get())); 252212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 253212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 254212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic CpuConsumer::LockedBuffer* Image_getLockedBuffer(JNIEnv* env, jobject image) 255212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 256ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown return reinterpret_cast<CpuConsumer::LockedBuffer*>( 257ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->GetLongField(image, gSurfaceImageClassInfo.mLockedBuffer)); 258212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 259212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 260212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void Image_setBuffer(JNIEnv* env, jobject thiz, 261212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He const CpuConsumer::LockedBuffer* buffer) 262212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 263ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(thiz, gSurfaceImageClassInfo.mLockedBuffer, reinterpret_cast<jlong>(buffer)); 264212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 265212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 266212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// Some formats like JPEG defined with different values between android.graphics.ImageFormat and 267212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// graphics.h, need convert to the one defined in graphics.h here. 268212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic int Image_getPixelFormat(JNIEnv* env, int format) 269212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 270d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He int jpegFormat; 271212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jfieldID fid; 272212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 273212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: format = 0x%x", __FUNCTION__, format); 274212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 275212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat"); 276212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(imageFormatClazz != NULL); 277212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 278212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He fid = env->GetStaticFieldID(imageFormatClazz, "JPEG", "I"); 279212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jpegFormat = env->GetStaticIntField(imageFormatClazz, fid); 280212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 281a5e1528f80f0472701dcbfc42d2f45ffc4a16466Zhijun He // Translate the JPEG to BLOB for camera purpose. 282212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (format == jpegFormat) { 283212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He format = HAL_PIXEL_FORMAT_BLOB; 284212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 285212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 286212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return format; 287212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 288212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 28931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer, bool usingRGBAOverride) 290534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He{ 291534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 292534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint32_t size = 0; 293534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint32_t width = buffer->width; 294534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint8_t* jpegBuffer = buffer->data; 295534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 29631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (usingRGBAOverride) { 2970c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4; 29831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 29931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 300534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He // First check for JPEG transport header at the end of the buffer 301534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob)); 302534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header); 303534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) { 304534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He size = blob->jpeg_size; 305534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He ALOGV("%s: Jpeg size = %d", __FUNCTION__, size); 306534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He } 307534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 308534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He // failed to find size, default to whole buffer 309534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He if (size == 0) { 3105096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin /* 3115096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * This is a problem because not including the JPEG header 3125096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * means that in certain rare situations a regular JPEG blob 3135096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * will be misidentified as having a header, in which case 3145096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin * we will get a garbage size value. 3155096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin */ 3165096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGW("%s: No JPEG header detected, defaulting to size=width=%d", 3175096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin __FUNCTION__, width); 318534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He size = width; 319534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He } 320534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 321534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He return size; 322534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He} 323534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 32431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic bool usingRGBAToJpegOverride(int32_t bufferFormat, int32_t readerCtxFormat) { 32531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return readerCtxFormat == HAL_PIXEL_FORMAT_BLOB && bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888; 32631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk} 32731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 3280fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic int32_t applyFormatOverrides(int32_t bufferFormat, int32_t readerCtxFormat) 3290fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk{ 3300fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW 3310fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // write limitations for some platforms (b/17379185). 33231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (usingRGBAToJpegOverride(bufferFormat, readerCtxFormat)) { 3330fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return HAL_PIXEL_FORMAT_BLOB; 3340fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } 3350fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return bufferFormat; 3360fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk} 3370fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 338212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 3390fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk uint8_t **base, uint32_t *size, int32_t readerFormat) 340212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 341212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 342212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(base != NULL, "base is NULL!!!"); 343212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(size != NULL, "size is NULL!!!"); 344212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 345212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 3467f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He ALOGV("%s: buffer: %p", __FUNCTION__, buffer); 347212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 348212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint32_t dataSize, ySize, cSize, cStride; 349212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *cb, *cr; 350212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *pData = NULL; 351708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He int bytesPerPixel = 0; 352212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 353212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = ySize = cSize = cStride = 0; 3544fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar int32_t fmt = buffer->flexFormat; 3550fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 35631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk bool usingRGBAOverride = usingRGBAToJpegOverride(fmt, readerFormat); 3570fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk fmt = applyFormatOverrides(fmt, readerFormat); 358212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 359212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 360212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 361212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 362212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 363212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 364212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->dataCb : 365212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->dataCr; 3664fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar // only map until last pixel 367212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (idx == 0) { 3684fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar dataSize = buffer->stride * (buffer->height - 1) + buffer->width; 369212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } else { 3704fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar dataSize = buffer->chromaStride * (buffer->height / 2 - 1) + 3714fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar buffer->chromaStep * (buffer->width / 2 - 1) + 1; 372212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 373212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 374212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // NV21 375212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 376212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr = buffer->data + (buffer->stride * buffer->height); 377212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb = cr + 1; 3784fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar // only map until last pixel 3794fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar ySize = buffer->width * (buffer->height - 1) + buffer->width; 3804fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar cSize = buffer->width * (buffer->height / 2 - 1) + buffer->width - 1; 381212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 382212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 383212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 384212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 385212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 386212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb: 387212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr; 388212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 389212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = (idx == 0) ? ySize : cSize; 390212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 391212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 392212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Y and C stride need to be 16 pixel aligned. 393212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 394212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 395212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 396212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ySize = buffer->stride * buffer->height; 397212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cStride = ALIGN(buffer->stride / 2, 16); 398212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr = buffer->data + ySize; 399212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cSize = cStride * buffer->height / 2; 400212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb = cr + cSize; 401212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 402212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = 403212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 0) ? 404212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He buffer->data : 405212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He (idx == 1) ? 406212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cb : 407212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He cr; 408212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = (idx == 0) ? ySize : cSize; 409212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 410212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 411212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane, 8bpp. 412212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 413212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 414212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 415212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He dataSize = buffer->stride * buffer->height; 416212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 417212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 418977ad8d26e701ed3902247852986d474e0e07f4dZhijun He bytesPerPixel = 2; 419212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane, 16bpp, strides are specified in pixels, not in bytes 420212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 421212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 422212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 423977ad8d26e701ed3902247852986d474e0e07f4dZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 424212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 425212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 426212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Used for JPEG data, height must be 1, width == size, single plane. 427212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 428212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height); 429212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 430212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 43131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk dataSize = Image_getJpegSize(buffer, usingRGBAOverride); 432212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 433212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_RAW_SENSOR: 434212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp bayer data. 435977ad8d26e701ed3902247852986d474e0e07f4dZhijun He bytesPerPixel = 2; 436212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 437212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pData = buffer->data; 438977ad8d26e701ed3902247852986d474e0e07f4dZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 439212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 440d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He case HAL_PIXEL_FORMAT_RAW10: 441d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He // Single plane 10bpp bayer data. 442d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 443d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He LOG_ALWAYS_FATAL_IF(buffer->width % 4, 444d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He "Width is not multiple of 4 %d", buffer->width); 445d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He LOG_ALWAYS_FATAL_IF(buffer->height % 2, 446d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He "Height is not even %d", buffer->height); 4474c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 10 / 8), 4484c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He "stride (%d) should be at least %d", 4494c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He buffer->stride, buffer->width * 10 / 8); 450d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He pData = buffer->data; 4514c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He dataSize = buffer->stride * buffer->height; 452d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He break; 453708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 454708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 455708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 32bpp. 456708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 4; 457708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 458708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 459708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 460708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 461708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 462708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 16bpp. 463708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 2; 464708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 465708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 466708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 467708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 468708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 469708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 470708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He bytesPerPixel = 3; 471708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 472708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pData = buffer->data; 473708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 474708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 475212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 476212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 477212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Pixel format: 0x%x is unsupported", fmt); 478212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 479212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 480212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 481212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *base = pData; 482212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He *size = dataSize; 483212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 484212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4850fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 4860fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk int32_t readerFormat) 487212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 488212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 489212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx); 490212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 491212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int pixelStride = 0; 492212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 493212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 4944fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar int32_t fmt = buffer->flexFormat; 4950fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 4960fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk fmt = applyFormatOverrides(fmt, readerFormat); 4970fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 498212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 499212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 500212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = (idx == 0) ? 1 : buffer->chromaStep; 501212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 502212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 503212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = (idx == 0) ? 1 : 2; 504212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 505212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 506212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 8bpp data. 507212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 508212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride; 509212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 510212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 511212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 1; 512212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 513212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 514d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He case HAL_PIXEL_FORMAT_RAW10: 515d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He // Blob is used for JPEG data, RAW10 is used for 10-bit raw data, they are 516d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He // single plane, row and pixel strides are 0. 517212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 518212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 0; 519212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 520212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 521212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_RAW_SENSOR: 522708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 523212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp data. 524212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 525212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He pixelStride = 2; 526212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 527708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 528708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 529708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 530708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pixelStride = 4; 531708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 532708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 533708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 534708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 535708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He pixelStride = 3; 536708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 537212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 538212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 539212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Pixel format: 0x%x is unsupported", fmt); 540212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 541212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 542212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 543212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return pixelStride; 544212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 545212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5460fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 5470fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk int32_t readerFormat) 548212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 549212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 550212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 551212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 552212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int rowStride = 0; 553212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 554212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5554fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar int32_t fmt = buffer->flexFormat; 556212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 5570fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk fmt = applyFormatOverrides(fmt, readerFormat); 5580fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 559212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He switch (fmt) { 560212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 561212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = (idx == 0) ? buffer->stride : buffer->chromaStride; 562212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 563212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 564212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->width; 565212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 566212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_YV12: 567212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 568212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 569212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16); 570212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 571212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_BLOB: 572d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He // Blob is used for JPEG data, RAW10 is used for 10-bit raw data, they are 573d1988a98ed69db8c33b77b5c085ab91d22ef3bbcZhijun He // single plane, row and pixel strides are 0. 574212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 575212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = 0; 576212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 5774c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He case HAL_PIXEL_FORMAT_RAW10: 5784c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 5794c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He rowStride = buffer->stride; 5804c4064fa66f551f49b7e1017b1ebe65a05f9df21Zhijun He break; 581212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y8: 582212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 583212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 584212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 585212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->stride; 586212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 587212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_Y16: 588212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He case HAL_PIXEL_FORMAT_RAW_SENSOR: 589212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // In native side, strides are specified in pixels, not in bytes. 590212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Single plane 16bpp bayer data. even width/height, 591212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // row stride multiple of 16 pixels (32 bytes) 592212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 593212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 594212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 595212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He rowStride = buffer->stride * 2; 596212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 597708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_565: 598708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 599708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 2; 600708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 601708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 602708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 603708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 604708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 4; 605708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 606708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He case HAL_PIXEL_FORMAT_RGB_888: 607708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He // Single plane, 24bpp. 608708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 609708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He rowStride = buffer->stride * 3; 610708e3595031fa15f4ac26c5675a53c1ed495b895Zhijun He break; 611212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He default: 612212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt); 613212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 614212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "unsupported buffer format"); 615212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He break; 616212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 617212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 618212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return rowStride; 619212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 620212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 621f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic int Image_getBufferWidth(CpuConsumer::LockedBuffer* buffer) { 622f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (buffer == NULL) return -1; 623f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 624f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (!buffer->crop.isEmpty()) { 625f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->crop.getWidth(); 626f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 627f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->width; 628f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 629f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 630f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic int Image_getBufferHeight(CpuConsumer::LockedBuffer* buffer) { 631f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (buffer == NULL) return -1; 632f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 633f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if (!buffer->crop.isEmpty()) { 634f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->crop.getHeight(); 635f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 636f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return buffer->height; 637f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 638f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 639212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 640212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 641212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_classInit(JNIEnv* env, jclass clazz) 642212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 643212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 644212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 645212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage"); 646212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(imageClazz == NULL, 647212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader$SurfaceImage"); 648ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mLockedBuffer = env->GetFieldID( 649ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J"); 650ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mLockedBuffer == NULL, 651212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 652212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID); 653212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 654ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfaceImageClassInfo.mTimestamp = env->GetFieldID( 655ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J"); 656ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL, 657212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 658212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); 659212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 660ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.mNativeContext = env->GetFieldID( 661ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J"); 662ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL, 663212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.%s", 664212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID); 665212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 666ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID( 667ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown clazz, "postEventFromNative", "(Ljava/lang/Object;)V"); 668ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL, 669212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "can't find android/graphics/ImageReader.postEventFromNative"); 670212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 671212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane"); 672212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class"); 673212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // FindClass only gives a local reference of jclass object. 674ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); 675ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>", 676ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "(Landroid/media/ImageReader$SurfaceImage;III)V"); 677ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, 678ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown "Can not find SurfacePlane constructor"); 679212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 680212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 681212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, 682212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jint width, jint height, jint format, jint maxImages) 683212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 684212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res; 685212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int nativeFormat; 686212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 687212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d", 688212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He __FUNCTION__, width, height, format, maxImages); 689212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 690212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He nativeFormat = Image_getPixelFormat(env, format); 691212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 6925b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<IGraphicBufferProducer> gbProducer; 6935b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<IGraphicBufferConsumer> gbConsumer; 6945b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 6955b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza sp<CpuConsumer> consumer = new CpuConsumer(gbConsumer, maxImages, 696dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin /*controlledByApp*/true); 697212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // TODO: throw dvm exOutOfMemoryError? 698212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer == NULL) { 699212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer"); 700212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 701212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 702212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 703212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jclass clazz = env->GetObjectClass(thiz); 704212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (clazz == NULL) { 705212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader"); 706212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 707212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 708212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages)); 709212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setCpuConsumer(consumer); 7105b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza ctx->setProducer(gbProducer); 711212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(ctx); 712212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, ctx); 713212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferFormat(nativeFormat); 714212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferWidth(width); 715212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->setBufferHeight(height); 716212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 717212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set the width/height/format to the CpuConsumer 718212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He res = consumer->setDefaultBufferSize(width, height); 719212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (res != OK) { 720212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 721212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Failed to set CpuConsumer buffer size"); 722212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 723212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 724212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He res = consumer->setDefaultBufferFormat(nativeFormat); 725212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (res != OK) { 726212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", 727212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "Failed to set CpuConsumer buffer format"); 728212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 729212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 730212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 731212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_close(JNIEnv* env, jobject thiz) 732212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 733212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 734212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 735212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 736212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 737212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // ImageReader is already closed. 738212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 739212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 740212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 741212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* consumer = ImageReader_getCpuConsumer(env, thiz); 742212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (consumer != NULL) { 743212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->abandon(); 744212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->setFrameAvailableListener(NULL); 745212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 746212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ImageReader_setNativeContext(env, thiz, NULL); 747212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 748212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 749212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image) 750212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 751212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 752212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 753212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 754212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("ImageReader#close called before Image#close, consider calling Image#close first"); 755212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 756212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 757212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 758212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* consumer = ctx->getCpuConsumer(); 759212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, image); 760212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (!buffer) { 761212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGW("Image already released!!!"); 762212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return; 763212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 764212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He consumer->unlockBuffer(*buffer); 765212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Image_setBuffer(env, image, NULL); 766212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ctx->returnLockedBuffer(buffer); 767212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 768212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 769e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkinstatic jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, 770212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject image) 771212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 772212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s:", __FUNCTION__); 773212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 774212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (ctx == NULL) { 775212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 776e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 777212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 778212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 779212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer* consumer = ctx->getCpuConsumer(); 780212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = ctx->getLockedBuffer(); 781212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 782d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkin ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than" 783d901c033756b01f5bd3c697fb3802331e9b45ad0Igor Murashkin " maxImages buffers"); 784e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 785212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 786212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He status_t res = consumer->lockNextBuffer(buffer); 787212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (res != NO_ERROR) { 788334778981dc01b5f8f4e137eb3f78745e214cf4dlina.x.pi ctx->returnLockedBuffer(buffer); 789f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown if (res != BAD_VALUE /*no buffers*/) { 790dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin if (res == NOT_ENOUGH_DATA) { 791e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_MAX_IMAGES; 792dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } else { 793dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin ALOGE("%s Fail to lockNextBuffer with error: %d ", 794dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin __FUNCTION__, res); 795e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin jniThrowExceptionFmt(env, "java/lang/AssertionError", 796dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin "Unknown error (%d) when we tried to lock buffer.", 797dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin res); 798dd0643202de80cc4ced37d1844e722c8a5e89154Igor Murashkin } 799f724c277d3362dbc8099fcbf8674609a424cd2eeJeff Brown } 800e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_NO_BUFFERS; 801212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 802212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 8034fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar if (buffer->flexFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) { 8044eda9f5359347c11914e47f477535c9533674d32Zhijun He jniThrowException(env, "java/lang/UnsupportedOperationException", 8054eda9f5359347c11914e47f477535c9533674d32Zhijun He "NV21 format is not supported by ImageReader"); 8064eda9f5359347c11914e47f477535c9533674d32Zhijun He return -1; 8074eda9f5359347c11914e47f477535c9533674d32Zhijun He } 8084eda9f5359347c11914e47f477535c9533674d32Zhijun He 809212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Check if the left-top corner of the crop rect is origin, we currently assume this point is 810212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // zero, will revist this once this assumption turns out problematic. 811212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Point lt = buffer->crop.leftTop(); 812212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (lt.x != 0 || lt.y != 0) { 8134eda9f5359347c11914e47f477535c9533674d32Zhijun He jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 8144eda9f5359347c11914e47f477535c9533674d32Zhijun He "crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 815e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return -1; 816212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 817212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 818212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Check if the producer buffer configurations match what ImageReader configured. 819f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk int outputWidth = Image_getBufferWidth(buffer); 820f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk int outputHeight = Image_getBufferHeight(buffer); 821534046d2b12fd13776ad782b982649cb0bea9b79Zhijun He 8220fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk int imgReaderFmt = ctx->getBufferFormat(); 823212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int imageReaderWidth = ctx->getBufferWidth(); 824212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int imageReaderHeight = ctx->getBufferHeight(); 8250fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) && 826f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) { 827f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", 828f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); 829212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 830212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 831feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int bufFmt = buffer->format; 8324fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888) { 8334fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar bufFmt = buffer->flexFormat; 8344fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar } 835feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (imgReaderFmt != bufFmt) { 83691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt == 83791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) { 8380fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // Special casing for when producer switches to a format compatible with flexible YUV 8390fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // (HAL_PIXEL_FORMAT_YCbCr_420_888). 84091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ctx->setBufferFormat(bufFmt); 8410fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGD("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt); 8420fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && bufFmt == HAL_PIXEL_FORMAT_RGBA_8888) { 8430fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW 8440fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk // write limitations for (b/17379185). 8450fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGD("%s: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.", __FUNCTION__); 846feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 847feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Return the buffer to the queue. 848feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk consumer->unlockBuffer(*buffer); 849feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ctx->returnLockedBuffer(buffer); 850feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 851feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Throw exception 852feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 853feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk buffer->format, ctx->getBufferFormat()); 854feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk String8 msg; 855feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk msg.appendFormat("The producer output buffer format 0x%x doesn't " 856feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "match the ImageReader's configured buffer format 0x%x.", 8574fb442617cdea52b11ed622b5cf0490337928ec1Lajos Molnar bufFmt, ctx->getBufferFormat()); 858feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowException(env, "java/lang/UnsupportedOperationException", 859feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk msg.string()); 860feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return -1; 861feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 862212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 863212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Set SurfaceImage instance member variables 864212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He Image_setBuffer(env, image, buffer); 865ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 866ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown static_cast<jlong>(buffer->timestamp)); 867212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 868e3351f1942bfe86682389b278e7ff128a72ea671Igor Murashkin return ACQUIRE_SUCCESS; 869212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 870212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 871212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) 872212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 873212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: ", __FUNCTION__); 874212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 8755b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza IGraphicBufferProducer* gbp = ImageReader_getProducer(env, thiz); 8765b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza if (gbp == NULL) { 877212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowRuntimeException(env, "CpuConsumer is uninitialized"); 878212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return NULL; 879212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 880212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 881212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Wrap the IGBP in a Java-language Surface. 8825b3c7c1e575a7fe1bc765e5d14690e1bfd971ffbDan Stoza return android_view_Surface_createFromIGraphicBufferProducer(env, gbp); 883212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 884212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 8850fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx, int readerFormat) 886212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 887212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int rowStride, pixelStride; 888212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 889212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 890212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 891212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 892212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOG_ASSERT(buffer != NULL); 893212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 894212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 895212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 8960fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 8970fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk readerFormat = Image_getPixelFormat(env, readerFormat); 8980fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 8990fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk rowStride = Image_imageGetRowStride(env, buffer, idx, readerFormat); 9000fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk pixelStride = Image_imageGetPixelStride(env, buffer, idx, readerFormat); 901212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 902ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz, 903ef961215599b1c154130d4e64e46a401d6bfef67Jeff Brown gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride); 904212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 905212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return surfPlaneObj; 906212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 907212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 9080fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunkstatic jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx, int readerFormat) 909212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He{ 910212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint8_t *base = NULL; 911212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He uint32_t size = 0; 912212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jobject byteBuffer; 913212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 914212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 915212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 916212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 917212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 918212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if (buffer == NULL) { 919212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 920212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 921212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 9220fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk readerFormat = Image_getPixelFormat(env, readerFormat); 9230fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 924212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // Create byteBuffer from native buffer 9250fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk Image_getLockedBufferInfo(env, buffer, idx, &base, &size, readerFormat); 9265096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 9275096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (size > static_cast<uint32_t>(INT32_MAX)) { 9285096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin // Byte buffer have 'int capacity', so check the range 9295096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 93031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk "Size too large for bytebuffer capacity %" PRIu32, size); 9315096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return NULL; 9325096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 9335096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 934212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He byteBuffer = env->NewDirectByteBuffer(base, size); 935212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He // TODO: throw dvm exOutOfMemoryError? 936212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { 937212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He jniThrowException(env, "java/lang/IllegalStateException", "Failed to allocate ByteBuffer"); 938212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He } 939212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 940212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return byteBuffer; 941212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 942212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 943f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic jint Image_getWidth(JNIEnv* env, jobject thiz) 944f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 945f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 946f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return Image_getBufferWidth(buffer); 947f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 948f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 949f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic jint Image_getHeight(JNIEnv* env, jobject thiz) 950f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk{ 951f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 952f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return Image_getBufferHeight(buffer); 953f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 954f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 955f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 956212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} // extern "C" 957212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 958212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He// ---------------------------------------------------------------------------- 959212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 960212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNINativeMethod gImageReaderMethods[] = { 961212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClassInit", "()V", (void*)ImageReader_classInit }, 962212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeInit", "(Ljava/lang/Object;IIII)V", (void*)ImageReader_init }, 963212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeClose", "()V", (void*)ImageReader_close }, 964212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, 965f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup }, 966212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, 967212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 968212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 969212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Hestatic JNINativeMethod gImageMethods[] = { 9700fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk {"nativeImageGetBuffer", "(II)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer }, 9710fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk {"nativeCreatePlane", "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", 972f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk (void*)Image_createSurfacePlane }, 973f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk {"nativeGetWidth", "()I", (void*)Image_getWidth }, 974f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk {"nativeGetHeight", "()I", (void*)Image_getHeight }, 975212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He}; 976212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 977212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun Heint register_android_media_ImageReader(JNIEnv *env) { 978212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 979212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret1 = AndroidRuntime::registerNativeMethods(env, 980212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods)); 981212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 982212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He int ret2 = AndroidRuntime::registerNativeMethods(env, 983212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods)); 984212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He 985212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He return (ret1 || ret2); 986212e78df9eb3bfff069de01aa7820cf4201c5f82Zhijun He} 987