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