From 71381051e2d048b2705c447b3d59db6e972493ee Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Mon, 4 Mar 2013 14:53:08 -0800 Subject: (Camera)FrameProcessor: Refactor to share code with ProFrameProcessor Change-Id: Ie8cd0df7caf83f9d0134f560ae31ab72f2f7d1fc --- services/camera/libcameraservice/Camera2Client.cpp | 2 +- services/camera/libcameraservice/Camera2Device.cpp | 4 + services/camera/libcameraservice/Camera2Device.h | 1 + services/camera/libcameraservice/Camera3Device.cpp | 4 + services/camera/libcameraservice/Camera3Device.h | 1 + .../camera/libcameraservice/CameraDeviceBase.h | 5 + .../camera/libcameraservice/ProCamera2Client.cpp | 3 +- .../libcameraservice/camera2/FrameProcessor.cpp | 175 +++++---------------- .../libcameraservice/camera2/FrameProcessor.h | 45 ++---- .../libcameraservice/camera2/ProFrameProcessor.cpp | 42 ++--- .../libcameraservice/camera2/ProFrameProcessor.h | 27 ++-- 11 files changed, 106 insertions(+), 203 deletions(-) (limited to 'services') diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index eb7a8d8..eb94d9f 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -115,7 +115,7 @@ status_t Camera2Client::initialize(camera_module_t *module) mStreamingProcessor = new StreamingProcessor(this); - mFrameProcessor = new FrameProcessor(this); + mFrameProcessor = new FrameProcessor(mDevice, this); threadName = String8::format("C2-%d-FrameProc", mCameraId); mFrameProcessor->run(threadName.string()); diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp index 81e58ca..37ba5ae 100644 --- a/services/camera/libcameraservice/Camera2Device.cpp +++ b/services/camera/libcameraservice/Camera2Device.cpp @@ -47,6 +47,10 @@ Camera2Device::~Camera2Device() disconnect(); } +int Camera2Device::getId() const { + return mId; +} + status_t Camera2Device::initialize(camera_module_t *module) { ATRACE_CALL(); diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h index 1adb7a9..3034a1d 100644 --- a/services/camera/libcameraservice/Camera2Device.h +++ b/services/camera/libcameraservice/Camera2Device.h @@ -38,6 +38,7 @@ class Camera2Device: public CameraDeviceBase { /** * CameraDevice interface */ + virtual int getId() const; virtual status_t initialize(camera_module_t *module); virtual status_t disconnect(); virtual status_t dump(int fd, const Vector& args); diff --git a/services/camera/libcameraservice/Camera3Device.cpp b/services/camera/libcameraservice/Camera3Device.cpp index 2a1be09..04a6e6a 100644 --- a/services/camera/libcameraservice/Camera3Device.cpp +++ b/services/camera/libcameraservice/Camera3Device.cpp @@ -50,6 +50,10 @@ Camera3Device::~Camera3Device() disconnect(); } +int Camera3Device::getId() const { + return mId; +} + status_t Camera3Device::initialize(camera_module_t *module) { ATRACE_CALL(); diff --git a/services/camera/libcameraservice/Camera3Device.h b/services/camera/libcameraservice/Camera3Device.h index 2bc7cf0..df7352c 100644 --- a/services/camera/libcameraservice/Camera3Device.h +++ b/services/camera/libcameraservice/Camera3Device.h @@ -57,6 +57,7 @@ class Camera3Device : /** * CameraDevice interface */ + virtual int getId() const; virtual status_t initialize(camera_module_t *module); virtual status_t disconnect(); virtual status_t dump(int fd, const Vector &args); diff --git a/services/camera/libcameraservice/CameraDeviceBase.h b/services/camera/libcameraservice/CameraDeviceBase.h index 8252af7..8c457d9 100644 --- a/services/camera/libcameraservice/CameraDeviceBase.h +++ b/services/camera/libcameraservice/CameraDeviceBase.h @@ -36,6 +36,11 @@ class CameraDeviceBase : public virtual RefBase { public: virtual ~CameraDeviceBase(); + /** + * The device's camera ID + */ + virtual int getId() const = 0; + virtual status_t initialize(camera_module_t *module) = 0; virtual status_t disconnect() = 0; diff --git a/services/camera/libcameraservice/ProCamera2Client.cpp b/services/camera/libcameraservice/ProCamera2Client.cpp index 4a5a3d5..1270751 100644 --- a/services/camera/libcameraservice/ProCamera2Client.cpp +++ b/services/camera/libcameraservice/ProCamera2Client.cpp @@ -27,6 +27,7 @@ #include "camera2/Parameters.h" #include "ProCamera2Client.h" #include "camera2/ProFrameProcessor.h" +#include "CameraDeviceBase.h" namespace android { using namespace camera2; @@ -61,7 +62,7 @@ status_t ProCamera2Client::initialize(camera_module_t *module) } String8 threadName; - mFrameProcessor = new ProFrameProcessor(this); + mFrameProcessor = new ProFrameProcessor(mDevice); threadName = String8::format("PC2-%d-FrameProc", mCameraId); mFrameProcessor->run(threadName.string()); diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.cpp b/services/camera/libcameraservice/camera2/FrameProcessor.cpp index 09b4b27..d13d398 100644 --- a/services/camera/libcameraservice/camera2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/camera2/FrameProcessor.cpp @@ -28,146 +28,37 @@ namespace android { namespace camera2 { -FrameProcessor::FrameProcessor(wp client): - Thread(false), mClient(client), mLastFrameNumberOfFaces(0) { +FrameProcessor::FrameProcessor(wp device, + wp client) : + ProFrameProcessor(device), + mClient(client), + mLastFrameNumberOfFaces(0) { } FrameProcessor::~FrameProcessor() { - ALOGV("%s: Exit", __FUNCTION__); } -status_t FrameProcessor::registerListener(int32_t minId, - int32_t maxId, wp listener) { - Mutex::Autolock l(mInputMutex); - ALOGV("%s: Registering listener for frame id range %d - %d", - __FUNCTION__, minId, maxId); - RangeListener rListener = { minId, maxId, listener }; - mRangeListeners.push_back(rListener); - return OK; -} +bool FrameProcessor::processSingleFrame(CameraMetadata &frame, + const sp &device) { -status_t FrameProcessor::removeListener(int32_t minId, - int32_t maxId, wp listener) { - Mutex::Autolock l(mInputMutex); - List::iterator item = mRangeListeners.begin(); - while (item != mRangeListeners.end()) { - if (item->minId == minId && - item->maxId == maxId && - item->listener == listener) { - item = mRangeListeners.erase(item); - } else { - item++; - } + sp client = mClient.promote(); + if (!client.get()) { + return false; } - return OK; -} -void FrameProcessor::dump(int fd, const Vector& /*args*/) { - String8 result(" Latest received frame:\n"); - write(fd, result.string(), result.size()); - mLastFrame.dump(fd, 2, 6); -} - -bool FrameProcessor::threadLoop() { - status_t res; - - sp device; - { - sp client = mClient.promote(); - if (client == 0) return false; - device = client->getCameraDevice(); - if (device == 0) return false; + if (processFaceDetect(frame, client) != OK) { + return false; } - res = device->waitForNextFrame(kWaitDuration); - if (res == OK) { - sp client = mClient.promote(); - if (client == 0) return false; - processNewFrames(client); - } else if (res != TIMED_OUT) { - ALOGE("Camera2Client::FrameProcessor: Error waiting for new " - "frames: %s (%d)", strerror(-res), res); + if (!ProFrameProcessor::processSingleFrame(frame, device)) { + return false; } return true; } -void FrameProcessor::processNewFrames(sp &client) { - status_t res; - ATRACE_CALL(); - CameraMetadata frame; - while ( (res = client->getCameraDevice()->getNextFrame(&frame)) == OK) { - camera_metadata_entry_t entry; - - entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); - if (entry.count == 0) { - ALOGE("%s: Camera %d: Error reading frame number", - __FUNCTION__, client->getCameraId()); - break; - } - ATRACE_INT("cam2_frame", entry.data.i32[0]); - - res = processFaceDetect(frame, client); - if (res != OK) break; - - res = processListeners(frame, client); - if (res != OK) break; - - if (!frame.isEmpty()) { - mLastFrame.acquire(frame); - } - } - if (res != NOT_ENOUGH_DATA) { - ALOGE("%s: Camera %d: Error getting next frame: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); - return; - } - - return; -} - -status_t FrameProcessor::processListeners(const CameraMetadata &frame, - sp &client) { - ATRACE_CALL(); - camera_metadata_ro_entry_t entry; - - entry = frame.find(ANDROID_REQUEST_ID); - if (entry.count == 0) { - ALOGE("%s: Camera %d: Error reading frame id", - __FUNCTION__, client->getCameraId()); - return BAD_VALUE; - } - int32_t frameId = entry.data.i32[0]; - - List > listeners; - { - Mutex::Autolock l(mInputMutex); - - List::iterator item = mRangeListeners.begin(); - while (item != mRangeListeners.end()) { - if (frameId >= item->minId && - frameId < item->maxId) { - sp listener = item->listener.promote(); - if (listener == 0) { - item = mRangeListeners.erase(item); - continue; - } else { - listeners.push_back(listener); - } - } - item++; - } - } - ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size()); - List >::iterator item = listeners.begin(); - for (; item != listeners.end(); item++) { - (*item)->onFrameAvailable(frameId, frame); - } - return OK; -} - status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, - sp &client) { + const sp &client) { status_t res = BAD_VALUE; ATRACE_CALL(); camera_metadata_ro_entry_t entry; @@ -190,7 +81,9 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, Vector faces; metadata.number_of_faces = 0; - if (enableFaceDetect && faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) { + if (enableFaceDetect && + faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) { + SharedParameters::Lock l(client->getParameters()); entry = frame.find(ANDROID_STATISTICS_FACE_RECTANGLES); if (entry.count == 0) { @@ -263,17 +156,17 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) { face.id = faceIds[i]; face.left_eye[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]); + l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]); face.left_eye[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]); + l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]); face.right_eye[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]); + l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]); face.right_eye[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]); + l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]); face.mouth[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]); + l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]); face.mouth[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]); + l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]); } else { face.id = 0; face.left_eye[0] = face.left_eye[1] = -2000; @@ -293,14 +186,24 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, } void FrameProcessor::callbackFaceDetection(sp client, - /*in*/camera_frame_metadata &metadata) { + const camera_frame_metadata &metadata) { + + camera_frame_metadata *metadata_ptr = + const_cast(&metadata); + + /** + * Filter out repeated 0-face callbacks, + * but not when the last frame was >0 + */ + if (metadata.number_of_faces != 0 || + mLastFrameNumberOfFaces != metadata.number_of_faces) { - /* Filter out repeated 0-face callbacks, but not when the last frame was >0 */ - if (metadata.number_of_faces != 0 || mLastFrameNumberOfFaces != metadata.number_of_faces) { - Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks); + Camera2Client::SharedCameraCallbacks::Lock + l(client->mSharedCameraCallbacks); if (l.mRemoteCallback != NULL) { l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_METADATA, - NULL, &metadata); + NULL, + metadata_ptr); } } diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.h b/services/camera/libcameraservice/camera2/FrameProcessor.h index 66e3cda..27ed8f6 100644 --- a/services/camera/libcameraservice/camera2/FrameProcessor.h +++ b/services/camera/libcameraservice/camera2/FrameProcessor.h @@ -22,7 +22,9 @@ #include #include #include -#include "camera/CameraMetadata.h" +#include + +#include "ProFrameProcessor.h" struct camera_frame_metadata; @@ -35,51 +37,26 @@ namespace camera2 { /* Output frame metadata processing thread. This thread waits for new * frames from the device, and analyzes them as necessary. */ -class FrameProcessor: public Thread { +class FrameProcessor : public ProFrameProcessor { public: - FrameProcessor(wp client); + FrameProcessor(wp device, wp client); ~FrameProcessor(); - struct FilteredListener: virtual public RefBase { - virtual void onFrameAvailable(int32_t frameId, - const CameraMetadata &frame) = 0; - }; - - // Register a listener for a range of IDs [minId, maxId). Multiple listeners - // can be listening to the same range - status_t registerListener(int32_t minId, int32_t maxId, wp listener); - status_t removeListener(int32_t minId, int32_t maxId, wp listener); - - void dump(int fd, const Vector& args); private: - static const nsecs_t kWaitDuration = 10000000; // 10 ms wp mClient; + int mLastFrameNumberOfFaces; - virtual bool threadLoop(); - - Mutex mInputMutex; - - struct RangeListener { - int32_t minId; - int32_t maxId; - wp listener; - }; - List mRangeListeners; + void processNewFrames(const sp &client); - void processNewFrames(sp &client); + virtual bool processSingleFrame(CameraMetadata &frame, + const sp &device); status_t processFaceDetect(const CameraMetadata &frame, - sp &client); - - status_t processListeners(const CameraMetadata &frame, - sp &client); - - CameraMetadata mLastFrame; - int mLastFrameNumberOfFaces; + const sp &client); // Emit FaceDetection event to java if faces changed void callbackFaceDetection(sp client, - camera_frame_metadata &metadata); + const camera_frame_metadata &metadata); }; diff --git a/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp b/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp index 742577a..257a45f 100644 --- a/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp +++ b/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp @@ -23,13 +23,13 @@ #include "ProFrameProcessor.h" #include "../CameraDeviceBase.h" -#include "../ProCamera2Client.h" namespace android { namespace camera2 { -ProFrameProcessor::ProFrameProcessor(wp client): - Thread(false), mClient(client) { +ProFrameProcessor::ProFrameProcessor(wp device) : + Thread(/*canCallJava*/false), + mDevice(device) { } ProFrameProcessor::~ProFrameProcessor() { @@ -47,7 +47,8 @@ status_t ProFrameProcessor::registerListener(int32_t minId, } status_t ProFrameProcessor::removeListener(int32_t minId, - int32_t maxId, wp listener) { + int32_t maxId, + wp listener) { Mutex::Autolock l(mInputMutex); List::iterator item = mRangeListeners.begin(); while (item != mRangeListeners.end()) { @@ -73,42 +74,40 @@ bool ProFrameProcessor::threadLoop() { sp device; { - sp client = mClient.promote(); - if (client == 0) return false; - device = client->getCameraDevice(); + device = mDevice.promote(); if (device == 0) return false; } res = device->waitForNextFrame(kWaitDuration); if (res == OK) { - sp client = mClient.promote(); - if (client == 0) return false; - processNewFrames(client); + processNewFrames(device); } else if (res != TIMED_OUT) { - ALOGE("ProCamera2Client::ProFrameProcessor: Error waiting for new " + ALOGE("ProFrameProcessor: Error waiting for new " "frames: %s (%d)", strerror(-res), res); } return true; } -void ProFrameProcessor::processNewFrames(sp &client) { +void ProFrameProcessor::processNewFrames(const sp &device) { status_t res; ATRACE_CALL(); CameraMetadata frame; - while ( (res = client->getCameraDevice()->getNextFrame(&frame)) == OK) { + while ( (res = device->getNextFrame(&frame)) == OK) { + camera_metadata_entry_t entry; entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); if (entry.count == 0) { ALOGE("%s: Camera %d: Error reading frame number", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, device->getId()); break; } ATRACE_INT("cam2_frame", entry.data.i32[0]); - res = processListeners(frame, client); - if (res != OK) break; + if (!processSingleFrame(frame, device)) { + break; + } if (!frame.isEmpty()) { mLastFrame.acquire(frame); @@ -116,22 +115,27 @@ void ProFrameProcessor::processNewFrames(sp &client) { } if (res != NOT_ENOUGH_DATA) { ALOGE("%s: Camera %d: Error getting next frame: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, device->getId(), strerror(-res), res); return; } return; } +bool ProFrameProcessor::processSingleFrame(CameraMetadata &frame, + const sp &device) { + return processListeners(frame, device) == OK; +} + status_t ProFrameProcessor::processListeners(const CameraMetadata &frame, - sp &client) { + const sp &device) { ATRACE_CALL(); camera_metadata_ro_entry_t entry; entry = frame.find(ANDROID_REQUEST_ID); if (entry.count == 0) { ALOGE("%s: Camera %d: Error reading frame id", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, device->getId()); return BAD_VALUE; } int32_t frameId = entry.data.i32[0]; diff --git a/services/camera/libcameraservice/camera2/ProFrameProcessor.h b/services/camera/libcameraservice/camera2/ProFrameProcessor.h index e4094a6..b82942c 100644 --- a/services/camera/libcameraservice/camera2/ProFrameProcessor.h +++ b/services/camera/libcameraservice/camera2/ProFrameProcessor.h @@ -24,11 +24,9 @@ #include #include -struct camera_frame_metadata; - namespace android { -class ProCamera2Client; +class CameraDeviceBase; namespace camera2 { @@ -37,23 +35,25 @@ namespace camera2 { */ class ProFrameProcessor: public Thread { public: - ProFrameProcessor(wp client); - ~ProFrameProcessor(); + ProFrameProcessor(wp device); + virtual ~ProFrameProcessor(); struct FilteredListener: virtual public RefBase { virtual void onFrameAvailable(int32_t frameId, - const CameraMetadata &frame) = 0; + const CameraMetadata &frame) = 0; }; // Register a listener for a range of IDs [minId, maxId). Multiple listeners // can be listening to the same range - status_t registerListener(int32_t minId, int32_t maxId, wp listener); - status_t removeListener(int32_t minId, int32_t maxId, wp listener); + status_t registerListener(int32_t minId, int32_t maxId, + wp listener); + status_t removeListener(int32_t minId, int32_t maxId, + wp listener); void dump(int fd, const Vector& args); - private: + protected: static const nsecs_t kWaitDuration = 10000000; // 10 ms - wp mClient; + wp mDevice; virtual bool threadLoop(); @@ -66,10 +66,13 @@ class ProFrameProcessor: public Thread { }; List mRangeListeners; - void processNewFrames(sp &client); + void processNewFrames(const sp &device); + + virtual bool processSingleFrame(CameraMetadata &frame, + const sp &device); status_t processListeners(const CameraMetadata &frame, - sp &client); + const sp &device); CameraMetadata mLastFrame; }; -- cgit v1.1