android_hardware_camera2_legacy_LegacyCameraDevice.cpp revision 31798f33184fd59dd3d3cc55e6373d9f91d220b6
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" 25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "JNIHelp.h" 26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/AndroidRuntime.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> 32feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <ui/GraphicBuffer.h> 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <system/window.h> 345096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <hardware/camera3.h> 3528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <system/camera_metadata.h> 36feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 373c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <stdint.h> 383c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <inttypes.h> 393c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkusing namespace android; 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// fully-qualified class name 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice" 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_BUFFER_SLACK 3 45ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk#define DONT_CARE 0 46feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 4991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 5091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Convert from RGB 888 to Y'CbCr using the conversion specified in ITU-R BT.601 for 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * digital RGB with K_b = 0.114, and K_r = 0.299. 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 5531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane, 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) { 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t R, G, B; 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t index = 0; 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 6031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t cStrideDiff = chromaStride - width; 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 6231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk for (size_t j = 0; j < height; j++) { 6331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk for (size_t i = 0; i < width; i++) { 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk R = rgbBuf[index++]; 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk G = rgbBuf[index++]; 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk B = rgbBuf[index++]; 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *(yPlane + i) = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16; 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (j % 2 == 0 && i % 2 == 0){ 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *uPlane = (( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128; 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *vPlane = (( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128; 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane += chromaStep; 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk vPlane += chromaStep; 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Skip alpha 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk index++; 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk yPlane += yStride; 79feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (j % 2 == 0) { 80feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane += cStrideDiff; 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk vPlane += cStrideDiff; 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 84feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 85feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 8631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_ycbcr* ycbcr) { 87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStep = ycbcr->chroma_step; 88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStride = ycbcr->cstride; 89feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = ycbcr->ystride; 90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y), 91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk reinterpret_cast<uint8_t*>(ycbcr->cb), reinterpret_cast<uint8_t*>(ycbcr->cr), 92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk cStep, yStride, cStride); 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 95feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t configureSurface(const sp<ANativeWindow>& anw, 96feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t width, 97feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t height, 98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, 99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t maxBufferSlack) { 100feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_dimensions(anw.get(), width, height); 102feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer dimensions, error %s (%d).", __FUNCTION__, 104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 106feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 107feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_format(anw.get(), pixelFmt); 109feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer format, error %s (%d).", __FUNCTION__, 111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 113feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); 116feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 117feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, 118feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int minUndequeuedBuffers; 123feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw.get()->query(anw.get(), 124feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 125feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk &minUndequeuedBuffers); 126feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 127feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", 128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk __FUNCTION__, strerror(-err), err); 129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 1325096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Setting buffer count to %d, size to (%dx%d), fmt (0x%x)", __FUNCTION__, 1335096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin maxBufferSlack + 1 + minUndequeuedBuffers, 1345096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin width, height, pixelFmt); 135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffer_count(anw.get(), maxBufferSlack + 1 + minUndequeuedBuffers); 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 137feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, 138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 141feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Produce a frame in the given surface. 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Args: 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * anw - a surface to produce a frame in. 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelBuffer - image buffer to generate a frame from. 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * width - width of the pixelBuffer in pixels. 151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * height - height of the pixelBuffer in pixels. 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelFmt - format of the pixelBuffer, one of: 153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCrCb_420_SP, 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCbCr_420_888, 155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_BLOB 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * bufSize - the size of the pixelBuffer in bytes. 157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t produceFrame(const sp<ANativeWindow>& anw, 159feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* pixelBuffer, 16031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufWidth, // Width of the pixelBuffer 16131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufHeight, // Height of the pixelBuffer 162feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, // Format of the pixelBuffer 1635096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin int32_t bufSize) { 164feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ATRACE_CALL(); 165feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 166feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ANativeWindowBuffer* anb; 1675096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)", 16831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, anw.get(), bufWidth, bufHeight, pixelFmt, bufSize); 1695096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 1705096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (anw == 0) { 1715096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: anw must not be NULL", __FUNCTION__); 1725096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1735096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (pixelBuffer == NULL) { 1745096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__); 1755096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 17631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufWidth < 0) { 1775096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: width must be non-negative", __FUNCTION__); 1785096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 17931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufHeight < 0) { 1805096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: height must be non-negative", __FUNCTION__); 1815096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1825096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (bufSize < 0) { 1835096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: bufSize must be non-negative", __FUNCTION__); 1845096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1855096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 186feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 18731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t width = static_cast<size_t>(bufWidth); 18831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t height = static_cast<size_t>(bufHeight); 18931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t bufferLength = static_cast<size_t>(bufSize); 19091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 191feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: Switch to using Surface::lock and Surface::unlockAndPost 192feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_dequeue_buffer_and_wait(anw.get(), &anb); 193feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 194feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 195feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<GraphicBuffer> buf(new GraphicBuffer(anb, /*keepOwnership*/false)); 19631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk uint32_t gBufWidth = buf->getWidth(); 19731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk uint32_t gBufHeight = buf->getHeight(); 19831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (gBufWidth != width || gBufHeight != height) { 19931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Received gralloc buffer with bad dimensions %" PRIu32 "x%" PRIu32 20031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ", expecting dimensions %zu x %zu", __FUNCTION__, gBufWidth, gBufHeight, 20131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk width, height); 20231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 20331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 20431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 20531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufFmt = 0; 20631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &bufFmt); 20731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (err != NO_ERROR) { 20831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, 20931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk strerror(-err), err); 21031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return err; 21131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 21231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 21331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk uint64_t tmpSize = width * height; 21431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt != pixelFmt) { 21531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt == HAL_PIXEL_FORMAT_RGBA_8888 && pixelFmt == HAL_PIXEL_FORMAT_BLOB) { 21631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGV("%s: Using BLOB to RGBA format override.", __FUNCTION__); 21731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk tmpSize *= 4; 21831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else { 21931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGW("%s: Format mismatch in produceFrame: expecting format %#" PRIx32 22031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ", but received buffer with format %#" PRIx32, __FUNCTION__, pixelFmt, bufFmt); 22131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 22231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 22331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 22431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (tmpSize > SIZE_MAX) { 22531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Overflow calculating size, buffer with dimens %zu x %zu is absurdly large...", 22631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, width, height); 22731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 22831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 22931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 23031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalSizeBytes = tmpSize; 231feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 232feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk switch(pixelFmt) { 233feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 23431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 23531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 23631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 237feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 238feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 239feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* img = NULL; 240feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 241feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 242feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 243feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 244feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* yPlane = img; 245feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane = img + height * width; 246feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* vPlane = uPlane + 1; 247feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStep = 2; 248feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = width; 249feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStride = width; 250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 252feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane, vPlane, chromaStep, yStride, chromaStride); 253feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 254feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 25591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk case HAL_PIXEL_FORMAT_YV12: { 25631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 25731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 25831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 25991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 26091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 26191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 26291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if ((width & 1) || (height & 1)) { 26331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Dimens %zu x %zu are not divisible by 2.", __FUNCTION__, width, height); 26491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 26591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 26691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 26791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* img = NULL; 26891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 26991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 27091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (err != NO_ERROR) { 27191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__, 27291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk strerror(-err), err); 27391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return err; 27491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 27591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 27691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t stride = buf->getStride(); 27791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride); 27891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 27991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t cStride = ALIGN(stride / 2, 16); 28091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk size_t chromaStep = 1; 28191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* yPlane = img; 28391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride; 28491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2; 28591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 28791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk crPlane, cbPlane, chromaStep, stride, cStride); 28891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk break; 28991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 290feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCbCr_420_888: { 291feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Software writes with YCbCr_420_888 format are unsupported 292feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // by the gralloc module for now 29331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 29431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 29531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 296feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 297feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 298feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk android_ycbcr ycbcr = android_ycbcr(); 299feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 300feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 301feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr); 302feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 303feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__, 304feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 305feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 306feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 307feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, &ycbcr); 308feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 309feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 310feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_BLOB: { 311feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int8_t* img = NULL; 3120fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk struct camera3_jpeg_blob footer = { 3130fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk jpeg_blob_id: CAMERA3_JPEG_BLOB_ID, 3140fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk jpeg_size: (uint32_t)width 3150fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk }; 3160fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 31731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalJpegSize = bufferLength + sizeof(footer); 31831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk totalJpegSize = (totalJpegSize + 3) & ~0x3; // round up to nearest octonibble 31931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 32031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (height != 1) { 32131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Invalid height set for JPEG buffer output, %zu", __FUNCTION__, height); 32231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 32331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 32431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 32531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (totalJpegSize > totalSizeBytes) { 32631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Pixel buffer needs size %zu, cannot fit in gralloc buffer of size %zu", 32731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, totalJpegSize, totalSizeBytes); 3280fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return BAD_VALUE; 3290fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } 330feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 331feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 332feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 333feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock buffer, error %s (%d).", __FUNCTION__, strerror(-err), 334feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err); 335feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 336feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 33731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 33831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk memcpy(img, pixelBuffer, bufferLength); 33931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk memcpy(img + totalSizeBytes - sizeof(footer), &footer, sizeof(footer)); 340feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 341feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 342feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk default: { 343feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Invalid pixel format in produceFrame: %x", __FUNCTION__, pixelFmt); 344feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 345feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 347feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Unlock buffer from %p", __FUNCTION__, anw.get()); 349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->unlock(); 350feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 351feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to unlock buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 352feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 353feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Queue buffer to %p", __FUNCTION__, anw.get()); 356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), /*fenceFd*/-1); 357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 358feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to queue buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 359feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 360feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 361feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 362feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 363feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 364feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) { 365feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 366feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (surface) { 367feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk anw = android_view_Surface_getNativeWindow(env, surface); 368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (env->ExceptionCheck()) { 3693c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 370feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 371feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "surface"); 3733c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (anw == NULL) { 376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 377feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "Surface had no valid native window."); 3783c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 379feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 380feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 381feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 382feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 38328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic sp<ANativeWindow> getNativeWindowFromTexture(JNIEnv* env, jobject surfaceTexture) { 38428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 38528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (surfaceTexture) { 38628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk anw = android_SurfaceTexture_getNativeWindow(env, surfaceTexture); 38728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 38828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 38928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 39028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } else { 39128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowNullPointerException(env, "surfaceTexture"); 39228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 39328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 39428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (anw == NULL) { 39528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 39628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "SurfaceTexture had no valid native window."); 39728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 39828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 39928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return anw; 40028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 40128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 4023c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic sp<Surface> getSurface(JNIEnv* env, jobject surface) { 4033c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 4043c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (surface) { 4053c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk s = android_view_Surface_getSurface(env, surface); 4063c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (env->ExceptionCheck()) { 4073c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4083c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4093c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } else { 4103c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowNullPointerException(env, "surface"); 4113c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4123c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4133c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (s == NULL) { 4143c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 4153c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "Surface had no valid native Surface."); 4163c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4173c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4183c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return s; 4193c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 4203c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 421feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkextern "C" { 422feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 423feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) { 424feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeDetectSurfaceType"); 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 427feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 428ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 429feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 430feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t fmt = 0; 431feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt); 432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 433ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err), 434ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 435ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 437feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return fmt; 438feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 440ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, 441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jobject surface, jintArray dimens) { 442feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeGetSurfaceDimens"); 44328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 44428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (dimens == NULL) { 44528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Null dimens argument passed to nativeDetectSurfaceDimens", __FUNCTION__); 44628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 44728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 44828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 44928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->GetArrayLength(dimens) < 2) { 45028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid length of dimens argument in nativeDetectSurfaceDimens", __FUNCTION__); 45128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 45228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 45328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 454feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 455feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 456feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 457ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 458feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 459feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t dimenBuf[2]; 460feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 461feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 462ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err), 463ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 464ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 465feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 466feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 467feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 468ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err), 469ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 470ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 471feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 472feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 473ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 474feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 475feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 47628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, 47728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surfaceTexture, jintArray dimens) { 47828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeDetectTextureDimens"); 47928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 48028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindowFromTexture(env, surfaceTexture)) == NULL) { 48128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from SurfaceTexture.", __FUNCTION__); 48228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 48328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 48428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 48528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t dimenBuf[2]; 48628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 48728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 48828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture width %s (%d)", __FUNCTION__, 48928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 49028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 49128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 49228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 49328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 49428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 49528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture height %s (%d)", __FUNCTION__, 49628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 49728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 49828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 49928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 50028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 50128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 50228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 50328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 50428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 50528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 50628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 507ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, 508feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height, jint pixelFormat) { 509feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeConfigureSurface"); 510feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 511feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 512feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 513ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 514feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 515feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); 516feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 517ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); 518ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 519feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 520ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 521feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 522feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 523ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, 524feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) { 525feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeProduceFrame"); 526feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 527feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 528feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 529feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 530ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 531feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 532feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 533feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixelBuffer == NULL) { 534feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixelBuffer"); 535ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 536feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 537feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 538feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer)); 539feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL); 540feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 541feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixels == NULL) { 542feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixels"); 543ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 544feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 545feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 546feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height, 547feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk pixelFormat, bufSize); 548feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT); 549feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 550feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 551ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err); 552ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 553feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 554ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 555feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 556feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 557ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, 558feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint pixelFormat) { 559feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceType"); 560feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 561feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 562feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 563ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 564feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 565feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_format(anw.get(), pixelFormat); 566feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 567ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err); 568ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 569feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 570ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 571feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 572feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 573ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, 574feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height) { 575feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceDimens"); 576feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 577feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 578feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 579ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 580feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 581feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_dimensions(anw.get(), width, height); 582feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 583ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface dimens %s (%d).", __FUNCTION__, strerror(-err), err); 584ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 585feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 586a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk 587a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk // WAR - Set user dimensions also to avoid incorrect scaling after TextureView orientation 588a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk // change. 589a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk err = native_window_set_buffers_user_dimensions(anw.get(), width, height); 590a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk if (err != NO_ERROR) { 591a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err), 592a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk err); 593a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk return err; 594a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk } 595ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 596feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 597feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 5983c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) { 5993c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGV("nativeGetSurfaceId"); 6003c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 6013c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if ((s = getSurface(env, surface)) == NULL) { 6023c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__); 6033c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6043c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6053c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer(); 6063c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (gbp == NULL) { 6073c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__); 6083c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6093c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6103c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IBinder> b = gbp->asBinder(); 6113c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (b == NULL) { 6123c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__); 6133c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6143c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6153c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk /* 6163c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * FIXME: Use better unique ID for surfaces than native IBinder pointer. Fix also in the camera 6173c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * service (CameraDeviceClient.h). 6183c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk */ 6193c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return reinterpret_cast<jlong>(b.get()); 6203c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 6213c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 62228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceOrientation(JNIEnv* env, jobject thiz, 62328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surface, jint facing, jint orientation) { 62428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeSetSurfaceOrientation"); 62528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 62628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 62728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 62828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 62928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 63028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 63128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = NO_ERROR; 63228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk CameraMetadata staticMetadata; 63328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 63428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t orientVal = static_cast<int32_t>(orientation); 63528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk uint8_t facingVal = static_cast<uint8_t>(facing); 63628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1); 63728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1); 63828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 63928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t transform = 0; 64028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 64191838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = CameraUtils::getRotationTransform(staticMetadata, /*out*/&transform)) != NO_ERROR) { 64228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid rotation transform %s (%d)", __FUNCTION__, strerror(-err), 64328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err); 64428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 64528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 64628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 64728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("%s: Setting buffer sticky transform to %d", __FUNCTION__, transform); 64828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 64991838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_sticky_transform(anw.get(), transform)) != NO_ERROR) { 65028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Unable to configure surface transform, error %s (%d)", __FUNCTION__, 65128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 65228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 65328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 65428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 65528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 65628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 65728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 65891838ded36131525312739c0929913b215519c2aRuben Brunkstatic jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz, jobject surface, 65991838ded36131525312739c0929913b215519c2aRuben Brunk jlong timestamp) { 66091838ded36131525312739c0929913b215519c2aRuben Brunk ALOGV("nativeSetNextTimestamp"); 66191838ded36131525312739c0929913b215519c2aRuben Brunk sp<ANativeWindow> anw; 66291838ded36131525312739c0929913b215519c2aRuben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 66391838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 66491838ded36131525312739c0929913b215519c2aRuben Brunk return BAD_VALUE; 66591838ded36131525312739c0929913b215519c2aRuben Brunk } 66691838ded36131525312739c0929913b215519c2aRuben Brunk 66791838ded36131525312739c0929913b215519c2aRuben Brunk status_t err = NO_ERROR; 66891838ded36131525312739c0929913b215519c2aRuben Brunk 66991838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_timestamp(anw.get(), static_cast<int64_t>(timestamp))) != 67091838ded36131525312739c0929913b215519c2aRuben Brunk NO_ERROR) { 67191838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Unable to set surface timestamp, error %s (%d)", __FUNCTION__, strerror(-err), 67291838ded36131525312739c0929913b215519c2aRuben Brunk err); 67391838ded36131525312739c0929913b215519c2aRuben Brunk return err; 67491838ded36131525312739c0929913b215519c2aRuben Brunk } 67591838ded36131525312739c0929913b215519c2aRuben Brunk return NO_ERROR; 67691838ded36131525312739c0929913b215519c2aRuben Brunk} 67791838ded36131525312739c0929913b215519c2aRuben Brunk 6781dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunkstatic jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) { 6791dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk ALOGV("nativeGetJpegFooterSize"); 6801dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk return static_cast<jint>(sizeof(struct camera3_jpeg_blob)); 6811dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk} 6821dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk 683feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} // extern "C" 684feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 685feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic JNINativeMethod gCameraDeviceMethods[] = { 686feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceType", 687feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "(Landroid/view/Surface;)I", 688feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceType }, 689feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceDimens", 690ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[I)I", 691feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, 692feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeConfigureSurface", 693ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;III)I", 694feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeConfigureSurface }, 695feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeProduceFrame", 696ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[BIII)I", 697feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeProduceFrame }, 698feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceFormat", 699ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;I)I", 700feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceFormat }, 701feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceDimens", 702ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;II)I", 703feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, 7043c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk { "nativeGetSurfaceId", 7053c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "(Landroid/view/Surface;)J", 7063c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk (void *)LegacyCameraDevice_nativeGetSurfaceId }, 70728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeDetectTextureDimens", 70828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/graphics/SurfaceTexture;[I)I", 70928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeDetectTextureDimens }, 71028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeSetSurfaceOrientation", 71128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/view/Surface;II)I", 71228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceOrientation }, 71391838ded36131525312739c0929913b215519c2aRuben Brunk { "nativeSetNextTimestamp", 71491838ded36131525312739c0929913b215519c2aRuben Brunk "(Landroid/view/Surface;J)I", 71591838ded36131525312739c0929913b215519c2aRuben Brunk (void *)LegacyCameraDevice_nativeSetNextTimestamp }, 7161dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk { "nativeGetJpegFooterSize", 7171dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk "()I", 7181dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk (void *)LegacyCameraDevice_nativeGetJpegFooterSize }, 719feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}; 720feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 721feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// Get all the required offsets in java class and register native functions 722feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkint register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env) 723feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{ 724feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Register native functions 725feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return AndroidRuntime::registerNativeMethods(env, 726feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk CAMERA_DEVICE_CLASS_NAME, 727feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk gCameraDeviceMethods, 728feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NELEM(gCameraDeviceMethods)); 729feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 730feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 731