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