blob: b8ecca146d6416c67d2ed3fddfbc7e8bc6d3a205 [file] [log] [blame] [edit]
// 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/sherlock/monitoring_config.h"
// This file contains static information for the Monitor Configuration
// There are three streams in one configuration
// FR --> OutputStreamMLFR (Directly from ISP) (10fps)
// FR --> GDC1 --> OutputStreamMLDS
// DS --> GDC2 --> GE2D --> OutputStreamMonitoring
namespace camera {
static InternalConfigNode Gdc1();
static InternalConfigNode Ge2dMonitoring();
static InternalConfigNode MLFRFrameSkipper();
/**********************************
* Output Stream ML FR parameters *
**********************************
*/
static std::vector<fuchsia::images2::ImageFormat> OutputStreamMLFRImageFormats() {
std::vector<fuchsia::images2::ImageFormat> result;
result.emplace_back(StreamConstraints::MakeImageFormat(
kOutputStreamMlFRWidth, kOutputStreamMlFRHeight, kOutputStreamMlFRPixelFormat));
return result;
}
static fuchsia::camera2::hal::StreamConfig OutputStreamMLFRConfig() {
StreamConstraints stream(fuchsia::camera2::CameraStreamType::FULL_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING);
stream.AddImageFormat(kOutputStreamMlFRWidth, kOutputStreamMlFRHeight,
kOutputStreamMlFRPixelFormat);
stream.set_bytes_per_row_divisor(kIspBytesPerRowDivisor);
stream.set_contiguous(true);
stream.set_frames_per_second(kOutputStreamMlFRFrameRate);
// TODO(https://fxbug.dev/42182036): Support releasing initial participants' camping buffer
// counts.
stream.set_buffer_count_for_camping(kMonitoringIspFROutputBuffers + kMonitoringGDC1InputBuffers);
stream.set_min_buffer_count(kMonitoringIspFROutputBuffers + kMonitoringGDC1InputBuffers +
kOutputStreamMlFRMaxClientBuffers);
return stream.ConvertToStreamConfig();
}
/***********************************
* Output Stream ML DS parameters *
***********************************
*/
static std::vector<fuchsia::images2::ImageFormat> OutputStreamMLDSImageFormats() {
std::vector<fuchsia::images2::ImageFormat> result;
result.emplace_back(StreamConstraints::MakeImageFormat(
kOutputStreamMlDSWidth, kOutputStreamMlDSHeight, kOutputStreamMlDSPixelFormat));
return result;
}
static fuchsia::camera2::hal::StreamConfig OutputStreamMLDSConfig() {
StreamConstraints stream(fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING);
stream.AddImageFormat(kOutputStreamMlDSWidth, kOutputStreamMlDSHeight,
kOutputStreamMlFRPixelFormat);
stream.set_bytes_per_row_divisor(kGdcBytesPerRowDivisor);
stream.set_contiguous(true);
stream.set_frames_per_second(kOutputStreamMlDSFrameRate);
stream.set_buffer_count_for_camping(kMonitoringGDC1OutputBuffers);
stream.set_min_buffer_count(kMonitoringGDC1OutputBuffers + kOutputStreamMlDSMaxClientBuffers);
return stream.ConvertToStreamConfig();
}
/******************************************
* Output Stream DS Monitoring parameters *
******************************************
*/
static std::vector<fuchsia::images2::ImageFormat> MonitorConfigDownScaledResImageFormats() {
std::vector<fuchsia::images2::ImageFormat> result;
result.emplace_back(StreamConstraints::MakeImageFormat(
kOutputStreamDSWidth, kOutputStreamDSHeight, kOutputStreamMonitoringPixelFormat));
return result;
}
static std::vector<fuchsia::images2::ImageFormat> OutputStreamMonitoringImageFormats() {
std::vector<fuchsia::images2::ImageFormat> result;
result.emplace_back(StreamConstraints::MakeImageFormat(kOutputStreamMonitoringWidth,
kOutputStreamMonitoringHeight,
kOutputStreamMonitoringPixelFormat));
result.emplace_back(StreamConstraints::MakeImageFormat(kOutputStreamMonitoringWidth1,
kOutputStreamMonitoringHeight1,
kOutputStreamMonitoringPixelFormat));
result.emplace_back(StreamConstraints::MakeImageFormat(kOutputStreamMonitoringWidth2,
kOutputStreamMonitoringHeight2,
kOutputStreamMonitoringPixelFormat));
return result;
}
static fuchsia::camera2::hal::StreamConfig OutputStreamMonitoringConfig() {
StreamConstraints stream(fuchsia::camera2::CameraStreamType::MONITORING);
stream.AddImageFormat(kOutputStreamMonitoringWidth, kOutputStreamMonitoringHeight,
kOutputStreamMonitoringPixelFormat);
stream.AddImageFormat(kOutputStreamMonitoringWidth1, kOutputStreamMonitoringHeight1,
kOutputStreamMonitoringPixelFormat);
stream.AddImageFormat(kOutputStreamMonitoringWidth2, kOutputStreamMonitoringHeight2,
kOutputStreamMonitoringPixelFormat);
stream.set_bytes_per_row_divisor(kGe2dBytesPerRowDivisor);
stream.set_contiguous(true);
stream.set_frames_per_second(kMonitoringThrottledOutputFrameRate);
stream.set_buffer_count_for_camping(kMonitoringGDC2OutputBuffers + kMonitoringGE2DInputBuffers);
stream.set_min_buffer_count(kMonitoringGDC2OutputBuffers + kMonitoringGE2DInputBuffers +
kOutputStreamMonitoringMaxClientBuffers);
return stream.ConvertToStreamConfig();
}
/*****************************
* EXTERNAL CONFIGURATIONS *
*****************************
*/
fuchsia::camera2::hal::Config MonitoringConfig() {
fuchsia::camera2::hal::Config config;
config.stream_configs.push_back(OutputStreamMLFRConfig());
config.stream_configs.push_back(OutputStreamMLDSConfig());
config.stream_configs.push_back(OutputStreamMonitoringConfig());
return config;
}
// ================== INTERNAL CONFIGURATION ======================== //
// FR --> OutputStreamMLFR (Directly from ISP) (10fps)
// FR --> GDC1 --> OutputStreamMLDS (10fps)
static InternalConfigNode OutputStreamMLFR() {
InternalConfigNode result;
result.type = kOutputStream;
result.output_frame_rate = {
.frames_per_sec_numerator = kOutputStreamMlFRFrameRate,
.frames_per_sec_denominator = 1,
};
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::FULL_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.input_constraints = CopyConstraintsWithOverrides(
MonitoringConfig().stream_configs[0].constraints, {.min_buffer_count_for_camping = 0});
result.image_formats = OutputStreamMLFRImageFormats();
return result;
}
static InternalConfigNode OutputStreamMLDS() {
InternalConfigNode result;
result.type = kOutputStream;
result.output_frame_rate = {
.frames_per_sec_numerator = kOutputStreamMlDSFrameRate,
.frames_per_sec_denominator = 1,
};
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.input_constraints = CopyConstraintsWithOverrides(
MonitoringConfig().stream_configs[1].constraints, {.min_buffer_count_for_camping = 0});
result.image_formats = OutputStreamMLDSImageFormats();
return result;
}
fuchsia::sysmem2::BufferCollectionConstraints Gdc1Constraints() {
StreamConstraints stream_constraints;
stream_constraints.set_bytes_per_row_divisor(kGdcBytesPerRowDivisor);
stream_constraints.set_contiguous(true);
stream_constraints.AddImageFormat(kOutputStreamMlFRWidth, kOutputStreamMlFRHeight,
kOutputStreamMlFRPixelFormat);
stream_constraints.set_buffer_count_for_camping(kMonitoringGDC1InputBuffers);
return stream_constraints.MakeBufferCollectionConstraints();
}
static InternalConfigNode Gdc1() {
InternalConfigNode result;
result.type = kGdc;
result.output_frame_rate = {
.frames_per_sec_numerator = kOutputStreamMlDSFrameRate,
.frames_per_sec_denominator = 1,
};
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.child_nodes = MakeVec(OutputStreamMLDS());
result.gdc_info = {
.config_type =
{
GdcConfig::MONITORING_ML,
},
};
result.input_constraints = Gdc1Constraints();
result.output_constraints =
CopyConstraintsWithOverrides(OutputStreamMLDSConfig().constraints,
{.min_buffer_count_for_camping = kMonitoringGDC1OutputBuffers});
result.image_formats = OutputStreamMLDSImageFormats();
return result;
}
fuchsia::sysmem2::BufferCollectionConstraints MonitorConfigFullResConstraints() {
StreamConstraints stream_constraints;
stream_constraints.set_bytes_per_row_divisor(kIspBytesPerRowDivisor);
stream_constraints.set_contiguous(true);
stream_constraints.AddImageFormat(kOutputStreamMlFRWidth, kOutputStreamMlFRHeight,
kOutputStreamMlFRPixelFormat);
stream_constraints.set_buffer_count_for_camping(kMonitoringIspFROutputBuffers);
return stream_constraints.MakeBufferCollectionConstraints();
}
InternalConfigNode MonitorConfigFullRes() {
InternalConfigNode result;
result.type = kInputStream;
result.output_frame_rate = {
.frames_per_sec_numerator = kSensorMaxFramesPerSecond,
.frames_per_sec_denominator = 1,
};
result.input_stream_type = fuchsia::camera2::CameraStreamType::FULL_RESOLUTION;
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::FULL_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
{
.type = fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.child_nodes = MakeVec(MLFRFrameSkipper());
// input constrains not applicable
result.output_constraints = MonitorConfigFullResConstraints();
result.image_formats = OutputStreamMLFRImageFormats();
return result;
}
static InternalConfigNode MLFRFrameSkipper() {
// This node serves to synchronize the skipped frames between the two reduced-fps downstream
// nodes.
static_assert(kOutputStreamMlFRFrameRate == kOutputStreamMlDSFrameRate);
InternalConfigNode result;
result.type = kPassthrough;
result.output_frame_rate = {
.frames_per_sec_numerator = kOutputStreamMlFRFrameRate,
.frames_per_sec_denominator = 1,
};
result.input_stream_type = fuchsia::camera2::CameraStreamType::FULL_RESOLUTION;
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::FULL_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
{
.type = fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION |
fuchsia::camera2::CameraStreamType::MACHINE_LEARNING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.child_nodes = MakeVec(OutputStreamMLFR(), Gdc1());
return result;
}
// DS --> GDC2 --> GE2D --> OutputStreamMonitoring
static InternalConfigNode OutputStreamMonitoring() {
InternalConfigNode result;
result.type = kOutputStream;
result.output_frame_rate = {
.frames_per_sec_numerator = kMonitoringThrottledOutputFrameRate,
.frames_per_sec_denominator = 1,
};
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::MONITORING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.input_constraints = CopyConstraintsWithOverrides(
MonitoringConfig().stream_configs[2].constraints, {.min_buffer_count_for_camping = 0});
result.image_formats = OutputStreamMonitoringImageFormats();
return result;
}
fuchsia::sysmem2::BufferCollectionConstraints Gdc2Constraints() {
StreamConstraints stream_constraints;
stream_constraints.set_bytes_per_row_divisor(kGdcBytesPerRowDivisor);
stream_constraints.set_contiguous(true);
stream_constraints.AddImageFormat(kOutputStreamDSWidth, kOutputStreamDSHeight,
kOutputStreamMonitoringPixelFormat);
stream_constraints.set_buffer_count_for_camping(kMonitoringGDC2InputBuffers);
return stream_constraints.MakeBufferCollectionConstraints();
}
fuchsia::sysmem2::BufferCollectionConstraints Ge2dMonitoringConstraints() {
StreamConstraints stream_constraints;
stream_constraints.set_bytes_per_row_divisor(kGe2dBytesPerRowDivisor);
stream_constraints.set_contiguous(true);
stream_constraints.AddImageFormat(kOutputStreamMonitoringWidth, kOutputStreamMonitoringHeight,
kOutputStreamMonitoringPixelFormat);
stream_constraints.AddImageFormat(kOutputStreamMonitoringWidth1, kOutputStreamMonitoringHeight1,
kOutputStreamMonitoringPixelFormat);
stream_constraints.AddImageFormat(kOutputStreamMonitoringWidth2, kOutputStreamMonitoringHeight2,
kOutputStreamMonitoringPixelFormat);
stream_constraints.set_buffer_count_for_camping(kMonitoringGE2DInputBuffers);
return stream_constraints.MakeBufferCollectionConstraints();
}
static InternalConfigNode Ge2dMonitoring() {
InternalConfigNode result;
result.type = kGe2d;
result.output_frame_rate = {
.frames_per_sec_numerator = kMonitoringThrottledOutputFrameRate,
.frames_per_sec_denominator = 1,
};
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::MONITORING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.child_nodes = MakeVec(OutputStreamMonitoring());
result.ge2d_info = [] {
Ge2DInfo result;
result.config_type = Ge2DConfig::GE2D_WATERMARK,
result.watermark = MakeVec(
[] {
WatermarkInfo result;
result.filename = "watermark-720p.rgba";
result.image_format = StreamConstraints::MakeImageFormat(
kWatermark720pWidth, kWatermark720pHeight, kWatermarkPixelFormat);
result.loc_x = kOutputStreamMonitoringWidth - kWatermark720pWidth;
result.loc_y = 0;
return result;
}(),
[] {
WatermarkInfo result;
result.filename = "watermark-480p.rgba";
result.image_format = StreamConstraints::MakeImageFormat(
kWatermark480pWidth, kWatermark480pHeight, kWatermarkPixelFormat);
result.loc_x = kOutputStreamMonitoringWidth1 - kWatermark480pWidth;
result.loc_y = 0;
return result;
}(),
[] {
WatermarkInfo result;
result.filename = "watermark-360p.rgba";
result.image_format = StreamConstraints::MakeImageFormat(
kWatermark360pWidth, kWatermark360pHeight, kWatermarkPixelFormat);
result.loc_x = kOutputStreamMonitoringWidth2 - kWatermark360pWidth;
result.loc_y = 0;
return result;
}());
return result;
}();
// Ge2dMonitoringConstraints uses kMonitoringGE2DInputBuffers, so modification is necessary to
// reflect the output constraints.
result.input_constraints = Ge2dMonitoringConstraints();
result.image_formats = OutputStreamMonitoringImageFormats();
return result;
}
fuchsia::sysmem2::BufferCollectionConstraints Gdc2OutputConstraints() {
StreamConstraints stream_constraints;
stream_constraints.set_bytes_per_row_divisor(kGdcBytesPerRowDivisor);
stream_constraints.set_contiguous(true);
stream_constraints.AddImageFormat(kOutputStreamMonitoringWidth, kOutputStreamMonitoringHeight,
kOutputStreamMonitoringPixelFormat);
stream_constraints.AddImageFormat(kOutputStreamMonitoringWidth1, kOutputStreamMonitoringHeight1,
kOutputStreamMonitoringPixelFormat);
stream_constraints.AddImageFormat(kOutputStreamMonitoringWidth2, kOutputStreamMonitoringHeight2,
kOutputStreamMonitoringPixelFormat);
stream_constraints.set_buffer_count_for_camping(kMonitoringGDC2OutputBuffers);
return stream_constraints.MakeBufferCollectionConstraints();
}
static InternalConfigNode Gdc2() {
InternalConfigNode result;
result.type = kGdc;
result.output_frame_rate = {
.frames_per_sec_numerator = kMonitoringThrottledOutputFrameRate,
.frames_per_sec_denominator = 1,
};
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::MONITORING,
.supports_dynamic_resolution = true,
.supports_crop_region = false,
},
};
result.child_nodes = MakeVec(Ge2dMonitoring());
result.gdc_info = {
.config_type =
{
GdcConfig::MONITORING_720p,
GdcConfig::MONITORING_480p,
GdcConfig::MONITORING_360p,
},
};
result.input_constraints = Gdc2Constraints();
result.output_constraints = Gdc2OutputConstraints();
result.image_formats = OutputStreamMonitoringImageFormats();
return result;
}
fuchsia::sysmem2::BufferCollectionConstraints MonitorConfigDownScaledResConstraints() {
StreamConstraints stream_constraints;
stream_constraints.set_bytes_per_row_divisor(kIspBytesPerRowDivisor);
stream_constraints.set_contiguous(true);
stream_constraints.AddImageFormat(kOutputStreamDSWidth, kOutputStreamDSHeight,
kOutputStreamMonitoringPixelFormat);
stream_constraints.set_buffer_count_for_camping(kMonitoringIspDSOutputBuffers);
return stream_constraints.MakeBufferCollectionConstraints();
}
InternalConfigNode MonitorConfigDownScaledRes() {
InternalConfigNode result;
result.type = kInputStream;
result.output_frame_rate = {
.frames_per_sec_numerator = kSensorMaxFramesPerSecond,
.frames_per_sec_denominator = 1,
};
result.input_stream_type = fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION;
result.supported_streams = {
{
.type = fuchsia::camera2::CameraStreamType::MONITORING,
.supports_dynamic_resolution = false,
.supports_crop_region = false,
},
};
result.child_nodes = MakeVec(Gdc2());
// input constraints not applicable
result.output_constraints = MonitorConfigDownScaledResConstraints();
result.image_formats = MonitorConfigDownScaledResImageFormats();
return result;
}
} // namespace camera