FrameProcessorBase.cpp revision fd6ecdd39bd83ea020f78b425e96310380d66c35
1418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin/* 2418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * Copyright (C) 2013 The Android Open Source Project 3418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * 4418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 5418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * you may not use this file except in compliance with the License. 6418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * You may obtain a copy of the License at 7418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * 8418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 9418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * 10418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * Unless required by applicable law or agreed to in writing, software 11418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 12418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * See the License for the specific language governing permissions and 14418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin * limitations under the License. 15418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin */ 16418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 177b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#define LOG_TAG "Camera2-FrameProcessorBase" 18418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin#define ATRACE_TAG ATRACE_TAG_CAMERA 19418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin//#define LOG_NDEBUG 0 20418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 21418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin#include <utils/Log.h> 22418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin#include <utils/Trace.h> 23418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 247b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/FrameProcessorBase.h" 257b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/CameraDeviceBase.h" 26418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 27418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinnamespace android { 28418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinnamespace camera2 { 29418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 307b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville TalvalaFrameProcessorBase::FrameProcessorBase(wp<CameraDeviceBase> device) : 3171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin Thread(/*canCallJava*/false), 3271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin mDevice(device) { 33418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 34418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 357b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville TalvalaFrameProcessorBase::~FrameProcessorBase() { 36418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGV("%s: Exit", __FUNCTION__); 37418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 38418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 397b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalastatus_t FrameProcessorBase::registerListener(int32_t minId, 40418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin int32_t maxId, wp<FilteredListener> listener) { 41418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 42418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGV("%s: Registering listener for frame id range %d - %d", 43418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin __FUNCTION__, minId, maxId); 44418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin RangeListener rListener = { minId, maxId, listener }; 45418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin mRangeListeners.push_back(rListener); 46418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return OK; 47418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 48418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 497b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalastatus_t FrameProcessorBase::removeListener(int32_t minId, 5071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin int32_t maxId, 5171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin wp<FilteredListener> listener) { 52418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 53418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<RangeListener>::iterator item = mRangeListeners.begin(); 54418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin while (item != mRangeListeners.end()) { 55418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (item->minId == minId && 56418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item->maxId == maxId && 57418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item->listener == listener) { 58418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item = mRangeListeners.erase(item); 59418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } else { 60418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item++; 61418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 62418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 63418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return OK; 64418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 65418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 667b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalavoid FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) { 67418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin String8 result(" Latest received frame:\n"); 68418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin write(fd, result.string(), result.size()); 69215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin 70215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin CameraMetadata lastFrame; 71215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin { 72215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin // Don't race while dumping metadata 73215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin Mutex::Autolock al(mLastFrameMutex); 74215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin lastFrame = CameraMetadata(mLastFrame); 75215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin } 76215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin lastFrame.dump(fd, 2, 6); 77418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 78418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 797b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalabool FrameProcessorBase::threadLoop() { 80418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin status_t res; 81418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 82a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin sp<CameraDeviceBase> device; 83418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin { 8471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin device = mDevice.promote(); 85418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (device == 0) return false; 86418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 87418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 88418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin res = device->waitForNextFrame(kWaitDuration); 89418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (res == OK) { 9071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin processNewFrames(device); 91418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } else if (res != TIMED_OUT) { 927b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala ALOGE("FrameProcessorBase: Error waiting for new " 93418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin "frames: %s (%d)", strerror(-res), res); 94418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 95418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 96418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return true; 97418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 98418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 997b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalavoid FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) { 100418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin status_t res; 101418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_CALL(); 102418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin CameraMetadata frame; 1034345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin 1044345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId()); 1054345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin 10671381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin while ( (res = device->getNextFrame(&frame)) == OK) { 10771381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin 108418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin camera_metadata_entry_t entry; 109418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 110418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); 111418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (entry.count == 0) { 112418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGE("%s: Camera %d: Error reading frame number", 11371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin __FUNCTION__, device->getId()); 114418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin break; 115418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 116418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_INT("cam2_frame", entry.data.i32[0]); 117418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 11871381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin if (!processSingleFrame(frame, device)) { 11971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin break; 12071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin } 121418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 122418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (!frame.isEmpty()) { 123215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin Mutex::Autolock al(mLastFrameMutex); 124418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin mLastFrame.acquire(frame); 125418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 126418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 127418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (res != NOT_ENOUGH_DATA) { 128418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGE("%s: Camera %d: Error getting next frame: %s (%d)", 12971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin __FUNCTION__, device->getId(), strerror(-res), res); 130418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return; 131418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 132418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 133418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return; 134418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 135418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 1367b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalabool FrameProcessorBase::processSingleFrame(CameraMetadata &frame, 13771381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin const sp<CameraDeviceBase> &device) { 1384345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin ALOGV("%s: Camera %d: Process single frame (is empty? %d)", 1394345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin __FUNCTION__, device->getId(), frame.isEmpty()); 14071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin return processListeners(frame, device) == OK; 14171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin} 14271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin 1437b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalastatus_t FrameProcessorBase::processListeners(const CameraMetadata &frame, 14471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin const sp<CameraDeviceBase> &device) { 145418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_CALL(); 146418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin camera_metadata_ro_entry_t entry; 147418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 148fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala // Quirks: Don't deliver partial results to listeners 149fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT); 150fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala if (entry.count != 0 && 151fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { 152fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala ALOGV("%s: Camera %d: Not forwarding partial result to listeners", 153fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala __FUNCTION__, device->getId()); 154fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala return OK; 155fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala } 156fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala 157418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin entry = frame.find(ANDROID_REQUEST_ID); 158418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (entry.count == 0) { 159418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGE("%s: Camera %d: Error reading frame id", 16071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin __FUNCTION__, device->getId()); 161418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return BAD_VALUE; 162418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 16311d0d44d583f679638cc927bfffe920e495e90ccZhijun He int32_t requestId = entry.data.i32[0]; 164418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 165418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<sp<FilteredListener> > listeners; 166418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin { 167418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 168418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 169418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<RangeListener>::iterator item = mRangeListeners.begin(); 170418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin while (item != mRangeListeners.end()) { 17111d0d44d583f679638cc927bfffe920e495e90ccZhijun He if (requestId >= item->minId && 17211d0d44d583f679638cc927bfffe920e495e90ccZhijun He requestId < item->maxId) { 173418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin sp<FilteredListener> listener = item->listener.promote(); 174418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (listener == 0) { 175418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item = mRangeListeners.erase(item); 176418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin continue; 177418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } else { 178418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin listeners.push_back(listener); 179418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 180418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 181418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item++; 182418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 183418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 184418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size()); 185418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<sp<FilteredListener> >::iterator item = listeners.begin(); 186418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin for (; item != listeners.end(); item++) { 18711d0d44d583f679638cc927bfffe920e495e90ccZhijun He (*item)->onFrameAvailable(requestId, frame); 188418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 189418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return OK; 190418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 191418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 192418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace camera2 193418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace android 194