blob: fc6ce5cee4e87b8dc425c8cbc5b8186af30706e5 [file] [log] [blame]
// 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";
fit::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 fit::error(ZX_ERR_INVALID_ARGS);
}
fuchsia::sysmem::BufferCollectionInfo_2 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 fit::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 fit::error(ZX_ERR_INTERNAL);
}
// Set the client stream.
output_node->set_client_stream(std::move(client_stream));
auto result = fit::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