android_hardware_camera2_legacy_LegacyCameraDevice.cpp revision ef14da32804b06bac872c9e0e14ce0e52120a0bd
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> 22feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "jni.h" 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "JNIHelp.h" 25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/AndroidRuntime.h" 26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/android_view_Surface.h" 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 28feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <ui/GraphicBuffer.h> 29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <system/window.h> 305096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <hardware/camera3.h> 31feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 32feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkusing namespace android; 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// fully-qualified class name 35feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice" 36feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_BUFFER_SLACK 3 37ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk#define DONT_CARE 0 38feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 39feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 4191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 4291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Convert from RGB 888 to Y'CbCr using the conversion specified in ITU-R BT.601 for 45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * digital RGB with K_b = 0.114, and K_r = 0.299. 46feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, int32_t width, int32_t height, uint8_t* yPlane, 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) { 49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t R, G, B; 50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t index = 0; 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t cStrideDiff = chromaStride - width; 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (int32_t j = 0; j < height; j++) { 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (int32_t i = 0; i < width; i++) { 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk R = rgbBuf[index++]; 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk G = rgbBuf[index++]; 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk B = rgbBuf[index++]; 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *(yPlane + i) = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16; 60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (j % 2 == 0 && i % 2 == 0){ 62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *uPlane = (( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128; 63feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *vPlane = (( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128; 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane += chromaStep; 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk vPlane += chromaStep; 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Skip alpha 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk index++; 69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk yPlane += yStride; 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (j % 2 == 0) { 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane += cStrideDiff; 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk vPlane += cStrideDiff; 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, int32_t width, int32_t height, android_ycbcr* ycbcr) { 79feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStep = ycbcr->chroma_step; 80feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t cStride = ycbcr->cstride; 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = ycbcr->ystride; 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y), 83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk reinterpret_cast<uint8_t*>(ycbcr->cb), reinterpret_cast<uint8_t*>(ycbcr->cr), 84feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk cStep, yStride, cStride); 85feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 86feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t configureSurface(const sp<ANativeWindow>& anw, 88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t width, 89feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t height, 90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, 91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t maxBufferSlack) { 92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_dimensions(anw.get(), width, height); 94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 95feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer dimensions, error %s (%d).", __FUNCTION__, 96feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 97feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 100feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffers_format(anw.get(), pixelFmt); 101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 102feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer format, error %s (%d).", __FUNCTION__, 103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 106feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 107feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_usage(anw.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; 115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw.get()->query(anw.get(), 116feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 117feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk &minUndequeuedBuffers); 118feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", 120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk __FUNCTION__, strerror(-err), err); 121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 123feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 1245096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Setting buffer count to %d, size to (%dx%d), fmt (0x%x)", __FUNCTION__, 1255096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin maxBufferSlack + 1 + minUndequeuedBuffers, 1265096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin width, height, pixelFmt); 127feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_set_buffer_count(anw.get(), maxBufferSlack + 1 + minUndequeuedBuffers); 128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 132feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 133feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 134feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 137feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Produce a frame in the given surface. 138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Args: 140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * anw - a surface to produce a frame in. 141feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelBuffer - image buffer to generate a frame from. 142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * width - width of the pixelBuffer in pixels. 143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * height - height of the pixelBuffer in pixels. 144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * pixelFmt - format of the pixelBuffer, one of: 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCrCb_420_SP, 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_YCbCr_420_888, 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * HAL_PIXEL_FORMAT_BLOB 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * bufSize - the size of the pixelBuffer in bytes. 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t produceFrame(const sp<ANativeWindow>& anw, 151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* pixelBuffer, 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t width, // Width of the pixelBuffer 153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t height, // Height of the pixelBuffer 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t pixelFmt, // Format of the pixelBuffer 1555096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin int32_t bufSize) { 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ATRACE_CALL(); 157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = NO_ERROR; 158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ANativeWindowBuffer* anb; 1595096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)", 1605096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin __FUNCTION__, anw.get(), width, height, pixelFmt, bufSize); 1615096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 1625096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin if (anw == 0) { 1635096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: anw must not be NULL", __FUNCTION__); 1645096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1655096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (pixelBuffer == NULL) { 1665096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__); 1675096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1685096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (width < 0) { 1695096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: width must be non-negative", __FUNCTION__); 1705096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1715096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (height < 0) { 1725096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: height must be non-negative", __FUNCTION__); 1735096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1745096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } else if (bufSize < 0) { 1755096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin ALOGE("%s: bufSize must be non-negative", __FUNCTION__); 1765096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin return BAD_VALUE; 1775096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin } 178feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (width < 0 || height < 0 || bufSize < 0) { 18091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Illegal argument, negative dimension passed to produceFrame", __FUNCTION__); 18191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 18291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 18391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 184feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: Switch to using Surface::lock and Surface::unlockAndPost 185feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = native_window_dequeue_buffer_and_wait(anw.get(), &anb); 186feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 187feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 1885096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin // TODO: check anb is large enough to store the results 1895096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin 190feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<GraphicBuffer> buf(new GraphicBuffer(anb, /*keepOwnership*/false)); 191feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 192feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk switch(pixelFmt) { 193feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 194feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (bufSize < width * height * 4) { 195feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__, 196feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk bufSize); 197feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 198feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 199feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* img = NULL; 200feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 201feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 202feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) return err; 203feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 204feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* yPlane = img; 205feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* uPlane = img + height * width; 206feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uint8_t* vPlane = uPlane + 1; 207feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStep = 2; 208feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t yStride = width; 209feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk size_t chromaStride = width; 210feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 211feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 212feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk uPlane, vPlane, chromaStep, yStride, chromaStride); 213feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 214feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 21591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk case HAL_PIXEL_FORMAT_YV12: { 21691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (bufSize < width * height * 4) { 21791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__, 21891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk bufSize); 21991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 22091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 22191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 22291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if ((width & 1) || (height & 1)) { 22391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Dimens %dx%d are not divisible by 2.", __FUNCTION__, width, height); 22491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return BAD_VALUE; 22591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 22691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 22791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* img = NULL; 22891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 22991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 23091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk if (err != NO_ERROR) { 23191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__, 23291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk strerror(-err), err); 23391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return err; 23491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 23591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 23691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t stride = buf->getStride(); 23791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride); 23891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 23991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint32_t cStride = ALIGN(stride / 2, 16); 24091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk size_t chromaStep = 1; 24191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 24291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* yPlane = img; 24391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride; 24491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2; 24591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk 24691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk rgbToYuv420(pixelBuffer, width, height, yPlane, 24791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk crPlane, cbPlane, chromaStep, stride, cStride); 24891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk break; 24991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk } 250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_YCbCr_420_888: { 251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Software writes with YCbCr_420_888 format are unsupported 252feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // by the gralloc module for now 253feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (bufSize < width * height * 4) { 254feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__, 255feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk bufSize); 256feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 257feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk android_ycbcr ycbcr = android_ycbcr(); 259feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 260feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 261feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr); 262feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 263feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__, 264feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk strerror(-err), err); 265feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 266feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 267feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk rgbToYuv420(pixelBuffer, width, height, &ycbcr); 268feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 269feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 270feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk case HAL_PIXEL_FORMAT_BLOB: { 271feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (bufSize != width || height != 1) { 272feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Incorrect pixelBuffer size: %lld", __FUNCTION__, bufSize); 273feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 274feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 275feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int8_t* img = NULL; 276feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 277feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get()); 278feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 279feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 280feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to lock buffer, error %s (%d).", __FUNCTION__, strerror(-err), 281feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err); 282feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 283feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 2845096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin struct camera3_jpeg_blob footer = { 2855096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin jpeg_blob_id: CAMERA3_JPEG_BLOB_ID, 2865096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin jpeg_size: (uint32_t)width 2875096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin }; 288feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk memcpy(img, pixelBuffer, width); 2895096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin memcpy(img + anb->width - sizeof(footer), &footer, sizeof(footer)); 290feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 291feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 292feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk default: { 293feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Invalid pixel format in produceFrame: %x", __FUNCTION__, pixelFmt); 294feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return BAD_VALUE; 295feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 296feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 297feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 298feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Unlock buffer from %p", __FUNCTION__, anw.get()); 299feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = buf->unlock(); 300feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 301feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to unlock buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 302feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 303feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 304feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 305feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("%s: Queue buffer to %p", __FUNCTION__, anw.get()); 306feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), /*fenceFd*/-1); 307feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 308feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Failed to queue buffer, error %s (%d).", __FUNCTION__, strerror(-err), err); 309feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return err; 310feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 311feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return NO_ERROR; 312feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 313feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 314feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) { 315feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 316feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (surface) { 317feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk anw = android_view_Surface_getNativeWindow(env, surface); 318feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (env->ExceptionCheck()) { 319feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 320feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 321feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 322feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "surface"); 323feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 324feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 325feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (anw == NULL) { 326feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 327feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "Surface had no valid native window."); 328feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 329feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 330feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return anw; 331feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 332feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 333feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkextern "C" { 334feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 335feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) { 336feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeDetectSurfaceType"); 337feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 338feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 339feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 340ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 341feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 342feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t fmt = 0; 343feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt); 344feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 345ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err), 346ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 347ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return fmt; 350feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 351feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 352ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, 353feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jobject surface, jintArray dimens) { 354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeGetSurfaceDimens"); 355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 358ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 359feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 360feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t dimenBuf[2]; 361feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); 362feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 363ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err), 364ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 365ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 366feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 367feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); 368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if(err != NO_ERROR) { 369ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err), 370ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk err); 371ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 373feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); 374ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 377ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, 378feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height, jint pixelFormat) { 379feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeConfigureSurface"); 380feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 381feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 382feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 383ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 384feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 385feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); 386feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 387ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); 388ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 389feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 390ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 391feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 392feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 393ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, 394feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) { 395feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeProduceFrame"); 396feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 397feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 398feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 399feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 400ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 401feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 402feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 403feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixelBuffer == NULL) { 404feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixelBuffer"); 405ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 406feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 407feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 408feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer)); 409feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL); 410feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 411feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (pixels == NULL) { 412feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jniThrowNullPointerException(env, "pixels"); 413ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return DONT_CARE; 414feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 415feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 416feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height, 417feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk pixelFormat, bufSize); 418feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT); 419feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 420feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 421ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err); 422ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 423feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 424ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 427ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, 428feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint pixelFormat) { 429feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceType"); 430feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 431feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 433ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 434feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 435feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_format(anw.get(), pixelFormat); 436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 437ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err); 438ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 440ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 442feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 443ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, 444feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk jint width, jint height) { 445feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGV("nativeSetSurfaceDimens"); 446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk sp<ANativeWindow> anw; 447feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if ((anw = getNativeWindow(env, surface)) == NULL) { 448feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); 449ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return BAD_VALUE; 450feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 451feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk status_t err = native_window_set_buffers_dimensions(anw.get(), width, height); 452feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (err != NO_ERROR) { 453ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk ALOGE("%s: Error while setting surface dimens %s (%d).", __FUNCTION__, strerror(-err), err); 454ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return err; 455feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 456ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk return NO_ERROR; 457feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 458feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 459feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} // extern "C" 460feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 461feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic JNINativeMethod gCameraDeviceMethods[] = { 462feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceType", 463feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "(Landroid/view/Surface;)I", 464feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceType }, 465feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeDetectSurfaceDimens", 466ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[I)I", 467feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, 468feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeConfigureSurface", 469ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;III)I", 470feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeConfigureSurface }, 471feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeProduceFrame", 472ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;[BIII)I", 473feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeProduceFrame }, 474feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceFormat", 475ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;I)I", 476feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceFormat }, 477feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk { "nativeSetSurfaceDimens", 478ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk "(Landroid/view/Surface;II)I", 479feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, 480feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}; 481feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 482feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// Get all the required offsets in java class and register native functions 483feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkint register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env) 484feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{ 485feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Register native functions 486feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return AndroidRuntime::registerNativeMethods(env, 487feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk CAMERA_DEVICE_CLASS_NAME, 488feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk gCameraDeviceMethods, 489feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk NELEM(gCameraDeviceMethods)); 490feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 492