You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
435 lines
14 KiB
435 lines
14 KiB
/*
|
|
* Copyright (C) 2012 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H
|
|
#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H
|
|
|
|
/*
|
|
* Contains declaration of a class EmulatedFakeCamera2 that encapsulates
|
|
* functionality of a fake camera that implements version 2 of the camera device
|
|
* interface.
|
|
*/
|
|
|
|
#include "EmulatedCamera2.h"
|
|
#include "fake-pipeline2/Base.h"
|
|
#include "fake-pipeline2/Sensor.h"
|
|
#include "fake-pipeline2/JpegCompressor.h"
|
|
#include <ui/GraphicBufferMapper.h>
|
|
#include <utils/Condition.h>
|
|
#include <utils/KeyedVector.h>
|
|
#include <utils/String8.h>
|
|
#include <utils/String16.h>
|
|
|
|
namespace android {
|
|
|
|
/* Encapsulates functionality of an advanced fake camera. This camera contains
|
|
* a simple simulation of a scene, sensor, and image processing pipeline.
|
|
*/
|
|
class EmulatedFakeCamera2 : public EmulatedCamera2 {
|
|
public:
|
|
/* Constructs EmulatedFakeCamera instance. */
|
|
EmulatedFakeCamera2(int cameraId, bool facingBack, struct hw_module_t* module,
|
|
GraphicBufferMapper* gbm);
|
|
|
|
/* Destructs EmulatedFakeCamera instance. */
|
|
~EmulatedFakeCamera2();
|
|
|
|
/****************************************************************************
|
|
* EmulatedCamera2 virtual overrides.
|
|
***************************************************************************/
|
|
|
|
public:
|
|
/* Initializes EmulatedFakeCamera2 instance. */
|
|
status_t Initialize();
|
|
|
|
/****************************************************************************
|
|
* Camera Module API and generic hardware device API implementation
|
|
***************************************************************************/
|
|
public:
|
|
|
|
virtual status_t connectCamera(hw_device_t** device);
|
|
|
|
virtual status_t plugCamera();
|
|
virtual status_t unplugCamera();
|
|
virtual camera_device_status_t getHotplugStatus();
|
|
|
|
virtual status_t closeCamera();
|
|
|
|
virtual status_t getCameraInfo(struct camera_info *info);
|
|
|
|
/****************************************************************************
|
|
* EmulatedCamera2 abstract API implementation.
|
|
***************************************************************************/
|
|
protected:
|
|
/** Request input queue */
|
|
|
|
virtual int requestQueueNotify();
|
|
|
|
/** Count of requests in flight */
|
|
virtual int getInProgressCount();
|
|
|
|
/** Cancel all captures in flight */
|
|
//virtual int flushCapturesInProgress();
|
|
|
|
/** Construct default request */
|
|
virtual int constructDefaultRequest(
|
|
int request_template,
|
|
camera_metadata_t **request);
|
|
|
|
virtual int allocateStream(
|
|
uint32_t width,
|
|
uint32_t height,
|
|
int format,
|
|
const camera2_stream_ops_t *stream_ops,
|
|
uint32_t *stream_id,
|
|
uint32_t *format_actual,
|
|
uint32_t *usage,
|
|
uint32_t *max_buffers);
|
|
|
|
virtual int registerStreamBuffers(
|
|
uint32_t stream_id,
|
|
int num_buffers,
|
|
buffer_handle_t *buffers);
|
|
|
|
virtual int releaseStream(uint32_t stream_id);
|
|
|
|
// virtual int allocateReprocessStream(
|
|
// uint32_t width,
|
|
// uint32_t height,
|
|
// uint32_t format,
|
|
// const camera2_stream_ops_t *stream_ops,
|
|
// uint32_t *stream_id,
|
|
// uint32_t *format_actual,
|
|
// uint32_t *usage,
|
|
// uint32_t *max_buffers);
|
|
|
|
virtual int allocateReprocessStreamFromStream(
|
|
uint32_t output_stream_id,
|
|
const camera2_stream_in_ops_t *stream_ops,
|
|
uint32_t *stream_id);
|
|
|
|
virtual int releaseReprocessStream(uint32_t stream_id);
|
|
|
|
virtual int triggerAction(uint32_t trigger_id,
|
|
int32_t ext1,
|
|
int32_t ext2);
|
|
|
|
/** Debug methods */
|
|
|
|
virtual int dump(int fd);
|
|
|
|
public:
|
|
/****************************************************************************
|
|
* Utility methods called by configure/readout threads and pipeline
|
|
***************************************************************************/
|
|
|
|
// Get information about a given stream. Will lock mMutex
|
|
const Stream &getStreamInfo(uint32_t streamId);
|
|
const ReprocessStream &getReprocessStreamInfo(uint32_t streamId);
|
|
|
|
// Notifies rest of camera subsystem of serious error
|
|
void signalError();
|
|
|
|
private:
|
|
/****************************************************************************
|
|
* Utility methods
|
|
***************************************************************************/
|
|
/** Construct static camera metadata, two-pass */
|
|
status_t constructStaticInfo(
|
|
camera_metadata_t **info,
|
|
bool sizeRequest) const;
|
|
|
|
/** Two-pass implementation of constructDefaultRequest */
|
|
status_t constructDefaultRequest(
|
|
int request_template,
|
|
camera_metadata_t **request,
|
|
bool sizeRequest) const;
|
|
/** Helper function for constructDefaultRequest */
|
|
static status_t addOrSize( camera_metadata_t *request,
|
|
bool sizeRequest,
|
|
size_t *entryCount,
|
|
size_t *dataCount,
|
|
uint32_t tag,
|
|
const void *entry_data,
|
|
size_t entry_count);
|
|
|
|
/** Determine if the stream id is listed in any currently-in-flight
|
|
* requests. Assumes mMutex is locked */
|
|
bool isStreamInUse(uint32_t streamId);
|
|
|
|
/** Determine if the reprocess stream id is listed in any
|
|
* currently-in-flight requests. Assumes mMutex is locked */
|
|
bool isReprocessStreamInUse(uint32_t streamId);
|
|
|
|
/****************************************************************************
|
|
* Pipeline controller threads
|
|
***************************************************************************/
|
|
|
|
class ConfigureThread: public Thread {
|
|
public:
|
|
ConfigureThread(EmulatedFakeCamera2 *parent);
|
|
~ConfigureThread();
|
|
|
|
status_t waitUntilRunning();
|
|
status_t newRequestAvailable();
|
|
status_t readyToRun();
|
|
|
|
bool isStreamInUse(uint32_t id);
|
|
int getInProgressCount();
|
|
private:
|
|
EmulatedFakeCamera2 *mParent;
|
|
static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms
|
|
|
|
bool mRunning;
|
|
bool threadLoop();
|
|
|
|
bool setupCapture();
|
|
bool setupReprocess();
|
|
|
|
bool configureNextCapture();
|
|
bool configureNextReprocess();
|
|
|
|
bool getBuffers();
|
|
|
|
Mutex mInputMutex; // Protects mActive, mRequestCount
|
|
Condition mInputSignal;
|
|
bool mActive; // Whether we're waiting for input requests or actively
|
|
// working on them
|
|
size_t mRequestCount;
|
|
|
|
camera_metadata_t *mRequest;
|
|
|
|
Mutex mInternalsMutex; // Lock before accessing below members.
|
|
bool mWaitingForReadout;
|
|
bool mNextNeedsJpeg;
|
|
bool mNextIsCapture;
|
|
int32_t mNextFrameNumber;
|
|
int64_t mNextExposureTime;
|
|
int64_t mNextFrameDuration;
|
|
int32_t mNextSensitivity;
|
|
Buffers *mNextBuffers;
|
|
};
|
|
|
|
class ReadoutThread: public Thread, private JpegCompressor::JpegListener {
|
|
public:
|
|
ReadoutThread(EmulatedFakeCamera2 *parent);
|
|
~ReadoutThread();
|
|
|
|
status_t readyToRun();
|
|
|
|
// Input
|
|
status_t waitUntilRunning();
|
|
bool waitForReady(nsecs_t timeout);
|
|
void setNextOperation(bool isCapture,
|
|
camera_metadata_t *request,
|
|
Buffers *buffers);
|
|
bool isStreamInUse(uint32_t id);
|
|
int getInProgressCount();
|
|
private:
|
|
EmulatedFakeCamera2 *mParent;
|
|
|
|
bool mRunning;
|
|
bool threadLoop();
|
|
|
|
bool readyForNextCapture();
|
|
status_t collectStatisticsMetadata(camera_metadata_t *frame);
|
|
|
|
// Inputs
|
|
Mutex mInputMutex; // Protects mActive, mInFlightQueue, mRequestCount
|
|
Condition mInputSignal;
|
|
Condition mReadySignal;
|
|
|
|
bool mActive;
|
|
|
|
static const int kInFlightQueueSize = 4;
|
|
struct InFlightQueue {
|
|
bool isCapture;
|
|
camera_metadata_t *request;
|
|
Buffers *buffers;
|
|
} *mInFlightQueue;
|
|
|
|
size_t mInFlightHead;
|
|
size_t mInFlightTail;
|
|
|
|
size_t mRequestCount;
|
|
|
|
// Internals
|
|
Mutex mInternalsMutex;
|
|
|
|
bool mIsCapture;
|
|
camera_metadata_t *mRequest;
|
|
Buffers *mBuffers;
|
|
|
|
// Jpeg completion listeners
|
|
void onJpegDone(const StreamBuffer &jpegBuffer, bool success);
|
|
void onJpegInputDone(const StreamBuffer &inputBuffer);
|
|
nsecs_t mJpegTimestamp;
|
|
};
|
|
|
|
// 3A management thread (auto-exposure, focus, white balance)
|
|
class ControlThread: public Thread {
|
|
public:
|
|
ControlThread(EmulatedFakeCamera2 *parent);
|
|
~ControlThread();
|
|
|
|
status_t readyToRun();
|
|
|
|
status_t waitUntilRunning();
|
|
|
|
// Interpret request's control parameters and override
|
|
// capture settings as needed
|
|
status_t processRequest(camera_metadata_t *request);
|
|
|
|
status_t triggerAction(uint32_t msgType,
|
|
int32_t ext1, int32_t ext2);
|
|
private:
|
|
ControlThread(const ControlThread &t);
|
|
ControlThread& operator=(const ControlThread &t);
|
|
|
|
// Constants controlling fake 3A behavior
|
|
static const nsecs_t kControlCycleDelay;
|
|
static const nsecs_t kMinAfDuration;
|
|
static const nsecs_t kMaxAfDuration;
|
|
static const float kAfSuccessRate;
|
|
static const float kContinuousAfStartRate;
|
|
|
|
static const float kAeScanStartRate;
|
|
static const nsecs_t kMinAeDuration;
|
|
static const nsecs_t kMaxAeDuration;
|
|
static const nsecs_t kMinPrecaptureAeDuration;
|
|
static const nsecs_t kMaxPrecaptureAeDuration;
|
|
|
|
static const nsecs_t kNormalExposureTime;
|
|
static const nsecs_t kExposureJump;
|
|
static const nsecs_t kMinExposureTime;
|
|
|
|
EmulatedFakeCamera2 *mParent;
|
|
|
|
bool mRunning;
|
|
bool threadLoop();
|
|
|
|
Mutex mInputMutex; // Protects input methods
|
|
Condition mInputSignal;
|
|
|
|
// Trigger notifications
|
|
bool mStartAf;
|
|
bool mCancelAf;
|
|
bool mStartPrecapture;
|
|
|
|
// Latest state for 3A request fields
|
|
uint8_t mControlMode;
|
|
|
|
uint8_t mEffectMode;
|
|
uint8_t mSceneMode;
|
|
|
|
uint8_t mAfMode;
|
|
bool mAfModeChange;
|
|
|
|
uint8_t mAwbMode;
|
|
uint8_t mAeMode;
|
|
|
|
// Latest trigger IDs
|
|
int32_t mAfTriggerId;
|
|
int32_t mPrecaptureTriggerId;
|
|
|
|
// Current state for 3A algorithms
|
|
uint8_t mAfState;
|
|
uint8_t mAeState;
|
|
uint8_t mAwbState;
|
|
bool mAeLock;
|
|
|
|
// Current control parameters
|
|
nsecs_t mExposureTime;
|
|
|
|
// Private to threadLoop and its utility methods
|
|
|
|
nsecs_t mAfScanDuration;
|
|
nsecs_t mAeScanDuration;
|
|
bool mLockAfterPassiveScan;
|
|
|
|
// Utility methods for AF
|
|
int processAfTrigger(uint8_t afMode, uint8_t afState);
|
|
int maybeStartAfScan(uint8_t afMode, uint8_t afState);
|
|
int updateAfScan(uint8_t afMode, uint8_t afState, nsecs_t *maxSleep);
|
|
void updateAfState(uint8_t newState, int32_t triggerId);
|
|
|
|
// Utility methods for precapture trigger
|
|
int processPrecaptureTrigger(uint8_t aeMode, uint8_t aeState);
|
|
int maybeStartAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState);
|
|
int updateAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState,
|
|
nsecs_t *maxSleep);
|
|
void updateAeState(uint8_t newState, int32_t triggerId);
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Static configuration information
|
|
***************************************************************************/
|
|
private:
|
|
static const uint32_t kMaxRawStreamCount = 1;
|
|
static const uint32_t kMaxProcessedStreamCount = 3;
|
|
static const uint32_t kMaxJpegStreamCount = 1;
|
|
static const uint32_t kMaxReprocessStreamCount = 2;
|
|
static const uint32_t kMaxBufferCount = 4;
|
|
static const uint32_t kAvailableFormats[];
|
|
static const uint32_t kAvailableRawSizes[];
|
|
static const uint64_t kAvailableRawMinDurations[];
|
|
static const uint32_t kAvailableProcessedSizesBack[];
|
|
static const uint32_t kAvailableProcessedSizesFront[];
|
|
static const uint64_t kAvailableProcessedMinDurations[];
|
|
static const uint32_t kAvailableJpegSizesBack[];
|
|
static const uint32_t kAvailableJpegSizesFront[];
|
|
static const uint64_t kAvailableJpegMinDurations[];
|
|
|
|
/****************************************************************************
|
|
* Data members.
|
|
***************************************************************************/
|
|
|
|
protected:
|
|
/* Facing back (true) or front (false) switch. */
|
|
bool mFacingBack;
|
|
|
|
private:
|
|
bool mIsConnected;
|
|
|
|
int32_t mSensorWidth, mSensorHeight;
|
|
|
|
/** Stream manipulation */
|
|
uint32_t mNextStreamId;
|
|
uint32_t mRawStreamCount;
|
|
uint32_t mProcessedStreamCount;
|
|
uint32_t mJpegStreamCount;
|
|
|
|
uint32_t mNextReprocessStreamId;
|
|
uint32_t mReprocessStreamCount;
|
|
|
|
KeyedVector<uint32_t, Stream> mStreams;
|
|
KeyedVector<uint32_t, ReprocessStream> mReprocessStreams;
|
|
GraphicBufferMapper* mGBM;
|
|
|
|
/** Simulated hardware interfaces */
|
|
sp<Sensor> mSensor;
|
|
sp<JpegCompressor> mJpegCompressor;
|
|
|
|
/** Pipeline control threads */
|
|
sp<ConfigureThread> mConfigureThread;
|
|
sp<ReadoutThread> mReadoutThread;
|
|
sp<ControlThread> mControlThread;
|
|
};
|
|
|
|
}; /* namespace android */
|
|
|
|
#endif /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H */
|