FrameProcessorBase.cpp revision cb0652e5a850b2fcd919e977247e87239efaf70e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2013 The Android Open Source Project
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you may not use this file except in compliance with the License.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_TAG "Camera2-FrameProcessorBase"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ATRACE_TAG ATRACE_TAG_CAMERA
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//#define LOG_NDEBUG 0
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utils/Log.h>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utils/Trace.h>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "common/FrameProcessorBase.h"
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "common/CameraDeviceBase.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace android {
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace camera2 {
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FrameProcessorBase::FrameProcessorBase(wp<CameraDeviceBase> device) :
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Thread(/*canCallJava*/false),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mDevice(device) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochFrameProcessorBase::~FrameProcessorBase() {
36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ALOGV("%s: Exit", __FUNCTION__);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t FrameProcessorBase::registerListener(int32_t minId,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int32_t maxId, wp<FilteredListener> listener, bool quirkSendPartials) {
41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    Mutex::Autolock l(mInputMutex);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ALOGV("%s: Registering listener for frame id range %d - %d",
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            __FUNCTION__, minId, maxId);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RangeListener rListener = { minId, maxId, listener, quirkSendPartials };
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mRangeListeners.push_back(rListener);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t FrameProcessorBase::removeListener(int32_t minId,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int32_t maxId,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           wp<FilteredListener> listener) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Mutex::Autolock l(mInputMutex);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    List<RangeListener>::iterator item = mRangeListeners.begin();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (item != mRangeListeners.end()) {
55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        if (item->minId == minId &&
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                item->maxId == maxId &&
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                item->listener == listener) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            item = mRangeListeners.erase(item);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            item++;
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) {
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    String8 result("    Latest received frame:\n");
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    write(fd, result.string(), result.size());
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CameraMetadata lastFrame;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Don't race while dumping metadata
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        Mutex::Autolock al(mLastFrameMutex);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lastFrame = CameraMetadata(mLastFrame);
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    lastFrame.dump(fd, 2, 6);
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool FrameProcessorBase::threadLoop() {
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    status_t res;
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    sp<CameraDeviceBase> device;
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device = mDevice.promote();
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (device == 0) return false;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    res = device->waitForNextFrame(kWaitDuration);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (res == OK) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        processNewFrames(device);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (res != TIMED_OUT) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ALOGE("FrameProcessorBase: Error waiting for new "
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "frames: %s (%d)", strerror(-res), res);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_t res;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ATRACE_CALL();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureResult result;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId());
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ( (res = device->getNextResult(&result)) == OK) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        // TODO: instead of getting frame number from metadata, we should read
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        // this from result.mResultExtras when CameraDeviceBase interface is fixed.
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        camera_metadata_entry_t entry;
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if (entry.count == 0) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ALOGE("%s: Camera %d: Error reading frame number",
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __FUNCTION__, device->getId());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ATRACE_INT("cam2_frame", entry.data.i32[0]);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!processSingleFrame(result, device)) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!result.mMetadata.isEmpty()) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Mutex::Autolock al(mLastFrameMutex);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mLastFrame.acquire(result.mMetadata);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (res != NOT_ENOUGH_DATA) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                __FUNCTION__, device->getId(), strerror(-res), res);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool FrameProcessorBase::processSingleFrame(CaptureResult &result,
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            const sp<CameraDeviceBase> &device) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ALOGV("%s: Camera %d: Process single frame (is empty? %d)",
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          __FUNCTION__, device->getId(), result.mMetadata.isEmpty());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return processListeners(result, device) == OK;
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t FrameProcessorBase::processListeners(const CaptureResult &result,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const sp<CameraDeviceBase> &device) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ATRACE_CALL();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    camera_metadata_ro_entry_t entry;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Quirks: Don't deliver partial results to listeners that don't want them
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool quirkIsPartial = false;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry = result.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry.count != 0 &&
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ALOGV("%s: Camera %d: Not forwarding partial result to listeners",
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                __FUNCTION__, device->getId());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        quirkIsPartial = true;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO: instead of getting requestID from CameraMetadata, we should get it
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // from CaptureResultExtras. This will require changing Camera2Device.
163    // Currently Camera2Device uses MetadataQueue to store results, which does not
164    // include CaptureResultExtras.
165    entry = result.mMetadata.find(ANDROID_REQUEST_ID);
166    if (entry.count == 0) {
167        ALOGE("%s: Camera %d: Error reading frame id", __FUNCTION__, device->getId());
168        return BAD_VALUE;
169    }
170    int32_t requestId = entry.data.i32[0];
171
172    List<sp<FilteredListener> > listeners;
173    {
174        Mutex::Autolock l(mInputMutex);
175
176        List<RangeListener>::iterator item = mRangeListeners.begin();
177        while (item != mRangeListeners.end()) {
178            if (requestId >= item->minId && requestId < item->maxId &&
179                    (!quirkIsPartial || item->quirkSendPartials)) {
180                sp<FilteredListener> listener = item->listener.promote();
181                if (listener == 0) {
182                    item = mRangeListeners.erase(item);
183                    continue;
184                } else {
185                    listeners.push_back(listener);
186                }
187            }
188            item++;
189        }
190    }
191    ALOGV("%s: Camera %d: Got %zu range listeners out of %zu", __FUNCTION__,
192          device->getId(), listeners.size(), mRangeListeners.size());
193
194    List<sp<FilteredListener> >::iterator item = listeners.begin();
195    for (; item != listeners.end(); item++) {
196        (*item)->onResultAvailable(result);
197    }
198    return OK;
199}
200
201}; // namespace camera2
202}; // namespace android
203