1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/* 2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project 3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License. 6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at 7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and 14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License. 15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define LOG_TAG "Legacy-CameraDevice-JNI" 185096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin// #define LOG_NDEBUG 0 19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Log.h> 20feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Errors.h> 21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Trace.h> 2228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <camera/CameraUtils.h> 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "jni.h" 252279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h> 26ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/android_view_Surface.h" 2828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include "android_runtime/android_graphics_SurfaceTexture.h" 29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 303c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/Surface.h> 313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/IGraphicBufferProducer.h> 3229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen#include <gui/IProducerListener.h> 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <ui/GraphicBuffer.h> 34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <system/window.h> 355096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <hardware/camera3.h> 3628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <system/camera_metadata.h> 37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 383c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <stdint.h> 393c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <inttypes.h> 403c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkusing namespace android; 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// fully-qualified class name 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice" 45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_BUFFER_SLACK 3 46ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk#define DONT_CARE 0 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 5091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 5191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 5236ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh// Use BAD_VALUE for surface abandoned error 5336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh#define OVERRIDE_SURFACE_ERROR(err) \ 5436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yehdo { \ 5536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh if (err == -ENODEV) { \ 5636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh err = BAD_VALUE; \ 5736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh } \ 5836ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh} while (0) 5936ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh 6036ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh#define UPDATE(md, tag, data, size) \ 6136ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yehdo { \ 6236ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh if ((md).update((tag), (data), (size))) { \ 6336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh ALOGE("Update " #tag " failed!"); \ 6436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh return BAD_VALUE; \ 6536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh } \ 6636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh} while (0) 6736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 69433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 7131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane, 728973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk uint8_t* crPlane, uint8_t* cbPlane, size_t chromaStep, size_t yStride, size_t chromaStride) { 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t R, G, B; 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t index = 0; 7531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk for (size_t j = 0; j < height; j++) { 768973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk uint8_t* cr = crPlane; 778973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk uint8_t* cb = cbPlane; 78433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk uint8_t* y = yPlane; 79433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk bool jEven = (j & 1) == 0; 8031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk for (size_t i = 0; i < width; i++) { 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk R = rgbBuf[index++]; 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk G = rgbBuf[index++]; 83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk B = rgbBuf[index++]; 84433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk *y++ = (77 * R + 150 * G + 29 * B) >> 8; 85433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk if (jEven && (i & 1) == 0) { 868973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk *cb = (( -43 * R - 85 * G + 128 * B) >> 8) + 128; 878973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk *cr = (( 128 * R - 107 * G - 21 * B) >> 8) + 128; 888973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk cr += chromaStep; 898973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk cb += chromaStep; 90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Skip alpha 92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk index++; 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk yPlane += yStride; 95433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk if (jEven) { 968973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk crPlane += chromaStride; 978973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk cbPlane += chromaStride; 98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 100feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 10231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_ycbcr* ycbcr) { 103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStep = ycbcr->chroma_step; 104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStride = ycbcr->cstride; 105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = ycbcr->ystride; 106433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride, 107433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk cStep); 108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y), 109433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb), 110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk cStep, yStride, cStride); 111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 11329c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic status_t connectSurface(const sp<Surface>& surface, int32_t maxBufferSlack) { 114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 11629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = surface->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/NULL); 11729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if (err != OK) { 11829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGE("%s: Unable to connect to surface, error %s (%d).", __FUNCTION__, 119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 12329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); 124feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 125feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, 126feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 12736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int minUndequeuedBuffers; 13229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = static_cast<ANativeWindow*>(surface.get())->query(surface.get(), 13329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); 134feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk __FUNCTION__, strerror(-err), err); 13736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 14129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("%s: Setting buffer count to %d", __FUNCTION__, 14229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen maxBufferSlack + 1 + minUndequeuedBuffers); 14329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = native_window_set_buffer_count(surface.get(), maxBufferSlack + 1 + minUndequeuedBuffers); 144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 14736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Produce a frame in the given surface. 155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Args: 157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * anw - a surface to produce a frame in. 158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelBuffer - image buffer to generate a frame from. 159feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * width - width of the pixelBuffer in pixels. 160feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * height - height of the pixelBuffer in pixels. 161feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelFmt - format of the pixelBuffer, one of: 162feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCrCb_420_SP, 163feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCbCr_420_888, 164feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_BLOB 165feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * bufSize - the size of the pixelBuffer in bytes. 166feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 167feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t produceFrame(const sp<ANativeWindow>& anw, 168feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* pixelBuffer, 16931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufWidth, // Width of the pixelBuffer 17031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufHeight, // Height of the pixelBuffer 171feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, // Format of the pixelBuffer 1725096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin int32_t bufSize) { 173feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ATRACE_CALL(); 174feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 175feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ANativeWindowBuffer* anb; 1765096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)", 17731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, anw.get(), bufWidth, bufHeight, pixelFmt, bufSize); 1785096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 1795096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (anw == 0) { 1805096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: anw must not be NULL", __FUNCTION__); 1815096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1825096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (pixelBuffer == NULL) { 1835096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__); 1845096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 18531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufWidth < 0) { 1865096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: width must be non-negative", __FUNCTION__); 1875096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 18831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufHeight < 0) { 1895096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: height must be non-negative", __FUNCTION__); 1905096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1915096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (bufSize < 0) { 1925096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: bufSize must be non-negative", __FUNCTION__); 1935096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1945096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 195feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 19631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t width = static_cast<size_t>(bufWidth); 19731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t height = static_cast<size_t>(bufHeight); 19831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t bufferLength = static_cast<size_t>(bufSize); 19991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 200feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: Switch to using Surface::lock and Surface::unlockAndPost 201feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_dequeue_buffer_and_wait(anw.get(), &anb); 20236ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh if (err != NO_ERROR) { 20336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh ALOGE("%s: Failed to dequeue buffer, error %s (%d).", __FUNCTION__, 20436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh strerror(-err), err); 20536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 20636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh return err; 20736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh } 208feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 209845eef05ffea53f4ce7a1e0551896be874c4f302Mathias Agopian sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 2100c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufWidth = buf->getWidth(); 2110c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufHeight = buf->getHeight(); 2120c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufStride = buf->getStride(); 2130c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk if (grallocBufWidth != width || grallocBufHeight != height) { 21431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Received gralloc buffer with bad dimensions %" PRIu32 "x%" PRIu32 2150c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk ", expecting dimensions %zu x %zu", __FUNCTION__, grallocBufWidth, 2160c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk grallocBufHeight, width, height); 21731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 21831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 21931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 22031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufFmt = 0; 22131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &bufFmt); 22231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (err != NO_ERROR) { 22331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, 22431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk strerror(-err), err); 22536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 22631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return err; 22731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 22831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 2290c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint64_t tmpSize = (pixelFmt == HAL_PIXEL_FORMAT_BLOB) ? grallocBufWidth : 2300c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk 4 * grallocBufHeight * grallocBufWidth; 23131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt != pixelFmt) { 23231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt == HAL_PIXEL_FORMAT_RGBA_8888 && pixelFmt == HAL_PIXEL_FORMAT_BLOB) { 23331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGV("%s: Using BLOB to RGBA format override.", __FUNCTION__); 2340c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk tmpSize = 4 * (grallocBufWidth + grallocBufStride * (grallocBufHeight - 1)); 23531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else { 23631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGW("%s: Format mismatch in produceFrame: expecting format %#" PRIx32 23731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ", but received buffer with format %#" PRIx32, __FUNCTION__, pixelFmt, bufFmt); 23831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 23931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 24031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 24131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (tmpSize > SIZE_MAX) { 24231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Overflow calculating size, buffer with dimens %zu x %zu is absurdly large...", 24331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, width, height); 24431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 24531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 24631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 24731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalSizeBytes = tmpSize; 248feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 249433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt); 250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk switch(pixelFmt) { 251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 25231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 25331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 25431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 255feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 256feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 257feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* img = NULL; 258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 259feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 260feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 261feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 262feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* yPlane = img; 263feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane = img + height * width; 264feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* vPlane = uPlane + 1; 265feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStep = 2; 266feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = width; 267feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStride = width; 268feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 269feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 270feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane, vPlane, chromaStep, yStride, chromaStride); 271feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 272feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 27391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk case HAL_PIXEL_FORMAT_YV12: { 27431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 27531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 27631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 27791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 27891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 27991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if ((width & 1) || (height & 1)) { 28131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Dimens %zu x %zu are not divisible by 2.", __FUNCTION__, width, height); 28291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 28391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 28491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* img = NULL; 28691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 28791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 28891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (err != NO_ERROR) { 28991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__, 29091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk strerror(-err), err); 29191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return err; 29291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 29391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 29491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t stride = buf->getStride(); 295433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride); 29691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride); 29791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 29891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t cStride = ALIGN(stride / 2, 16); 29991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk size_t chromaStep = 1; 30091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 30191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* yPlane = img; 30291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride; 30391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2; 30491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 30591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 30691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk crPlane, cbPlane, chromaStep, stride, cStride); 30791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk break; 30891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 309feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCbCr_420_888: { 310feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Software writes with YCbCr_420_888 format are unsupported 311feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // by the gralloc module for now 31231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 31331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 31431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 315feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 316feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 317feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk android_ycbcr ycbcr = android_ycbcr(); 318feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 319feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 320feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr); 321feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 322feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__, 323feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 324feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 325feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 326feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, &ycbcr); 327feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 328feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 329feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_BLOB: { 330feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int8_t* img = NULL; 3310fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk struct camera3_jpeg_blob footer = { 332452efb218eb9af6ab2763879645bfc92db8ba02aBernhard Rosenkränzer .jpeg_blob_id = CAMERA3_JPEG_BLOB_ID, 333452efb218eb9af6ab2763879645bfc92db8ba02aBernhard Rosenkränzer .jpeg_size = (uint32_t)bufferLength 3340fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk }; 3350fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 33631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalJpegSize = bufferLength + sizeof(footer); 33731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk totalJpegSize = (totalJpegSize + 3) & ~0x3; // round up to nearest octonibble 33831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 33931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (totalJpegSize > totalSizeBytes) { 34031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Pixel buffer needs size %zu, cannot fit in gralloc buffer of size %zu", 34131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, totalJpegSize, totalSizeBytes); 3420fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return BAD_VALUE; 3430fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } 344feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 345feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 347feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock buffer, error %s (%d).", __FUNCTION__, strerror(-err), 348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err); 349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 350feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 35131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 35231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk memcpy(img, pixelBuffer, bufferLength); 35331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk memcpy(img + totalSizeBytes - sizeof(footer), &footer, sizeof(footer)); 354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk default: { 357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Invalid pixel format in produceFrame: %x", __FUNCTION__, pixelFmt); 358feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 359feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 360feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 361feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 362feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Unlock buffer from %p", __FUNCTION__, anw.get()); 363feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->unlock(); 364feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 365feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to unlock buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 366feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 367feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 369feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Queue buffer to %p", __FUNCTION__, anw.get()); 370feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), /*fenceFd*/-1); 371feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to queue buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 37336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 377feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 378feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 379feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) { 380feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 381feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (surface) { 382feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk anw = android_view_Surface_getNativeWindow(env, surface); 383feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (env->ExceptionCheck()) { 3843c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 385feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 386feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 387feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "surface"); 3883c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 389feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 390feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (anw == NULL) { 391443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk ALOGE("%s: Surface had no valid native window.", __FUNCTION__); 3923c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 393feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 394feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 395feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 396feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 39728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic sp<ANativeWindow> getNativeWindowFromTexture(JNIEnv* env, jobject surfaceTexture) { 39828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 39928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (surfaceTexture) { 40028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk anw = android_SurfaceTexture_getNativeWindow(env, surfaceTexture); 40128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 40228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 40328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 40428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } else { 40528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowNullPointerException(env, "surfaceTexture"); 40628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 40728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 40828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (anw == NULL) { 40928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 41028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "SurfaceTexture had no valid native window."); 41128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 41228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 41328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return anw; 41428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 41528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 4163c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic sp<Surface> getSurface(JNIEnv* env, jobject surface) { 4173c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 4183c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (surface) { 4193c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk s = android_view_Surface_getSurface(env, surface); 4203c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (env->ExceptionCheck()) { 4213c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4223c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4233c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } else { 4243c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowNullPointerException(env, "surface"); 4253c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4263c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4273c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (s == NULL) { 4283c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 4293c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "Surface had no valid native Surface."); 4303c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4323c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return s; 4333c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 4343c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 435feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkextern "C" { 436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 437feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) { 438feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeDetectSurfaceType"); 439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 440feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 442ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 443feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 444feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t fmt = 0; 445feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt); 446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 447ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err), 448ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 44936ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 450ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 451feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 452feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return fmt; 453feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 454feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 455e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvalastatic jint LegacyCameraDevice_nativeDetectSurfaceDataspace(JNIEnv* env, jobject thiz, jobject surface) { 456e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala ALOGV("nativeDetectSurfaceDataspace"); 457e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala sp<ANativeWindow> anw; 458e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala if ((anw = getNativeWindow(env, surface)) == NULL) { 459e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 460e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala return BAD_VALUE; 461e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala } 462e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala int32_t fmt = 0; 463e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala status_t err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &fmt); 464e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala if(err != NO_ERROR) { 465e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala ALOGE("%s: Error while querying surface dataspace %s (%d).", __FUNCTION__, strerror(-err), 466e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala err); 46736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 468e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala return err; 469e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala } 470e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala return fmt; 471e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala} 472e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala 473ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, 474feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jobject surface, jintArray dimens) { 475feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeGetSurfaceDimens"); 47628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 47728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (dimens == NULL) { 47828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Null dimens argument passed to nativeDetectSurfaceDimens", __FUNCTION__); 47928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 48028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 48128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 48228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->GetArrayLength(dimens) < 2) { 48328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid length of dimens argument in nativeDetectSurfaceDimens", __FUNCTION__); 48428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 48528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 48628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 487feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 488feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 489feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 490ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 492feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t dimenBuf[2]; 493feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 494feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 495ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err), 496ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 49736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 498ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 501feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 502ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err), 503ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 50436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 505ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 506feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 507feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 508ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 509feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 510feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 511f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz, 512f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk jobject surface) { 513f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk ALOGV("nativeDetectSurfaceUsageFlags"); 514f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 515f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk sp<ANativeWindow> anw; 516f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 5172a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh jniThrowException(env, "java/lang/UnsupportedOperationException;", 518f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "Could not retrieve native window from surface."); 519f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return BAD_VALUE; 520f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 521f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk int32_t usage = 0; 522f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage); 523f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if(err != NO_ERROR) { 5242a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh jniThrowException(env, "java/lang/UnsupportedOperationException;", 525f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "Error while querying surface usage bits"); 52636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 527f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return err; 528f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 529f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return usage; 530f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 531f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 53229c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic jint LegacyCameraDevice_nativeDisconnectSurface(JNIEnv* env, jobject thiz, 53329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen jobject surface) { 53429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("nativeDisconnectSurface"); 53529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if (surface == nullptr) return NO_ERROR; 53629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 53729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen sp<ANativeWindow> anw; 53829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if ((anw = getNativeWindow(env, surface)) == NULL) { 53929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("Buffer queue has already been abandoned."); 54029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen return NO_ERROR; 54129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen } 54229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 54329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen status_t err = native_window_api_disconnect(anw.get(), NATIVE_WINDOW_API_CAMERA); 54429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if(err != NO_ERROR) { 5452a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh jniThrowException(env, "java/lang/UnsupportedOperationException;", 54629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen "Error while disconnecting surface"); 54736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 54829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen return err; 54929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen } 55029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen return NO_ERROR; 55129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen} 55229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 55328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, 55428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surfaceTexture, jintArray dimens) { 55528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeDetectTextureDimens"); 55628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 55728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindowFromTexture(env, surfaceTexture)) == NULL) { 55828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from SurfaceTexture.", __FUNCTION__); 55928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 56028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 56128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 56228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t dimenBuf[2]; 56328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 56428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 56528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture width %s (%d)", __FUNCTION__, 56628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 56736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 56828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 56928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 57028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 57128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 57228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 57328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture height %s (%d)", __FUNCTION__, 57428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 57536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 57628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 57728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 57828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 57928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 58028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 58128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 58228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 58328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 58428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 58528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 58629c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic jint LegacyCameraDevice_nativeConnectSurface(JNIEnv* env, jobject thiz, jobject surface) { 58729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("nativeConnectSurface"); 58829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen sp<Surface> s; 58929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if ((s = getSurface(env, surface)) == NULL) { 59029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGE("%s: Could not retrieve surface.", __FUNCTION__); 591ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 592feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 59329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen status_t err = connectSurface(s, CAMERA_DEVICE_BUFFER_SLACK); 594feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 595ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); 59636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 597ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 598feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 599ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 600feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 601feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 602ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, 603feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) { 604feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeProduceFrame"); 605feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 606feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 607feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 608feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 609ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 610feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 611feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 612feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixelBuffer == NULL) { 613feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixelBuffer"); 614ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 615feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 616feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 617feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer)); 618feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL); 619feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 620feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixels == NULL) { 621feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixels"); 622ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 623feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 624feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 625feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height, 626feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk pixelFormat, bufSize); 627feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT); 628feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 629feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 630ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err); 631ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 632feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 633ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 634feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 635feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 636ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, 637feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint pixelFormat) { 638feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceType"); 639feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 640feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 641feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 642ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 643feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 644feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_format(anw.get(), pixelFormat); 645feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 646ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err); 64736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 648ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 649feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 650ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 651feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 652feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 653ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, 654feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height) { 655feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceDimens"); 656feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 657feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 658feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 659ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 660feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 661a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk 662b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala // Set user dimensions only 663b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala // The producer dimensions are owned by GL 664b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala status_t err = native_window_set_buffers_user_dimensions(anw.get(), width, height); 665a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk if (err != NO_ERROR) { 666a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err), 667a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk err); 66836ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh OVERRIDE_SURFACE_ERROR(err); 669a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk return err; 670a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk } 671ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 672feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 673feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 6743c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) { 6753c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGV("nativeGetSurfaceId"); 6763c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 6773c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if ((s = getSurface(env, surface)) == NULL) { 6783c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__); 6793c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6803c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6813c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer(); 6823c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (gbp == NULL) { 6833c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__); 6843c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6853c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 68697069dd4fd5454ba057ccf2854d7f925c337884cMarco Nelissen sp<IBinder> b = IInterface::asBinder(gbp); 6873c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (b == NULL) { 6883c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__); 6893c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6903c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6913c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk /* 6923c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * FIXME: Use better unique ID for surfaces than native IBinder pointer. Fix also in the camera 6933c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * service (CameraDeviceClient.h). 6943c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk */ 6953c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return reinterpret_cast<jlong>(b.get()); 6963c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 6973c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 69828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceOrientation(JNIEnv* env, jobject thiz, 69928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surface, jint facing, jint orientation) { 70028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeSetSurfaceOrientation"); 70128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 70228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 70328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 70428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 70528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 70628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 70728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = NO_ERROR; 70828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk CameraMetadata staticMetadata; 70928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 71028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t orientVal = static_cast<int32_t>(orientation); 71128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk uint8_t facingVal = static_cast<uint8_t>(facing); 71228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1); 71328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1); 71428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 71528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t transform = 0; 71628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 71791838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = CameraUtils::getRotationTransform(staticMetadata, /*out*/&transform)) != NO_ERROR) { 71828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid rotation transform %s (%d)", __FUNCTION__, strerror(-err), 71928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err); 72028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 72128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 72228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 72328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("%s: Setting buffer sticky transform to %d", __FUNCTION__, transform); 72428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 72591838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_sticky_transform(anw.get(), transform)) != NO_ERROR) { 72628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Unable to configure surface transform, error %s (%d)", __FUNCTION__, 72728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 72828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 72928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 73028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 73128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 73228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 73328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 73491838ded36131525312739c0929913b215519c2aRuben Brunkstatic jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz, jobject surface, 73591838ded36131525312739c0929913b215519c2aRuben Brunk jlong timestamp) { 73691838ded36131525312739c0929913b215519c2aRuben Brunk ALOGV("nativeSetNextTimestamp"); 73791838ded36131525312739c0929913b215519c2aRuben Brunk sp<ANativeWindow> anw; 73891838ded36131525312739c0929913b215519c2aRuben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 73991838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 74091838ded36131525312739c0929913b215519c2aRuben Brunk return BAD_VALUE; 74191838ded36131525312739c0929913b215519c2aRuben Brunk } 74291838ded36131525312739c0929913b215519c2aRuben Brunk 74391838ded36131525312739c0929913b215519c2aRuben Brunk status_t err = NO_ERROR; 74491838ded36131525312739c0929913b215519c2aRuben Brunk 74591838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_timestamp(anw.get(), static_cast<int64_t>(timestamp))) != 74691838ded36131525312739c0929913b215519c2aRuben Brunk NO_ERROR) { 74791838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Unable to set surface timestamp, error %s (%d)", __FUNCTION__, strerror(-err), 74891838ded36131525312739c0929913b215519c2aRuben Brunk err); 74991838ded36131525312739c0929913b215519c2aRuben Brunk return err; 75091838ded36131525312739c0929913b215519c2aRuben Brunk } 75191838ded36131525312739c0929913b215519c2aRuben Brunk return NO_ERROR; 75291838ded36131525312739c0929913b215519c2aRuben Brunk} 75391838ded36131525312739c0929913b215519c2aRuben Brunk 754a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunkstatic jint LegacyCameraDevice_nativeSetScalingMode(JNIEnv* env, jobject thiz, jobject surface, 755a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk jint mode) { 756a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk ALOGV("nativeSetScalingMode"); 757a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk sp<ANativeWindow> anw; 758a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 759a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 760a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk return BAD_VALUE; 761a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk } 762a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk status_t err = NO_ERROR; 763a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk if ((err = native_window_set_scaling_mode(anw.get(), static_cast<int>(mode))) != NO_ERROR) { 764a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk ALOGE("%s: Unable to set surface scaling mode, error %s (%d)", __FUNCTION__, 765a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk strerror(-err), err); 766a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk return err; 767a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk } 768a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk return NO_ERROR; 769a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk} 770a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk 7711dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunkstatic jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) { 7721dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk ALOGV("nativeGetJpegFooterSize"); 7731dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk return static_cast<jint>(sizeof(struct camera3_jpeg_blob)); 7741dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk} 7751dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk 776feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} // extern "C" 777feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 77876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gCameraDeviceMethods[] = { 779feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceType", 780feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "(Landroid/view/Surface;)I", 781feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceType }, 782e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala { "nativeDetectSurfaceDataspace", 783e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala "(Landroid/view/Surface;)I", 784e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala (void *)LegacyCameraDevice_nativeDetectSurfaceDataspace }, 785feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceDimens", 786ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[I)I", 787feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, 78829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen { "nativeConnectSurface", 78929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen "(Landroid/view/Surface;)I", 79029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen (void *)LegacyCameraDevice_nativeConnectSurface }, 791feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeProduceFrame", 792ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[BIII)I", 793feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeProduceFrame }, 794feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceFormat", 795ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;I)I", 796feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceFormat }, 797feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceDimens", 798ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;II)I", 799feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, 8003c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk { "nativeGetSurfaceId", 8013c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "(Landroid/view/Surface;)J", 8023c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk (void *)LegacyCameraDevice_nativeGetSurfaceId }, 80328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeDetectTextureDimens", 80428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/graphics/SurfaceTexture;[I)I", 80528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeDetectTextureDimens }, 80628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeSetSurfaceOrientation", 80728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/view/Surface;II)I", 80828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceOrientation }, 80991838ded36131525312739c0929913b215519c2aRuben Brunk { "nativeSetNextTimestamp", 81091838ded36131525312739c0929913b215519c2aRuben Brunk "(Landroid/view/Surface;J)I", 81191838ded36131525312739c0929913b215519c2aRuben Brunk (void *)LegacyCameraDevice_nativeSetNextTimestamp }, 8121dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk { "nativeGetJpegFooterSize", 8131dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk "()I", 8141dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk (void *)LegacyCameraDevice_nativeGetJpegFooterSize }, 815f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk { "nativeDetectSurfaceUsageFlags", 816f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "(Landroid/view/Surface;)I", 817f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags }, 818a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk { "nativeSetScalingMode", 819a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk "(Landroid/view/Surface;I)I", 820a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk (void *)LegacyCameraDevice_nativeSetScalingMode }, 82129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen { "nativeDisconnectSurface", 82229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen "(Landroid/view/Surface;)I", 82329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen (void *)LegacyCameraDevice_nativeDisconnectSurface }, 824feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}; 825feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 826feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// Get all the required offsets in java class and register native functions 827feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkint register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env) 828feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{ 829feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Register native functions 830ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return RegisterMethodsOrDie(env, 831feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk CAMERA_DEVICE_CLASS_NAME, 832feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk gCameraDeviceMethods, 833feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NELEM(gCameraDeviceMethods)); 834feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 835