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.
336 lines
13 KiB
336 lines
13 KiB
/*
|
|
* Copyright (C) 2023 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <chrono>
|
|
#include <deque>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <thread>
|
|
|
|
#include <aidl/android/hardware/camera/common/Status.h>
|
|
#include <aidl/android/hardware/camera/device/BnCameraDeviceSession.h>
|
|
|
|
#include <fmq/AidlMessageQueue.h>
|
|
|
|
#include "BlockingQueue.h"
|
|
#include "HwCamera.h"
|
|
#include "StreamBufferCache.h"
|
|
#include <unordered_map>
|
|
|
|
#include "HandleImporter.h"
|
|
#include <fmq/MessageQueue.h>
|
|
#include <aidl/android/hardware/camera/device/NotifyMsg.h>
|
|
|
|
#include <hardware/gralloc1.h>
|
|
#define RK_GRALLOC_USAGE_RANGE_FULL GRALLOC1_CONSUMER_USAGE_PRIVATE_17
|
|
#define RK_GRALLOC_USAGE_YUV_COLOR_SPACE_BT601 GRALLOC1_CONSUMER_USAGE_PRIVATE_18
|
|
#define GRALLOC_USAGE_PRIVATE_11 (1ULL << 56)
|
|
/* Gralloc 4.0 中, 表征 "调用 alloc() 的 client 要求分配的 buffer 的所有物理 page 的地址都在 4G 以内".
|
|
*/
|
|
#define RK_GRALLOC_USAGE_RGA_ACCESS GRALLOC_USAGE_PRIVATE_11
|
|
|
|
namespace android {
|
|
namespace hardware {
|
|
namespace camera {
|
|
namespace device {
|
|
namespace implementation {
|
|
|
|
using aidl::android::hardware::camera::common::Status;
|
|
|
|
using aidl::android::hardware::camera::device::BnCameraDeviceSession;
|
|
using aidl::android::hardware::camera::device::BufferCache;
|
|
using aidl::android::hardware::camera::device::CameraMetadata;
|
|
using aidl::android::hardware::camera::device::CameraOfflineSessionInfo;
|
|
using aidl::android::hardware::camera::device::CaptureRequest;
|
|
using aidl::android::hardware::camera::device::CaptureResult;
|
|
using aidl::android::hardware::camera::device::HalStream;
|
|
using aidl::android::hardware::camera::device::ICameraDeviceCallback;
|
|
using aidl::android::hardware::camera::device::ICameraOfflineSession;
|
|
using aidl::android::hardware::camera::device::RequestTemplate;
|
|
using aidl::android::hardware::camera::device::StreamBuffer;
|
|
using aidl::android::hardware::camera::device::StreamConfiguration;
|
|
|
|
using aidl::android::hardware::common::fmq::MQDescriptor;
|
|
using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
|
|
|
|
using aidl::android::hardware::graphics::common::BufferUsage;
|
|
using aidl::android::hardware::graphics::common::PixelFormat;
|
|
|
|
using ndk::ScopedAStatus;
|
|
|
|
using ::android::hardware::camera::external::common::helper::HandleImporter;
|
|
|
|
|
|
using ::android::hardware::kSynchronizedReadWrite;
|
|
using ::android::hardware::MessageQueue;
|
|
|
|
using ::aidl::android::hardware::camera::device::NotifyMsg;
|
|
|
|
struct CameraDevice;
|
|
|
|
|
|
// The camera3_stream_t sent to conventional HAL. Added mId fields to enable stream ID lookup
|
|
// fromt a downcasted camera3_stream
|
|
struct Camera3Stream : public camera3_stream {
|
|
int mId;
|
|
};
|
|
|
|
/**
|
|
* Function pointer types with C calling convention to
|
|
* use for HAL callback functions.
|
|
*/
|
|
extern "C" {
|
|
typedef void (callbacks_process_capture_result_t)(
|
|
const struct camera3_callback_ops *,
|
|
const camera3_capture_result_t *);
|
|
|
|
typedef void (callbacks_notify_t)(
|
|
const struct camera3_callback_ops *,
|
|
const camera3_notify_msg_t *);
|
|
}
|
|
|
|
struct CameraDeviceSession : public BnCameraDeviceSession,protected camera3_callback_ops{
|
|
CameraDeviceSession(std::shared_ptr<CameraDevice> parent,
|
|
std::shared_ptr<ICameraDeviceCallback> cb,
|
|
hw::HwCamera& hwCamera);
|
|
~CameraDeviceSession() override;
|
|
|
|
ScopedAStatus close() override;
|
|
bool isClosed();
|
|
ScopedAStatus configureStreams(const StreamConfiguration& cfg,
|
|
std::vector<HalStream>* halStreamsOut) override;
|
|
ScopedAStatus constructDefaultRequestSettings(RequestTemplate tpl,
|
|
CameraMetadata* metadata) override;
|
|
ScopedAStatus flush() override;
|
|
ScopedAStatus getCaptureRequestMetadataQueue(
|
|
MQDescriptor<int8_t, SynchronizedReadWrite>* desc) override;
|
|
ScopedAStatus getCaptureResultMetadataQueue(
|
|
MQDescriptor<int8_t, SynchronizedReadWrite>* desc) override;
|
|
ScopedAStatus isReconfigurationRequired(const CameraMetadata& oldSessionParams,
|
|
const CameraMetadata& newSessionParams,
|
|
bool* result) override;
|
|
ScopedAStatus processCaptureRequest(const std::vector<CaptureRequest>& requests,
|
|
const std::vector<BufferCache>& cachesToRemove,
|
|
int32_t* count) override;
|
|
ScopedAStatus signalStreamFlush(const std::vector<int32_t>& streamIds,
|
|
int32_t streamConfigCounter) override;
|
|
ScopedAStatus switchToOffline(const std::vector<int32_t>& streamsToKeep,
|
|
CameraOfflineSessionInfo* offlineSessionInfo,
|
|
std::shared_ptr<ICameraOfflineSession>* session) override;
|
|
ScopedAStatus repeatingRequestEnd(int32_t frameNumber,
|
|
const std::vector<int32_t>& streamIds) override;
|
|
|
|
static bool isStreamCombinationSupported(const StreamConfiguration& cfg,
|
|
hw::HwCamera& hwCamera);
|
|
status_t constructCaptureResult(CaptureResult& result,
|
|
const camera3_capture_result *hal_result);
|
|
bool preProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration,
|
|
camera3_stream_configuration_t *stream_list /*out*/,
|
|
std::vector<camera3_stream_t*> *streams /*out*/);
|
|
void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration);
|
|
protected:
|
|
|
|
void notify(NotifyMsg msg);
|
|
/**
|
|
* Static callback forwarding methods from HAL to instance
|
|
*/
|
|
static callbacks_process_capture_result_t sProcessCaptureResult;
|
|
static callbacks_notify_t sNotify;
|
|
|
|
// By default camera service uses frameNumber/streamId pair to retrieve the buffer that
|
|
// was sent to HAL. Override this implementation if HAL is using buffers from buffer management
|
|
// APIs to send output buffer.
|
|
virtual uint64_t getCapResultBufferId(const buffer_handle_t& buf, int streamId);
|
|
|
|
// Static helper method to copy/shrink capture result metadata sent by HAL
|
|
// Temporarily allocated metadata copy will be hold in mds
|
|
static void sShrinkCaptureResult(
|
|
camera3_capture_result* dst, const camera3_capture_result* src,
|
|
std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
|
|
std::vector<const camera_metadata_t*>* physCamMdArray,
|
|
bool handlePhysCam);
|
|
static bool sShouldShrink(const camera_metadata_t* md);
|
|
static camera_metadata_t* sCreateCompactCopy(const camera_metadata_t* src);
|
|
|
|
struct AETriggerCancelOverride {
|
|
bool applyAeLock;
|
|
uint8_t aeLock;
|
|
bool applyAePrecaptureTrigger;
|
|
uint8_t aePrecaptureTrigger;
|
|
};
|
|
common::V1_0::helper::CameraMetadata mDeviceInfo;
|
|
|
|
using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
|
|
std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
|
|
using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
|
|
std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
|
|
void processCaptureResult(
|
|
const camera3_callback_ops *cb,
|
|
const camera3_capture_result *hal_result);
|
|
|
|
private:
|
|
using MetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
|
|
using HwCaptureRequest = hw::HwCaptureRequest;
|
|
|
|
struct DelayedCaptureResult {
|
|
hw::DelayedStreamBuffer delayedBuffer;
|
|
int frameNumber;
|
|
};
|
|
|
|
void closeImpl();
|
|
void flushImpl(std::chrono::steady_clock::time_point start);
|
|
int waitFlushingDone(std::chrono::steady_clock::time_point start);
|
|
static std::pair<Status, std::vector<HalStream>>
|
|
configureStreamsStatic(const StreamConfiguration& cfg,
|
|
hw::HwCamera& hwCamera);
|
|
Status processOneCaptureRequest(const CaptureRequest& request);
|
|
void captureThreadLoop();
|
|
void delayedCaptureThreadLoop();
|
|
bool popCaptureRequest(HwCaptureRequest* req);
|
|
struct timespec captureOneFrame(struct timespec nextFrameT, HwCaptureRequest req);
|
|
void disposeCaptureRequest(HwCaptureRequest req);
|
|
void consumeCaptureResult(CaptureResult cr);
|
|
void notifyBuffersReturned(size_t n);
|
|
|
|
const std::shared_ptr<CameraDevice> mParent;
|
|
const std::shared_ptr<ICameraDeviceCallback> mCb;
|
|
hw::HwCamera& mHwCamera;
|
|
camera3_device_t* mDevice;
|
|
const uint32_t mDeviceVersion;
|
|
const bool mFreeBufEarly;
|
|
MetadataQueue mRequestQueue;
|
|
MetadataQueue mResultQueue;
|
|
std::mutex mResultQueueMutex;
|
|
|
|
StreamBufferCache mStreamBufferCache;
|
|
|
|
BlockingQueue<HwCaptureRequest> mCaptureRequests;
|
|
BlockingQueue<DelayedCaptureResult> mDelayedCaptureResults;
|
|
|
|
size_t mNumBuffersInFlight = 0;
|
|
std::condition_variable mNoBuffersInFlight;
|
|
std::mutex mNumBuffersInFlightMtx;
|
|
|
|
std::thread mCaptureThread;
|
|
std::thread mDelayedCaptureThread;
|
|
std::atomic<bool> mFlushing = false;
|
|
|
|
mutable Mutex mStateLock;
|
|
|
|
std::atomic<bool> mClosed = false;
|
|
|
|
bool mIsAELockAvailable;
|
|
bool mDerivePostRawSensKey;
|
|
uint32_t mNumPartialResults;
|
|
|
|
// Stream ID -> Camera3Stream cache
|
|
std::map<int, Camera3Stream> mStreamMap;
|
|
|
|
mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
|
|
// (streamID, frameNumber) -> inflight buffer cache
|
|
std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t> mInflightBuffers;
|
|
mutable Mutex mInflightRequestLock;
|
|
std::map<uint32_t, HwCaptureRequest> mInflightRequest;
|
|
std::unordered_map<int,std::unordered_map<int,buffer_handle_t>> mMapReqInputBuffers;
|
|
std::unordered_map<int,std::unordered_map<int,buffer_handle_t>> mMapReqOutputBuffers;
|
|
|
|
// (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
|
|
std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
|
|
::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
|
|
std::map<uint32_t, bool> mInflightRawBoostPresent;
|
|
::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
|
|
|
|
static const uint64_t BUFFER_ID_NO_BUFFER = 0;
|
|
// buffers currently ciculating between HAL and camera service
|
|
// key: bufferId sent via HIDL interface
|
|
// value: imported buffer_handle_t
|
|
// Buffer will be imported during process_capture_request and will be freed
|
|
// when the its stream is deleted or camera device session is closed
|
|
typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
|
|
// Stream ID -> circulating buffers map
|
|
std::map<int, CirculatingBuffers> mCirculatingBuffers;
|
|
|
|
bool mInitFail;
|
|
bool mFirstRequest = false;
|
|
bool mDisconnected = false;
|
|
std::vector<int> mVideoStreamIds;
|
|
|
|
static HandleImporter sHandleImporter;
|
|
static buffer_handle_t sEmptyBuffer;
|
|
|
|
bool initialize();
|
|
|
|
static bool shouldFreeBufEarly();
|
|
|
|
Status initStatus() const;
|
|
|
|
// Validate and import request's input buffer and acquire fence
|
|
virtual Status importRequest(
|
|
const CaptureRequest& request,
|
|
std::vector<buffer_handle_t*>& allBufPtrs,
|
|
std::vector<int>& allFences);
|
|
|
|
Status importRequestImpl(
|
|
const CaptureRequest& request,
|
|
std::vector<buffer_handle_t*>& allBufPtrs,
|
|
std::vector<int>& allFences,
|
|
// Optional argument for ICameraDeviceSession@3.5 impl
|
|
bool allowEmptyBuf = false);
|
|
Status importBuffer(int32_t streamId,
|
|
uint64_t bufId, buffer_handle_t buf,
|
|
/*out*/buffer_handle_t** outBufPtr,
|
|
bool allowEmptyBuf);
|
|
|
|
static void cleanupInflightFences(
|
|
std::vector<int>& allFences, size_t numFences);
|
|
|
|
void cleanupBuffersLocked(int id);
|
|
void updateBufferCaches(const std::vector<BufferCache>& cachesToRemove);
|
|
android_dataspace mapToLegacyDataspace(
|
|
android_dataspace dataSpace) const;
|
|
|
|
|
|
bool handleAePrecaptureCancelRequestLocked(
|
|
const camera3_capture_request_t &halRequest,
|
|
android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
|
|
AETriggerCancelOverride *override /*out*/);
|
|
|
|
void overrideResultForPrecaptureCancelLocked(
|
|
const AETriggerCancelOverride &aeTriggerCancelOverride,
|
|
::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/);
|
|
|
|
mutable Mutex mInflightExposureTimeLock;
|
|
std::map<int32_t, int64_t> mInflightExposureTimeNs;
|
|
int64_t mSensorExposureTimeNs;
|
|
int64_t getSensorExposureTime(){
|
|
Mutex::Autolock _l(mInflightExposureTimeLock);
|
|
return mSensorExposureTimeNs;
|
|
}
|
|
void setSensorExposureTime(int32_t frameNumber, int64_t expouserTimeNs){
|
|
Mutex::Autolock _l(mInflightExposureTimeLock);
|
|
mInflightExposureTimeNs[frameNumber] = expouserTimeNs;
|
|
}
|
|
};
|
|
|
|
} // namespace implementation
|
|
} // namespace device
|
|
} // namespace camera
|
|
} // namespace hardware
|
|
} // namespace android
|