/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __QCAMERA3HARDWAREINTERFACE_H__ #define __QCAMERA3HARDWAREINTERFACE_H__ // System dependencies #include #include #include #include #include #include // Camera dependencies #include "hardware/camera3.h" #include "QCamera3Channel.h" #include "QCamera3CropRegionMapper.h" #include "QCamera3HALHeader.h" #include "QCamera3Mem.h" #include "QCameraPerf.h" #include "QCameraCommon.h" #include "QCamera3VendorTags.h" #include "QCameraDualCamSettings.h" #include "QCamera3HdrPlusListenerThread.h" #include "EaselManagerClient.h" #include "HdrPlusClient.h" extern "C" { #include "mm_camera_interface.h" #include "mm_jpeg_interface.h" } using ::android::hardware::camera::common::V1_0::helper::CameraMetadata; using namespace android; namespace qcamera { #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif /* Time related macros */ typedef int64_t nsecs_t; #define NSEC_PER_SEC 1000000000LLU #define NSEC_PER_USEC 1000LLU #define NSEC_PER_33MSEC 33000000LLU /*Orchestrate Macros */ #define EV_COMP_SETTLE_DELAY 2 #define GB_HDR_HALF_STEP_EV -6 #define GB_HDR_2X_STEP_EV 6 #define FRAME_REGISTER_LRU_SIZE 256 #define INTERNAL_FRAME_STARTING_NUMBER 800 #define EMPTY_FRAMEWORK_FRAME_NUMBER 0xFFFFFFFF typedef enum { SET_ENABLE, SET_CONTROLENABLE, SET_RELOAD_CHROMATIX, SET_STATUS, } optype_t; #define MODULE_ALL 0 extern volatile uint32_t gCamHal3LogLevel; class QCamera3MetadataChannel; class QCamera3PicChannel; class QCamera3HeapMemory; class QCamera3Exif; class ShutterDispatcher; class BufferDispatcher; typedef struct { camera3_stream_t *stream; camera3_stream_buffer_set_t buffer_set; stream_status_t status; int registered; QCamera3ProcessingChannel *channel; uint32_t id; // unique ID } stream_info_t; typedef struct { // Stream handle camera3_stream_t *stream; // Buffer handle buffer_handle_t *buffer; // Buffer status camera3_buffer_status_t bufStatus = CAMERA3_BUFFER_STATUS_OK; } PendingBufferInfo; typedef struct { // Frame number corresponding to request uint32_t frame_number; // Time when request queued into system nsecs_t timestamp; nsecs_t av_timestamp; List mPendingBufferList; std::shared_ptr mHdrplusInputBuf; std::shared_ptr mHdrplusInputMetaBuf; } PendingBuffersInRequest; class PendingBuffersMap { public: // Number of outstanding buffers at flush uint32_t numPendingBufsAtFlush; // List of pending buffers per request List mPendingBuffersInRequest; uint32_t get_num_overall_buffers(); void removeBuf(buffer_handle_t *buffer); int32_t getBufErrStatus(buffer_handle_t *buffer); }; class FrameNumberRegistry { public: FrameNumberRegistry(); ~FrameNumberRegistry(); int32_t allocStoreInternalFrameNumber(uint32_t frameworkFrameNumber, uint32_t &internalFrameNumber); int32_t generateStoreInternalFrameNumber(uint32_t &internalFrameNumber); int32_t freeInternalFrameNumber(uint32_t internalFrameNumber); int32_t getFrameworkFrameNumber(uint32_t internalFrameNumber, uint32_t &frameworkFrameNumber); void purgeOldEntriesLocked(); private: std::map _register; uint32_t _nextFreeInternalNumber; Mutex mRegistryLock; }; class QCamera3HardwareInterface; /* * ShutterDispatcher class dispatches shutter callbacks in order of the frame * number. It will dispatch a shutter callback only after all shutter callbacks * of previous frames were dispatched. */ class ShutterDispatcher { public: ShutterDispatcher(QCamera3HardwareInterface *parent); virtual ~ShutterDispatcher() = default; // Tell dispatch to expect a shutter for a frame number. void expectShutter(uint32_t frameNumber, bool isReprocess, bool isZsl); // Mark a shutter callback for a frame ready. void markShutterReady(uint32_t frameNumber, uint64_t timestamp); // Discard a pending shutter for frame number. void clear(uint32_t frameNumber); // Discard all pending shutters. void clear(); private: struct Shutter { bool ready; // If the shutter is ready. uint64_t timestamp; // Timestamp of the shutter. Shutter() : ready(false), timestamp(0) {}; }; std::mutex mLock; // frame number -> shutter map. Protected by mLock. std::map mShutters; std::map mReprocessShutters; std::map mZslShutters; QCamera3HardwareInterface *mParent; }; /* * BufferDispatcher class dispatches output buffers in a stream in order of the * frame number. It will dispatch an output buffer in a stream only after all * previous output buffers in the same stream were dispatched. */ class OutputBufferDispatcher { public: OutputBufferDispatcher(QCamera3HardwareInterface *parent); virtual ~OutputBufferDispatcher() = default; // Configure streams. status_t configureStreams(camera3_stream_configuration_t *streamList); // Tell dispatcher to expect a buffer for a stream for a frame number. status_t expectBuffer(uint32_t frameNumber, camera3_stream_t *stream); // Mark a buffer ready for a stream for a frame number. void markBufferReady(uint32_t frameNumber, const camera3_stream_buffer_t &buffer); // Discard all pending buffers. If clearConfiguredStreams is true, discard configured streams // as well. void clear(bool clearConfiguredStreams = true); private: struct Buffer { bool ready; // If the buffer is ready. camera3_stream_buffer_t buffer; Buffer() : ready(false), buffer({}) {}; }; std::mutex mLock; // A two-level map: stream -> (frame number -> buffer). Protected by mLock. std::map> mStreamBuffers; QCamera3HardwareInterface *mParent; }; class QCamera3HardwareInterface : public HdrPlusClientListener, public EaselManagerClientListener { public: /* static variable and functions accessed by camera service */ static camera3_device_ops_t mCameraOps; //Id of each session in bundle/link static uint32_t sessionId[MM_CAMERA_MAX_NUM_SENSORS]; static int initialize(const struct camera3_device *, const camera3_callback_ops_t *callback_ops); static int configure_streams(const struct camera3_device *, camera3_stream_configuration_t *stream_list); static const camera_metadata_t* construct_default_request_settings( const struct camera3_device *, int type); static int process_capture_request(const struct camera3_device *, camera3_capture_request_t *request); static void dump(const struct camera3_device *, int fd); static int flush(const struct camera3_device *); static int close_camera_device(struct hw_device_t* device); public: QCamera3HardwareInterface(uint32_t cameraId, const camera_module_callbacks_t *callbacks); virtual ~QCamera3HardwareInterface(); static void camEvtHandle(uint32_t camera_handle, mm_camera_event_t *evt, void *user_data); int openCamera(struct hw_device_t **hw_device); camera_metadata_t* translateCapabilityToMetadata(int type); typedef struct { camera3_stream_t *stream; bool need_metadata; bool meteringOnly; } InternalRequest; static int getCamInfo(uint32_t cameraId, struct camera_info *info); static int isStreamCombinationSupported(uint32_t cameraId, const camera_stream_combination_t *streams); static cam_capability_t *getCapabilities(mm_camera_ops_t *ops, uint32_t cam_handle); static int initCapabilities(uint32_t cameraId); static int initStaticMetadata(uint32_t cameraId); static int initHdrPlusClientLocked(); static void makeTable(cam_dimension_t *dimTable, size_t size, size_t max_size, int32_t *sizeTable); static void makeFPSTable(cam_fps_range_t *fpsTable, size_t size, size_t max_size, int32_t *fpsRangesTable); static void makeOverridesList(cam_scene_mode_overrides_t *overridesTable, size_t size, size_t max_size, uint8_t *overridesList, uint8_t *supported_indexes, uint32_t camera_id); static size_t filterJpegSizes(int32_t *jpegSizes, int32_t *processedSizes, size_t processedSizesCnt, size_t maxCount, cam_rect_t active_array_size, uint8_t downscale_factor); static void convertToRegions(cam_rect_t rect, int32_t* region, int weight); static void convertFromRegions(cam_area_t &roi, const CameraMetadata &frame_settings, uint32_t tag); static bool resetIfNeededROI(cam_area_t* roi, const cam_crop_region_t* scalerCropRegion); static int32_t getSensorSensitivity(int32_t iso_mode); double computeNoiseModelEntryS(int32_t sensitivity); double computeNoiseModelEntryO(int32_t sensitivity); static void captureResultCb(mm_camera_super_buf_t *metadata, camera3_stream_buffer_t *buffer, uint32_t frame_number, bool isInputBuffer, void *userdata); int initialize(const camera3_callback_ops_t *callback_ops); int configureStreams(camera3_stream_configuration_t *stream_list); int configureStreamsPerfLocked(camera3_stream_configuration_t *stream_list); int processCaptureRequest(camera3_capture_request_t *request, List &internalReqs); int orchestrateRequest(camera3_capture_request_t *request); void orchestrateResult(camera3_capture_result_t *result); void orchestrateNotify(camera3_notify_msg_t *notify_msg); void dump(int fd); int flushPerf(); int setFrameParameters(camera3_capture_request_t *request, cam_stream_ID_t streamID, int blob_request, uint32_t snapshotStreamId); int32_t setReprocParameters(camera3_capture_request_t *request, metadata_buffer_t *reprocParam, uint32_t snapshotStreamId); int translateToHalMetadata(const camera3_capture_request_t *request, metadata_buffer_t *parm, uint32_t snapshotStreamId); int translateFwkMetadataToHalMetadata(const camera_metadata_t *frameworkMetadata, metadata_buffer_t *hal_metadata, uint32_t snapshotStreamId, int64_t minFrameDuration); camera_metadata_t* saveRequestSettings(const CameraMetadata& jpegMetadata, camera3_capture_request_t *request); int initParameters(); void deinitParameters(); QCamera3ReprocessChannel *addOfflineReprocChannel(const reprocess_config_t &config, QCamera3ProcessingChannel *inputChHandle); bool needRotationReprocess(); bool needJpegExifRotation(); bool needReprocess(cam_feature_mask_t postprocess_mask); bool needJpegRotation(); cam_denoise_process_type_t getWaveletDenoiseProcessPlate(); cam_denoise_process_type_t getTemporalDenoiseProcessPlate(); void captureResultCb(mm_camera_super_buf_t *metadata, camera3_stream_buffer_t *buffer, uint32_t frame_number, bool isInputBuffer); cam_dimension_t calcMaxJpegDim(); bool needOnlineRotation(); uint32_t getJpegQuality(); QCamera3Exif *getExifData(); mm_jpeg_exif_params_t get3AExifParams(); uint8_t getMobicatMask(); static void getFlashInfo(const int cameraId, bool& hasFlash, char (&flashNode)[QCAMERA_MAX_FILEPATH_LENGTH]); const char *getEepromVersionInfo(); const uint32_t *getLdafCalib(); const char *getEaselFwVersion(); void get3AVersion(cam_q3a_version_t &swVersion); static void setBufferErrorStatus(QCamera3Channel*, uint32_t frameNumber, camera3_buffer_status_t err, void *userdata); void setBufferErrorStatus(QCamera3Channel*, uint32_t frameNumber, camera3_buffer_status_t err); bool is60HzZone(); // Get dual camera related info bool isDeviceLinked() {return mIsDeviceLinked;} bool isMainCamera() {return mIsMainCamera;} uint32_t getSensorMountAngle(); const cam_related_system_calibration_data_t *getRelatedCalibrationData(); template struct QCameraMap { fwkType fwk_name; halType hal_name; }; typedef struct { const char *const desc; cam_cds_mode_type_t val; } QCameraPropMap; private: // State transition conditions: // "\" means not applicable // "x" means not valid // +------------+----------+----------+-------------+------------+---------+-------+--------+ // | | CLOSED | OPENED | INITIALIZED | CONFIGURED | STARTED | ERROR | DEINIT | // +------------+----------+----------+-------------+------------+---------+-------+--------+ // | CLOSED | \ | open | x | x | x | x | x | // +------------+----------+----------+-------------+------------+---------+-------+--------+ // | OPENED | close | \ | initialize | x | x | error | x | // +------------+----------+----------+-------------+------------+---------+-------+--------+ // |INITIALIZED | close | x | \ | configure | x | error | x | // +------------+----------+----------+-------------+------------+---------+-------+--------+ // | CONFIGURED | close | x | x | configure | request | error | x | // +------------+----------+----------+-------------+------------+---------+-------+--------+ // | STARTED | close | x | x | configure | \ | error | x | // +------------+----------+----------+-------------+------------+---------+-------+--------+ // | ERROR | close | x | x | x | x | \ | any | // +------------+----------+----------+-------------+------------+---------+-------+--------+ // | DEINIT | close | x | x | x | x | x | \ | // +------------+----------+----------+-------------+------------+---------+-------+--------+ typedef enum { CLOSED, OPENED, INITIALIZED, CONFIGURED, STARTED, ERROR, DEINIT } State; int openCamera(); int closeCamera(); int flush(bool restartChannels, bool stopChannelImmediately = false); static size_t calcMaxJpegSize(uint32_t camera_id); cam_dimension_t getMaxRawSize(uint32_t camera_id); static void addStreamConfig(Vector &available_stream_configs, int32_t scalar_format, const cam_dimension_t &dim, int32_t config_type); struct StreamValidateStatus { bool bIsVideo, bIs4KVideo, bEisSupportedSize, depthPresent, bUseCommonFeatureMask; bool isZsl, bSmallJpegSize, bYuv888OverrideJpeg, bEisSupported, bY80OnEncoder; camera3_stream *inputStream; cam_feature_mask_t commonFeatureMask; size_t numStreamsOnEncoder; uint32_t videoWidth, videoHeight; cam_dimension_t maxViewfinderSize, largeYuv888Size; StreamValidateStatus() : bIsVideo(false), bIs4KVideo(false), bEisSupportedSize(true), depthPresent(false), bUseCommonFeatureMask(false), isZsl(false), bSmallJpegSize(false), bYuv888OverrideJpeg(false), bEisSupported(false), bY80OnEncoder(false), inputStream(nullptr), commonFeatureMask(0), numStreamsOnEncoder(0), videoWidth(0U), videoHeight(0U) {}; }; static int32_t validateStreamCombination(uint32_t cameraId, camera3_stream_configuration_t *streamList /*in*/, StreamValidateStatus *status /*out*/); int validateCaptureRequest(camera3_capture_request_t *request, List &internallyRequestedStreams); static int validateStreamDimensions(uint32_t cameraId, camera3_stream_configuration_t *streamList); static int validateStreamRotations(camera3_stream_configuration_t *streamList); static int validateUsageFlags(uint32_t cameraId, const camera3_stream_configuration_t *streamList); static int validateUsageFlagsForEis(bool bEisEnable, bool bEisSupportedSize, const camera3_stream_configuration_t *streamList); void deriveMinFrameDuration(); void handleBuffersDuringFlushLock(camera3_stream_buffer_t *buffer); int64_t getMinFrameDuration(const camera3_capture_request_t *request); void handleMetadataWithLock(mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf, bool lastUrgentMetadataInBatch, bool lastMetadataInBatch, bool *p_is_metabuf_queued); void handleBatchMetadata(mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf); void handleBufferWithLock(camera3_stream_buffer_t *buffer, uint32_t frame_number); void handleInputBufferWithLock(uint32_t frame_number); // Handle pending results when a new result metadata of a frame is received. // metadata callbacks are invoked in the order of frame number. void handlePendingResultMetadataWithLock(uint32_t frameNumber, camera_metadata_t *resultMetadata); // Going through pending request list and send out result metadata for requests // that are ready. // frameNumber is the lastest frame whose result metadata is ready. typedef enum { NORMAL, REPROCESS, ZSL } RequestType; void dispatchResultMetadataWithLock(uint32_t frameNumber, RequestType requestType, bool isHdrPlus); void handleDepthDataLocked(const cam_depth_data_t &depthData, uint32_t frameNumber, uint8_t valid); void notifyErrorFoPendingDepthData(QCamera3DepthChannel *depthCh); void unblockRequestIfNecessary(); void dumpMetadataToFile(tuning_params_t &meta, uint32_t &dumpFrameCount, bool enabled, const char *type, uint32_t frameNumber); static void getLogLevel(); static int32_t getPDStatIndex(cam_capability_t *caps); void cleanAndSortStreamInfo(); void extractJpegMetadata(CameraMetadata& jpegMetadata, const camera3_capture_request_t *request); bool isSupportChannelNeeded(camera3_stream_configuration_t *streamList, cam_stream_size_info_t stream_config_info); bool isHdrSnapshotRequest(camera3_capture_request *request); int32_t setMobicat(); int32_t getSensorModeInfo(cam_sensor_mode_info_t &sensorModeInfo); // Get information of the sensor mode that is currently selected. int32_t getCurrentSensorModeInfo(cam_sensor_mode_info_t &sensorModeInfo); int32_t setHalFpsRange(const CameraMetadata &settings, metadata_buffer_t *hal_metadata); int32_t extractSceneMode(const CameraMetadata &frame_settings, uint8_t metaMode, metadata_buffer_t *hal_metadata); int32_t setVideoHdrMode(metadata_buffer_t *hal_metadata, cam_video_hdr_mode_t vhdr); int32_t numOfSizesOnEncoder(const camera3_stream_configuration_t *streamList, const cam_dimension_t &maxViewfinderSize); void addToPPFeatureMask(int stream_format, uint32_t stream_idx); void updateFpsInPreviewBuffer(metadata_buffer_t *metadata, uint32_t frame_number); void updateTimeStampInPendingBuffers(uint32_t frameNumber, nsecs_t timestamp); void enablePowerHint(); void disablePowerHint(); int32_t dynamicUpdateMetaStreamInfo(); int32_t startAllChannels(); int32_t stopAllChannels(); int32_t notifyErrorForPendingRequests(); void notifyError(uint32_t frameNumber, camera3_error_msg_code_t errorCode); int32_t getReprocessibleOutputStreamId(uint32_t &id); int32_t handleCameraDeviceError(bool stopChannelImmediately = false); bool isEISEnabled(const CameraMetadata& meta); static bool isOnEncoder(const cam_dimension_t max_viewfinder_size, uint32_t width, uint32_t height); void hdrPlusPerfLock(mm_camera_super_buf_t *metadata_buf); static bool supportBurstCapture(uint32_t cameraId); int32_t setBundleInfo(); int32_t setInstantAEC(const CameraMetadata &meta); static void convertLandmarks(cam_face_landmarks_info_t face, int32_t* landmarks); static void setInvalidLandmarks(int32_t* landmarks); static void setPAAFSupport(cam_feature_mask_t& feature_mask, cam_stream_type_t stream_type, cam_color_filter_arrangement_t filter_arrangement); int32_t setSensorHDR(metadata_buffer_t *hal_metadata, bool enable, bool isVideoHdrEnable = false); template static void adjustBlackLevelForCFA(T input[BLACK_LEVEL_PATTERN_CNT], T output[BLACK_LEVEL_PATTERN_CNT], cam_color_filter_arrangement_t color_arrangement); int32_t startChannelLocked(); void stopChannelLocked(bool stopChannelImmediately); camera3_device_t mCameraDevice; uint32_t mCameraId; mm_camera_vtbl_t *mCameraHandle; bool mCameraInitialized; camera_metadata_t *mDefaultMetadata[CAMERA3_TEMPLATE_COUNT]; const camera3_callback_ops_t *mCallbackOps; QCamera3MetadataChannel *mMetadataChannel; QCamera3PicChannel *mPictureChannel; QCamera3RawChannel *mRawChannel; QCamera3SupportChannel *mSupportChannel; QCamera3SupportChannel *mAnalysisChannel; QCamera3RawDumpChannel *mRawDumpChannel; QCamera3HdrPlusRawSrcChannel *mHdrPlusRawSrcChannel; QCamera3RegularChannel *mDummyBatchChannel; QCamera3DepthChannel *mDepthChannel; cam_sensor_pd_data_t mDepthCloudMode; //Cache last configured mode QCameraPerfLockMgr mPerfLockMgr; uint32_t mChannelHandle; void saveExifParams(metadata_buffer_t *metadata); mm_jpeg_exif_params_t mExifParams; //First request yet to be processed after configureStreams bool mFirstConfiguration; bool mFlush; bool mFlushPerf; bool mEnableRawDump; bool mForceHdrSnapshot; QCamera3HeapMemory *mParamHeap; metadata_buffer_t* mParameters; metadata_buffer_t* mPrevParameters; CameraMetadata mCurJpegMeta; cam_is_type_t m_ISTypeVideo; bool m_bIsVideo; bool m_bIs4KVideo; bool m_bEisSupportedSize; bool m_bEisEnable; bool m_bEis3PropertyEnabled; bool m_bEisSupported; bool m_bAVTimerEnabled; typedef struct { cam_dimension_t dim; int format; uint32_t usage; } InputStreamInfo; InputStreamInfo mInputStreamInfo; uint8_t m_MobicatMask; uint8_t m_bTnrEnabled; int8_t mSupportedFaceDetectMode; uint8_t m_bTnrPreview; uint8_t m_bSwTnrPreview; uint8_t m_bTnrVideo; uint8_t m_debug_avtimer; uint8_t m_bVideoHdrEnabled; uint8_t m_cacModeDisabled; uint8_t m_bForceInfinityAf; /* Data structure to store pending request */ typedef struct { camera3_stream_t *stream; camera3_stream_buffer_t *buffer; // metadata needs to be consumed by the corresponding stream // in order to generate the buffer. bool need_metadata; // Do we need additional crop due to EIS. bool need_crop; cam_eis_crop_info_t crop_info; } RequestedBufferInfo; typedef struct { uint32_t frame_number; uint32_t num_buffers; int32_t request_id; List buffers; List internalRequestList; int blob_request; uint8_t bUseFirstPartial; // Use first available partial result in case of jumpstart. nsecs_t timestamp; nsecs_t expectedFrameDuration; camera3_stream_buffer_t *input_buffer; const camera_metadata_t *settings; const camera_metadata_t *resultMetadata; // Result metadata for this request. CameraMetadata jpegMetadata; uint8_t pipeline_depth; uint32_t partial_result_cnt; uint8_t capture_intent; uint8_t fwkCacMode; uint8_t hybrid_ae_enable; uint8_t motion_detection_enable; /* DevCamDebug metadata PendingRequestInfo */ uint8_t DevCamDebug_meta_enable; /* DevCamDebug metadata end */ bool focusStateSent = false; bool focusStateValid = false; uint8_t focusState = ANDROID_CONTROL_AF_STATE_INACTIVE; bool enableZsl; // If ZSL is enabled. bool hdrplus; // If this is an HDR+ request. uint8_t requestedLensShadingMapMode; // Lens shading map mode for this request. uint8_t requestedFaceDetectMode; // Face detect mode for this request. bool partialResultDropped; // Whether partial metadata is dropped. uint8_t requestedOisDataMode; // OIS data mode for this request. float zoomRatio; } PendingRequestInfo; typedef struct { uint32_t frame_number; uint32_t stream_ID; } PendingFrameDropInfo; class FrameNumberRegistry _orchestrationDb; typedef KeyedVector > FlushMap; typedef List::iterator pendingRequestIterator; typedef List::iterator pendingBufferIterator; List mPendingRequestsList; List mPendingFrameDropList; /* Use last frame number of the batch as key and first frame number of the * batch as value for that key */ KeyedVector mPendingBatchMap; cam_stream_ID_t mBatchedStreamsArray; PendingBuffersMap mPendingBuffersMap; pthread_cond_t mRequestCond; uint32_t mPendingLiveRequest; bool mWokenUpByDaemon; int32_t mCurrentRequestId; cam_stream_size_info_t mStreamConfigInfo; ShutterDispatcher mShutterDispatcher; OutputBufferDispatcher mOutputBufferDispatcher; //mutex for serialized access to camera3_device_ops_t functions pthread_mutex_t mMutex; //condition used to signal flush after buffers have returned pthread_cond_t mBuffersCond; List mStreamInfo; int64_t mMinProcessedFrameDuration; int64_t mMinJpegFrameDuration; int64_t mMinRawFrameDuration; nsecs_t mExpectedFrameDuration; nsecs_t mExpectedInflightDuration; static const nsecs_t kDefaultExpectedDuration = 100000000; // 100 ms uint32_t mMetaFrameCount; bool mUpdateDebugLevel; const camera_module_callbacks_t *mCallbacks; uint8_t mCaptureIntent; uint8_t mCacMode; // DevCamDebug metadata internal variable uint8_t mDevCamDebugMetaEnable; /* DevCamDebug metadata end */ metadata_buffer_t mReprocMeta; //scratch meta buffer /* 0: Not batch, non-zero: Number of image buffers in a batch */ uint8_t mBatchSize; // Used only in batch mode uint8_t mToBeQueuedVidBufs; // Fixed video fps float mHFRVideoFps; public: uint32_t mOpMode; bool mStreamConfig; QCameraCommon mCommon; private: uint32_t mFirstFrameNumberInBatch; camera3_stream_t mDummyBatchStream; bool mNeedSensorRestart; bool mPreviewStarted; uint32_t mMinInFlightRequests; uint32_t mMaxInFlightRequests; bool mPDSupported; int32_t mPDIndex; // Param to trigger instant AEC. bool mInstantAEC; // Param to know when to reset AEC bool mResetInstantAEC; // Frame number, untill which we need to drop the frames. uint32_t mInstantAECSettledFrameNumber; // Max number of frames, that HAL will hold without displaying, for instant AEC mode. uint8_t mAecSkipDisplayFrameBound; // Counter to keep track of number of frames that took for AEC convergence. uint8_t mInstantAecFrameIdxCount; /* sensor output size with current stream configuration */ QCamera3CropRegionMapper mCropRegionMapper; // Last lens shading map mode framework requsted. uint8_t mLastRequestedLensShadingMapMode; // Last face detect mode framework requsted. uint8_t mLastRequestedFaceDetectMode; // Last OIS data mode framework requested. uint8_t mLastRequestedOisDataMode; // Last zoom ratio framework requested float mLastRequestedZoomRatio; cam_feature_mask_t mCurrFeatureState; /* Ldaf calibration data */ bool mLdafCalibExist; uint32_t mLdafCalib[2]; int32_t mLastCustIntentFrmNum; // Easel firmware version char mEaselFwVersion[FW_VER_SIZE]; bool mEaselFwUpdated; static const QCameraMap EFFECT_MODES_MAP[]; static const QCameraMap WHITE_BALANCE_MODES_MAP[]; static const QCameraMap SCENE_MODES_MAP[]; static const QCameraMap FOCUS_MODES_MAP[]; static const QCameraMap COLOR_ABERRATION_MAP[]; static const QCameraMap ANTIBANDING_MODES_MAP[]; static const QCameraMap LENS_STATE_MAP[]; static const QCameraMap AE_FLASH_MODE_MAP[]; static const QCameraMap FLASH_MODES_MAP[]; static const QCameraMap FACEDETECT_MODES_MAP[]; static const QCameraMap FOCUS_CALIBRATION_MAP[]; static const QCameraMap TEST_PATTERN_MAP[]; static const QCameraMap VIDEO_HDR_MODES_MAP[]; static const QCameraMap REFERENCE_ILLUMINANT_MAP[]; static const QCameraMap HFR_MODE_MAP[]; static const QCameraMap IR_MODES_MAP[]; static const QCameraMap INSTANT_AEC_MODES_MAP[]; static const QCameraMap BINNING_CORRECTION_MODES_MAP[]; static const QCameraMap AEC_MODES_MAP[]; static const QCameraMap ISO_MODES_MAP[]; static const QCameraPropMap CDS_MAP[]; pendingRequestIterator erasePendingRequest(pendingRequestIterator i); // Remove unrequested metadata due to Easel HDR+. void removeUnrequestedMetadata(pendingRequestIterator requestIter, camera_metadata_t *resultMetadata); //GPU library to read buffer padding details. void *lib_surface_utils; int (*LINK_get_surface_pixel_alignment)(); uint32_t mSurfaceStridePadding; bool mFirstMetadataCallback; void sendPartialMetadataWithLock(metadata_buffer_t *metadata, const pendingRequestIterator requestIter, bool lastUrgentMetadataInBatch, bool isJumpstartMetadata); camera_metadata_t* translateFromHalMetadata(metadata_buffer_t *metadata, const PendingRequestInfo& pendingRequest, /* DevCamDebug metadata end */ bool pprocDone, bool lastMetadataInBatch, const bool *enableZsl); camera_metadata_t* translateCbUrgentMetadataToResultMetadata ( metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch, const pendingRequestIterator requestIter, bool isJumpstartMetadata); State mState; //Dual camera related params bool mIsDeviceLinked; bool mIsMainCamera; uint8_t mLinkedCameraId; QCamera3HeapMemory *m_pDualCamCmdHeap; cam_dual_camera_cmd_info_t *m_pDualCamCmdPtr; cam_sync_related_sensors_event_info_t m_relCamSyncInfo; Mutex mFlushLock; bool m60HzZone; // Issue an additional RAW for every 10 requests to control RAW capture rate. Requesting RAW // too often will cause frame drops due to latency of sending RAW to HDR+ service. const static uint32_t kHdrPlusRawPeriod = 10; // Define a pending HDR+ request submitted to HDR+ service and not yet received by HAL. struct HdrPlusPendingRequest { // HDR+ stream ID -> output buffer to be filled by HDR+ client with an HDR+ processed frame. std::map> outputBuffers; // HDR+ stream ID -> output buffers in camera framework's request. std::map frameworkOutputBuffers; // Settings in camera framework's request. std::shared_ptr settings; }; // Fill pbcamera::StreamConfiguration based on the channel stream. status_t fillPbStreamConfig(pbcamera::StreamConfiguration *config, uint32_t pbStreamId, QCamera3Channel *channel, uint32_t streamIndex); // Open HDR+ client asynchronously. status_t openHdrPlusClientAsyncLocked(); // Enable HDR+ mode. Easel will start capturing ZSL buffers. status_t enableHdrPlusModeLocked(); // Disable HDR+ mode. Easel will stop capturing ZSL buffers. void disableHdrPlusModeLocked(); // Return if current session with configured streams is compatible with HDR+ mode. bool isSessionHdrPlusModeCompatible(); // Return if the request is compatible with HDR+. bool isRequestHdrPlusCompatible( const camera3_capture_request_t &request, const CameraMetadata &metadata); // Configure streams for HDR+. status_t configureHdrPlusStreamsLocked(); // Check whether additional EIS crop is needed. bool isEISCropInSnapshotNeeded(const CameraMetadata &metadata) const; // Various crop sanity checks. bool isCropValid(int32_t startX, int32_t startY, int32_t width, int32_t height, int32_t maxWidth, int32_t maxHeight) const; // Try to submit an HDR+ request. Returning true if an HDR+ request was submitted. Returning // false if it is not an HDR+ request or submitting an HDR+ request failed. Must be called with // gHdrPlusClientLock held. bool trySubmittingHdrPlusRequestLocked(HdrPlusPendingRequest *hdrPlusRequest, const camera3_capture_request_t &request, const CameraMetadata &metadata); // Abort an HDR+ request that was not submitted successfully in // trySubmittingHdrPlusRequestLocked. void abortPendingHdrplusRequest(HdrPlusPendingRequest *hdrPlusRequest); // Update HDR+ result metadata with the still capture's request settings. void updateHdrPlusResultMetadata(CameraMetadata &resultMetadata, std::shared_ptr settings); // Wait until opening HDR+ client completes if it's being opened. void finishHdrPlusClientOpeningLocked(std::unique_lock &lock); // Handle Easel error asynchronuously in another thread. void handleEaselFatalErrorAsync(); // Handle Easel error. void handleEaselFatalError(); // Close HDR+ client. Must be protected by gHdrPlusClientLock. void closeHdrPlusClientLocked(); // Easel manager client callbacks. void onEaselFatalError(std::string errMsg); void onThermalThrottle(); // Clean up and wait for Easel error future. void cleanupEaselErrorFuture(); // HDR+ client callbacks. void onOpened(std::unique_ptr client) override; void onOpenFailed(status_t err) override; void onFatalError() override; void onCaptureResult(pbcamera::CaptureResult *result, const camera_metadata_t &resultMetadata) override; void onFailedCaptureResult(pbcamera::CaptureResult *failedResult) override; void onShutter(uint32_t requestId, int64_t apSensorTimestampNs) override; void onNextCaptureReady(uint32_t requestId) override; void onPostview(uint32_t requestId, std::unique_ptr> postview, uint32_t width, uint32_t height, uint32_t stride, int32_t format) override; nsecs_t calculateMaxExpectedDuration(const camera_metadata_t *request); void getExpectedFrameDuration(const camera_metadata_t *request, nsecs_t *frameDuration); // Map from frame number to frame. Must be protected by mHdrPlusPendingRequestsLock. std::map mHdrPlusPendingRequests; Mutex mHdrPlusPendingRequestsLock; // If HDR+ mode is enabled i.e. if Easel is capturing ZSL buffers. bool mHdrPlusModeEnabled; // If ZSL is enabled (android.control.enableZsl). bool mZslEnabled; // If Easel MIPI has been started. bool mEaselMipiStarted; // If HAL provides RAW input buffers to Easel. This is just for prototyping. bool mIsApInputUsedForHdrPlus; // Current sensor mode information. cam_sensor_mode_info_t mSensorModeInfo; // If there is a capture request with preview intent since stream configuration. bool mFirstPreviewIntentSeen; bool m_bSensorHDREnabled; cam_trigger_t mAfTrigger; int32_t mSceneDistance; std::mutex mEaselErrorFutureLock; std::future mEaselErrorFuture; // If HDR+ should be thermal throttled. std::atomic mEaselThermalThrottled = false; // Thread to handle callbacks from HDR+ client. Protected by gHdrPlusClientLock. sp mQCamera3HdrPlusListenerThread; // Read sensor calibration XML file for lens calibration fields. On failure to read // the file, leaves passed-in values unchanged and returns false. static bool readSensorCalibration(int activeArrayWidth, float poseRotation[4], float poseTranslation[3], float cameraIntrinsics[5], float radialDistortion[6]); // Parse a string of form " [ x; y; z ...]" into a floating-point array. // Returns false on parse error static bool parseStringArray(const char *str, float *dest, int count); static bool isStillZsl(const PendingRequestInfo& requestInfo) { return requestInfo.enableZsl && requestInfo.capture_intent == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; } float mLastFocusDistance; // Last cached EIS crop info. cam_eis_crop_info_t mLastEISCropInfo; // Maps between active region and specific stream crop. QCamera3CropRegionMapper mStreamCropMapper; }; }; // namespace qcamera #endif /* __QCAMERA2HARDWAREINTERFACE_H__ */