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), 32204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He mDevice(device), 33204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He mNumPartialResults(1) { 34204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He sp<CameraDeviceBase> cameraDevice = device.promote(); 3508dd245c7c30900637197065213fbaa2b2a5c1eeEmilian Peev if (cameraDevice != 0) { 36204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He CameraMetadata staticInfo = cameraDevice->info(); 37204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT); 38204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He if (entry.count > 0) { 39204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He mNumPartialResults = entry.data.i32[0]; 40204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He } 41204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He } 42418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 43418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 447b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville TalvalaFrameProcessorBase::~FrameProcessorBase() { 45418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGV("%s: Exit", __FUNCTION__); 46418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 47418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 487b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalastatus_t FrameProcessorBase::registerListener(int32_t minId, 498b0b971b1416738f22488a80be726d1ec12552a8Chih-Hung Hsieh int32_t maxId, const wp<FilteredListener>& listener, bool sendPartials) { 50418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 51954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra List<RangeListener>::iterator item = mRangeListeners.begin(); 52954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra while (item != mRangeListeners.end()) { 53954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra if (item->minId == minId && 54954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra item->maxId == maxId && 55954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra item->listener == listener) { 56954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra // already registered, just return 57954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra ALOGV("%s: Attempt to register the same client twice, ignoring", 58954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra __FUNCTION__); 59954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra return OK; 60954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra } 61954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra item++; 62954d248e02e19f8ecd165804b7d063d346154f4cGaurav Batra } 63418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ALOGV("%s: Registering listener for frame id range %d - %d", 64418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin __FUNCTION__, minId, maxId); 6525a0aef19e170d2695f64b4c48296e7914155a88Zhijun He RangeListener rListener = { minId, maxId, listener, sendPartials }; 66418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin mRangeListeners.push_back(rListener); 67418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return OK; 68418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 69418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 707b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalastatus_t FrameProcessorBase::removeListener(int32_t minId, 7171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin int32_t maxId, 728b0b971b1416738f22488a80be726d1ec12552a8Chih-Hung Hsieh const wp<FilteredListener>& listener) { 73418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 74418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<RangeListener>::iterator item = mRangeListeners.begin(); 75418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin while (item != mRangeListeners.end()) { 76418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (item->minId == minId && 77418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item->maxId == maxId && 78418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item->listener == listener) { 79418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item = mRangeListeners.erase(item); 80418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } else { 81418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item++; 82418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 83418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 84418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return OK; 85418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 86418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 877b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalavoid FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) { 88418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin String8 result(" Latest received frame:\n"); 89418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin write(fd, result.string(), result.size()); 90215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin 91215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin CameraMetadata lastFrame; 92215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin { 93215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin // Don't race while dumping metadata 94215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin Mutex::Autolock al(mLastFrameMutex); 95215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin lastFrame = CameraMetadata(mLastFrame); 96215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin } 97215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin lastFrame.dump(fd, 2, 6); 98418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 99418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 1007b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalabool FrameProcessorBase::threadLoop() { 101418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin status_t res; 102418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 103a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin sp<CameraDeviceBase> device; 104418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin { 10571381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin device = mDevice.promote(); 106418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (device == 0) return false; 107418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 108418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 109418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin res = device->waitForNextFrame(kWaitDuration); 110418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (res == OK) { 11171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin processNewFrames(device); 112418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } else if (res != TIMED_OUT) { 1137b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala ALOGE("FrameProcessorBase: Error waiting for new " 114418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin "frames: %s (%d)", strerror(-res), res); 115418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 116418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 117418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return true; 118418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 119418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 1207b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvalavoid FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) { 121418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin status_t res; 122418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_CALL(); 123cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei CaptureResult result; 1244345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin 1250b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala ALOGV("%s: Camera %s: Process new frames", __FUNCTION__, device->getId().string()); 1264345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin 127cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei while ( (res = device->getNextResult(&result)) == OK) { 12871381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin 129cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // TODO: instead of getting frame number from metadata, we should read 130cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // this from result.mResultExtras when CameraDeviceBase interface is fixed. 131418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin camera_metadata_entry_t entry; 132418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 133cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT); 134418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (entry.count == 0) { 1350b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala ALOGE("%s: Camera %s: Error reading frame number", 1360b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala __FUNCTION__, device->getId().string()); 137418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin break; 138418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 139418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_INT("cam2_frame", entry.data.i32[0]); 140418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 141cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei if (!processSingleFrame(result, device)) { 14271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin break; 14371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin } 144418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 145cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei if (!result.mMetadata.isEmpty()) { 146215bb3499c7eeea6303e55fac66452f2574c022aIgor Murashkin Mutex::Autolock al(mLastFrameMutex); 147cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei mLastFrame.acquire(result.mMetadata); 148418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 149418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 150418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (res != NOT_ENOUGH_DATA) { 1510b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala ALOGE("%s: Camera %s: Error getting next frame: %s (%d)", 1520b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala __FUNCTION__, device->getId().string(), strerror(-res), res); 153418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return; 154418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 155418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 156418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return; 157418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 158418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 159cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weibool FrameProcessorBase::processSingleFrame(CaptureResult &result, 160cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei const sp<CameraDeviceBase> &device) { 1610b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala ALOGV("%s: Camera %s: Process single frame (is empty? %d)", 1620b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala __FUNCTION__, device->getId().string(), result.mMetadata.isEmpty()); 163cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei return processListeners(result, device) == OK; 16471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin} 16571381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin 166cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t FrameProcessorBase::processListeners(const CaptureResult &result, 16771381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin const sp<CameraDeviceBase> &device) { 168418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin ATRACE_CALL(); 169cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei 170418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin camera_metadata_ro_entry_t entry; 171418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 172204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He // Check if this result is partial. 17308dd245c7c30900637197065213fbaa2b2a5c1eeEmilian Peev bool isPartialResult = 17408dd245c7c30900637197065213fbaa2b2a5c1eeEmilian Peev result.mResultExtras.partialResultCount < mNumPartialResults; 175fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala 176cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // TODO: instead of getting requestID from CameraMetadata, we should get it 177cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // from CaptureResultExtras. This will require changing Camera2Device. 178cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // Currently Camera2Device uses MetadataQueue to store results, which does not 179cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei // include CaptureResultExtras. 180cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei entry = result.mMetadata.find(ANDROID_REQUEST_ID); 181418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (entry.count == 0) { 1820b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala ALOGE("%s: Camera %s: Error reading frame id", __FUNCTION__, device->getId().string()); 183418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return BAD_VALUE; 184418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 18511d0d44d583f679638cc927bfffe920e495e90ccZhijun He int32_t requestId = entry.data.i32[0]; 186418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 187418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<sp<FilteredListener> > listeners; 188418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin { 189418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin Mutex::Autolock l(mInputMutex); 190418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 191418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<RangeListener>::iterator item = mRangeListeners.begin(); 192204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He // Don't deliver partial results to listeners that don't want them 193418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin while (item != mRangeListeners.end()) { 194cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei if (requestId >= item->minId && requestId < item->maxId && 195204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He (!isPartialResult || item->sendPartials)) { 196418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin sp<FilteredListener> listener = item->listener.promote(); 197418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin if (listener == 0) { 198418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item = mRangeListeners.erase(item); 199418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin continue; 200418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } else { 201418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin listeners.push_back(listener); 202418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 203418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 204418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin item++; 205418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 206418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 2070b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala ALOGV("%s: Camera %s: Got %zu range listeners out of %zu", __FUNCTION__, 2080b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala device->getId().string(), listeners.size(), mRangeListeners.size()); 209cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei 210418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin List<sp<FilteredListener> >::iterator item = listeners.begin(); 211418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin for (; item != listeners.end(); item++) { 212cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei (*item)->onResultAvailable(result); 213418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin } 214418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin return OK; 215418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin} 216418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin 217418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace camera2 218418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace android 219