1d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala/*
2d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
3d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *
4d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * you may not use this file except in compliance with the License.
6d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * You may obtain a copy of the License at
7d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *
8d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *
10d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * See the License for the specific language governing permissions and
14d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * limitations under the License.
15d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala */
16d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
174bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala#define LOG_TAG "Camera2-CallbackProcessor"
18d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
19d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala//#define LOG_NDEBUG 0
20d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
21d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include <utils/Log.h>
22d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include <utils/Trace.h>
23d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
24d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include "CallbackProcessor.h"
25d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include <gui/SurfaceTextureClient.h>
26d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include "../Camera2Device.h"
27d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include "../Camera2Client.h"
28d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
29d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
30d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalanamespace android {
31d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalanamespace camera2 {
32d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
33d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville TalvalaCallbackProcessor::CallbackProcessor(wp<Camera2Client> client):
34d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Thread(false),
35d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mClient(client),
36d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable(false),
37d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId(NO_STREAM) {
38d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
39d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
40d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville TalvalaCallbackProcessor::~CallbackProcessor() {
41d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Exit", __FUNCTION__);
42cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala    deleteStream();
43d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
44d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
45d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalavoid CallbackProcessor::onFrameAvailable() {
46d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
47d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (!mCallbackAvailable) {
48d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = true;
49d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailableSignal.signal();
50d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
51d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
52d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
53d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::updateStream(const Parameters &params) {
54d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
55d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
56d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
57d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
58d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
59d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
60d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (client == 0) return OK;
61d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Device> device = client->getCameraDevice();
62d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
63d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackConsumer == 0) {
64d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // Create CPU buffer queue endpoint
65d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
66d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->setFrameAvailableListener(this);
67d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
68d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackWindow = new SurfaceTextureClient(
69d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->getProducerInterface());
70d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
71d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
72d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId != NO_STREAM) {
73d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // Check if stream parameters have to change
74d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        uint32_t currentWidth, currentHeight, currentFormat;
75d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->getStreamInfo(mCallbackStreamId,
76d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                &currentWidth, &currentHeight, &currentFormat);
77d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
78d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error querying callback output stream info: "
79d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(),
80d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
81d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
82d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
83d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (currentWidth != (uint32_t)params.previewWidth ||
84d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                currentHeight != (uint32_t)params.previewHeight ||
85d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                currentFormat != (uint32_t)params.previewFormat) {
86d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // Since size should only change while preview is not running,
87d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // assuming that all existing use of old callback stream is
88d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // completed.
89ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
90ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin                __FUNCTION__, client->getCameraId(), mCallbackStreamId);
91d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = device->deleteStream(mCallbackStreamId);
92d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res != OK) {
93d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
94d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        "for callbacks: %s (%d)", __FUNCTION__, client->getCameraId(),
95d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        strerror(-res), res);
96d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                return res;
97d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            }
98d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackStreamId = NO_STREAM;
99d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
100d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
101d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
102d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId == NO_STREAM) {
103d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        ALOGV("Creating callback stream: %d %d format 0x%x",
104d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
105d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewFormat);
106d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->createStream(mCallbackWindow,
107d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
108d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewFormat, 0, &mCallbackStreamId);
109d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
110d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
111d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(),
112d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
113d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
114d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
115d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
116d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
117d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
118d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
119d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
120d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::deleteStream() {
121d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
122d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
123d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
124d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
125d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
126d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId != NO_STREAM) {
127d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
128d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (client == 0) return OK;
129d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Device> device = client->getCameraDevice();
130d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
131d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        device->deleteStream(mCallbackStreamId);
132cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
133cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackHeap.clear();
134cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackWindow.clear();
135cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackConsumer.clear();
136cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
137d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId = NO_STREAM;
138d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
139d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
140d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
141d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
142d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalaint CallbackProcessor::getStreamId() const {
143d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
144d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return mCallbackStreamId;
145d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
146d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
147da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalavoid CallbackProcessor::dump(int fd, const Vector<String16>& args) const {
148d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
149d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
150d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalabool CallbackProcessor::threadLoop() {
151d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
152d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
153d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
154d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
155d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        while (!mCallbackAvailable) {
156d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = mCallbackAvailableSignal.waitRelative(mInputMutex,
157d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    kWaitDuration);
158d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res == TIMED_OUT) return true;
159d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
160d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = false;
161d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
162d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
163d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    do {
164d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
165d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (client == 0) return false;
166d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = processNewCallback(client);
167d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    } while (res == OK);
168d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
169d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return true;
170d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
171d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
172d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
173d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
174d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
175d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
176d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    int callbackHeapId;
177d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Heap> callbackHeap;
178d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t heapIdx;
179d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
180d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    CpuConsumer::LockedBuffer imgBuffer;
181d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Getting buffer", __FUNCTION__);
182d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
183d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (res != OK) {
184d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != BAD_VALUE) {
185d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
186d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res);
187d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
188d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        return res;
189d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
190d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
191d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            client->getCameraId());
192d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
193d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
194d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
195d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
196d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ( l.mParameters.state != Parameters::PREVIEW
197d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::RECORD
198d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
199d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: No longer streaming",
200d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    __FUNCTION__, client->getCameraId());
201d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
202d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
203d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
204d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
205d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (! (l.mParameters.previewCallbackFlags &
206d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
207d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
208d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
209d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
210d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
211d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ((l.mParameters.previewCallbackFlags &
212d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
213d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                !l.mParameters.previewCallbackOneShot) {
214d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
215d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
216d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
217d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
218d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
219d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (imgBuffer.format != l.mParameters.previewFormat) {
220d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unexpected format for callback: "
221d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    "%x, expected %x", __FUNCTION__, client->getCameraId(),
222d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    imgBuffer.format, l.mParameters.previewFormat);
223d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
224d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
225d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
226d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
227d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // In one-shot mode, stop sending callbacks after the first one
228d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mParameters.previewCallbackFlags &
229d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
230d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: clearing oneshot", __FUNCTION__);
231d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mParameters.previewCallbackOneShot = false;
232d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
233d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
234d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
235d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t bufferSize = Camera2Client::calculateBufferSize(
236d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            imgBuffer.width, imgBuffer.height,
237d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            imgBuffer.format, imgBuffer.stride);
238d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t currentBufferSize = (mCallbackHeap == 0) ?
239d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
240d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (bufferSize != currentBufferSize) {
241d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeap.clear();
242d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
243d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                "Camera2Client::CallbackHeap");
244d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (mCallbackHeap->mHeap->getSize() == 0) {
245d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
246d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    __FUNCTION__, client->getCameraId());
247d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
248d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
249d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
250d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
251d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeapHead = 0;
252d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeapFree = kCallbackHeapCount;
253d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
254d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
255d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackHeapFree == 0) {
256d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
257d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                __FUNCTION__, client->getCameraId());
258d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->unlockBuffer(imgBuffer);
259d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        return OK;
260d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
261d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
262d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    heapIdx = mCallbackHeapHead;
263d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
264d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
265d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree--;
266d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
267d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // TODO: Get rid of this memcpy by passing the gralloc queue all the way
268d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // to app
269d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
270d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ssize_t offset;
271d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t size;
272d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<IMemoryHeap> heap =
273d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
274d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    &size);
275d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    uint8_t *data = (uint8_t*)heap->getBase() + offset;
276d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    memcpy(data, imgBuffer.data, bufferSize);
277d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
278d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Freeing buffer", __FUNCTION__);
279d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackConsumer->unlockBuffer(imgBuffer);
280d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
281d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Call outside parameter lock to allow re-entrancy from notification
282d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
283d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
284d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mCameraClient != 0) {
285d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: Invoking client data callback",
286d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    __FUNCTION__, client->getCameraId());
287d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
288d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    mCallbackHeap->mBuffers[heapIdx], NULL);
289d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
290d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
291d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
292d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Only increment free if we're still using the same heap
293d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree++;
294d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
295d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: exit", __FUNCTION__);
296d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
297d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
298d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
299d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
300d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace camera2
301d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace android
302