blob: b189cc7acc06ea500435f1b9608f1aeff5dbfb12 [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.
#ifndef SRC_CAMERA_DRIVERS_CONTROLLER_OUTPUT_NODE_H_
#define SRC_CAMERA_DRIVERS_CONTROLLER_OUTPUT_NODE_H_
#include <fuchsia/camera2/cpp/fidl.h>
#include <fuchsia/hardware/ge2d/cpp/banjo.h>
#include <lib/fidl/cpp/binding.h>
#include <map>
#include <utility>
#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"
#include "src/camera/drivers/controller/util.h"
// |OutputNode| represents a |ProcessNode| of NodeType |kOutputStream|.
// This node handles the communication with the clients.
namespace camera {
constexpr uint32_t kBindingWarningsInitial = 5;
constexpr uint32_t kBindingWarningsInterval = 100;
constexpr uint32_t kFrameCountHeartbeatInterval = 30 * 5; // Roughly every 5 seconds at 30fps
class OutputNode : public ProcessNode, public fuchsia::camera2::Stream {
public:
OutputNode(async_dispatcher_t* dispatcher, BufferAttachments attachments);
// Container for caller-provided callbacks. The node invokes these when the Stream client
// disconnects or calls the named method.
struct Callbacks {
// Invoked when the remote endpoint of the request channel is closed.
fit::closure disconnect;
// Invoked when the client calls fuchsia::camera2::Stream.SetRegionOfInterest
fit::function<void(float, float, float, float, SetRegionOfInterestCallback)>
set_region_of_interest;
// Invoked when the client calls fuchsia::camera2::Stream.SetImageFormat
fit::function<void(uint32_t, SetImageFormatCallback)> set_image_format;
// Invoked when the client calls fuchsia::camera2::Stream.GetImageFormats
fit::function<void(GetImageFormatsCallback)> get_image_formats;
// Invoked when the client calls fuchsia::camera2::Stream.GetBuffers
fit::function<void(GetBuffersCallback)> get_buffers;
};
// Creates an |OutputNode| object.
// Args:
// |dispatcher| : Dispatcher on which GDC tasks can be queued up.
// |info| : StreamCreationData for the requested stream.
// |parent_node| : pointer to the node to which we need to append this |OutputNode|.
// |internal_output_node| : InternalConfigNode corresponding to this node.
//
static fpromise::result<std::unique_ptr<OutputNode>, zx_status_t> Create(
async_dispatcher_t* dispatcher, BufferAttachments attachments,
fidl::InterfaceRequest<fuchsia::camera2::Stream> request, Callbacks callbacks);
// | fuchsia::camera2::Stream |
void Start() override;
void Stop() override;
void ReleaseFrame(uint32_t buffer_id) override;
void AcknowledgeFrameError() override;
void SetRegionOfInterest(float x_min, float y_min, float x_max, float y_max,
SetRegionOfInterestCallback callback) override;
void SetImageFormat(uint32_t image_format_index, SetImageFormatCallback callback) override;
void GetImageFormats(GetImageFormatsCallback callback) override;
void GetBuffers(GetBuffersCallback callback) override;
private:
// ProcessNode method implementations.
void ProcessFrame(FrameToken token, frame_metadata_t metadata) override;
void SetOutputFormat(uint32_t output_format_index, fit::closure callback) override;
void ShutdownImpl(fit::closure callback) override;
// fuchsia.hardware.camerahwaccel.*Callback implementations.
void HwFrameReady(frame_available_info_t info) override;
void HwFrameResolutionChanged(frame_available_info_t info) override;
void HwTaskRemoved(task_remove_status_t status) override;
async_dispatcher_t* dispatcher_;
Callbacks callbacks_;
bool started_ = false;
fidl::Binding<fuchsia::camera2::Stream> binding_;
std::map<uint32_t, FrameToken> client_tokens_;
fuchsia::sysmem::BufferCollectionPtr observer_collection_;
uint32_t binding_warnings_ = 0;
uint32_t frame_count_ = 0;
};
} // namespace camera
#endif // SRC_CAMERA_DRIVERS_CONTROLLER_OUTPUT_NODE_H_