android_hardware_camera2_legacy_LegacyCameraDevice.cpp revision 2a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6
1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/* 2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project 3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License. 6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at 7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and 14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License. 15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define LOG_TAG "Legacy-CameraDevice-JNI" 185096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin// #define LOG_NDEBUG 0 19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Log.h> 20feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Errors.h> 21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Trace.h> 2228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <camera/CameraUtils.h> 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "jni.h" 252279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h> 26ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/android_view_Surface.h" 2828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include "android_runtime/android_graphics_SurfaceTexture.h" 29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 303c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/Surface.h> 313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/IGraphicBufferProducer.h> 3229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen#include <gui/IProducerListener.h> 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <ui/GraphicBuffer.h> 34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <system/window.h> 355096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <hardware/camera3.h> 3628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <system/camera_metadata.h> 37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 383c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <stdint.h> 393c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <inttypes.h> 403c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkusing namespace android; 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// fully-qualified class name 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice" 45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_BUFFER_SLACK 3 46ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk#define DONT_CARE 0 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 5091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 5191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 53433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 5531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane, 568973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk uint8_t* crPlane, uint8_t* cbPlane, size_t chromaStep, size_t yStride, size_t chromaStride) { 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t R, G, B; 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t index = 0; 5931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk for (size_t j = 0; j < height; j++) { 608973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk uint8_t* cr = crPlane; 618973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk uint8_t* cb = cbPlane; 62433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk uint8_t* y = yPlane; 63433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk bool jEven = (j & 1) == 0; 6431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk for (size_t i = 0; i < width; i++) { 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk R = rgbBuf[index++]; 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk G = rgbBuf[index++]; 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk B = rgbBuf[index++]; 68433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk *y++ = (77 * R + 150 * G + 29 * B) >> 8; 69433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk if (jEven && (i & 1) == 0) { 708973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk *cb = (( -43 * R - 85 * G + 128 * B) >> 8) + 128; 718973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk *cr = (( 128 * R - 107 * G - 21 * B) >> 8) + 128; 728973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk cr += chromaStep; 738973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk cb += chromaStep; 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Skip alpha 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk index++; 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk yPlane += yStride; 79433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk if (jEven) { 808973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk crPlane += chromaStride; 818973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk cbPlane += chromaStride; 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; 90433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride, 91433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk cStep); 92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y), 93433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb), 94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk cStep, yStride, cStride); 95feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 96feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 9729c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic status_t connectSurface(const sp<Surface>& surface, int32_t maxBufferSlack) { 98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 10029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = surface->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/NULL); 10129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if (err != OK) { 10229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGE("%s: Unable to connect to surface, error %s (%d).", __FUNCTION__, 103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 106feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 10729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); 108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 109feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, 110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 113feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int minUndequeuedBuffers; 11529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = static_cast<ANativeWindow*>(surface.get())->query(surface.get(), 11629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); 117feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 118feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", 119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk __FUNCTION__, strerror(-err), err); 120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 12329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("%s: Setting buffer count to %d", __FUNCTION__, 12429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen maxBufferSlack + 1 + minUndequeuedBuffers); 12529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen err = native_window_set_buffer_count(surface.get(), maxBufferSlack + 1 + minUndequeuedBuffers); 126feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 127feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, 128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 132feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 133feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 134feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Produce a frame in the given surface. 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 137feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Args: 138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * anw - a surface to produce a frame in. 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelBuffer - image buffer to generate a frame from. 140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * width - width of the pixelBuffer in pixels. 141feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * height - height of the pixelBuffer in pixels. 142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelFmt - format of the pixelBuffer, one of: 143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCrCb_420_SP, 144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCbCr_420_888, 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_BLOB 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * bufSize - the size of the pixelBuffer in bytes. 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t produceFrame(const sp<ANativeWindow>& anw, 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* pixelBuffer, 15031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufWidth, // Width of the pixelBuffer 15131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufHeight, // Height of the pixelBuffer 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, // Format of the pixelBuffer 1535096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin int32_t bufSize) { 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ATRACE_CALL(); 155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ANativeWindowBuffer* anb; 1575096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)", 15831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, anw.get(), bufWidth, bufHeight, pixelFmt, bufSize); 1595096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 1605096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (anw == 0) { 1615096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: anw must not be NULL", __FUNCTION__); 1625096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1635096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (pixelBuffer == NULL) { 1645096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__); 1655096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 16631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufWidth < 0) { 1675096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: width must be non-negative", __FUNCTION__); 1685096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 16931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else if (bufHeight < 0) { 1705096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: height must be non-negative", __FUNCTION__); 1715096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1725096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (bufSize < 0) { 1735096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: bufSize must be non-negative", __FUNCTION__); 1745096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1755096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 176feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t width = static_cast<size_t>(bufWidth); 17831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t height = static_cast<size_t>(bufHeight); 17931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t bufferLength = static_cast<size_t>(bufSize); 18091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 181feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: Switch to using Surface::lock and Surface::unlockAndPost 182feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_dequeue_buffer_and_wait(anw.get(), &anb); 183feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 184feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 185845eef05ffea53f4ce7a1e0551896be874c4f302Mathias Agopian sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 1860c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufWidth = buf->getWidth(); 1870c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufHeight = buf->getHeight(); 1880c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint32_t grallocBufStride = buf->getStride(); 1890c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk if (grallocBufWidth != width || grallocBufHeight != height) { 19031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Received gralloc buffer with bad dimensions %" PRIu32 "x%" PRIu32 1910c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk ", expecting dimensions %zu x %zu", __FUNCTION__, grallocBufWidth, 1920c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk grallocBufHeight, width, height); 19331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 19431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 19531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 19631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk int32_t bufFmt = 0; 19731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &bufFmt); 19831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (err != NO_ERROR) { 19931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, 20031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk strerror(-err), err); 20131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return err; 20231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 20331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 2040c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk uint64_t tmpSize = (pixelFmt == HAL_PIXEL_FORMAT_BLOB) ? grallocBufWidth : 2050c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk 4 * grallocBufHeight * grallocBufWidth; 20631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt != pixelFmt) { 20731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufFmt == HAL_PIXEL_FORMAT_RGBA_8888 && pixelFmt == HAL_PIXEL_FORMAT_BLOB) { 20831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGV("%s: Using BLOB to RGBA format override.", __FUNCTION__); 2090c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk tmpSize = 4 * (grallocBufWidth + grallocBufStride * (grallocBufHeight - 1)); 21031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } else { 21131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGW("%s: Format mismatch in produceFrame: expecting format %#" PRIx32 21231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ", but received buffer with format %#" PRIx32, __FUNCTION__, pixelFmt, bufFmt); 21331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 21431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 21531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 21631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (tmpSize > SIZE_MAX) { 21731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Overflow calculating size, buffer with dimens %zu x %zu is absurdly large...", 21831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, width, height); 21931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk return BAD_VALUE; 22031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk } 22131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 22231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalSizeBytes = tmpSize; 223feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 224433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt); 225feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk switch(pixelFmt) { 226feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 22731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 22831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 22931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 230feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 231feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 232feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* img = NULL; 233feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 234feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 235feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 236feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 237feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* yPlane = img; 238feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane = img + height * width; 239feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* vPlane = uPlane + 1; 240feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStep = 2; 241feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = width; 242feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStride = width; 243feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 244feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 245feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane, vPlane, chromaStep, yStride, chromaStride); 246feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 247feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 24891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk case HAL_PIXEL_FORMAT_YV12: { 24931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 25031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 25131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 25291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 25391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 25491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 25591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if ((width & 1) || (height & 1)) { 25631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Dimens %zu x %zu are not divisible by 2.", __FUNCTION__, width, height); 25791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 25891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 25991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 26091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* img = NULL; 26191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 26291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 26391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (err != NO_ERROR) { 26491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__, 26591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk strerror(-err), err); 26691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return err; 26791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 26891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 26991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t stride = buf->getStride(); 270433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride); 27191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride); 27291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 27391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t cStride = ALIGN(stride / 2, 16); 27491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk size_t chromaStep = 1; 27591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 27691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* yPlane = img; 27791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride; 27891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2; 27991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 28091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 28191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk crPlane, cbPlane, chromaStep, stride, cStride); 28291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk break; 28391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 284feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCbCr_420_888: { 285feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Software writes with YCbCr_420_888 format are unsupported 286feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // by the gralloc module for now 28731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (bufferLength < totalSizeBytes) { 28831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: PixelBuffer size %zu too small for given dimensions", 28931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, bufferLength); 290feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 291feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 292feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk android_ycbcr ycbcr = android_ycbcr(); 293feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 294feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 295feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr); 296feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 297feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__, 298feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 299feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 300feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 301feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, &ycbcr); 302feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 303feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 304feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_BLOB: { 305feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int8_t* img = NULL; 3060fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk struct camera3_jpeg_blob footer = { 307452efb218eb9af6ab2763879645bfc92db8ba02aBernhard Rosenkränzer .jpeg_blob_id = CAMERA3_JPEG_BLOB_ID, 308452efb218eb9af6ab2763879645bfc92db8ba02aBernhard Rosenkränzer .jpeg_size = (uint32_t)bufferLength 3090fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk }; 3100fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 31131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk size_t totalJpegSize = bufferLength + sizeof(footer); 31231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk totalJpegSize = (totalJpegSize + 3) & ~0x3; // round up to nearest octonibble 31331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 31431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk if (totalJpegSize > totalSizeBytes) { 31531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk ALOGE("%s: Pixel buffer needs size %zu, cannot fit in gralloc buffer of size %zu", 31631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk __FUNCTION__, totalJpegSize, totalSizeBytes); 3170fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return BAD_VALUE; 3180fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } 319feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 320feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 321feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 322feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock buffer, error %s (%d).", __FUNCTION__, strerror(-err), 323feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err); 324feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 325feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 32631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk 32731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk memcpy(img, pixelBuffer, bufferLength); 32831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk memcpy(img + totalSizeBytes - sizeof(footer), &footer, sizeof(footer)); 329feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 330feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 331feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk default: { 332feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Invalid pixel format in produceFrame: %x", __FUNCTION__, pixelFmt); 333feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 334feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 335feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 336feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 337feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Unlock buffer from %p", __FUNCTION__, anw.get()); 338feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->unlock(); 339feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 340feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to unlock buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 341feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 342feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 343feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 344feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Queue buffer to %p", __FUNCTION__, anw.get()); 345feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), /*fenceFd*/-1); 346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 347feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to queue buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 350feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 351feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 352feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 353feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) { 354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (surface) { 356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk anw = android_view_Surface_getNativeWindow(env, surface); 357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (env->ExceptionCheck()) { 3583c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 359feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 360feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 361feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "surface"); 3623c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 363feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 364feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (anw == NULL) { 365443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk ALOGE("%s: Surface had no valid native window.", __FUNCTION__); 3663c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 367feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 369feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 370feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 37128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic sp<ANativeWindow> getNativeWindowFromTexture(JNIEnv* env, jobject surfaceTexture) { 37228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 37328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (surfaceTexture) { 37428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk anw = android_SurfaceTexture_getNativeWindow(env, surfaceTexture); 37528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 37628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 37728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 37828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } else { 37928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowNullPointerException(env, "surfaceTexture"); 38028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 38128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 38228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (anw == NULL) { 38328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 38428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "SurfaceTexture had no valid native window."); 38528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 38628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 38728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return anw; 38828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 38928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 3903c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic sp<Surface> getSurface(JNIEnv* env, jobject surface) { 3913c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 3923c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (surface) { 3933c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk s = android_view_Surface_getSurface(env, surface); 3943c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (env->ExceptionCheck()) { 3953c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 3963c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 3973c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } else { 3983c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowNullPointerException(env, "surface"); 3993c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4003c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4013c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (s == NULL) { 4023c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 4033c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "Surface had no valid native Surface."); 4043c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 4053c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 4063c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return s; 4073c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 4083c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 409feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkextern "C" { 410feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 411feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) { 412feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeDetectSurfaceType"); 413feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 414feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 415feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 416ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 417feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 418feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t fmt = 0; 419feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt); 420feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 421ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err), 422ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 423ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 424feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return fmt; 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 427feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 428e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvalastatic jint LegacyCameraDevice_nativeDetectSurfaceDataspace(JNIEnv* env, jobject thiz, jobject surface) { 429e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala ALOGV("nativeDetectSurfaceDataspace"); 430e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala sp<ANativeWindow> anw; 431e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala if ((anw = getNativeWindow(env, surface)) == NULL) { 432e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 433e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala return BAD_VALUE; 434e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala } 435e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala int32_t fmt = 0; 436e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala status_t err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &fmt); 437e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala if(err != NO_ERROR) { 438e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala ALOGE("%s: Error while querying surface dataspace %s (%d).", __FUNCTION__, strerror(-err), 439e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala err); 440e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala return err; 441e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala } 442e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala return fmt; 443e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala} 444e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala 445ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, 446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jobject surface, jintArray dimens) { 447feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeGetSurfaceDimens"); 44828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 44928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (dimens == NULL) { 45028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Null dimens argument passed to nativeDetectSurfaceDimens", __FUNCTION__); 45128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 45228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 45328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 45428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->GetArrayLength(dimens) < 2) { 45528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid length of dimens argument in nativeDetectSurfaceDimens", __FUNCTION__); 45628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 45728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 45828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 459feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 460feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 461feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 462ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 463feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 464feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t dimenBuf[2]; 465feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 466feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 467ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err), 468ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 469ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 470feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 471feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 472feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 473ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err), 474ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 475ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 476feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 477feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 478ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 479feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 480feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 481f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz, 482f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk jobject surface) { 483f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk ALOGV("nativeDetectSurfaceUsageFlags"); 484f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 485f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk sp<ANativeWindow> anw; 486f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 4872a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh jniThrowException(env, "java/lang/UnsupportedOperationException;", 488f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "Could not retrieve native window from surface."); 489f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return BAD_VALUE; 490f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 491f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk int32_t usage = 0; 492f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage); 493f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk if(err != NO_ERROR) { 4942a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh jniThrowException(env, "java/lang/UnsupportedOperationException;", 495f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "Error while querying surface usage bits"); 496f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return err; 497f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk } 498f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk return usage; 499f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk} 500f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk 50129c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic jint LegacyCameraDevice_nativeDisconnectSurface(JNIEnv* env, jobject thiz, 50229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen jobject surface) { 50329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("nativeDisconnectSurface"); 50429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if (surface == nullptr) return NO_ERROR; 50529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 50629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen sp<ANativeWindow> anw; 50729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if ((anw = getNativeWindow(env, surface)) == NULL) { 50829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("Buffer queue has already been abandoned."); 50929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen return NO_ERROR; 51029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen } 51129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 51229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen status_t err = native_window_api_disconnect(anw.get(), NATIVE_WINDOW_API_CAMERA); 51329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if(err != NO_ERROR) { 5142a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh jniThrowException(env, "java/lang/UnsupportedOperationException;", 51529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen "Error while disconnecting surface"); 51629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen return err; 51729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen } 51829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen return NO_ERROR; 51929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen} 52029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen 52128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, 52228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surfaceTexture, jintArray dimens) { 52328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeDetectTextureDimens"); 52428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 52528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindowFromTexture(env, surfaceTexture)) == NULL) { 52628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from SurfaceTexture.", __FUNCTION__); 52728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 52828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 52928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 53028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t dimenBuf[2]; 53128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 53228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 53328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture width %s (%d)", __FUNCTION__, 53428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 53528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 53628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 53728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 53828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 53928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 54028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture height %s (%d)", __FUNCTION__, 54128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 54228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 54328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 54428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 54528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 54628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 54728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 54828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 54928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 55028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 55128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 55229c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic jint LegacyCameraDevice_nativeConnectSurface(JNIEnv* env, jobject thiz, jobject surface) { 55329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGV("nativeConnectSurface"); 55429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen sp<Surface> s; 55529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen if ((s = getSurface(env, surface)) == NULL) { 55629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen ALOGE("%s: Could not retrieve surface.", __FUNCTION__); 557ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 558feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 55929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen status_t err = connectSurface(s, CAMERA_DEVICE_BUFFER_SLACK); 560feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 561ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); 562ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 563feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 564ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 565feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 566feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 567ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, 568feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) { 569feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeProduceFrame"); 570feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 571feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 572feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 573feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 574ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 575feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 576feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 577feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixelBuffer == NULL) { 578feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixelBuffer"); 579ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 580feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 581feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 582feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer)); 583feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL); 584feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 585feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixels == NULL) { 586feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixels"); 587ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 588feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 589feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 590feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height, 591feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk pixelFormat, bufSize); 592feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT); 593feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 594feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 595ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err); 596ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 597feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 598ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 599feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 600feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 601ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, 602feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint pixelFormat) { 603feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceType"); 604feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 605feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 606feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 607ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 608feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 609feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_format(anw.get(), pixelFormat); 610feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 611ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err); 612ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 613feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 614ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 615feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 616feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 617ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, 618feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height) { 619feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceDimens"); 620feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 621feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 622feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 623ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 624feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 625a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk 626b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala // Set user dimensions only 627b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala // The producer dimensions are owned by GL 628b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala status_t err = native_window_set_buffers_user_dimensions(anw.get(), width, height); 629a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk if (err != NO_ERROR) { 630a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err), 631a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk err); 632a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk return err; 633a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk } 634ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 635feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 636feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 6373c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) { 6383c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGV("nativeGetSurfaceId"); 6393c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 6403c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if ((s = getSurface(env, surface)) == NULL) { 6413c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__); 6423c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6433c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6443c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer(); 6453c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (gbp == NULL) { 6463c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__); 6473c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6483c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 64997069dd4fd5454ba057ccf2854d7f925c337884cMarco Nelissen sp<IBinder> b = IInterface::asBinder(gbp); 6503c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (b == NULL) { 6513c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__); 6523c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 6533c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 6543c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk /* 6553c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * FIXME: Use better unique ID for surfaces than native IBinder pointer. Fix also in the camera 6563c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * service (CameraDeviceClient.h). 6573c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk */ 6583c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return reinterpret_cast<jlong>(b.get()); 6593c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 6603c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 66128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceOrientation(JNIEnv* env, jobject thiz, 66228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surface, jint facing, jint orientation) { 66328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeSetSurfaceOrientation"); 66428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 66528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 66628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 66728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 66828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 66928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 67028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = NO_ERROR; 67128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk CameraMetadata staticMetadata; 67228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 67328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t orientVal = static_cast<int32_t>(orientation); 67428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk uint8_t facingVal = static_cast<uint8_t>(facing); 67528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1); 67628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1); 67728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 67828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t transform = 0; 67928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 68091838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = CameraUtils::getRotationTransform(staticMetadata, /*out*/&transform)) != NO_ERROR) { 68128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid rotation transform %s (%d)", __FUNCTION__, strerror(-err), 68228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err); 68328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 68428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 68528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 68628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("%s: Setting buffer sticky transform to %d", __FUNCTION__, transform); 68728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 68891838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_sticky_transform(anw.get(), transform)) != NO_ERROR) { 68928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Unable to configure surface transform, error %s (%d)", __FUNCTION__, 69028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 69128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 69228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 69328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 69428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 69528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 69628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 69791838ded36131525312739c0929913b215519c2aRuben Brunkstatic jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz, jobject surface, 69891838ded36131525312739c0929913b215519c2aRuben Brunk jlong timestamp) { 69991838ded36131525312739c0929913b215519c2aRuben Brunk ALOGV("nativeSetNextTimestamp"); 70091838ded36131525312739c0929913b215519c2aRuben Brunk sp<ANativeWindow> anw; 70191838ded36131525312739c0929913b215519c2aRuben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 70291838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 70391838ded36131525312739c0929913b215519c2aRuben Brunk return BAD_VALUE; 70491838ded36131525312739c0929913b215519c2aRuben Brunk } 70591838ded36131525312739c0929913b215519c2aRuben Brunk 70691838ded36131525312739c0929913b215519c2aRuben Brunk status_t err = NO_ERROR; 70791838ded36131525312739c0929913b215519c2aRuben Brunk 70891838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_timestamp(anw.get(), static_cast<int64_t>(timestamp))) != 70991838ded36131525312739c0929913b215519c2aRuben Brunk NO_ERROR) { 71091838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Unable to set surface timestamp, error %s (%d)", __FUNCTION__, strerror(-err), 71191838ded36131525312739c0929913b215519c2aRuben Brunk err); 71291838ded36131525312739c0929913b215519c2aRuben Brunk return err; 71391838ded36131525312739c0929913b215519c2aRuben Brunk } 71491838ded36131525312739c0929913b215519c2aRuben Brunk return NO_ERROR; 71591838ded36131525312739c0929913b215519c2aRuben Brunk} 71691838ded36131525312739c0929913b215519c2aRuben Brunk 717a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunkstatic jint LegacyCameraDevice_nativeSetScalingMode(JNIEnv* env, jobject thiz, jobject surface, 718a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk jint mode) { 719a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk ALOGV("nativeSetScalingMode"); 720a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk sp<ANativeWindow> anw; 721a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 722a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 723a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk return BAD_VALUE; 724a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk } 725a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk status_t err = NO_ERROR; 726a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk if ((err = native_window_set_scaling_mode(anw.get(), static_cast<int>(mode))) != NO_ERROR) { 727a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk ALOGE("%s: Unable to set surface scaling mode, error %s (%d)", __FUNCTION__, 728a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk strerror(-err), err); 729a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk return err; 730a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk } 731a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk return NO_ERROR; 732a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk} 733a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk 7341dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunkstatic jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) { 7351dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk ALOGV("nativeGetJpegFooterSize"); 7361dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk return static_cast<jint>(sizeof(struct camera3_jpeg_blob)); 7371dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk} 7381dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk 739feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} // extern "C" 740feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 74176f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gCameraDeviceMethods[] = { 742feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceType", 743feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "(Landroid/view/Surface;)I", 744feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceType }, 745e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala { "nativeDetectSurfaceDataspace", 746e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala "(Landroid/view/Surface;)I", 747e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala (void *)LegacyCameraDevice_nativeDetectSurfaceDataspace }, 748feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceDimens", 749ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[I)I", 750feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, 75129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen { "nativeConnectSurface", 75229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen "(Landroid/view/Surface;)I", 75329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen (void *)LegacyCameraDevice_nativeConnectSurface }, 754feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeProduceFrame", 755ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[BIII)I", 756feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeProduceFrame }, 757feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceFormat", 758ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;I)I", 759feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceFormat }, 760feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceDimens", 761ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;II)I", 762feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, 7633c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk { "nativeGetSurfaceId", 7643c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "(Landroid/view/Surface;)J", 7653c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk (void *)LegacyCameraDevice_nativeGetSurfaceId }, 76628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeDetectTextureDimens", 76728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/graphics/SurfaceTexture;[I)I", 76828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeDetectTextureDimens }, 76928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeSetSurfaceOrientation", 77028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/view/Surface;II)I", 77128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceOrientation }, 77291838ded36131525312739c0929913b215519c2aRuben Brunk { "nativeSetNextTimestamp", 77391838ded36131525312739c0929913b215519c2aRuben Brunk "(Landroid/view/Surface;J)I", 77491838ded36131525312739c0929913b215519c2aRuben Brunk (void *)LegacyCameraDevice_nativeSetNextTimestamp }, 7751dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk { "nativeGetJpegFooterSize", 7761dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk "()I", 7771dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk (void *)LegacyCameraDevice_nativeGetJpegFooterSize }, 778f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk { "nativeDetectSurfaceUsageFlags", 779f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk "(Landroid/view/Surface;)I", 780f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags }, 781a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk { "nativeSetScalingMode", 782a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk "(Landroid/view/Surface;I)I", 783a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk (void *)LegacyCameraDevice_nativeSetScalingMode }, 78429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen { "nativeDisconnectSurface", 78529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen "(Landroid/view/Surface;)I", 78629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen (void *)LegacyCameraDevice_nativeDisconnectSurface }, 787feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}; 788feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 789feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// Get all the required offsets in java class and register native functions 790feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkint register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env) 791feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{ 792feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Register native functions 793ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return RegisterMethodsOrDie(env, 794feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk CAMERA_DEVICE_CLASS_NAME, 795feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk gCameraDeviceMethods, 796feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NELEM(gCameraDeviceMethods)); 797feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 798