android_media_ImageReader.cpp revision f724c277d3362dbc8099fcbf8674609a424cd2ee
13399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi/* 23399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * Copyright 2013 The Android Open Source Project 33399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * 43399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * Licensed under the Apache License, Version 2.0 (the "License"); 53399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * you may not use this file except in compliance with the License. 63399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * You may obtain a copy of the License at 73399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * 83399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * http://www.apache.org/licenses/LICENSE-2.0 93399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * 103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * Unless required by applicable law or agreed to in writing, software 113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * distributed under the License is distributed on an "AS IS" BASIS, 123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * See the License for the specific language governing permissions and 143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * limitations under the License. 153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi */ 163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 17bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam//#define LOG_NDEBUG 0 180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi#define LOG_TAG "ImageReader_JNI" 193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/Log.h> 203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/misc.h> 213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/List.h> 223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/String8.h> 230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi#include <cstdio> 253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 261a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi#include <gui/CpuConsumer.h> 270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi#include <gui/Surface.h> 283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <camera3.h> 293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 30df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <android_runtime/AndroidRuntime.h> 31df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <android_runtime/android_view_Surface.h> 32df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian 33df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <jni.h> 343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <JNIHelp.h> 353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 38f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#define ANDROID_MEDIA_IMAGEREADER_JNI_ID "mCpuConsumer" 390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" 403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mLockedBuffer" 413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" 423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// ---------------------------------------------------------------------------- 443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketiusing namespace android; 463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketienum { 480c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi IMAGE_READER_MAX_NUM_PLANES = 3, 493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}; 503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic struct { 520c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jfieldID mNativeContext; 530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jmethodID postEventFromNative; 540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} gImageReaderClassInfo; 550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 560c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic struct { 570c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jfieldID mLockedBuffer; 580c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jfieldID mTimestamp; 590c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} gSurfaceImageClassInfo; 600c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 613856b090cd04ba5dd4a59a12430ed724d5995909Steve Blockstatic struct { 620c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jclass clazz; 630c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jmethodID ctor; 640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} gSurfacePlaneClassInfo; 650c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// ---------------------------------------------------------------------------- 670c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketiclass JNIImageReaderContext : public CpuConsumer::FrameAvailableListener 690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketipublic: 710c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIImageReaderContext(JNIEnv* env, jobject weakThiz, jclass clazz, int maxImages); 720c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 730c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi virtual ~JNIImageReaderContext(); 740c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 750c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi virtual void onFrameAvailable(); 760c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 770c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi CpuConsumer::LockedBuffer* getLockedBuffer(); 780c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 790c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi void returnLockedBuffer(CpuConsumer::LockedBuffer* buffer); 800c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 810c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi void setCpuConsumer(const sp<CpuConsumer>& consumer) { mConsumer = consumer; } 820c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi CpuConsumer* getCpuConsumer() { return mConsumer.get(); } 830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 840c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi void setBufferQueue(const sp<BufferQueue>& bq) { mBufferQueue = bq; } 850c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi BufferQueue* getBufferQueue() { return mBufferQueue.get(); } 860c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 870c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi void setBufferFormat(int format) { mFormat = format; } 880c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int getBufferFormat() { return mFormat; } 890c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 900c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi void setBufferWidth(int width) { mWidth = width; } 910c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int getBufferWidth() { return mWidth; } 920c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 930c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi void setBufferHeight(int height) { mHeight = height; } 940c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int getBufferHeight() { return mHeight; } 950c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 960c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketiprivate: 970c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi static JNIEnv* getJNIEnv(bool* needsDetach); 980c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi static void detachJNI(); 990c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi List<CpuConsumer::LockedBuffer*> mBuffers; 1010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi sp<CpuConsumer> mConsumer; 1020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi sp<BufferQueue> mBufferQueue; 1030c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jobject mWeakThiz; 1040c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jclass mClazz; 1050c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int mFormat; 1060c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int mWidth; 1070c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int mHeight; 1080c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi}; 1093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 110bdddc659a941afdb7f4958f582c6901c07246097Daniel LamJNIImageReaderContext::JNIImageReaderContext(JNIEnv* env, 111bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam jobject weakThiz, jclass clazz, int maxImages) : 11221fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi mWeakThiz(env->NewGlobalRef(weakThiz)), 11321fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi mClazz((jclass)env->NewGlobalRef(clazz)) { 1140c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi for (int i = 0; i < maxImages; i++) { 11521fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi CpuConsumer::LockedBuffer *buffer = new CpuConsumer::LockedBuffer; 11621fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi mBuffers.push_back(buffer); 1170c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 1190c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1200c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag SanketiJNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) { 1210c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!"); 1220c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi *needsDetach = false; 1230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIEnv* env = AndroidRuntime::getJNIEnv(); 1240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (env == NULL) { 1250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; 1260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JavaVM* vm = AndroidRuntime::getJavaVM(); 1270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int result = vm->AttachCurrentThread(&env, (void*) &args); 1280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (result != JNI_OK) { 1290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGE("thread attach failed: %#x", result); 1300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return NULL; 1310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi *needsDetach = true; 1330c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return env; 1350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 1360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1370c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketivoid JNIImageReaderContext::detachJNI() { 1380c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JavaVM* vm = AndroidRuntime::getJavaVM(); 1390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int result = vm->DetachCurrentThread(); 1400c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (result != JNI_OK) { 1410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGE("thread detach failed: %#x", result); 1420c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 1440c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag SanketiCpuConsumer::LockedBuffer* JNIImageReaderContext::getLockedBuffer() { 1460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (mBuffers.empty()) { 1470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return NULL; 1480c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1490c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Return a LockedBuffer pointer and remove it from the list 1500c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi List<CpuConsumer::LockedBuffer*>::iterator it = mBuffers.begin(); 1510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi CpuConsumer::LockedBuffer* buffer = *it; 1520c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mBuffers.erase(it); 1530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return buffer; 1540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 1550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1560c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketivoid JNIImageReaderContext::returnLockedBuffer(CpuConsumer::LockedBuffer * buffer) { 1570c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mBuffers.push_back(buffer); 1580c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 1590c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1600c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag SanketiJNIImageReaderContext::~JNIImageReaderContext() { 1610c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi bool needsDetach = false; 1620c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIEnv* env = getJNIEnv(&needsDetach); 1630c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (env != NULL) { 1640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi env->DeleteGlobalRef(mWeakThiz); 1653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block env->DeleteGlobalRef(mClazz); 1660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } else { 1670c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGW("leaking JNI object references"); 1680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (needsDetach) { 1700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi detachJNI(); 1710c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1720c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1730c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Delete LockedBuffers 1740c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi for (List<CpuConsumer::LockedBuffer *>::iterator it = mBuffers.begin(); 1750c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi it != mBuffers.end(); it++) { 1760c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi delete *it; 1770c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1780c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mBuffers.clear(); 1790c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mConsumer.clear(); 1800c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 1810c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1820c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketivoid JNIImageReaderContext::onFrameAvailable() 1830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 1840c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s: frame available", __FUNCTION__); 1850c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi bool needsDetach = false; 1860c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIEnv* env = getJNIEnv(&needsDetach); 1870c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (env != NULL) { 1880c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz); 1890c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } else { 1900c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGW("onFrameAvailable event will not posted"); 1910c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1920c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (needsDetach) { 1930c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi detachJNI(); 1940c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 1950c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 1960c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1970c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// ---------------------------------------------------------------------------- 1980c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1990c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketiextern "C" { 2000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz) 2020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2030c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIImageReaderContext *ctx; 2040c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx = reinterpret_cast<JNIImageReaderContext *> 2050c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext)); 2060c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return ctx; 2070c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 2080c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2090c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic CpuConsumer* ImageReader_getCpuConsumer(JNIEnv* env, jobject thiz) 2100c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2110c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s:", __FUNCTION__); 2120c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 2130c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (ctx == NULL) { 2140c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 2150c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return NULL; 2160c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 2170c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return ctx->getCpuConsumer(); 2180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 2190c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2200c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic BufferQueue* ImageReader_getBufferQueue(JNIEnv* env, jobject thiz) 2210c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2220c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s:", __FUNCTION__); 2230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 2240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (ctx == NULL) { 2250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 2260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return NULL; 2270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 2280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return ctx->getBufferQueue(); 2290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 2300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic void ImageReader_setNativeContext(JNIEnv* env, 2320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jobject thiz, sp<JNIImageReaderContext> ctx) 2330c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s:", __FUNCTION__); 2350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi JNIImageReaderContext* const p = ImageReader_getContext(env, thiz); 2360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (ctx != 0) { 2370c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx->incStrong((void*)ImageReader_setNativeContext); 2380c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 2390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (p) { 2400c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi p->decStrong((void*)ImageReader_setNativeContext); 2410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 2420c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext, 2430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi reinterpret_cast<jlong>(ctx.get())); 2440c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 2450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic CpuConsumer::LockedBuffer* Image_getLockedBuffer(JNIEnv* env, jobject image) 2470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2480c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return reinterpret_cast<CpuConsumer::LockedBuffer*>( 2490c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi env->GetLongField(image, gSurfaceImageClassInfo.mLockedBuffer)); 2500c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 2510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2520c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic void Image_setBuffer(JNIEnv* env, jobject thiz, 2530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi const CpuConsumer::LockedBuffer* buffer) 2540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi env->SetLongField(thiz, gSurfaceImageClassInfo.mLockedBuffer, reinterpret_cast<jlong>(buffer)); 2560c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 2570c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2580c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// Some formats like JPEG defined with different values between android.graphics.ImageFormat and 2590c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// graphics.h, need convert to the one defined in graphics.h here. 2600c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic int Image_getPixelFormat(JNIEnv* env, int format) 2610c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2620c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int jpegFormat, rawSensorFormat; 2630c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jfieldID fid; 2640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2650c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s: format = 0x%x", __FUNCTION__, format); 2660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2670c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat"); 2680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(imageFormatClazz != NULL); 2690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi fid = env->GetStaticFieldID(imageFormatClazz, "JPEG", "I"); 2710c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jpegFormat = env->GetStaticIntField(imageFormatClazz, fid); 2720c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi fid = env->GetStaticFieldID(imageFormatClazz, "RAW_SENSOR", "I"); 2730c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi rawSensorFormat = env->GetStaticIntField(imageFormatClazz, fid); 2740c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2750c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Translate the JPEG to BLOB for camera purpose, an add more if more mismatch is found. 2760c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (format == jpegFormat) { 2770c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi format = HAL_PIXEL_FORMAT_BLOB; 2780c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 2790c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Same thing for RAW_SENSOR format 2800c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (format == rawSensorFormat) { 2810c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi format = HAL_PIXEL_FORMAT_RAW_SENSOR; 2820c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 2830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2840c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return format; 2853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 2860c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2870c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer) 2880c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 2890c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 2900c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint32_t size = 0; 2910c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint32_t width = buffer->width; 2920c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint8_t* jpegBuffer = buffer->data; 2930c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 2940c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // First check for JPEG transport header at the end of the buffer 2950c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob)); 2960c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header); 2970c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) { 2980c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi size = blob->jpeg_size; 2990c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s: Jpeg size = %d", __FUNCTION__, size); 3000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 3010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // failed to find size, default to whole buffer 3030c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (size == 0) { 3040c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi size = width; 3050c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 3060c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3070c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return size; 3080c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 3090c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3100c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, 3110c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint8_t **base, uint32_t *size) 3120c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 3130c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); 3140c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(base != NULL, "base is NULL!!!"); 3150c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(size != NULL, "size is NULL!!!"); 3160c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 3170c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s: buffer: %p", __FUNCTION__, buffer); 3190c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3200c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint32_t dataSize, ySize, cSize, cStride; 3210c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint8_t *cb, *cr; 3220c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint8_t *pData = NULL; 3230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int bytesPerPixel = 0; 3240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = ySize = cSize = cStride = 0; 3260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int32_t fmt = buffer->format; 3270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi switch (fmt) { 3280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YCbCr_420_888: 3290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pData = 3300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (idx == 0) ? 3310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi buffer->data : 3320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (idx == 1) ? 3330c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi buffer->dataCb : 3340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi buffer->dataCr; 3350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (idx == 0) { 3360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = buffer->stride * buffer->height; 3370c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } else { 3380c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = buffer->chromaStride * buffer->height / 2; 3390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 3400c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 3410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // NV21 3420c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YCrCb_420_SP: 3430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi cr = buffer->data + (buffer->stride * buffer->height); 3440c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi cb = cr + 1; 3450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ySize = buffer->width * buffer->height; 3460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi cSize = buffer->width * buffer->height / 2; 3470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3481a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi pData = 3493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi (idx == 0) ? 3503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi buffer->data : 3510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (idx == 1) ? 3523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi cb: 3530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi cr; 3543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 3553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi dataSize = (idx == 0) ? ySize : cSize; 3563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 3573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_YV12: 3583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Y and C stride need to be 16 pixel aligned. 3593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 360b6f2fced47866a5d095b2b18d2e28d7c4321e3a6James Dong "Stride is not 16 pixel aligned %d", buffer->stride); 3611a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi 362bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ySize = buffer->stride * buffer->height; 363abf0610a8cea021548f2909e1d47d656206f641cDaniel Lam cStride = ALIGN(buffer->stride / 2, 16); 364bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam cr = buffer->data + ySize; 3653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi cSize = cStride * buffer->height / 2; 3660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi cb = cr + cSize; 3673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 3680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pData = 3690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (idx == 0) ? 3700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi buffer->data : 3710c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (idx == 1) ? 3723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi cb : 3733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi cr; 3740c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = (idx == 0) ? ySize : cSize; 3750c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 3760c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_Y8: 3770c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Single plane, 8bpp. 3780c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 3790c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3800c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pData = buffer->data; 3810c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = buffer->stride * buffer->height; 3820c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 3830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_Y16: 3840c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Single plane, 16bpp, strides are specified in pixels, not in bytes 3850c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 3860c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3870c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pData = buffer->data; 3880c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = buffer->stride * buffer->height * 2; 3890c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 3900c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_BLOB: 3910c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Used for JPEG data, height must be 1, width == size, single plane. 3920c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 3930c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height); 3940c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 3950c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pData = buffer->data; 3963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block dataSize = Image_getJpegSize(buffer); 3970c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 3980c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RAW_SENSOR: 399bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // Single plane 16bpp bayer data. 4000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 4010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pData = buffer->data; 4020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = buffer->width * 2 * buffer->height; 4030c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4040c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RGBA_8888: 4053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_RGBX_8888: 4063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Single plane, 32bpp. 4071a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi bytesPerPixel = 4; 4083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 4093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi pData = buffer->data; 4100c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = buffer->stride * buffer->height * bytesPerPixel; 4113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 4123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_RGB_565: 4130c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Single plane, 16bpp. 4140c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi bytesPerPixel = 2; 415a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 416a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi pData = buffer->data; 4173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi dataSize = buffer->stride * buffer->height * bytesPerPixel; 4181a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi break; 4193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_RGB_888: 4203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Single plane, 24bpp. 4213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi bytesPerPixel = 3; 4223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 4230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pData = buffer->data; 4240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi dataSize = buffer->stride * buffer->height * bytesPerPixel; 4250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi default: 4273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 4280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi "Pixel format: 0x%x is unsupported", fmt); 4290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 4310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 4320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi *base = pData; 4330c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi *size = dataSize; 4340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 4350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 4360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx) 4370c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 4380c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 4390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx); 4400c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 4410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int pixelStride = 0; 4420c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 4430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 4440c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int32_t fmt = buffer->format; 4450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi switch (fmt) { 4460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YCbCr_420_888: 4470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pixelStride = (idx == 0) ? 1 : buffer->chromaStep; 4480c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4490c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YCrCb_420_SP: 4500c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pixelStride = (idx == 0) ? 1 : 2; 4510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4520c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_Y8: 4530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Single plane 8bpp data. 4540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 4550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pixelStride; 4560c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4570c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YV12: 4580c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pixelStride = 1; 4590c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4600c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_BLOB: 4610c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Used for JPEG data, single plane, row and pixel strides are 0 46221fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 46331292d99f62a812af691e67e8e732c6ae582ee08Pannag Sanketi pixelStride = 0; 4640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4650c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_Y16: 4660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RAW_SENSOR: 4670c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RGB_565: 4680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Single plane 16bpp data. 4690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 4700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pixelStride = 2; 4710c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4720c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RGBA_8888: 4730c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RGBX_8888: 4740c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 4750c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pixelStride = 4; 4760c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4770c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RGB_888: 4783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // Single plane, 24bpp. 479f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 4800c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi pixelStride = 3; 4810c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4820c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi default: 4830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", 4840c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi "Pixel format: 0x%x is unsupported", fmt); 4850c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 4860c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 4870c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 4880c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return pixelStride; 4899d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam} 4909d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam 4919d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lamstatic jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx) 4929d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam{ 49321fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 4940c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); 4950c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 49621fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi int rowStride = 0; 4970c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(buffer != NULL, "buffer is NULL"); 49821fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi 4990c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int32_t fmt = buffer->format; 5000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 5010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi switch (fmt) { 5020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YCbCr_420_888: 5030c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi rowStride = (idx == 0) ? buffer->stride : buffer->chromaStride; 5040c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 5050c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YCrCb_420_SP: 5060c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi rowStride = buffer->width; 5070c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 5080c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_YV12: 5090c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 5101a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi "Stride is not 16 pixel aligned %d", buffer->stride); 5113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi rowStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16); 5123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 5133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_BLOB: 5143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Used for JPEG data, single plane, row and pixel strides are 0 5153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 5163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi rowStride = 0; 5173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 5183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_Y8: 5193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 5203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 5211a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi "Stride is not 16 pixel aligned %d", buffer->stride); 5223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi rowStride = buffer->stride; 5233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 5243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_Y16: 5253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_RAW_SENSOR: 5263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // In native side, strides are specified in pixels, not in bytes. 5270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Single plane 16bpp bayer data. even width/height, 5280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // row stride multiple of 16 pixels (32 bytes) 5290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 5300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 5310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi "Stride is not 16 pixel aligned %d", buffer->stride); 5323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi rowStride = buffer->stride * 2; 5330c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi break; 5340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi case HAL_PIXEL_FORMAT_RGB_565: 5350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 5360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi rowStride = buffer->stride * 2; 5373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 5383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_RGBA_8888: 5393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_RGBX_8888: 5401a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 5413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi rowStride = buffer->stride * 4; 5423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 5433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi case HAL_PIXEL_FORMAT_RGB_888: 5443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Single plane, 24bpp. 5453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); 5463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi rowStride = buffer->stride * 3; 5473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 5483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi default: 5493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt); 5503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jniThrowException(env, "java/lang/UnsupportedOperationException", 5513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "unsupported buffer format"); 5523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 5533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 5543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return rowStride; 5563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 5573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// ---------------------------------------------------------------------------- 5593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketistatic void ImageReader_classInit(JNIEnv* env, jclass clazz) 5613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 5623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGV("%s:", __FUNCTION__); 5633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage"); 5653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(imageClazz == NULL, 5663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "can't find android/graphics/ImageReader$SurfaceImage"); 5673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi gSurfaceImageClassInfo.mLockedBuffer = env->GetFieldID( 5683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J"); 5693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mLockedBuffer == NULL, 5701a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi "can't find android/graphics/ImageReader.%s", 5713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID); 5723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi gSurfaceImageClassInfo.mTimestamp = env->GetFieldID( 5743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J"); 5753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL, 5763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "can't find android/graphics/ImageReader.%s", 5773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID); 5783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi gImageReaderClassInfo.mNativeContext = env->GetFieldID( 5803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J"); 5813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL, 5823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "can't find android/graphics/ImageReader.%s", 5833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID); 5843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID( 5863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi clazz, "postEventFromNative", "(Ljava/lang/Object;)V"); 5873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL, 5883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "can't find android/graphics/ImageReader.postEventFromNative"); 5893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 5903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane"); 5913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class"); 5921a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi // FindClass only gives a local reference of jclass object. 5933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz); 5943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>", 5953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "(Landroid/media/ImageReader$SurfaceImage;III)V"); 5963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL, 5973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "Can not find SurfacePlane constructor"); 5983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 5993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketistatic void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, 6013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jint width, jint height, jint format, jint maxImages) 6023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 6033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi status_t res; 6043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi int nativeFormat; 6053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d", 6073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi __FUNCTION__, width, height, format, maxImages); 6083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi nativeFormat = Image_getPixelFormat(env, format); 6103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi sp<BufferQueue> bq = new BufferQueue(); 6123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi sp<CpuConsumer> consumer = new CpuConsumer(bq, true, maxImages); 6133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // TODO: throw dvm exOutOfMemoryError? 6143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (consumer == NULL) { 6153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer"); 6163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return; 6173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 6183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jclass clazz = env->GetObjectClass(thiz); 6200c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (clazz == NULL) { 6210c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader"); 6220c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return; 6230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 6240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages)); 6250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx->setCpuConsumer(consumer); 6260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx->setBufferQueue(bq); 6270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi consumer->setFrameAvailableListener(ctx); 6281a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi ImageReader_setNativeContext(env, thiz, ctx); 6290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx->setBufferFormat(nativeFormat); 6300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx->setBufferWidth(width); 6310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx->setBufferHeight(height); 6323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 6333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // Set the width/height/format to the CpuConsumer 6343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi res = consumer->setDefaultBufferSize(width, height); 6350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (res != OK) { 6360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowException(env, "java/lang/IllegalStateException", 6373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "Failed to set CpuConsumer buffer size"); 6383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return; 6393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 6403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi res = consumer->setDefaultBufferFormat(nativeFormat); 6410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (res != OK) { 6420c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowException(env, "java/lang/IllegalStateException", 6433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block "Failed to set CpuConsumer buffer format"); 6443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block } 6453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 6463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic void ImageReader_close(JNIEnv* env, jobject thiz) 6480c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 6490c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s:", __FUNCTION__); 6500c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 6513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz); 6523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (ctx == NULL) { 6533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // ImageReader is already closed. 6540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return; 6553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 6563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi CpuConsumer* consumer = ImageReader_getCpuConsumer(env, thiz); 6581a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi if (consumer != NULL) { 6590c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi consumer->abandon(); 6600c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi consumer->setFrameAvailableListener(NULL); 6613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block } 6623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ImageReader_setNativeContext(env, thiz, NULL); 6630c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 6640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 665a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketistatic void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image) 6661a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi{ 6673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGV("%s:", __FUNCTION__); 6683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 6693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (ctx == NULL) { 6703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGW("ImageReader#close called before Image#close, consider calling Image#close first"); 6713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return; 6723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 6733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 6743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi CpuConsumer* consumer = ctx->getCpuConsumer(); 6753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, image); 6763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (!buffer) { 6773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGW("Image already released!!!"); 6783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return; 6793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 6801a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi consumer->unlockBuffer(*buffer); 6810c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi Image_setBuffer(env, image, NULL); 682bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ctx->returnLockedBuffer(buffer); 6833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block} 6843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 685a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketistatic jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz, 6860c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jobject image) 6870c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 688a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi ALOGV("%s:", __FUNCTION__); 6891a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); 6903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (ctx == NULL) { 6913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jniThrowRuntimeException(env, "ImageReaderContext is not initialized"); 6923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return false; 693bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 694bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 6953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi CpuConsumer* consumer = ctx->getCpuConsumer(); 696bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam CpuConsumer::LockedBuffer* buffer = ctx->getLockedBuffer(); 6973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (buffer == NULL) { 6983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGE("Unable to acquire a lockedBuffer, very likely client tries to lock more than" 6993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "maxImages buffers"); 7003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return false; 7013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 7023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi status_t res = consumer->lockNextBuffer(buffer); 7033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (res != NO_ERROR) { 7043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (res != BAD_VALUE /*no buffers*/) { 7053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGE("%s Fail to lockNextBuffer with error: %d ", __FUNCTION__, res); 7063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 7071a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi return false; 7083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 709bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 7103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // Check if the left-top corner of the crop rect is origin, we currently assume this point is 7113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // zero, will revist this once this assumption turns out problematic. 7120c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi Point lt = buffer->crop.leftTop(); 7130c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (lt.x != 0 || lt.y != 0) { 7143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi ALOGE("crop left: %d, top = %d", lt.x, lt.y); 7151a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi jniThrowException(env, "java/lang/UnsupportedOperationException", 7163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi "crop left top corner need to at origin"); 7173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 7183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 7193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Check if the producer buffer configurations match what ImageReader configured. 720bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // We want to fail for the very first image because this case is too bad. 7213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi int outputWidth = buffer->width; 7223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi int outputHeight = buffer->height; 7233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 7243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Correct with/height when crop is set. 7253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (buffer->crop.getWidth() > 0) { 7263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi outputWidth = buffer->crop.getWidth() + 1; 7273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 7280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (buffer->crop.getHeight() > 0) { 7290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi outputHeight = buffer->crop.getHeight() + 1; 7300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 7310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 7320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int imageReaderWidth = ctx->getBufferWidth(); 7330c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int imageReaderHeight = ctx->getBufferHeight(); 7340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (imageReaderWidth != outputWidth 7353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block || imageReaderHeight != outputHeight) { 7363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // Spew warning for now, since MediaCodec decoder has a bug to setup the right crop 7373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // TODO: make it throw exception once the decoder bug is fixed. 7380c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGW("Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", 7390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); 7400c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 7410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 74229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block if (ctx->getBufferFormat() != buffer->format) { 7430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Return the buffer to the queue. 7440c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi consumer->unlockBuffer(*buffer); 7450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ctx->returnLockedBuffer(buffer); 7460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 7470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Throw exception 7480c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 7490c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi buffer->format, ctx->getBufferFormat()); 7500c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi String8 msg; 7510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi msg.appendFormat("The producer output buffer format 0x%x doesn't " 7520c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi "match the ImageReader's configured buffer format 0x%x.", 7530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi buffer->format, ctx->getBufferFormat()); 7540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowException(env, "java/lang/UnsupportedOperationException", 7550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi msg.string()); 7560c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return false; 7570c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 7583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // Set SurfaceImage instance member variables 7593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi Image_setBuffer(env, image, buffer); 7603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp, 7610c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi static_cast<jlong>(buffer->timestamp)); 7623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 7633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block return true; 7643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 7653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 7660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) 7673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block{ 768f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong ALOGV("%s: ", __FUNCTION__); 7690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 7700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi BufferQueue* bq = ImageReader_getBufferQueue(env, thiz); 7713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (bq == NULL) { 7723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi jniThrowRuntimeException(env, "CpuConsumer is uninitialized"); 7730c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return NULL; 7740c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 7750c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 7760c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // Wrap the IGBP in a Java-language Surface. 7770c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return android_view_Surface_createFromIGraphicBufferProducer(env, bq); 7780c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 77921fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi 7803856b090cd04ba5dd4a59a12430ed724d5995909Steve Blockstatic jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx) 7813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block{ 7820c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int rowStride, pixelStride; 7830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 784bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 7850c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 7860c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 7870c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOG_ASSERT(buffer != NULL); 7880c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (buffer == NULL) { 7890c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 7909d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam } 7919d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam rowStride = Image_imageGetRowStride(env, buffer, idx); 7929d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam pixelStride = Image_imageGetPixelStride(env, buffer, idx); 7939d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam 7949d06df4ecfe39e7e46873f7cd75a71e32a01d4f7Daniel Lam jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz, 79521fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride); 7960c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 7970c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return surfPlaneObj; 79821fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketi} 7990c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 80021fcf0830c8b4fb544a09467bc96a8d0463ad966Pannag Sanketistatic jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx) 8010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi{ 8020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi uint8_t *base = NULL; 8033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi uint32_t size = 0; 8040c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jobject byteBuffer; 8050c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8060c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi ALOGV("%s: buffer index: %d", __FUNCTION__, idx); 8070c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); 8090c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8100c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (buffer == NULL) { 81131292d99f62a812af691e67e8e732c6ae582ee08Pannag Sanketi jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); 81231292d99f62a812af691e67e8e732c6ae582ee08Pannag Sanketi } 81331292d99f62a812af691e67e8e732c6ae582ee08Pannag Sanketi 81431292d99f62a812af691e67e8e732c6ae582ee08Pannag Sanketi // Create byteBuffer from native buffer 81531292d99f62a812af691e67e8e732c6ae582ee08Pannag Sanketi Image_getLockedBufferInfo(env, buffer, idx, &base, &size); 81631292d99f62a812af691e67e8e732c6ae582ee08Pannag Sanketi byteBuffer = env->NewDirectByteBuffer(base, size); 8170c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi // TODO: throw dvm exOutOfMemoryError? 8180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { 8190c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi jniThrowException(env, "java/lang/IllegalStateException", "Failed to allocate ByteBuffer"); 8200c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 8210c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block return byteBuffer; 8233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block} 8240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} // extern "C" 8260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// ---------------------------------------------------------------------------- 8280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8290c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic JNINativeMethod gImageReaderMethods[] = { 8300c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeClassInit", "()V", (void*)ImageReader_classInit }, 8310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeInit", "(Ljava/lang/Object;IIII)V", (void*)ImageReader_init }, 8320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeClose", "()V", (void*)ImageReader_close }, 8330c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, 8340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeImageSetup", "(Landroid/media/Image;)Z", (void*)ImageReader_imageSetup }, 8350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, 8360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi}; 8370c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8380c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatic JNINativeMethod gImageMethods[] = { 8390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeImageGetBuffer", "(I)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer }, 8400c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi {"nativeCreatePlane", "(I)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", 8410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (void*)Image_createSurfacePlane }, 8420c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi}; 8430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8440c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketiint register_android_media_ImageReader(JNIEnv *env) { 8450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int ret1 = AndroidRuntime::registerNativeMethods(env, 8470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods)); 8480c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8490c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int ret2 = AndroidRuntime::registerNativeMethods(env, 8500c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods)); 8510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 8520c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi return (ret1 || ret2); 8530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 8540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi