summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2013-03-04 14:53:08 -0800
committerIgor Murashkin <iam@google.com>2013-03-11 16:32:24 -0700
commit71381051e2d048b2705c447b3d59db6e972493ee (patch)
tree608f234db150d2805d0d3f0c42e29073fb8ba34e /services
parenta2e203bdb911bd5595723651d06ad91c330a7873 (diff)
downloadframeworks_av-71381051e2d048b2705c447b3d59db6e972493ee.zip
frameworks_av-71381051e2d048b2705c447b3d59db6e972493ee.tar.gz
frameworks_av-71381051e2d048b2705c447b3d59db6e972493ee.tar.bz2
(Camera)FrameProcessor: Refactor to share code with ProFrameProcessor
Change-Id: Ie8cd0df7caf83f9d0134f560ae31ab72f2f7d1fc
Diffstat (limited to 'services')
-rw-r--r--services/camera/libcameraservice/Camera2Client.cpp2
-rw-r--r--services/camera/libcameraservice/Camera2Device.cpp4
-rw-r--r--services/camera/libcameraservice/Camera2Device.h1
-rw-r--r--services/camera/libcameraservice/Camera3Device.cpp4
-rw-r--r--services/camera/libcameraservice/Camera3Device.h1
-rw-r--r--services/camera/libcameraservice/CameraDeviceBase.h5
-rw-r--r--services/camera/libcameraservice/ProCamera2Client.cpp3
-rw-r--r--services/camera/libcameraservice/camera2/FrameProcessor.cpp175
-rw-r--r--services/camera/libcameraservice/camera2/FrameProcessor.h45
-rw-r--r--services/camera/libcameraservice/camera2/ProFrameProcessor.cpp42
-rw-r--r--services/camera/libcameraservice/camera2/ProFrameProcessor.h27
11 files changed, 106 insertions, 203 deletions
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<String16>& 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<String16> &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<Camera2Client> client):
- Thread(false), mClient(client), mLastFrameNumberOfFaces(0) {
+FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device,
+ wp<Camera2Client> client) :
+ ProFrameProcessor(device),
+ mClient(client),
+ mLastFrameNumberOfFaces(0) {
}
FrameProcessor::~FrameProcessor() {
- ALOGV("%s: Exit", __FUNCTION__);
}
-status_t FrameProcessor::registerListener(int32_t minId,
- int32_t maxId, wp<FilteredListener> 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<CameraDeviceBase> &device) {
-status_t FrameProcessor::removeListener(int32_t minId,
- int32_t maxId, wp<FilteredListener> listener) {
- Mutex::Autolock l(mInputMutex);
- List<RangeListener>::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<Camera2Client> client = mClient.promote();
+ if (!client.get()) {
+ return false;
}
- return OK;
-}
-void FrameProcessor::dump(int fd, const Vector<String16>& /*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<CameraDeviceBase> device;
- {
- sp<Camera2Client> 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<Camera2Client> 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<Camera2Client> &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<Camera2Client> &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<sp<FilteredListener> > listeners;
- {
- Mutex::Autolock l(mInputMutex);
-
- List<RangeListener>::iterator item = mRangeListeners.begin();
- while (item != mRangeListeners.end()) {
- if (frameId >= item->minId &&
- frameId < item->maxId) {
- sp<FilteredListener> 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<sp<FilteredListener> >::iterator item = listeners.begin();
- for (; item != listeners.end(); item++) {
- (*item)->onFrameAvailable(frameId, frame);
- }
- return OK;
-}
-
status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,
- sp<Camera2Client> &client) {
+ const sp<Camera2Client> &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<camera_face_t> 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<Camera2Client> client,
- /*in*/camera_frame_metadata &metadata) {
+ const camera_frame_metadata &metadata) {
+
+ camera_frame_metadata *metadata_ptr =
+ const_cast<camera_frame_metadata*>(&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 <utils/Vector.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
-#include "camera/CameraMetadata.h"
+#include <camera/CameraMetadata.h>
+
+#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<Camera2Client> client);
+ FrameProcessor(wp<CameraDeviceBase> device, wp<Camera2Client> 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<FilteredListener> listener);
- status_t removeListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener);
-
- void dump(int fd, const Vector<String16>& args);
private:
- static const nsecs_t kWaitDuration = 10000000; // 10 ms
wp<Camera2Client> mClient;
+ int mLastFrameNumberOfFaces;
- virtual bool threadLoop();
-
- Mutex mInputMutex;
-
- struct RangeListener {
- int32_t minId;
- int32_t maxId;
- wp<FilteredListener> listener;
- };
- List<RangeListener> mRangeListeners;
+ void processNewFrames(const sp<Camera2Client> &client);
- void processNewFrames(sp<Camera2Client> &client);
+ virtual bool processSingleFrame(CameraMetadata &frame,
+ const sp<CameraDeviceBase> &device);
status_t processFaceDetect(const CameraMetadata &frame,
- sp<Camera2Client> &client);
-
- status_t processListeners(const CameraMetadata &frame,
- sp<Camera2Client> &client);
-
- CameraMetadata mLastFrame;
- int mLastFrameNumberOfFaces;
+ const sp<Camera2Client> &client);
// Emit FaceDetection event to java if faces changed
void callbackFaceDetection(sp<Camera2Client> 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<ProCamera2Client> client):
- Thread(false), mClient(client) {
+ProFrameProcessor::ProFrameProcessor(wp<CameraDeviceBase> 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<FilteredListener> listener) {
+ int32_t maxId,
+ wp<FilteredListener> listener) {
Mutex::Autolock l(mInputMutex);
List<RangeListener>::iterator item = mRangeListeners.begin();
while (item != mRangeListeners.end()) {
@@ -73,42 +74,40 @@ bool ProFrameProcessor::threadLoop() {
sp<CameraDeviceBase> device;
{
- sp<ProCamera2Client> 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<ProCamera2Client> 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<ProCamera2Client> &client) {
+void ProFrameProcessor::processNewFrames(const sp<CameraDeviceBase> &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<ProCamera2Client> &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<CameraDeviceBase> &device) {
+ return processListeners(frame, device) == OK;
+}
+
status_t ProFrameProcessor::processListeners(const CameraMetadata &frame,
- sp<ProCamera2Client> &client) {
+ const sp<CameraDeviceBase> &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 <utils/List.h>
#include <camera/CameraMetadata.h>
-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<ProCamera2Client> client);
- ~ProFrameProcessor();
+ ProFrameProcessor(wp<CameraDeviceBase> 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<FilteredListener> listener);
- status_t removeListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener);
+ status_t registerListener(int32_t minId, int32_t maxId,
+ wp<FilteredListener> listener);
+ status_t removeListener(int32_t minId, int32_t maxId,
+ wp<FilteredListener> listener);
void dump(int fd, const Vector<String16>& args);
- private:
+ protected:
static const nsecs_t kWaitDuration = 10000000; // 10 ms
- wp<ProCamera2Client> mClient;
+ wp<CameraDeviceBase> mDevice;
virtual bool threadLoop();
@@ -66,10 +66,13 @@ class ProFrameProcessor: public Thread {
};
List<RangeListener> mRangeListeners;
- void processNewFrames(sp<ProCamera2Client> &client);
+ void processNewFrames(const sp<CameraDeviceBase> &device);
+
+ virtual bool processSingleFrame(CameraMetadata &frame,
+ const sp<CameraDeviceBase> &device);
status_t processListeners(const CameraMetadata &frame,
- sp<ProCamera2Client> &client);
+ const sp<CameraDeviceBase> &device);
CameraMetadata mLastFrame;
};