Home | History | Annotate | Download | only in common
      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 
     30 FrameProcessorBase::FrameProcessorBase(wp<CameraDeviceBase> device) :
     31     Thread(/*canCallJava*/false),
     32     mDevice(device) {
     33 }
     34 
     35 FrameProcessorBase::~FrameProcessorBase() {
     36     ALOGV("%s: Exit", __FUNCTION__);
     37 }
     38 
     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 
     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 
     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 
     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 
     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 
    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 
    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