diff options
| author | Eino-Ville Talvala <etalvala@google.com> | 2013-04-09 18:53:30 -0700 |
|---|---|---|
| committer | Eino-Ville Talvala <etalvala@google.com> | 2013-04-15 11:39:11 -0700 |
| commit | 4e8dfb1f38cb0f0ed72f05452d26f6b271e20419 (patch) | |
| tree | be106f00ee7571efab16c3a92eea1d11248ca990 /camera | |
| parent | 7c38b54b3c52b4a22d113c0a0e52e61f8be7746b (diff) | |
| download | android_device_generic_goldfish-4e8dfb1f38cb0f0ed72f05452d26f6b271e20419.tar.gz android_device_generic_goldfish-4e8dfb1f38cb0f0ed72f05452d26f6b271e20419.tar.bz2 android_device_generic_goldfish-4e8dfb1f38cb0f0ed72f05452d26f6b271e20419.zip | |
Camera3: Add shutter notification
Mandatory now due to fragmented process_capture_result calls.
Bug: 8565103
Change-Id: I4e815e99a5220cc61650157894869189ceaf883d
Diffstat (limited to 'camera')
| -rw-r--r-- | camera/EmulatedFakeCamera3.cpp | 30 | ||||
| -rw-r--r-- | camera/EmulatedFakeCamera3.h | 6 | ||||
| -rw-r--r-- | camera/fake-pipeline2/Sensor.cpp | 24 | ||||
| -rw-r--r-- | camera/fake-pipeline2/Sensor.h | 20 |
4 files changed, 77 insertions, 3 deletions
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 @@ EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, bool facingBack, 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 @@ status_t EmulatedFakeCamera3::connectCamera(hw_device_t** device) { } mSensor = new Sensor(); + mSensor->setSensorListener(this); res = mSensor->startUp(); if (res != NO_ERROR) return res; @@ -906,6 +907,7 @@ status_t EmulatedFakeCamera3::processCaptureRequest( 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 @@ status_t EmulatedFakeCamera3::processCaptureRequest( 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::signalReadoutIdle() { } } +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 @@ bool EmulatedFakeCamera3::ReadoutThread::threadLoop() { 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 @@ bool EmulatedFakeCamera3::ReadoutThread::threadLoop() { 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 @@ namespace android { * 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 @@ private: /** 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 @@ Sensor::Sensor(): mFrameDuration(kFrameDurationRange[0]), mGainFactor(kDefaultSensitivity), mNextBuffers(NULL), + mFrameNumber(0), mCapturedBuffers(NULL), + mListener(NULL), mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond) { @@ -169,6 +171,11 @@ void Sensor::setDestinationBuffers(Buffers *buffers) { 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 @@ bool Sensor::waitForNewFrame(nsecs_t reltime, 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 @@ bool Sensor::threadLoop() { 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 @@ bool Sensor::threadLoop() { /** * 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 @@ class Sensor: private Thread, public virtual RefBase { 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 @@ class Sensor: private Thread, public virtual RefBase { 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 @@ class Sensor: private Thread, public virtual RefBase { uint64_t mFrameDuration; uint32_t mGainFactor; Buffers *mNextBuffers; + uint32_t mFrameNumber; // End of control parameters @@ -189,6 +208,7 @@ class Sensor: private Thread, public virtual RefBase { Condition mReadoutComplete; Buffers *mCapturedBuffers; nsecs_t mCaptureTime; + SensorListener *mListener; // End of readout variables // Time of sensor startup, used for simulation zero-time point |
