FrameProcessorBase.cpp revision 25a0aef19e170d2695f64b4c48296e7914155a88
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, 4025a0aef19e170d2695f64b4c48296e7914155a88Zhijun He int32_t maxId, wp<FilteredListener> listener, bool sendPartials) { 41418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 42418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGV("%s: Registering listener for frame id range %d - %d", 43418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin __FUNCTION__, minId, maxId); 4425a0aef19e170d2695f64b4c48296e7914155a88Zhijun He RangeListener rListener = { minId, maxId, listener, sendPartials }; 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(); 102cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei CaptureResult result; 1034345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin 1044345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId()); 1054345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin 106cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei while ( (res = device->getNextResult(&result)) == OK) { 10771381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin 108cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // TODO: instead of getting frame number from metadata, we should read 109cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // this from result.mResultExtras when CameraDeviceBase interface is fixed. 110418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin camera_metadata_entry_t entry; 111418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 112cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT); 113418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (entry.count == 0) { 114418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGE("%s: Camera %d: Error reading frame number", 11571381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin __FUNCTION__, device->getId()); 116418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin break; 117418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 118418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_INT("cam2_frame", entry.data.i32[0]); 119418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 120cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei if (!processSingleFrame(result, device)) { 12171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin break; 12271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin } 123418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 124cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei if (!result.mMetadata.isEmpty()) { 125215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin Mutex::Autolock al(mLastFrameMutex); 126cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei mLastFrame.acquire(result.mMetadata); 127418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 128418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 129418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (res != NOT_ENOUGH_DATA) { 130418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGE("%s: Camera %d: Error getting next frame: %s (%d)", 13171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin __FUNCTION__, device->getId(), strerror(-res), res); 132418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return; 133418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 134418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 135418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return; 136418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 137418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 138cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weibool FrameProcessorBase::processSingleFrame(CaptureResult &result, 139cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei const sp<CameraDeviceBase> &device) { 1404345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin ALOGV("%s: Camera %d: Process single frame (is empty? %d)", 141cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei __FUNCTION__, device->getId(), result.mMetadata.isEmpty()); 142cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei return processListeners(result, device) == OK; 14371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin} 14471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin 145cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t FrameProcessorBase::processListeners(const CaptureResult &result, 14671381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin const sp<CameraDeviceBase> &device) { 147418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_CALL(); 148cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei 149418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin camera_metadata_ro_entry_t entry; 150418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 151184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala // Quirks: Don't deliver partial results to listeners that don't want them 152184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala bool quirkIsPartial = false; 153cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei entry = result.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT); 154fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala if (entry.count != 0 && 155fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { 156fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala ALOGV("%s: Camera %d: Not forwarding partial result to listeners", 157fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala __FUNCTION__, device->getId()); 158184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala quirkIsPartial = true; 159fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala } 160fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala 161cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // TODO: instead of getting requestID from CameraMetadata, we should get it 162cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // from CaptureResultExtras. This will require changing Camera2Device. 163cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // Currently Camera2Device uses MetadataQueue to store results, which does not 164cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // include CaptureResultExtras. 165cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei entry = result.mMetadata.find(ANDROID_REQUEST_ID); 166418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (entry.count == 0) { 167cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei ALOGE("%s: Camera %d: Error reading frame id", __FUNCTION__, device->getId()); 168418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return BAD_VALUE; 169418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 17011d0d44d583f679638cc927bfffe920e495e90ccZhijun He int32_t requestId = entry.data.i32[0]; 171418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 172418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<sp<FilteredListener> > listeners; 173418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin { 174418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 175418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 176418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<RangeListener>::iterator item = mRangeListeners.begin(); 177418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin while (item != mRangeListeners.end()) { 178cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei if (requestId >= item->minId && requestId < item->maxId && 17925a0aef19e170d2695f64b4c48296e7914155a88Zhijun He (!quirkIsPartial || item->sendPartials)) { 180418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin sp<FilteredListener> listener = item->listener.promote(); 181418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (listener == 0) { 182418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item = mRangeListeners.erase(item); 183418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin continue; 184418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } else { 185418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin listeners.push_back(listener); 186418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 187418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 188418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item++; 189418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 190418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 191cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei ALOGV("%s: Camera %d: Got %zu range listeners out of %zu", __FUNCTION__, 192cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei device->getId(), listeners.size(), mRangeListeners.size()); 193cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei 194418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<sp<FilteredListener> >::iterator item = listeners.begin(); 195418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin for (; item != listeners.end(); item++) { 196cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei (*item)->onResultAvailable(result); 197418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 198418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return OK; 199418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 200418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 201418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace camera2 202418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace android 203