CallbackProcessor.cpp revision 1a2952aee048ca7b1765e2bc09ebe9aeddaeafa3
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"
251a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.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"));
681a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        mCallbackWindow = new Surface(
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
123d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
124d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
125d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId != NO_STREAM) {
126d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
127d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (client == 0) return OK;
128d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Device> device = client->getCameraDevice();
129d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
130d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        device->deleteStream(mCallbackStreamId);
131cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
132cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackHeap.clear();
133cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackWindow.clear();
134cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackConsumer.clear();
135cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
136d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId = NO_STREAM;
137d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
138d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
139d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
140d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
141d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalaint CallbackProcessor::getStreamId() const {
142d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
143d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return mCallbackStreamId;
144d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
145d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
146ddf3c5025e2f6f35a4c188c19f30142c64a092c4Igor Murashkinvoid CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
147d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
148d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
149d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalabool CallbackProcessor::threadLoop() {
150d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
151d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
152d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
153d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
154d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        while (!mCallbackAvailable) {
155d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = mCallbackAvailableSignal.waitRelative(mInputMutex,
156d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    kWaitDuration);
157d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res == TIMED_OUT) return true;
158d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
159d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = false;
160d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
161d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
162d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    do {
163d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
164d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (client == 0) return false;
165d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = processNewCallback(client);
166d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    } while (res == OK);
167d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
168d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return true;
169d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
170d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
171d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
172d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
173d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
174d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
175d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Heap> callbackHeap;
176d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t heapIdx;
177d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
178d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    CpuConsumer::LockedBuffer imgBuffer;
179d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Getting buffer", __FUNCTION__);
180d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
181d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (res != OK) {
182d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != BAD_VALUE) {
183d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
184d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res);
185d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
186d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        return res;
187d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
188d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
189d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            client->getCameraId());
190d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
191d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
192d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
193d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
194d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ( l.mParameters.state != Parameters::PREVIEW
195d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::RECORD
196d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
197d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: No longer streaming",
198d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    __FUNCTION__, client->getCameraId());
199d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
200d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
201d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
202d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
203d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (! (l.mParameters.previewCallbackFlags &
204d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
205d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
206d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
207d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
208d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
209d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ((l.mParameters.previewCallbackFlags &
210d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
211d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                !l.mParameters.previewCallbackOneShot) {
212d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
213d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
214d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
215d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
216d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
217d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (imgBuffer.format != l.mParameters.previewFormat) {
218d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unexpected format for callback: "
219d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    "%x, expected %x", __FUNCTION__, client->getCameraId(),
220d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    imgBuffer.format, l.mParameters.previewFormat);
221d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
222d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
223d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
224d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
225d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // In one-shot mode, stop sending callbacks after the first one
226d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mParameters.previewCallbackFlags &
227d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
228d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: clearing oneshot", __FUNCTION__);
229d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mParameters.previewCallbackOneShot = false;
230d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
231d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
232d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
233d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t bufferSize = Camera2Client::calculateBufferSize(
234d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            imgBuffer.width, imgBuffer.height,
235d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            imgBuffer.format, imgBuffer.stride);
236d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t currentBufferSize = (mCallbackHeap == 0) ?
237d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
238d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (bufferSize != currentBufferSize) {
239d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeap.clear();
240d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
241d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                "Camera2Client::CallbackHeap");
242d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (mCallbackHeap->mHeap->getSize() == 0) {
243d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
244d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    __FUNCTION__, client->getCameraId());
245d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
246d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
247d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
248d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
249d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeapHead = 0;
250d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeapFree = kCallbackHeapCount;
251d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
252d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
253d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackHeapFree == 0) {
254d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
255d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                __FUNCTION__, client->getCameraId());
256d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->unlockBuffer(imgBuffer);
257d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        return OK;
258d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
259d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
260d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    heapIdx = mCallbackHeapHead;
261d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
262d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
263d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree--;
264d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
265d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // TODO: Get rid of this memcpy by passing the gralloc queue all the way
266d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // to app
267d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
268d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ssize_t offset;
269d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t size;
270d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<IMemoryHeap> heap =
271d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
272d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    &size);
273d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    uint8_t *data = (uint8_t*)heap->getBase() + offset;
274d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    memcpy(data, imgBuffer.data, bufferSize);
275d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
276d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Freeing buffer", __FUNCTION__);
277d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackConsumer->unlockBuffer(imgBuffer);
278d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
279d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Call outside parameter lock to allow re-entrancy from notification
280d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
281d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
282d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mCameraClient != 0) {
283d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: Invoking client data callback",
284d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    __FUNCTION__, client->getCameraId());
285d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
286d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    mCallbackHeap->mBuffers[heapIdx], NULL);
287d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
288d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
289d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
290d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Only increment free if we're still using the same heap
291d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree++;
292d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
293d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: exit", __FUNCTION__);
294d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
295d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
296d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
297d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
298d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace camera2
299d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace android
300