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