blob: 44b98b58010edad5747a8150d7f0d833e0851435 [file] [log] [blame]
/*
* Copyright 2021 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef CAMERA_FEATURES_HDRNET_HDRNET_STREAM_MANIPULATOR_H_
#define CAMERA_FEATURES_HDRNET_HDRNET_STREAM_MANIPULATOR_H_
#include "common/stream_manipulator.h"
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <vector>
#include <base/files/scoped_file.h>
#include <camera/camera_metadata.h>
#include "common/reloadable_config_file.h"
#include "common/still_capture_processor.h"
#include "cros-camera/camera_buffer_manager.h"
#include "cros-camera/camera_thread.h"
#include "features/hdrnet/hdrnet_config.h"
#include "features/hdrnet/hdrnet_metrics.h"
#include "features/hdrnet/hdrnet_processor.h"
#include "gpu/shared_image.h"
namespace cros {
class HdrNetStreamManipulator : public StreamManipulator {
public:
HdrNetStreamManipulator(
base::FilePath config_file_path,
std::unique_ptr<StillCaptureProcessor> still_capture_processor,
HdrNetProcessor::Factory hdrnet_processor_factory = base::NullCallback());
~HdrNetStreamManipulator() override;
// Implementations of StreamManipulator. These methods are trampolines and
// all the actual tasks are carried out and sequenced on the |gpu_thread_|
// with the internal implementations below.
bool Initialize(const camera_metadata_t* static_info,
CaptureResultCallback result_callback) override;
bool ConfigureStreams(Camera3StreamConfiguration* stream_config) override;
bool OnConfiguredStreams(Camera3StreamConfiguration* stream_config) override;
bool ConstructDefaultRequestSettings(
android::CameraMetadata* default_request_settings, int type) override;
bool ProcessCaptureRequest(Camera3CaptureDescriptor* request) override;
bool ProcessCaptureResult(Camera3CaptureDescriptor* result) override;
bool Notify(camera3_notify_msg_t* msg) override;
bool Flush() override;
private:
struct HdrNetStreamContext {
enum class Mode {
kReplaceYuv,
kAppendWithBlob,
};
Mode mode = Mode::kReplaceYuv;
// The original stream requested by the client.
camera3_stream_t* original_stream = nullptr;
// The stream that will be set in place of |original_stream| in capture
// requests.
std::unique_ptr<camera3_stream_t> hdrnet_stream;
// The buffers bound as SharedImage for the |hdrnet_stream|, which will
// be used in capture requests and for HDRnet processing.
std::vector<SharedImage> shared_images;
// Intermediate buffer used in HDRnet processing for still capture requests.
ScopedBufferHandle still_capture_intermediate;
// The list of available buffers specified as index to |shared_images| that
// can be set in capture requests when |hdrnet_stream| is set.
struct UsableBufferInfo {
int index;
base::ScopedFD acquire_fence;
};
std::queue<UsableBufferInfo> usable_buffer_list;
// The HDRnet processor instance for this stream.
std::unique_ptr<HdrNetProcessor> processor;
// Pops a free buffer from |usable_buffer_list|.
base::Optional<int> PopBuffer();
// Pushes a free buffer into |usable_buffer_list|.
void PushBuffer(int index, base::ScopedFD acquire_fence);
};
struct HdrNetRequestBufferInfo {
HdrNetRequestBufferInfo(HdrNetStreamContext* context,
std::vector<camera3_stream_buffer_t>&& buffers);
HdrNetRequestBufferInfo(HdrNetRequestBufferInfo&& other);
HdrNetRequestBufferInfo& operator=(HdrNetRequestBufferInfo&& other);
~HdrNetRequestBufferInfo();
void Invalidate();
static constexpr int kInvalidBufferIndex = -1;
// The HdrNetStreamContext this request buffer is associated with.
HdrNetStreamContext* stream_context = nullptr;
// The index to the |stream_context->shared_images| specifying the
// SharedImage used in the request
int buffer_index = -1;
// The release fence that needs to be waited before accessing the HDRnet
// buffer returned by the camera HAL.
base::ScopedFD release_fence;
// The buffers requested by the client. These buffers will be filled by
// HDRnet pipeline with the buffers rendered by the pipeline, with
// downscaling if needed.
std::vector<camera3_stream_buffer_t> client_requested_yuv_buffers;
// Indicator for whether the request is pending on a BLOB buffer from the
// camera HAL. The metadata from the BLOB buffer will be extracted and
// filled in the final still capture result.
bool blob_result_pending = false;
// Indicator for whether the request if pending on a intermediate YUV output
// from the HDRnet pipeline. The YUV buffer rendered by the HDRnet pipeline
// is used to produce the final still capture result.
bool blob_intermediate_yuv_pending = false;
// Skips the HDRnet processing and directly copies the ISP output to the
// result buffer. When the tonemap mode is set to CONTRAST_CURVE,
// GAMMA_VALUE or PRESET_CURVE, we need to disable HDRnet per the API
// requirement.
bool skip_hdrnet_processing = false;
};
using HdrNetBufferInfoList = std::vector<HdrNetRequestBufferInfo>;
static HdrNetBufferInfoList::iterator FindMatchingBufferInfo(
HdrNetBufferInfoList* list, const HdrNetStreamContext* const context);
HdrNetRequestBufferInfo* GetBufferInfoWithPendingBlobStream(
int frame_number, const camera3_stream_t* blob_stream);
// Internal implementations of StreamManipulator. All these methods are
// sequenced on the |gpu_thread_|.
bool InitializeOnGpuThread(const camera_metadata_t* static_info,
CaptureResultCallback result_callback);
bool ConfigureStreamsOnGpuThread(Camera3StreamConfiguration* stream_config);
bool OnConfiguredStreamsOnGpuThread(
Camera3StreamConfiguration* stream_config);
bool ProcessCaptureRequestOnGpuThread(Camera3CaptureDescriptor* request);
bool ProcessCaptureResultOnGpuThread(Camera3CaptureDescriptor* result);
bool NotifyOnGpuThread(camera3_notify_msg_t* msg);
bool FlushOnGpuThread();
// Check if |raw_result_buffers| has any HdrNet buffer that we need to
// process. |hdrnet_buffer_to_process| stored the HDRnet buffers that are
// pending further processing, and |output_buffers_to_client| stores the
// buffers that will be returned to the camera client as-is.
void ExtractHdrNetBuffersToProcess(
int frame_number,
base::span<const camera3_stream_buffer_t> raw_result_buffers,
std::vector<camera3_stream_buffer_t>* hdrnet_buffer_to_process,
std::vector<camera3_stream_buffer_t>* output_buffers_to_client);
// Prepare the set of client-requested buffers that will be rendered by the
// HDRnet pipeline.
bool GetBuffersToRender(HdrNetStreamContext* stream_context,
HdrNetRequestBufferInfo* request_buffer_info,
std::vector<buffer_handle_t>* buffers_to_write);
// Callback for the buffers rendered by the HDRnet pipeline.
void OnBuffersRendered(
int frame_number,
HdrNetStreamContext* stream_context,
HdrNetRequestBufferInfo* request_buffer_info,
std::vector<camera3_stream_buffer_t>* output_buffers_to_client);
HdrNetConfig::Options PrepareProcessorConfig(
Camera3CaptureDescriptor* result,
const HdrNetRequestBufferInfo& buf_info) const;
bool SetUpPipelineOnGpuThread();
void ResetStateOnGpuThread();
void UpdateRequestSettingsOnGpuThread(Camera3CaptureDescriptor* request);
void RecordYuvBufferForAeControllerOnGpuThread(int frame_number,
const SharedImage& yuv_input);
HdrNetStreamContext* CreateHdrNetStreamContext(camera3_stream_t* requested,
uint32_t replace_format);
HdrNetStreamContext* GetHdrNetContextFromRequestedStream(
camera3_stream_t* requested);
HdrNetStreamContext* GetHdrNetContextFromHdrNetStream(
camera3_stream_t* hdrnet);
void OnOptionsUpdated(const base::Value& json_values);
void UploadMetrics();
CameraThread gpu_thread_;
HdrNetProcessor::Factory hdrnet_processor_factory_;
ReloadableConfigFile config_;
HdrNetConfig::Options options_;
android::CameraMetadata static_info_;
std::unique_ptr<EglContext> egl_context_;
std::unique_ptr<StillCaptureProcessor> still_capture_processor_;
CaptureResultCallback result_callback_;
// The mapping between original and replacement buffers for in-flight
// requests.
std::vector<std::unique_ptr<HdrNetStreamContext>> hdrnet_stream_context_;
std::map<uint32_t, HdrNetBufferInfoList> request_buffer_info_;
std::map<camera3_stream_t*, HdrNetStreamContext*> request_stream_mapping_;
std::map<camera3_stream_t*, HdrNetStreamContext*> result_stream_mapping_;
HdrnetMetrics hdrnet_metrics_;
std::unique_ptr<CameraMetrics> camera_metrics_;
// Metadata logger for tests and debugging.
MetadataLogger metadata_logger_;
};
} // namespace cros
#endif // CAMERA_FEATURES_HDRNET_HDRNET_STREAM_MANIPULATOR_H_