• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 namespace android {
28 namespace camera2 {
29 
FrameProcessorBase(wp<CameraDeviceBase> device)30 FrameProcessorBase::FrameProcessorBase(wp<CameraDeviceBase> device) :
31     Thread(/*canCallJava*/false),
32     mDevice(device) {
33 }
34 
~FrameProcessorBase()35 FrameProcessorBase::~FrameProcessorBase() {
36     ALOGV("%s: Exit", __FUNCTION__);
37 }
38 
registerListener(int32_t minId,int32_t maxId,wp<FilteredListener> listener,bool quirkSendPartials)39 status_t FrameProcessorBase::registerListener(int32_t minId,
40         int32_t maxId, wp<FilteredListener> listener, bool quirkSendPartials) {
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, quirkSendPartials };
45     mRangeListeners.push_back(rListener);
46     return OK;
47 }
48 
removeListener(int32_t minId,int32_t maxId,wp<FilteredListener> listener)49 status_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 
dump(int fd,const Vector<String16> &)66 void FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) {
67     String8 result("    Latest received frame:\n");
68     write(fd, result.string(), result.size());
69 
70     CameraMetadata lastFrame;
71     {
72         // Don't race while dumping metadata
73         Mutex::Autolock al(mLastFrameMutex);
74         lastFrame = CameraMetadata(mLastFrame);
75     }
76     lastFrame.dump(fd, 2, 6);
77 }
78 
threadLoop()79 bool FrameProcessorBase::threadLoop() {
80     status_t res;
81 
82     sp<CameraDeviceBase> device;
83     {
84         device = mDevice.promote();
85         if (device == 0) return false;
86     }
87 
88     res = device->waitForNextFrame(kWaitDuration);
89     if (res == OK) {
90         processNewFrames(device);
91     } else if (res != TIMED_OUT) {
92         ALOGE("FrameProcessorBase: Error waiting for new "
93                 "frames: %s (%d)", strerror(-res), res);
94     }
95 
96     return true;
97 }
98 
processNewFrames(const sp<CameraDeviceBase> & device)99 void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) {
100     status_t res;
101     ATRACE_CALL();
102     CameraMetadata frame;
103 
104     ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId());
105 
106     while ( (res = device->getNextFrame(&frame)) == OK) {
107 
108         camera_metadata_entry_t entry;
109 
110         entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
111         if (entry.count == 0) {
112             ALOGE("%s: Camera %d: Error reading frame number",
113                     __FUNCTION__, device->getId());
114             break;
115         }
116         ATRACE_INT("cam2_frame", entry.data.i32[0]);
117 
118         if (!processSingleFrame(frame, device)) {
119             break;
120         }
121 
122         if (!frame.isEmpty()) {
123             Mutex::Autolock al(mLastFrameMutex);
124             mLastFrame.acquire(frame);
125         }
126     }
127     if (res != NOT_ENOUGH_DATA) {
128         ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
129                 __FUNCTION__, device->getId(), strerror(-res), res);
130         return;
131     }
132 
133     return;
134 }
135 
processSingleFrame(CameraMetadata & frame,const sp<CameraDeviceBase> & device)136 bool FrameProcessorBase::processSingleFrame(CameraMetadata &frame,
137                                            const sp<CameraDeviceBase> &device) {
138     ALOGV("%s: Camera %d: Process single frame (is empty? %d)",
139           __FUNCTION__, device->getId(), frame.isEmpty());
140     return processListeners(frame, device) == OK;
141 }
142 
processListeners(const CameraMetadata & frame,const sp<CameraDeviceBase> & device)143 status_t FrameProcessorBase::processListeners(const CameraMetadata &frame,
144         const sp<CameraDeviceBase> &device) {
145     ATRACE_CALL();
146     camera_metadata_ro_entry_t entry;
147 
148     // Quirks: Don't deliver partial results to listeners that don't want them
149     bool quirkIsPartial = false;
150     entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT);
151     if (entry.count != 0 &&
152             entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
153         ALOGV("%s: Camera %d: Not forwarding partial result to listeners",
154                 __FUNCTION__, device->getId());
155         quirkIsPartial = true;
156     }
157 
158     entry = frame.find(ANDROID_REQUEST_ID);
159     if (entry.count == 0) {
160         ALOGE("%s: Camera %d: Error reading frame id",
161                 __FUNCTION__, device->getId());
162         return BAD_VALUE;
163     }
164     int32_t requestId = entry.data.i32[0];
165 
166     List<sp<FilteredListener> > listeners;
167     {
168         Mutex::Autolock l(mInputMutex);
169 
170         List<RangeListener>::iterator item = mRangeListeners.begin();
171         while (item != mRangeListeners.end()) {
172             if (requestId >= item->minId &&
173                     requestId < item->maxId &&
174                     (!quirkIsPartial || item->quirkSendPartials) ) {
175                 sp<FilteredListener> listener = item->listener.promote();
176                 if (listener == 0) {
177                     item = mRangeListeners.erase(item);
178                     continue;
179                 } else {
180                     listeners.push_back(listener);
181                 }
182             }
183             item++;
184         }
185     }
186     ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size());
187     List<sp<FilteredListener> >::iterator item = listeners.begin();
188     for (; item != listeners.end(); item++) {
189         (*item)->onFrameAvailable(requestId, frame);
190     }
191     return OK;
192 }
193 
194 }; // namespace camera2
195 }; // namespace android
196