android_hardware_camera2_legacy_LegacyCameraDevice.cpp revision b0acf7fcfab08b5af1f99daa51bedbb659d18926
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/** 52433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 5431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane, 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) { 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t R, G, B; 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t index = 0; 5831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk for (size_t j = 0; j < height; j++) { 59433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk uint8_t* u = uPlane; 60433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk uint8_t* v = vPlane; 61433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk uint8_t* y = yPlane; 62433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk bool jEven = (j & 1) == 0; 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++]; 67433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk *y++ = (77 * R + 150 * G + 29 * B) >> 8; 68433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk if (jEven && (i & 1) == 0) { 69433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk *v = (( -43 * R - 85 * G + 128 * B) >> 8) + 128; 70433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk *u = (( 128 * R - 107 * G - 21 * B) >> 8) + 128; 71433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk u += chromaStep; 72433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk v += chromaStep; 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Skip alpha 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk index++; 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk yPlane += yStride; 78433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk if (jEven) { 79433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk uPlane += chromaStride; 80433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk vPlane += chromaStride; 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 84feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 8531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_ycbcr* ycbcr) { 86feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStep = ycbcr->chroma_step; 87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStride = ycbcr->cstride; 88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = ycbcr->ystride; 89433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride, 90433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk cStep); 91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y), 92433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb), 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk cStep, yStride, cStride); 94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 95feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 96feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t configureSurface(const sp<ANativeWindow>& anw, 97feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t width, 98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t height, 99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, 100feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t maxBufferSlack) { 101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 102feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_dimensions(anw.get(), width, height); 103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer dimensions, error %s (%d).", __FUNCTION__, 105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 106feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 107feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 109feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_format(anw.get(), pixelFmt); 110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer format, error %s (%d).", __FUNCTION__, 112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 113feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 116feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); 117feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 118feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, 119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 123feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int minUndequeuedBuffers; 124feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw.get()->query(anw.get(), 125feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 126feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk &minUndequeuedBuffers); 127feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", 129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk __FUNCTION__, strerror(-err), err); 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 132feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 1335096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Setting buffer count to %d, size to (%dx%d), fmt (0x%x)", __FUNCTION__, 1345096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin maxBufferSlack + 1 + minUndequeuedBuffers, 1355096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin width, height, pixelFmt); 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffer_count(anw.get(), maxBufferSlack + 1 + minUndequeuedBuffers); 137feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 141feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Produce a frame in the given surface. 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Args: 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * anw - a surface to produce a frame in. 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelBuffer - image buffer to generate a frame from. 151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * width - width of the pixelBuffer in pixels. 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * height - height of the pixelBuffer in pixels. 153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelFmt - format of the pixelBuffer, one of: 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCrCb_420_SP, 155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCbCr_420_888, 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_BLOB 157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * bufSize - the size of the pixelBuffer in bytes. 158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 159feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t produceFrame(const sp<ANativeWindow>& anw, 160feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* pixelBuffer, 16131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufWidth, // Width of the pixelBuffer 16231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufHeight, // Height of the pixelBuffer 163feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, // Format of the pixelBuffer 1645096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin int32_t bufSize) { 165feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ATRACE_CALL(); 166feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 167feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ANativeWindowBuffer* anb; 1685096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)", 16931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, anw.get(), bufWidth, bufHeight, pixelFmt, bufSize); 1705096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 1715096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (anw == 0) { 1725096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: anw must not be NULL", __FUNCTION__); 1735096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1745096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (pixelBuffer == NULL) { 1755096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__); 1765096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 17731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufWidth < 0) { 1785096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: width must be non-negative", __FUNCTION__); 1795096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 18031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufHeight < 0) { 1815096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: height must be non-negative", __FUNCTION__); 1825096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1835096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (bufSize < 0) { 1845096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: bufSize must be non-negative", __FUNCTION__); 1855096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1865096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 187feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 18831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t width = static_cast<size_t>(bufWidth); 18931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t height = static_cast<size_t>(bufHeight); 19031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t bufferLength = static_cast<size_t>(bufSize); 19191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 192feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: Switch to using Surface::lock and Surface::unlockAndPost 193feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_dequeue_buffer_and_wait(anw.get(), &anb); 194feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 195feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 196feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<GraphicBuffer> buf(new GraphicBuffer(anb, /*keepOwnership*/false)); 1970c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufWidth = buf->getWidth(); 1980c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufHeight = buf->getHeight(); 1990c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufStride = buf->getStride(); 2000c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk if (grallocBufWidth != width || grallocBufHeight != height) { 20131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Received gralloc buffer with bad dimensions %" PRIu32 "x%" PRIu32 2020c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk ", expecting dimensions %zu x %zu", __FUNCTION__, grallocBufWidth, 2030c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk grallocBufHeight, width, height); 20431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 20531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 20631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 20731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufFmt = 0; 20831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &bufFmt); 20931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (err != NO_ERROR) { 21031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, 21131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk strerror(-err), err); 21231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return err; 21331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 21431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 2150c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint64_t tmpSize = (pixelFmt == HAL_PIXEL_FORMAT_BLOB) ? grallocBufWidth : 2160c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk 4 * grallocBufHeight * grallocBufWidth; 21731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt != pixelFmt) { 21831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt == HAL_PIXEL_FORMAT_RGBA_8888 && pixelFmt == HAL_PIXEL_FORMAT_BLOB) { 21931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGV("%s: Using BLOB to RGBA format override.", __FUNCTION__); 2200c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk tmpSize = 4 * (grallocBufWidth + grallocBufStride * (grallocBufHeight - 1)); 22131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else { 22231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGW("%s: Format mismatch in produceFrame: expecting format %#" PRIx32 22331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ", but received buffer with format %#" PRIx32, __FUNCTION__, pixelFmt, bufFmt); 22431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 22531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 22631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 22731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (tmpSize > SIZE_MAX) { 22831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Overflow calculating size, buffer with dimens %zu x %zu is absurdly large...", 22931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, width, height); 23031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 23131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 23231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 23331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalSizeBytes = tmpSize; 234feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 235433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt); 236feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk switch(pixelFmt) { 237feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 23831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 23931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 24031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 241feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 242feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 243feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* img = NULL; 244feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 245feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 246feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 247feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 248feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* yPlane = img; 249feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane = img + height * width; 250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* vPlane = uPlane + 1; 251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStep = 2; 252feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = width; 253feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStride = width; 254feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 255feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 256feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane, vPlane, chromaStep, yStride, chromaStride); 257feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 25991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk case HAL_PIXEL_FORMAT_YV12: { 26031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 26131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 26231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 26391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 26491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 26591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 26691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if ((width & 1) || (height & 1)) { 26731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Dimens %zu x %zu are not divisible by 2.", __FUNCTION__, width, height); 26891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 26991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 27091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 27191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* img = NULL; 27291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 27391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 27491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (err != NO_ERROR) { 27591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__, 27691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk strerror(-err), err); 27791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return err; 27891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 27991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t stride = buf->getStride(); 281433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride); 28291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride); 28391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t cStride = ALIGN(stride / 2, 16); 28591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk size_t chromaStep = 1; 28691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* yPlane = img; 28891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride; 28991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2; 29091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 29191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 29291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk crPlane, cbPlane, chromaStep, stride, cStride); 29391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk break; 29491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 295feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCbCr_420_888: { 296feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Software writes with YCbCr_420_888 format are unsupported 297feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // by the gralloc module for now 29831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 29931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 30031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 301feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 302feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 303feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk android_ycbcr ycbcr = android_ycbcr(); 304feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 305feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 306feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr); 307feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 308feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__, 309feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 310feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 311feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 312feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, &ycbcr); 313feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 314feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 315feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_BLOB: { 316feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int8_t* img = NULL; 3170fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk struct camera3_jpeg_blob footer = { 3180fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk jpeg_blob_id: CAMERA3_JPEG_BLOB_ID, 3190c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk jpeg_size: (uint32_t)bufferLength 3200fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk }; 3210fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 32231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalJpegSize = bufferLength + sizeof(footer); 32331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk totalJpegSize = (totalJpegSize + 3) & ~0x3; // round up to nearest octonibble 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 476f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz, 477f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk jobject surface) { 478f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk ALOGV("nativeDetectSurfaceUsageFlags"); 479f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 480f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk sp<ANativeWindow> anw; 481f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 482f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk jniThrowException(env, "Ljava/lang/UnsupportedOperationException;", 483f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "Could not retrieve native window from surface."); 484f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return BAD_VALUE; 485f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 486f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk int32_t usage = 0; 487f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage); 488f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if(err != NO_ERROR) { 489f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk jniThrowException(env, "Ljava/lang/UnsupportedOperationException;", 490f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "Error while querying surface usage bits"); 491f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return err; 492f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 493f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return usage; 494f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 495f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 49628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, 49728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surfaceTexture, jintArray dimens) { 49828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeDetectTextureDimens"); 49928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 50028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindowFromTexture(env, surfaceTexture)) == NULL) { 50128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from SurfaceTexture.", __FUNCTION__); 50228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 50328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 50428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 50528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t dimenBuf[2]; 50628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 50728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 50828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture width %s (%d)", __FUNCTION__, 50928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 51028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 51128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 51228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 51328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 51428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 51528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture height %s (%d)", __FUNCTION__, 51628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 51728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 51828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 51928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 52028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 52128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 52228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 52328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 52428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 52528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 52628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 527ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, 528feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height, jint pixelFormat) { 529feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeConfigureSurface"); 530feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 531feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 532feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 533ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 534feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 535feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); 536feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 537ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); 538ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 539feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 540ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 541feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 542feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 543ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, 544feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) { 545feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeProduceFrame"); 546feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 547feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 548feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 549feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 550ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 551feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 552feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 553feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixelBuffer == NULL) { 554feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixelBuffer"); 555ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 556feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 557feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 558feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer)); 559feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL); 560feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 561feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixels == NULL) { 562feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixels"); 563ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 564feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 565feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 566feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height, 567feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk pixelFormat, bufSize); 568feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT); 569feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 570feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 571ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err); 572ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 573feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 574ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 575feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 576feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 577ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, 578feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint pixelFormat) { 579feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceType"); 580feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 581feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 582feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 583ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 584feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 585feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_format(anw.get(), pixelFormat); 586feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 587ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err); 588ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 589feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 590ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 591feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 592feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 593ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, 594feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height) { 595feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceDimens"); 596feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 597feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 598feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 599ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 600feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 601a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk 602b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala // Set user dimensions only 603b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala // The producer dimensions are owned by GL 604b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala status_t err = native_window_set_buffers_user_dimensions(anw.get(), width, height); 605a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk if (err != NO_ERROR) { 606a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err), 607a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk err); 608a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk return err; 609a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk } 610ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 611feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 612feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 6133c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) { 6143c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGV("nativeGetSurfaceId"); 6153c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 6163c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if ((s = getSurface(env, surface)) == NULL) { 6173c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__); 6183c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6193c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6203c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer(); 6213c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (gbp == NULL) { 6223c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__); 6233c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6243c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6253c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IBinder> b = gbp->asBinder(); 6263c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (b == NULL) { 6273c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__); 6283c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6293c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6303c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk /* 6313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * FIXME: Use better unique ID for surfaces than native IBinder pointer. Fix also in the camera 6323c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * service (CameraDeviceClient.h). 6333c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk */ 6343c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return reinterpret_cast<jlong>(b.get()); 6353c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 6363c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 63728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceOrientation(JNIEnv* env, jobject thiz, 63828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surface, jint facing, jint orientation) { 63928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeSetSurfaceOrientation"); 64028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 64128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 64228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 64328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 64428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 64528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 64628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = NO_ERROR; 64728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk CameraMetadata staticMetadata; 64828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 64928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t orientVal = static_cast<int32_t>(orientation); 65028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk uint8_t facingVal = static_cast<uint8_t>(facing); 65128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1); 65228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1); 65328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 65428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t transform = 0; 65528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 65691838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = CameraUtils::getRotationTransform(staticMetadata, /*out*/&transform)) != NO_ERROR) { 65728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid rotation transform %s (%d)", __FUNCTION__, strerror(-err), 65828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err); 65928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 66028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 66128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 66228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("%s: Setting buffer sticky transform to %d", __FUNCTION__, transform); 66328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 66491838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_sticky_transform(anw.get(), transform)) != NO_ERROR) { 66528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Unable to configure surface transform, error %s (%d)", __FUNCTION__, 66628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 66728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 66828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 66928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 67028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 67128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 67228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 67391838ded36131525312739c0929913b215519c2aRuben Brunkstatic jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz, jobject surface, 67491838ded36131525312739c0929913b215519c2aRuben Brunk jlong timestamp) { 67591838ded36131525312739c0929913b215519c2aRuben Brunk ALOGV("nativeSetNextTimestamp"); 67691838ded36131525312739c0929913b215519c2aRuben Brunk sp<ANativeWindow> anw; 67791838ded36131525312739c0929913b215519c2aRuben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 67891838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 67991838ded36131525312739c0929913b215519c2aRuben Brunk return BAD_VALUE; 68091838ded36131525312739c0929913b215519c2aRuben Brunk } 68191838ded36131525312739c0929913b215519c2aRuben Brunk 68291838ded36131525312739c0929913b215519c2aRuben Brunk status_t err = NO_ERROR; 68391838ded36131525312739c0929913b215519c2aRuben Brunk 68491838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_timestamp(anw.get(), static_cast<int64_t>(timestamp))) != 68591838ded36131525312739c0929913b215519c2aRuben Brunk NO_ERROR) { 68691838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Unable to set surface timestamp, error %s (%d)", __FUNCTION__, strerror(-err), 68791838ded36131525312739c0929913b215519c2aRuben Brunk err); 68891838ded36131525312739c0929913b215519c2aRuben Brunk return err; 68991838ded36131525312739c0929913b215519c2aRuben Brunk } 69091838ded36131525312739c0929913b215519c2aRuben Brunk return NO_ERROR; 69191838ded36131525312739c0929913b215519c2aRuben Brunk} 69291838ded36131525312739c0929913b215519c2aRuben Brunk 6931dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunkstatic jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) { 6941dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk ALOGV("nativeGetJpegFooterSize"); 6951dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk return static_cast<jint>(sizeof(struct camera3_jpeg_blob)); 6961dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk} 6971dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk 698feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} // extern "C" 699feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 700feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic JNINativeMethod gCameraDeviceMethods[] = { 701feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceType", 702feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "(Landroid/view/Surface;)I", 703feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceType }, 704feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceDimens", 705ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[I)I", 706feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, 707feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeConfigureSurface", 708ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;III)I", 709feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeConfigureSurface }, 710feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeProduceFrame", 711ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[BIII)I", 712feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeProduceFrame }, 713feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceFormat", 714ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;I)I", 715feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceFormat }, 716feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceDimens", 717ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;II)I", 718feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, 7193c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk { "nativeGetSurfaceId", 7203c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "(Landroid/view/Surface;)J", 7213c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk (void *)LegacyCameraDevice_nativeGetSurfaceId }, 72228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeDetectTextureDimens", 72328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/graphics/SurfaceTexture;[I)I", 72428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeDetectTextureDimens }, 72528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeSetSurfaceOrientation", 72628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/view/Surface;II)I", 72728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceOrientation }, 72891838ded36131525312739c0929913b215519c2aRuben Brunk { "nativeSetNextTimestamp", 72991838ded36131525312739c0929913b215519c2aRuben Brunk "(Landroid/view/Surface;J)I", 73091838ded36131525312739c0929913b215519c2aRuben Brunk (void *)LegacyCameraDevice_nativeSetNextTimestamp }, 7311dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk { "nativeGetJpegFooterSize", 7321dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk "()I", 7331dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk (void *)LegacyCameraDevice_nativeGetJpegFooterSize }, 734f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk { "nativeDetectSurfaceUsageFlags", 735f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "(Landroid/view/Surface;)I", 736f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags }, 737feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}; 738feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 739feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// Get all the required offsets in java class and register native functions 740feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkint register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env) 741feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{ 742feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Register native functions 743feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return AndroidRuntime::registerNativeMethods(env, 744feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk CAMERA_DEVICE_CLASS_NAME, 745feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk gCameraDeviceMethods, 746feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NELEM(gCameraDeviceMethods)); 747feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 748