| // Copyright 2019 The Fuchsia 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 SRC_CAMERA_DRIVERS_CONTROLLER_INPUT_NODE_H_ | |
| #define SRC_CAMERA_DRIVERS_CONTROLLER_INPUT_NODE_H_ | |
| #include <fuchsia/camera2/cpp/fidl.h> | |
| #include <lib/trace/event.h> | |
| #include <zircon/assert.h> | |
| #include <ddktl/protocol/isp.h> | |
| #include "src/camera/drivers/controller/isp_stream_protocol.h" | |
| #include "src/camera/drivers/controller/memory_allocation.h" | |
| #include "src/camera/drivers/controller/processing_node.h" | |
| #include "src/camera/drivers/controller/stream_pipeline_info.h" | |
| // |InputNode| represents a |ProcessNode| which would talk to the | |
| // ISP driver. | |
| namespace camera { | |
| class InputNode : public ProcessNode { | |
| public: | |
| InputNode(StreamCreationData* info, | |
| fuchsia::sysmem::BufferCollectionInfo_2 output_buffer_collection, | |
| async_dispatcher_t* dispatcher, const ddk::IspProtocolClient& isp) | |
| : ProcessNode(NodeType::kInputStream, nullptr, info->stream_type(), info->node.image_formats, | |
| std::move(output_buffer_collection), info->node.supported_streams, dispatcher, | |
| info->node.output_frame_rate, info->image_format_index), | |
| isp_stream_type_(info->node.input_stream_type), | |
| isp_frame_callback_{OnIspFrameAvailable, this}, | |
| isp_(isp) {} | |
| // Creates an |InputNode| object. | |
| // 1. Creates the ISP stream protocol | |
| // 2. Creates the requested ISP stream | |
| // 3. Allocates buffers if needed | |
| // Args: | |
| // |info| : StreamCreationData for the requested stream. | |
| // |memory_allocator| : Memory allocator object to allocate memory using sysmem. | |
| // |dispatcher| : Dispatcher on which GDC tasks can be queued up. | |
| // |isp| : ISP protocol to talk to the driver. | |
| static fit::result<std::unique_ptr<InputNode>, zx_status_t> CreateInputNode( | |
| StreamCreationData* info, const ControllerMemoryAllocator& memory_allocator, | |
| async_dispatcher_t* dispatcher, const ddk::IspProtocolClient& isp); | |
| const hw_accel_frame_callback_t* isp_frame_callback() { return &isp_frame_callback_; } | |
| std::unique_ptr<camera::IspStreamProtocol>& isp_stream_protocol() { return isp_stream_protocol_; } | |
| void set_isp_stream_protocol(std::unique_ptr<camera::IspStreamProtocol> isp_stream_protocol) { | |
| isp_stream_protocol_ = std::move(isp_stream_protocol); | |
| } | |
| // Notifies that a frame is ready to be sent to the client. | |
| void OnReadyToProcess(const frame_available_info_t* info) override; | |
| // Releases the frame associated with | buffer_index |. | |
| void OnReleaseFrame(uint32_t buffer_index) override; | |
| // Notifies that a frame is done processing by this node. | |
| void OnFrameAvailable(const frame_available_info_t* info) override; | |
| // Shuts down the stream with ISP. | |
| void OnShutdown(fit::function<void(void)> shutdown_callback) override; | |
| // Notifies that the client has requested to start streaming. | |
| void OnStartStreaming() override; | |
| // Notifies that the client has requested to stop streaming. | |
| void OnStopStreaming() override; | |
| // Notifies that the client has requested to change resolution. | |
| void OnResolutionChangeRequest(uint32_t output_format_index) override {} | |
| private: | |
| // Notifies when a new frame is available from the ISP. | |
| static void OnIspFrameAvailable(void* ctx, const frame_available_info_t* info) { | |
| auto nonce = TRACE_NONCE(); | |
| TRACE_DURATION("camera", "OnIspFrameAvailable"); | |
| TRACE_FLOW_BEGIN("camera", "post_ready_to_process", nonce); | |
| // This method is invoked by the ISP in its own thread, | |
| // so the event must be marshalled to the | |
| // controller's thread. | |
| auto* input_node = static_cast<InputNode*>(ctx); | |
| input_node->RunOnMainThread([input_node, nonce, info = *info]() { | |
| TRACE_DURATION("camera", "OnIspFrameAvailable.task"); | |
| TRACE_FLOW_END("camera", "post_ready_to_process", nonce); | |
| input_node->OnReadyToProcess(&info); | |
| }); | |
| } | |
| // ISP stream type. | |
| __UNUSED fuchsia::camera2::CameraStreamType isp_stream_type_; | |
| // ISP Frame callback. | |
| hw_accel_frame_callback_t isp_frame_callback_; | |
| // ISP stream protocol. | |
| std::unique_ptr<IspStreamProtocol> isp_stream_protocol_; | |
| // Protocol to talk to ISP driver. | |
| ddk::IspProtocolClient isp_; | |
| }; | |
| } // namespace camera | |
| #endif // SRC_CAMERA_DRIVERS_CONTROLLER_INPUT_NODE_H_ |