| // 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. |
| |
| #include "src/camera/drivers/controller/output_node.h" |
| |
| #include <lib/syslog/cpp/macros.h> |
| #include <lib/trace/event.h> |
| #include <zircon/errors.h> |
| #include <zircon/types.h> |
| |
| #include "src/camera/drivers/controller/stream_protocol.h" |
| |
| namespace camera { |
| |
| constexpr auto kTag = "camera_controller_output_node"; |
| |
| fpromise::result<OutputNode*, zx_status_t> OutputNode::CreateOutputNode( |
| async_dispatcher_t* dispatcher, StreamCreationData* info, ProcessNode* parent_node, |
| const InternalConfigNode& internal_output_node) { |
| if (dispatcher == nullptr || info == nullptr || parent_node == nullptr) { |
| FX_LOGST(DEBUG, kTag) << "Invalid input parameters"; |
| return fpromise::error(ZX_ERR_INVALID_ARGS); |
| } |
| |
| BufferCollection unused_buffer_collection; |
| |
| auto output_node = std::make_unique<camera::OutputNode>( |
| dispatcher, parent_node, internal_output_node, std::move(unused_buffer_collection), |
| info->stream_type(), info->image_format_index); |
| if (!output_node) { |
| FX_LOGST(ERROR, kTag) << "Failed to create output ProcessNode"; |
| return fpromise::error(ZX_ERR_NO_MEMORY); |
| } |
| |
| auto client_stream = std::make_unique<camera::StreamImpl>(output_node.get()); |
| if (!client_stream) { |
| FX_LOGST(ERROR, kTag) << "Failed to create StreamImpl"; |
| return fpromise::error(ZX_ERR_INTERNAL); |
| } |
| |
| // Set the client stream. |
| output_node->set_client_stream(std::move(client_stream)); |
| auto result = fpromise::ok(output_node.get()); |
| |
| // Add child node. |
| parent_node->AddChildNodeInfo(std::move(output_node)); |
| return result; |
| } |
| |
| void OutputNode::OnReadyToProcess(const frame_available_info_t* info) { |
| TRACE_DURATION("camera", "OutputNode::OnReadyToProcess", "info->buffer_id", info->buffer_id); |
| if (enabled_) { |
| ZX_ASSERT(client_stream_ != nullptr); |
| client_stream_->FrameReady(info); |
| return; |
| } |
| // Since streaming is disabled the incoming frame is released |
| // so it gets added back to the pool. |
| OnReleaseFrame(info->buffer_id); |
| } |
| |
| void OutputNode::OnReleaseFrame(uint32_t buffer_index) { |
| TRACE_DURATION("camera", "OutputNode::OnReleaseFrame", "buffer_index", buffer_index); |
| parent_node_->OnReleaseFrame(buffer_index); |
| } |
| |
| zx_status_t OutputNode::Attach(zx::channel channel, fit::function<void(void)> disconnect_handler) { |
| return client_stream_->Attach(std::move(channel), std::move(disconnect_handler)); |
| } |
| |
| } // namespace camera |