Camera3: Add shutter notification
Mandatory now due to fragmented process_capture_result calls.
Bug: 8565103
Change-Id: I4e815e99a5220cc61650157894869189ceaf883d
diff --git a/camera/EmulatedFakeCamera3.cpp b/camera/EmulatedFakeCamera3.cpp
index 87a0a3c..d4c51e4 100644
--- a/camera/EmulatedFakeCamera3.cpp
+++ b/camera/EmulatedFakeCamera3.cpp
@@ -120,7 +120,7 @@
struct hw_module_t* module) :
EmulatedCamera3(cameraId, module),
mFacingBack(facingBack) {
- ALOGD("Constructing emulated fake camera 3 facing %s",
+ ALOGI("Constructing emulated fake camera 3 facing %s",
facingBack ? "back" : "front");
for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
@@ -166,6 +166,7 @@
}
mSensor = new Sensor();
+ mSensor->setSensorListener(this);
res = mSensor->startUp();
if (res != NO_ERROR) return res;
@@ -906,6 +907,7 @@
mSensor->setFrameDuration(frameDuration);
mSensor->setSensitivity(sensitivity);
mSensor->setDestinationBuffers(sensorBuffers);
+ mSensor->setFrameNumber(request->frame_number);
ReadoutThread::Request r;
r.frameNumber = request->frame_number;
@@ -914,6 +916,7 @@
r.buffers = buffers;
mReadoutThread->queueCaptureRequest(r);
+ ALOGVV("%s: Queued frame %d", __FUNCTION__, request->frame_number);
// Cache the settings for next time
mPrevSettings.acquire(settings);
@@ -1730,6 +1733,27 @@
}
}
+void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e,
+ nsecs_t timestamp) {
+ switch(e) {
+ case Sensor::SensorListener::EXPOSURE_START: {
+ ALOGVV("%s: Frame %d: Sensor started exposure at %lld",
+ __FUNCTION__, frameNumber, timestamp);
+ // Trigger shutter notify to framework
+ camera3_notify_msg_t msg;
+ msg.type = CAMERA3_MSG_SHUTTER;
+ msg.message.shutter.frame_number = frameNumber;
+ msg.message.shutter.timestamp = timestamp;
+ sendNotify(&msg);
+ break;
+ }
+ default:
+ ALOGW("%s: Unexpected sensor event %d at %lld", __FUNCTION__,
+ e, timestamp);
+ break;
+ }
+}
+
EmulatedFakeCamera3::ReadoutThread::ReadoutThread(EmulatedFakeCamera3 *parent) :
mParent(parent) {
}
@@ -1799,6 +1823,8 @@
mInFlightQueue.erase(mInFlightQueue.begin());
mInFlightSignal.signal();
mThreadActive = true;
+ ALOGVV("Beginning readout of frame %d", __FUNCTION__,
+ mCurrentRequest.frameNumber);
}
// Then wait for it to be delivered from the sensor
@@ -1808,6 +1834,8 @@
mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime);
if (!gotFrame) return true;
+ ALOGVV("Sensor done with readout for frame %d, captured at %lld ",
+ mCurrentRequest.frameNumber, captureTime);
// Check if we need to JPEG encode a buffer
for (size_t i = 0; i < mCurrentRequest.buffers->size(); i++) {
diff --git a/camera/EmulatedFakeCamera3.h b/camera/EmulatedFakeCamera3.h
index dd9e6a1..d65e6a0 100644
--- a/camera/EmulatedFakeCamera3.h
+++ b/camera/EmulatedFakeCamera3.h
@@ -42,7 +42,8 @@
* connectDevice(), and closeCamera() methods of this class that are invoked in
* response to hw_module_methods_t::open, and camera_device::close callbacks.
*/
-class EmulatedFakeCamera3 : public EmulatedCamera3 {
+class EmulatedFakeCamera3 : public EmulatedCamera3,
+ private Sensor::SensorListener {
public:
EmulatedFakeCamera3(int cameraId, bool facingBack,
@@ -118,6 +119,9 @@
/** Signal from readout thread that it doesn't have anything to do */
void signalReadoutIdle();
+ /** Handle interrupt events from the sensor */
+ void onSensorEvent(uint32_t frameNumber, Event e, nsecs_t timestamp);
+
/****************************************************************************
* Static configuration information
***************************************************************************/
diff --git a/camera/fake-pipeline2/Sensor.cpp b/camera/fake-pipeline2/Sensor.cpp
index 0c12f6f..3f9f318 100644
--- a/camera/fake-pipeline2/Sensor.cpp
+++ b/camera/fake-pipeline2/Sensor.cpp
@@ -107,7 +107,9 @@
mFrameDuration(kFrameDurationRange[0]),
mGainFactor(kDefaultSensitivity),
mNextBuffers(NULL),
+ mFrameNumber(0),
mCapturedBuffers(NULL),
+ mListener(NULL),
mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond)
{
@@ -169,6 +171,11 @@
mNextBuffers = buffers;
}
+void Sensor::setFrameNumber(uint32_t frameNumber) {
+ Mutex::Autolock lock(mControlMutex);
+ mFrameNumber = frameNumber;
+}
+
bool Sensor::waitForVSync(nsecs_t reltime) {
int res;
Mutex::Autolock lock(mControlMutex);
@@ -204,6 +211,14 @@
return true;
}
+Sensor::SensorListener::~SensorListener() {
+}
+
+void Sensor::setSensorListener(SensorListener *listener) {
+ Mutex::Autolock lock(mControlMutex);
+ mListener = listener;
+}
+
status_t Sensor::readyToRun() {
ALOGV("Starting up sensor thread");
mStartupTime = systemTime();
@@ -227,12 +242,16 @@
uint64_t frameDuration;
uint32_t gain;
Buffers *nextBuffers;
+ uint32_t frameNumber;
+ SensorListener *listener = NULL;
{
Mutex::Autolock lock(mControlMutex);
exposureDuration = mExposureTime;
frameDuration = mFrameDuration;
gain = mGainFactor;
nextBuffers = mNextBuffers;
+ frameNumber = mFrameNumber;
+ listener = mListener;
// Don't reuse a buffer set
mNextBuffers = NULL;
@@ -284,11 +303,14 @@
/**
* Stage 2: Capture new image
*/
-
mNextCaptureTime = simulatedTime;
mNextCapturedBuffers = nextBuffers;
if (mNextCapturedBuffers != NULL) {
+ if (listener != NULL) {
+ listener->onSensorEvent(frameNumber, SensorListener::EXPOSURE_START,
+ mNextCaptureTime);
+ }
ALOGVV("Starting next capture: Exposure: %f ms, gain: %d",
(float)exposureDuration/1e6, gain);
mScene.setExposureDuration((float)exposureDuration/1e9);
diff --git a/camera/fake-pipeline2/Sensor.h b/camera/fake-pipeline2/Sensor.h
index 72128c5..8e2ffe8 100644
--- a/camera/fake-pipeline2/Sensor.h
+++ b/camera/fake-pipeline2/Sensor.h
@@ -111,6 +111,8 @@
void setSensitivity(uint32_t gain);
// Buffer must be at least stride*height*2 bytes in size
void setDestinationBuffers(Buffers *buffers);
+ // To simplify tracking sensor's current frame
+ void setFrameNumber(uint32_t frameNumber);
/*
* Controls that cause reconfiguration delay
@@ -134,6 +136,22 @@
bool waitForNewFrame(nsecs_t reltime,
nsecs_t *captureTime);
+ /*
+ * Interrupt event servicing from the sensor. Only triggers for sensor
+ * cycles that have valid buffers to write to.
+ */
+ struct SensorListener {
+ enum Event {
+ EXPOSURE_START, // Start of exposure
+ };
+
+ virtual void onSensorEvent(uint32_t frameNumber, Event e,
+ nsecs_t timestamp) = 0;
+ virtual ~SensorListener();
+ };
+
+ void setSensorListener(SensorListener *listener);
+
/**
* Static sensor characteristics
*/
@@ -180,6 +198,7 @@
uint64_t mFrameDuration;
uint32_t mGainFactor;
Buffers *mNextBuffers;
+ uint32_t mFrameNumber;
// End of control parameters
@@ -189,6 +208,7 @@
Condition mReadoutComplete;
Buffers *mCapturedBuffers;
nsecs_t mCaptureTime;
+ SensorListener *mListener;
// End of readout variables
// Time of sensor startup, used for simulation zero-time point