FrameProcessorBase.cpp revision 7b82efe7a376c882f8f938e1c41b8311a8cdda4a
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Camera2-FrameProcessorBase" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20 21#include <utils/Log.h> 22#include <utils/Trace.h> 23 24#include "common/FrameProcessorBase.h" 25#include "common/CameraDeviceBase.h" 26 27namespace android { 28namespace camera2 { 29 30FrameProcessorBase::FrameProcessorBase(wp<CameraDeviceBase> device) : 31 Thread(/*canCallJava*/false), 32 mDevice(device) { 33} 34 35FrameProcessorBase::~FrameProcessorBase() { 36 ALOGV("%s: Exit", __FUNCTION__); 37} 38 39status_t FrameProcessorBase::registerListener(int32_t minId, 40 int32_t maxId, wp<FilteredListener> listener) { 41 Mutex::Autolock l(mInputMutex); 42 ALOGV("%s: Registering listener for frame id range %d - %d", 43 __FUNCTION__, minId, maxId); 44 RangeListener rListener = { minId, maxId, listener }; 45 mRangeListeners.push_back(rListener); 46 return OK; 47} 48 49status_t FrameProcessorBase::removeListener(int32_t minId, 50 int32_t maxId, 51 wp<FilteredListener> listener) { 52 Mutex::Autolock l(mInputMutex); 53 List<RangeListener>::iterator item = mRangeListeners.begin(); 54 while (item != mRangeListeners.end()) { 55 if (item->minId == minId && 56 item->maxId == maxId && 57 item->listener == listener) { 58 item = mRangeListeners.erase(item); 59 } else { 60 item++; 61 } 62 } 63 return OK; 64} 65 66void FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) { 67 String8 result(" Latest received frame:\n"); 68 write(fd, result.string(), result.size()); 69 mLastFrame.dump(fd, 2, 6); 70} 71 72bool FrameProcessorBase::threadLoop() { 73 status_t res; 74 75 sp<CameraDeviceBase> device; 76 { 77 device = mDevice.promote(); 78 if (device == 0) return false; 79 } 80 81 res = device->waitForNextFrame(kWaitDuration); 82 if (res == OK) { 83 processNewFrames(device); 84 } else if (res != TIMED_OUT) { 85 ALOGE("FrameProcessorBase: Error waiting for new " 86 "frames: %s (%d)", strerror(-res), res); 87 } 88 89 return true; 90} 91 92void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) { 93 status_t res; 94 ATRACE_CALL(); 95 CameraMetadata frame; 96 97 ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId()); 98 99 while ( (res = device->getNextFrame(&frame)) == OK) { 100 101 camera_metadata_entry_t entry; 102 103 entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); 104 if (entry.count == 0) { 105 ALOGE("%s: Camera %d: Error reading frame number", 106 __FUNCTION__, device->getId()); 107 break; 108 } 109 ATRACE_INT("cam2_frame", entry.data.i32[0]); 110 111 if (!processSingleFrame(frame, device)) { 112 break; 113 } 114 115 if (!frame.isEmpty()) { 116 mLastFrame.acquire(frame); 117 } 118 } 119 if (res != NOT_ENOUGH_DATA) { 120 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)", 121 __FUNCTION__, device->getId(), strerror(-res), res); 122 return; 123 } 124 125 return; 126} 127 128bool FrameProcessorBase::processSingleFrame(CameraMetadata &frame, 129 const sp<CameraDeviceBase> &device) { 130 ALOGV("%s: Camera %d: Process single frame (is empty? %d)", 131 __FUNCTION__, device->getId(), frame.isEmpty()); 132 return processListeners(frame, device) == OK; 133} 134 135status_t FrameProcessorBase::processListeners(const CameraMetadata &frame, 136 const sp<CameraDeviceBase> &device) { 137 ATRACE_CALL(); 138 camera_metadata_ro_entry_t entry; 139 140 entry = frame.find(ANDROID_REQUEST_ID); 141 if (entry.count == 0) { 142 ALOGE("%s: Camera %d: Error reading frame id", 143 __FUNCTION__, device->getId()); 144 return BAD_VALUE; 145 } 146 int32_t frameId = entry.data.i32[0]; 147 148 List<sp<FilteredListener> > listeners; 149 { 150 Mutex::Autolock l(mInputMutex); 151 152 List<RangeListener>::iterator item = mRangeListeners.begin(); 153 while (item != mRangeListeners.end()) { 154 if (frameId >= item->minId && 155 frameId < item->maxId) { 156 sp<FilteredListener> listener = item->listener.promote(); 157 if (listener == 0) { 158 item = mRangeListeners.erase(item); 159 continue; 160 } else { 161 listeners.push_back(listener); 162 } 163 } 164 item++; 165 } 166 } 167 ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size()); 168 List<sp<FilteredListener> >::iterator item = listeners.begin(); 169 for (; item != listeners.end(); item++) { 170 (*item)->onFrameAvailable(frameId, frame); 171 } 172 return OK; 173} 174 175}; // namespace camera2 176}; // namespace android 177