android_hardware_camera2_legacy_LegacyCameraDevice.cpp revision 0fd198ad89ec9c600bb1761b10d938146c28bb98
1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/* 2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project 3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License. 6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at 7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and 14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License. 15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define LOG_TAG "Legacy-CameraDevice-JNI" 185096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin// #define LOG_NDEBUG 0 19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Log.h> 20feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Errors.h> 21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Trace.h> 2228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <camera/CameraUtils.h> 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "jni.h" 25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "JNIHelp.h" 26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/AndroidRuntime.h" 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/android_view_Surface.h" 2828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include "android_runtime/android_graphics_SurfaceTexture.h" 29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 303c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/Surface.h> 313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/IGraphicBufferProducer.h> 32feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <ui/GraphicBuffer.h> 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <system/window.h> 345096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <hardware/camera3.h> 3528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <system/camera_metadata.h> 36feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 373c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <stdint.h> 383c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <inttypes.h> 393c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkusing namespace android; 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// fully-qualified class name 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice" 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_BUFFER_SLACK 3 45ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk#define DONT_CARE 0 46feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 4991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 5091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Convert from RGB 888 to Y'CbCr using the conversion specified in ITU-R BT.601 for 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * digital RGB with K_b = 0.114, and K_r = 0.299. 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, int32_t width, int32_t height, uint8_t* yPlane, 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) { 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t R, G, B; 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t index = 0; 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t cStrideDiff = chromaStride - width; 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (int32_t j = 0; j < height; j++) { 63feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (int32_t i = 0; i < width; i++) { 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk R = rgbBuf[index++]; 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk G = rgbBuf[index++]; 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk B = rgbBuf[index++]; 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *(yPlane + i) = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16; 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (j % 2 == 0 && i % 2 == 0){ 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *uPlane = (( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128; 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *vPlane = (( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128; 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane += chromaStep; 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk vPlane += chromaStep; 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Skip alpha 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk index++; 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk yPlane += yStride; 79feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (j % 2 == 0) { 80feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane += cStrideDiff; 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk vPlane += cStrideDiff; 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 84feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 85feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 86feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, int32_t width, int32_t height, android_ycbcr* ycbcr) { 87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStep = ycbcr->chroma_step; 88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStride = ycbcr->cstride; 89feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = ycbcr->ystride; 90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y), 91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk reinterpret_cast<uint8_t*>(ycbcr->cb), reinterpret_cast<uint8_t*>(ycbcr->cr), 92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk cStep, yStride, cStride); 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 95feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t configureSurface(const sp<ANativeWindow>& anw, 96feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t width, 97feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t height, 98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, 99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t maxBufferSlack) { 100feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_dimensions(anw.get(), width, height); 102feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer dimensions, error %s (%d).", __FUNCTION__, 104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 106feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 107feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_format(anw.get(), pixelFmt); 109feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer format, error %s (%d).", __FUNCTION__, 111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 113feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); 116feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 117feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, 118feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int minUndequeuedBuffers; 123feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw.get()->query(anw.get(), 124feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 125feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk &minUndequeuedBuffers); 126feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 127feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", 128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk __FUNCTION__, strerror(-err), err); 129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 1325096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Setting buffer count to %d, size to (%dx%d), fmt (0x%x)", __FUNCTION__, 1335096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin maxBufferSlack + 1 + minUndequeuedBuffers, 1345096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin width, height, pixelFmt); 135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffer_count(anw.get(), maxBufferSlack + 1 + minUndequeuedBuffers); 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 137feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, 138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 141feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Produce a frame in the given surface. 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Args: 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * anw - a surface to produce a frame in. 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelBuffer - image buffer to generate a frame from. 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * width - width of the pixelBuffer in pixels. 151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * height - height of the pixelBuffer in pixels. 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelFmt - format of the pixelBuffer, one of: 153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCrCb_420_SP, 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCbCr_420_888, 155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_BLOB 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * bufSize - the size of the pixelBuffer in bytes. 157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t produceFrame(const sp<ANativeWindow>& anw, 159feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* pixelBuffer, 160feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t width, // Width of the pixelBuffer 161feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t height, // Height of the pixelBuffer 162feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, // Format of the pixelBuffer 1635096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin int32_t bufSize) { 164feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ATRACE_CALL(); 165feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 166feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ANativeWindowBuffer* anb; 1675096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)", 1685096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin __FUNCTION__, anw.get(), width, height, pixelFmt, bufSize); 1695096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 1705096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (anw == 0) { 1715096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: anw must not be NULL", __FUNCTION__); 1725096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1735096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (pixelBuffer == NULL) { 1745096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__); 1755096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1765096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (width < 0) { 1775096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: width must be non-negative", __FUNCTION__); 1785096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1795096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (height < 0) { 1805096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: height must be non-negative", __FUNCTION__); 1815096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1825096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (bufSize < 0) { 1835096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: bufSize must be non-negative", __FUNCTION__); 1845096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1855096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 186feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 18791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (width < 0 || height < 0 || bufSize < 0) { 18891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Illegal argument, negative dimension passed to produceFrame", __FUNCTION__); 18991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 19091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 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 1965096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin // TODO: check anb is large enough to store the results 1975096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 198feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<GraphicBuffer> buf(new GraphicBuffer(anb, /*keepOwnership*/false)); 199feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 200feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk switch(pixelFmt) { 201feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 202feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (bufSize < width * height * 4) { 2030fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGE("%s: PixelBuffer size %" PRId32 " too small for given dimensions", 2043c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk __FUNCTION__, bufSize); 205feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 206feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 207feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* img = NULL; 208feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 209feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 210feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 211feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 212feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* yPlane = img; 213feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane = img + height * width; 214feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* vPlane = uPlane + 1; 215feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStep = 2; 216feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = width; 217feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStride = width; 218feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 219feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 220feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane, vPlane, chromaStep, yStride, chromaStride); 221feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 222feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 22391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk case HAL_PIXEL_FORMAT_YV12: { 22491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (bufSize < width * height * 4) { 2250fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGE("%s: PixelBuffer size %" PRId32 " too small for given dimensions", 2263c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk __FUNCTION__, bufSize); 22791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 22891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 22991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 23091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if ((width & 1) || (height & 1)) { 23191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Dimens %dx%d are not divisible by 2.", __FUNCTION__, width, height); 23291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 23391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 23491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 23591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* img = NULL; 23691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 23791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 23891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (err != NO_ERROR) { 23991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__, 24091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk strerror(-err), err); 24191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return err; 24291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 24391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 24491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t stride = buf->getStride(); 24591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride); 24691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 24791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t cStride = ALIGN(stride / 2, 16); 24891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk size_t chromaStep = 1; 24991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 25091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* yPlane = img; 25191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride; 25291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2; 25391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 25491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 25591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk crPlane, cbPlane, chromaStep, stride, cStride); 25691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk break; 25791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCbCr_420_888: { 259feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Software writes with YCbCr_420_888 format are unsupported 260feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // by the gralloc module for now 261feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (bufSize < width * height * 4) { 2620fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGE("%s: PixelBuffer size %" PRId32 " too small for given dimensions", 2633c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk __FUNCTION__, bufSize); 264feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 265feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 266feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk android_ycbcr ycbcr = android_ycbcr(); 267feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 268feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 269feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr); 270feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 271feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__, 272feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 273feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 274feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 275feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, &ycbcr); 276feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 277feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 278feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_BLOB: { 279feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (bufSize != width || height != 1) { 2803c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Incorrect pixelBuffer size: %" PRId32, __FUNCTION__, bufSize); 281feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 282feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 283feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int8_t* img = NULL; 2840fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk struct camera3_jpeg_blob footer = { 2850fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk jpeg_blob_id: CAMERA3_JPEG_BLOB_ID, 2860fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk jpeg_size: (uint32_t)width 2870fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk }; 2880fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk 2890fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk size_t totalSize = static_cast<size_t>(width) + sizeof(footer); 2900fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk size_t padding = ((totalSize - 1) & ~0x3) + 4; // align to next octonibble 2910fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk totalSize += padding; 2920fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk if (anb->width != totalSize) { 2930fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk ALOGE("%s: gralloc buffer wrong size to hold jpeg, failed to produce buffer."); 2940fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk return BAD_VALUE; 2950fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } 296feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 297feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 298feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 299feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 300feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock buffer, error %s (%d).", __FUNCTION__, strerror(-err), 301feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err); 302feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 303feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 304feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk memcpy(img, pixelBuffer, width); 3050fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk memset(img + width, 0, padding); 3060fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk memcpy(img + totalSize - sizeof(footer), &footer, sizeof(footer)); 307feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 308feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 309feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk default: { 310feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Invalid pixel format in produceFrame: %x", __FUNCTION__, pixelFmt); 311feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 312feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 313feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 314feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 315feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Unlock buffer from %p", __FUNCTION__, anw.get()); 316feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->unlock(); 317feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 318feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to unlock buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 319feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 320feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 321feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 322feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Queue buffer to %p", __FUNCTION__, anw.get()); 323feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), /*fenceFd*/-1); 324feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 325feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to queue buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 326feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 327feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 328feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 329feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 330feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 331feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) { 332feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 333feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (surface) { 334feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk anw = android_view_Surface_getNativeWindow(env, surface); 335feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (env->ExceptionCheck()) { 3363c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 337feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 338feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 339feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "surface"); 3403c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 341feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 342feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (anw == NULL) { 343feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 344feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "Surface had no valid native window."); 3453c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 347feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 35028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic sp<ANativeWindow> getNativeWindowFromTexture(JNIEnv* env, jobject surfaceTexture) { 35128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 35228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (surfaceTexture) { 35328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk anw = android_SurfaceTexture_getNativeWindow(env, surfaceTexture); 35428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 35528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 35628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 35728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } else { 35828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowNullPointerException(env, "surfaceTexture"); 35928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 36028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 36128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (anw == NULL) { 36228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 36328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "SurfaceTexture had no valid native window."); 36428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NULL; 36528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 36628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return anw; 36728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 36828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 3693c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic sp<Surface> getSurface(JNIEnv* env, jobject surface) { 3703c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 3713c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (surface) { 3723c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk s = android_view_Surface_getSurface(env, surface); 3733c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (env->ExceptionCheck()) { 3743c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 3753c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 3763c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } else { 3773c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowNullPointerException(env, "surface"); 3783c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 3793c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 3803c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (s == NULL) { 3813c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 3823c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "Surface had no valid native Surface."); 3833c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return NULL; 3843c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 3853c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return s; 3863c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 3873c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 388feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkextern "C" { 389feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 390feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) { 391feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeDetectSurfaceType"); 392feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 393feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 394feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 395ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 396feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 397feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t fmt = 0; 398feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt); 399feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 400ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err), 401ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 402ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 403feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 404feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return fmt; 405feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 406feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 407ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, 408feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jobject surface, jintArray dimens) { 409feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeGetSurfaceDimens"); 41028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 41128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (dimens == NULL) { 41228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Null dimens argument passed to nativeDetectSurfaceDimens", __FUNCTION__); 41328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 41428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 41528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 41628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->GetArrayLength(dimens) < 2) { 41728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid length of dimens argument in nativeDetectSurfaceDimens", __FUNCTION__); 41828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 41928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 42028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 421feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 422feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 423feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 424ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t dimenBuf[2]; 427feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 428feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 429ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err), 430ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 431ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 433feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 434feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 435ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err), 436ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 437ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 438feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 440ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 442feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 44328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, 44428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surfaceTexture, jintArray dimens) { 44528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeDetectTextureDimens"); 44628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 44728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindowFromTexture(env, surfaceTexture)) == NULL) { 44828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from SurfaceTexture.", __FUNCTION__); 44928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 45028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 45128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 45228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t dimenBuf[2]; 45328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 45428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 45528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture width %s (%d)", __FUNCTION__, 45628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 45728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 45828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 45928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 46028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 46128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if(err != NO_ERROR) { 46228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Error while querying SurfaceTexture height %s (%d)", __FUNCTION__, 46328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 46428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 46528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 46628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 46728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 46828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if (env->ExceptionCheck()) { 46928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 47028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 47128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 47228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 47328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 474ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, 475feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height, jint pixelFormat) { 476feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeConfigureSurface"); 477feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 478feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 479feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 480ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 481feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 482feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); 483feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 484ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); 485ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 486feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 487ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 488feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 489feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 490ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, 491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) { 492feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeProduceFrame"); 493feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 494feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 495feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 496feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 497ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 498feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixelBuffer == NULL) { 501feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixelBuffer"); 502ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 503feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 504feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 505feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer)); 506feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL); 507feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 508feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixels == NULL) { 509feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixels"); 510ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 511feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 512feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 513feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height, 514feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk pixelFormat, bufSize); 515feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT); 516feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 517feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 518ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err); 519ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 520feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 521ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 522feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 523feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 524ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, 525feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint pixelFormat) { 526feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceType"); 527feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 528feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 529feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 530ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 531feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 532feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_format(anw.get(), pixelFormat); 533feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 534ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err); 535ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 536feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 537ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 538feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 539feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 540ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, 541feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height) { 542feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceDimens"); 543feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 544feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 545feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 546ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 547feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 548feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_dimensions(anw.get(), width, height); 549feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 550ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface dimens %s (%d).", __FUNCTION__, strerror(-err), err); 551ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 552feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 553a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk 554a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk // WAR - Set user dimensions also to avoid incorrect scaling after TextureView orientation 555a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk // change. 556a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk err = native_window_set_buffers_user_dimensions(anw.get(), width, height); 557a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk if (err != NO_ERROR) { 558a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err), 559a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk err); 560a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk return err; 561a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk } 562ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 563feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 564feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 5653c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) { 5663c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGV("nativeGetSurfaceId"); 5673c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<Surface> s; 5683c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if ((s = getSurface(env, surface)) == NULL) { 5693c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__); 5703c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 5713c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 5723c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer(); 5733c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (gbp == NULL) { 5743c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__); 5753c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 5763c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 5773c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk sp<IBinder> b = gbp->asBinder(); 5783c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk if (b == NULL) { 5793c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__); 5803c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return 0; 5813c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk } 5823c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk /* 5833c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * FIXME: Use better unique ID for surfaces than native IBinder pointer. Fix also in the camera 5843c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk * service (CameraDeviceClient.h). 5853c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk */ 5863c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk return reinterpret_cast<jlong>(b.get()); 5873c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk} 5883c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk 58928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceOrientation(JNIEnv* env, jobject thiz, 59028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk jobject surface, jint facing, jint orientation) { 59128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("nativeSetSurfaceOrientation"); 59228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk sp<ANativeWindow> anw; 59328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 59428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 59528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return BAD_VALUE; 59628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 59728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 59828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk status_t err = NO_ERROR; 59928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk CameraMetadata staticMetadata; 60028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 60128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t orientVal = static_cast<int32_t>(orientation); 60228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk uint8_t facingVal = static_cast<uint8_t>(facing); 60328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1); 60428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1); 60528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 60628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk int32_t transform = 0; 60728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 60891838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = CameraUtils::getRotationTransform(staticMetadata, /*out*/&transform)) != NO_ERROR) { 60928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Invalid rotation transform %s (%d)", __FUNCTION__, strerror(-err), 61028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk err); 61128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 61228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 61328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 61428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGV("%s: Setting buffer sticky transform to %d", __FUNCTION__, transform); 61528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 61691838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_sticky_transform(anw.get(), transform)) != NO_ERROR) { 61728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk ALOGE("%s: Unable to configure surface transform, error %s (%d)", __FUNCTION__, 61828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk strerror(-err), err); 61928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return err; 62028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk } 62128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 62228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk return NO_ERROR; 62328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk} 62428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk 62591838ded36131525312739c0929913b215519c2aRuben Brunkstatic jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz, jobject surface, 62691838ded36131525312739c0929913b215519c2aRuben Brunk jlong timestamp) { 62791838ded36131525312739c0929913b215519c2aRuben Brunk ALOGV("nativeSetNextTimestamp"); 62891838ded36131525312739c0929913b215519c2aRuben Brunk sp<ANativeWindow> anw; 62991838ded36131525312739c0929913b215519c2aRuben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 63091838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 63191838ded36131525312739c0929913b215519c2aRuben Brunk return BAD_VALUE; 63291838ded36131525312739c0929913b215519c2aRuben Brunk } 63391838ded36131525312739c0929913b215519c2aRuben Brunk 63491838ded36131525312739c0929913b215519c2aRuben Brunk status_t err = NO_ERROR; 63591838ded36131525312739c0929913b215519c2aRuben Brunk 63691838ded36131525312739c0929913b215519c2aRuben Brunk if ((err = native_window_set_buffers_timestamp(anw.get(), static_cast<int64_t>(timestamp))) != 63791838ded36131525312739c0929913b215519c2aRuben Brunk NO_ERROR) { 63891838ded36131525312739c0929913b215519c2aRuben Brunk ALOGE("%s: Unable to set surface timestamp, error %s (%d)", __FUNCTION__, strerror(-err), 63991838ded36131525312739c0929913b215519c2aRuben Brunk err); 64091838ded36131525312739c0929913b215519c2aRuben Brunk return err; 64191838ded36131525312739c0929913b215519c2aRuben Brunk } 64291838ded36131525312739c0929913b215519c2aRuben Brunk return NO_ERROR; 64391838ded36131525312739c0929913b215519c2aRuben Brunk} 64491838ded36131525312739c0929913b215519c2aRuben Brunk 6451dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunkstatic jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) { 6461dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk ALOGV("nativeGetJpegFooterSize"); 6471dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk return static_cast<jint>(sizeof(struct camera3_jpeg_blob)); 6481dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk} 6491dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk 650feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} // extern "C" 651feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 652feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic JNINativeMethod gCameraDeviceMethods[] = { 653feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceType", 654feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "(Landroid/view/Surface;)I", 655feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceType }, 656feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceDimens", 657ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[I)I", 658feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, 659feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeConfigureSurface", 660ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;III)I", 661feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeConfigureSurface }, 662feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeProduceFrame", 663ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[BIII)I", 664feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeProduceFrame }, 665feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceFormat", 666ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;I)I", 667feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceFormat }, 668feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceDimens", 669ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;II)I", 670feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, 6713c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk { "nativeGetSurfaceId", 6723c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk "(Landroid/view/Surface;)J", 6733c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk (void *)LegacyCameraDevice_nativeGetSurfaceId }, 67428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeDetectTextureDimens", 67528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/graphics/SurfaceTexture;[I)I", 67628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeDetectTextureDimens }, 67728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk { "nativeSetSurfaceOrientation", 67828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk "(Landroid/view/Surface;II)I", 67928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceOrientation }, 68091838ded36131525312739c0929913b215519c2aRuben Brunk { "nativeSetNextTimestamp", 68191838ded36131525312739c0929913b215519c2aRuben Brunk "(Landroid/view/Surface;J)I", 68291838ded36131525312739c0929913b215519c2aRuben Brunk (void *)LegacyCameraDevice_nativeSetNextTimestamp }, 6831dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk { "nativeGetJpegFooterSize", 6841dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk "()I", 6851dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk (void *)LegacyCameraDevice_nativeGetJpegFooterSize }, 686feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}; 687feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 688feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// Get all the required offsets in java class and register native functions 689feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkint register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env) 690feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{ 691feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Register native functions 692feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return AndroidRuntime::registerNativeMethods(env, 693feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk CAMERA_DEVICE_CLASS_NAME, 694feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk gCameraDeviceMethods, 695feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NELEM(gCameraDeviceMethods)); 696feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 697feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 698