blob: aa119fc183c95222e905a9516d55be3098b87a0d [file] [log] [blame]
/*
* Copyright (C) 2018 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 ANDROID_HARDWARE_CAMERA_DEVICE_V3_5_EXTCAMERADEVICE3SESSION_H
#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_5_EXTCAMERADEVICE3SESSION_H
#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
#include <../../3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h>
namespace android {
namespace hardware {
namespace camera {
namespace device {
namespace V3_5 {
namespace implementation {
using ::android::hardware::camera::device::V3_2::BufferCache;
using ::android::hardware::camera::device::V3_5::BufferRequest;
using ::android::hardware::camera::device::V3_5::BufferRequestStatus;
using ::android::hardware::camera::device::V3_2::BufferStatus;
using ::android::hardware::camera::device::V3_2::CameraMetadata;
using ::android::hardware::camera::device::V3_2::CaptureRequest;
using ::android::hardware::camera::device::V3_2::CaptureResult;
using ::android::hardware::camera::device::V3_2::ErrorCode;
using ::android::hardware::camera::device::V3_5::ICameraDeviceCallback;
using ::android::hardware::camera::device::V3_2::MsgType;
using ::android::hardware::camera::device::V3_2::NotifyMsg;
using ::android::hardware::camera::device::V3_2::RequestTemplate;
using ::android::hardware::camera::device::V3_2::Stream;
using ::android::hardware::camera::device::V3_5::StreamConfiguration;
using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
using ::android::hardware::camera::device::V3_2::StreamRotation;
using ::android::hardware::camera::device::V3_2::StreamType;
using ::android::hardware::camera::device::V3_2::DataspaceFlags;
using ::android::hardware::camera::device::V3_2::CameraBlob;
using ::android::hardware::camera::device::V3_2::CameraBlobId;
using ::android::hardware::camera::device::V3_4::HalStreamConfiguration;
using ::android::hardware::camera::device::V3_5::ICameraDeviceSession;
using ::android::hardware::camera::common::V1_0::Status;
using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
using ::android::hardware::camera::common::V1_0::helper::ExifUtils;
using ::android::hardware::camera::external::common::ExternalCameraConfig;
using ::android::hardware::camera::external::common::Size;
using ::android::hardware::camera::external::common::SizeHasher;
using ::android::hardware::graphics::common::V1_0::BufferUsage;
using ::android::hardware::graphics::common::V1_0::Dataspace;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
using ::android::hardware::kSynchronizedReadWrite;
using ::android::hardware::MessageQueue;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
using ::android::Mutex;
using ::android::base::unique_fd;
using ::android::hardware::camera::device::V3_4::implementation::SupportedV4L2Format;
using ::android::hardware::camera::device::V3_4::implementation::CroppingType;
struct ExternalCameraDeviceSession : public V3_4::implementation::ExternalCameraDeviceSession {
ExternalCameraDeviceSession(const sp<V3_2::ICameraDeviceCallback>&,
const ExternalCameraConfig& cfg,
const std::vector<SupportedV4L2Format>& sortedFormats,
const CroppingType& croppingType,
const common::V1_0::helper::CameraMetadata& chars,
const std::string& cameraId,
unique_fd v4l2Fd);
virtual ~ExternalCameraDeviceSession();
// Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
// dealing with minor version revs and simultaneous implementation and interface inheritance
virtual sp<V3_4::ICameraDeviceSession> getInterface() override {
return new TrampolineSessionInterface_3_5(this);
}
static Status isStreamCombinationSupported(const V3_2::StreamConfiguration& config,
const std::vector<SupportedV4L2Format>& supportedFormats) {
return V3_4::implementation::ExternalCameraDeviceSession::isStreamCombinationSupported(
config, supportedFormats);
}
protected:
// Methods from v3.4 and earlier will trampoline to inherited implementation
Return<void> configureStreams_3_5(
const StreamConfiguration& requestedConfiguration,
ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb);
Return<void> signalStreamFlush(
const hidl_vec<int32_t>& requests,
uint32_t streamConfigCounter);
virtual void initOutputThread() override;
virtual void closeOutputThread() override;
void closeOutputThreadImpl();
virtual Status importRequestLocked(
const CaptureRequest& request,
hidl_vec<buffer_handle_t*>& allBufPtrs,
hidl_vec<int>& allFences) override;
class BufferRequestThread : public android::Thread {
public:
BufferRequestThread(
wp<ExternalCameraDeviceSession> parent,
sp<V3_5::ICameraDeviceCallback> callbacks);
int requestBufferStart(const std::vector<HalStreamBuffer>&);
int waitForBufferRequestDone(
/*out*/std::vector<HalStreamBuffer>*);
virtual bool threadLoop() override;
private:
void waitForNextRequest();
const wp<ExternalCameraDeviceSession> mParent;
const sp<V3_5::ICameraDeviceCallback> mCallbacks;
std::mutex mLock;
bool mRequestingBuffer = false;
std::vector<HalStreamBuffer> mBufferReqs;
std::vector<HalStreamBuffer> mPendingReturnBufferReqs;
// mHalBufferReqs is not under mLock protection during the HIDL transaction
hidl_vec<BufferRequest> mHalBufferReqs;
// request buffers takes much less time in steady state, but can take much longer
// when requesting 1st buffer from a stream.
// TODO: consider a separate timeout for new vs. steady state?
// TODO: or make sure framework is warming up the pipeline during configure new stream?
static const int kReqProcTimeoutMs = 66;
static const int kReqWaitTimeoutMs = 33;
static const int kReqWaitTimesWarn = 90; // 33ms * 90 ~= 3 sec
std::condition_variable mRequestCond; // signaled when a new buffer request incoming
std::condition_variable mRequestDoneCond; // signaled when a request is done
};
sp<BufferRequestThread> mBufferRequestThread;
class OutputThread :
public V3_4::implementation::ExternalCameraDeviceSession::OutputThread {
public:
// TODO: pass buffer request thread to OutputThread ctor
OutputThread(wp<ExternalCameraDeviceSession> parent, CroppingType,
sp<BufferRequestThread> bufReqThread);
virtual ~OutputThread();
protected:
// Methods to request output buffer in parallel
virtual int requestBufferStart(const std::vector<HalStreamBuffer>&) override;
virtual int waitForBufferRequestDone(
/*out*/std::vector<HalStreamBuffer>*) override;
const sp<BufferRequestThread> mBufferRequestThread;
};
sp<V3_5::ICameraDeviceCallback> mCallback_3_5;
bool mSupportBufMgr;
private:
struct TrampolineSessionInterface_3_5 : public ICameraDeviceSession {
TrampolineSessionInterface_3_5(sp<ExternalCameraDeviceSession> parent) :
mParent(parent) {}
virtual Return<void> constructDefaultRequestSettings(
RequestTemplate type,
V3_3::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
return mParent->constructDefaultRequestSettings(type, _hidl_cb);
}
virtual Return<void> configureStreams(
const V3_2::StreamConfiguration& requestedConfiguration,
V3_3::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
return mParent->configureStreams(requestedConfiguration, _hidl_cb);
}
virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
const hidl_vec<V3_2::BufferCache>& cachesToRemove,
V3_3::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
}
virtual Return<void> getCaptureRequestMetadataQueue(
V3_3::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override {
return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
}
virtual Return<void> getCaptureResultMetadataQueue(
V3_3::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override {
return mParent->getCaptureResultMetadataQueue(_hidl_cb);
}
virtual Return<Status> flush() override {
return mParent->flush();
}
virtual Return<void> close() override {
return mParent->close();
}
virtual Return<void> configureStreams_3_3(
const V3_2::StreamConfiguration& requestedConfiguration,
configureStreams_3_3_cb _hidl_cb) override {
return mParent->configureStreams_3_3(requestedConfiguration, _hidl_cb);
}
virtual Return<void> configureStreams_3_4(
const V3_4::StreamConfiguration& requestedConfiguration,
configureStreams_3_4_cb _hidl_cb) override {
return mParent->configureStreams_3_4(requestedConfiguration, _hidl_cb);
}
virtual Return<void> processCaptureRequest_3_4(const hidl_vec<V3_4::CaptureRequest>& requests,
const hidl_vec<V3_2::BufferCache>& cachesToRemove,
ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb) override {
return mParent->processCaptureRequest_3_4(requests, cachesToRemove, _hidl_cb);
}
virtual Return<void> configureStreams_3_5(
const StreamConfiguration& requestedConfiguration,
configureStreams_3_5_cb _hidl_cb) override {
return mParent->configureStreams_3_5(requestedConfiguration, _hidl_cb);
}
virtual Return<void> signalStreamFlush(
const hidl_vec<int32_t>& requests,
uint32_t streamConfigCounter) override {
return mParent->signalStreamFlush(requests, streamConfigCounter);
}
private:
sp<ExternalCameraDeviceSession> mParent;
};
};
} // namespace implementation
} // namespace V3_5
} // namespace device
} // namespace camera
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_5_EXTCAMERADEVICE3SESSION_H