FrameProcessorBase.cpp revision 4345d5b57a93ec6d003df84f5cce2db7cccfbd86
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
17418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin#define LOG_TAG "Camera2-ProFrameProcessor"
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
24418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin#include "ProFrameProcessor.h"
25a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin#include "../CameraDeviceBase.h"
26418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
27418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinnamespace android {
28418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinnamespace camera2 {
29418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
3071381051e2d048b2705c447b3d59db6e972493eeIgor MurashkinProFrameProcessor::ProFrameProcessor(wp<CameraDeviceBase> device) :
3171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    Thread(/*canCallJava*/false),
3271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    mDevice(device) {
33418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
34418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
35418e493e8d67924cfda652cb64965647ce6381cbIgor MurashkinProFrameProcessor::~ProFrameProcessor() {
36418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    ALOGV("%s: Exit", __FUNCTION__);
37418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
38418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
39418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinstatus_t ProFrameProcessor::registerListener(int32_t minId,
40418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        int32_t maxId, wp<FilteredListener> listener) {
41418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    Mutex::Autolock l(mInputMutex);
42418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    ALOGV("%s: Registering listener for frame id range %d - %d",
43418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            __FUNCTION__, minId, maxId);
44418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    RangeListener rListener = { minId, maxId, listener };
45418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    mRangeListeners.push_back(rListener);
46418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    return OK;
47418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
48418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
49418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinstatus_t ProFrameProcessor::removeListener(int32_t minId,
5071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                                           int32_t maxId,
5171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                                           wp<FilteredListener> listener) {
52418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    Mutex::Autolock l(mInputMutex);
53418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    List<RangeListener>::iterator item = mRangeListeners.begin();
54418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    while (item != mRangeListeners.end()) {
55418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        if (item->minId == minId &&
56418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                item->maxId == maxId &&
57418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                item->listener == listener) {
58418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            item = mRangeListeners.erase(item);
59418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        } else {
60418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            item++;
61418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        }
62418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
63418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    return OK;
64418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
65418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
66a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkinvoid ProFrameProcessor::dump(int fd, const Vector<String16>& /*args*/) {
67418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    String8 result("    Latest received frame:\n");
68418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    write(fd, result.string(), result.size());
69418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    mLastFrame.dump(fd, 2, 6);
70418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
71418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
72418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinbool ProFrameProcessor::threadLoop() {
73418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    status_t res;
74418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
75a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin    sp<CameraDeviceBase> device;
76418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    {
7771381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        device = mDevice.promote();
78418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        if (device == 0) return false;
79418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
80418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
81418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    res = device->waitForNextFrame(kWaitDuration);
82418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    if (res == OK) {
8371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        processNewFrames(device);
84418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    } else if (res != TIMED_OUT) {
8571381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        ALOGE("ProFrameProcessor: Error waiting for new "
86418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                "frames: %s (%d)", strerror(-res), res);
87418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
88418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
89418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    return true;
90418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
91418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
9271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkinvoid ProFrameProcessor::processNewFrames(const sp<CameraDeviceBase> &device) {
93418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    status_t res;
94418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    ATRACE_CALL();
95418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    CameraMetadata frame;
964345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
974345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId());
984345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
9971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    while ( (res = device->getNextFrame(&frame)) == OK) {
10071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin
101418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        camera_metadata_entry_t entry;
102418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
103418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
104418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        if (entry.count == 0) {
105418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            ALOGE("%s: Camera %d: Error reading frame number",
10671381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                    __FUNCTION__, device->getId());
107418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            break;
108418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        }
109418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        ATRACE_INT("cam2_frame", entry.data.i32[0]);
110418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
11171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        if (!processSingleFrame(frame, device)) {
11271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin            break;
11371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        }
114418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
115418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        if (!frame.isEmpty()) {
116418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            mLastFrame.acquire(frame);
117418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        }
118418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
119418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    if (res != NOT_ENOUGH_DATA) {
120418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
12171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                __FUNCTION__, device->getId(), strerror(-res), res);
122418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        return;
123418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
124418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
125418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    return;
126418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
127418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
12871381051e2d048b2705c447b3d59db6e972493eeIgor Murashkinbool ProFrameProcessor::processSingleFrame(CameraMetadata &frame,
12971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                                           const sp<CameraDeviceBase> &device) {
1304345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    ALOGV("%s: Camera %d: Process single frame (is empty? %d)",
1314345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin          __FUNCTION__, device->getId(), frame.isEmpty());
13271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    return processListeners(frame, device) == OK;
13371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin}
13471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin
135418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkinstatus_t ProFrameProcessor::processListeners(const CameraMetadata &frame,
13671381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        const sp<CameraDeviceBase> &device) {
137418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    ATRACE_CALL();
138418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    camera_metadata_ro_entry_t entry;
139418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
140418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    entry = frame.find(ANDROID_REQUEST_ID);
141418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    if (entry.count == 0) {
142418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        ALOGE("%s: Camera %d: Error reading frame id",
14371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                __FUNCTION__, device->getId());
144418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        return BAD_VALUE;
145418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
146418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    int32_t frameId = entry.data.i32[0];
147418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
148418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    List<sp<FilteredListener> > listeners;
149418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    {
150418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        Mutex::Autolock l(mInputMutex);
151418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
152418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        List<RangeListener>::iterator item = mRangeListeners.begin();
153418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        while (item != mRangeListeners.end()) {
154418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            if (frameId >= item->minId &&
155418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                    frameId < item->maxId) {
156418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                sp<FilteredListener> listener = item->listener.promote();
157418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                if (listener == 0) {
158418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                    item = mRangeListeners.erase(item);
159418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                    continue;
160418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                } else {
161418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                    listeners.push_back(listener);
162418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin                }
163418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            }
164418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin            item++;
165418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        }
166418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
167418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size());
168418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    List<sp<FilteredListener> >::iterator item = listeners.begin();
169418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    for (; item != listeners.end(); item++) {
170418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin        (*item)->onFrameAvailable(frameId, frame);
171418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    }
172418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin    return OK;
173418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}
174418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin
175418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace camera2
176418e493e8d67924cfda652cb64965647ce6381cbIgor Murashkin}; // namespace android
177