From 807562381d1cc8957b9548a66e74730079c3eb67 Mon Sep 17 00:00:00 2001 From: aangerma Date: Sat, 20 Apr 2019 21:54:46 +0300 Subject: [PATCH 1/3] Added support for l500 metadata --- src/l500/l500-color.cpp | 38 ++++++++++++++++++++++ src/l500/l500-depth.cpp | 17 ++++++++++ src/metadata-parser.h | 2 +- src/metadata.h | 71 ++++++++++++++++++++++++++++++++++------- 4 files changed, 115 insertions(+), 13 deletions(-) diff --git a/src/l500/l500-color.cpp b/src/l500/l500-color.cpp index 65d120b925..4f39bf4d47 100644 --- a/src/l500/l500-color.cpp +++ b/src/l500/l500-color.cpp @@ -3,6 +3,7 @@ #include "l500-color.h" #include "l500-private.h" +#include namespace librealsense { @@ -44,6 +45,43 @@ namespace librealsense exposure_option, auto_exposure_option)); + color_ep->register_metadata(RS2_FRAME_METADATA_FRAME_TIMESTAMP, make_uvc_header_parser(&platform::uvc_header::timestamp)); + + // attributes of md_capture_timing + auto md_prop_offset = offsetof(metadata_raw, mode) + + offsetof(md_rgb_normal_mode, intel_capture_timing); + + color_ep->register_metadata(RS2_FRAME_METADATA_FRAME_COUNTER, make_attribute_parser(&l500_md_capture_timing::frame_counter, md_capture_timing_attributes::frame_counter_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_SENSOR_TIMESTAMP, make_attribute_parser(&l500_md_capture_timing::sensor_timestamp, md_capture_timing_attributes::sensor_timestamp_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_ACTUAL_FPS, make_attribute_parser(&l500_md_capture_timing::exposure_time, md_capture_timing_attributes::sensor_timestamp_attribute, md_prop_offset)); + + // attributes of md_capture_stats + md_prop_offset = offsetof(metadata_raw, mode) + + offsetof(md_rgb_normal_mode, intel_capture_stats); + + color_ep->register_metadata(RS2_FRAME_METADATA_WHITE_BALANCE, make_attribute_parser(&md_capture_stats::white_balance, md_capture_stat_attributes::white_balance_attribute, md_prop_offset)); + + // attributes of md_rgb_control + md_prop_offset = offsetof(metadata_raw, mode) + + offsetof(md_rgb_normal_mode, intel_rgb_control); + + color_ep->register_metadata(RS2_FRAME_METADATA_GAIN_LEVEL, make_attribute_parser(&md_rgb_control::gain, md_rgb_control_attributes::gain_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_ACTUAL_EXPOSURE, make_attribute_parser(&md_rgb_control::manual_exp, md_rgb_control_attributes::manual_exp_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_AUTO_EXPOSURE, make_attribute_parser(&md_rgb_control::ae_mode, md_rgb_control_attributes::ae_mode_attribute, md_prop_offset, + [](rs2_metadata_type param) { return (param != 1); })); + + color_ep->register_metadata(RS2_FRAME_METADATA_BRIGHTNESS, make_attribute_parser(&md_rgb_control::brightness, md_rgb_control_attributes::brightness_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_CONTRAST, make_attribute_parser(&md_rgb_control::contrast, md_rgb_control_attributes::contrast_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_SATURATION, make_attribute_parser(&md_rgb_control::saturation, md_rgb_control_attributes::saturation_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_SHARPNESS, make_attribute_parser(&md_rgb_control::sharpness, md_rgb_control_attributes::sharpness_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_AUTO_WHITE_BALANCE_TEMPERATURE, make_attribute_parser(&md_rgb_control::awb_temp, md_rgb_control_attributes::awb_temp_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_BACKLIGHT_COMPENSATION, make_attribute_parser(&md_rgb_control::backlight_comp, md_rgb_control_attributes::backlight_comp_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_GAMMA, make_attribute_parser(&md_rgb_control::gamma, md_rgb_control_attributes::gamma_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_HUE, make_attribute_parser(&md_rgb_control::hue, md_rgb_control_attributes::hue_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_MANUAL_WHITE_BALANCE, make_attribute_parser(&md_rgb_control::manual_wb, md_rgb_control_attributes::manual_wb_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_POWER_LINE_FREQUENCY, make_attribute_parser(&md_rgb_control::power_line_frequency, md_rgb_control_attributes::power_line_frequency_attribute, md_prop_offset)); + color_ep->register_metadata(RS2_FRAME_METADATA_LOW_LIGHT_COMPENSATION, make_attribute_parser(&md_rgb_control::low_light_comp, md_rgb_control_attributes::low_light_comp_attribute, md_prop_offset)); + return color_ep; } diff --git a/src/l500/l500-depth.cpp b/src/l500/l500-depth.cpp index fc1a2061c2..e6c61b9fbc 100644 --- a/src/l500/l500-depth.cpp +++ b/src/l500/l500-depth.cpp @@ -13,6 +13,8 @@ #include "proc/temporal-filter.h" #include "proc/hole-filling-filter.h" #include "proc/zero-order.h" +#include +#include "metadata-parser.h" #define MM_TO_METER 1/1000 #define MIN_ALGO_VERSION 115 @@ -146,6 +148,21 @@ namespace librealsense std::unique_ptr(new l500_notification_decoder()))); get_depth_sensor().register_option(RS2_OPTION_ERROR_POLLING_ENABLED, std::make_shared(_polling_error_handler.get())); + + // attributes of md_capture_timing + auto md_prop_offset = offsetof(metadata_raw, mode) + + offsetof(md_l500_depth, intel_capture_timing); + + get_depth_sensor().register_metadata(RS2_FRAME_METADATA_FRAME_COUNTER, make_attribute_parser(&l500_md_capture_timing::frame_counter, md_capture_timing_attributes::frame_counter_attribute, md_prop_offset)); + get_depth_sensor().register_metadata(RS2_FRAME_METADATA_SENSOR_TIMESTAMP, make_attribute_parser(&l500_md_capture_timing::sensor_timestamp, md_capture_timing_attributes::sensor_timestamp_attribute, md_prop_offset)); + get_depth_sensor().register_metadata(RS2_FRAME_METADATA_ACTUAL_FPS, make_attribute_parser(&l500_md_capture_timing::exposure_time, md_capture_timing_attributes::sensor_timestamp_attribute, md_prop_offset)); + + // attributes of md_depth_control + md_prop_offset = offsetof(metadata_raw, mode) + + offsetof(md_l500_depth, intel_depth_control); + + get_depth_sensor().register_metadata(RS2_FRAME_METADATA_FRAME_LASER_POWER, make_attribute_parser(&md_l500_depth_control::laser_power, md_l500_depth_control_attributes::laser_power, md_prop_offset)); + get_depth_sensor().register_metadata(RS2_FRAME_METADATA_FRAME_LASER_POWER_MODE, make_attribute_parser(&md_l500_depth_control::laser_power_mode, md_rgb_control_attributes::manual_exp_attribute, md_prop_offset)); } void l500_depth::create_snapshot(std::shared_ptr& snapshot) const diff --git a/src/metadata-parser.h b/src/metadata-parser.h index 99b8df22bd..18583f7697 100644 --- a/src/metadata-parser.h +++ b/src/metadata-parser.h @@ -144,7 +144,7 @@ namespace librealsense // Note that this heurisic is not deterministic and may validate false frames! TODO - requires review md_type expected_type = md_type_trait::type; - if ((s->header.md_type_id != expected_type) || (s->header.md_size !=sizeof(*s))) + if ((s->header.md_type_id != expected_type) || (s->header.md_size < sizeof(*s))) { std::string type = (md_type_desc.count(s->header.md_type_id) > 0) ? md_type_desc.at(s->header.md_type_id) : (to_string() diff --git a/src/metadata.h b/src/metadata.h index b67e388894..f99f6fb6c8 100644 --- a/src/metadata.h +++ b/src/metadata.h @@ -39,22 +39,26 @@ namespace librealsense META_DATA_CAPTURE_STATS_ID = 0x00000003, META_DATA_CAMERA_EXTRINSICS_ID = 0x00000004, META_DATA_CAMERA_INTRINSICS_ID = 0x00000005, + META_DATA_INTEL_L500_CAPTURE_TIMING_ID = 0x80000010, + META_DATA_INTEL_L500_DEPTH_CONTROL_ID = 0x80000012, META_DATA_CAMERA_DEBUG_ID = 0x800000FF, }; static const std::map md_type_desc = { - { md_type::META_DATA_INTEL_DEPTH_CONTROL_ID, "Intel Depth Control"}, - { md_type::META_DATA_INTEL_CAPTURE_TIMING_ID, "Intel Capture timing"}, - { md_type::META_DATA_INTEL_CONFIGURATION_ID, "Intel Configuration"}, - { md_type::META_DATA_INTEL_STAT_ID, "Intel Statistics"}, - { md_type::META_DATA_INTEL_FISH_EYE_CONTROL_ID, "Intel Fisheye Control"}, - { md_type::META_DATA_INTEL_RGB_CONTROL_ID, "Intel RGB Control"}, - { md_type::META_DATA_INTEl_FE_FOV_MODEL_ID, "Intel Fisheye FOV Model"}, - { md_type::META_DATA_CAPTURE_STATS_ID, "Capture Statistics"}, - { md_type::META_DATA_CAMERA_EXTRINSICS_ID, "Camera Extrinsic"}, - { md_type::META_DATA_CAMERA_INTRINSICS_ID, "Camera Intrinsic"}, - { md_type::META_DATA_CAMERA_DEBUG_ID, "Camera Debug"}, + { md_type::META_DATA_INTEL_DEPTH_CONTROL_ID, "Intel Depth Control"}, + { md_type::META_DATA_INTEL_CAPTURE_TIMING_ID, "Intel Capture timing"}, + { md_type::META_DATA_INTEL_CONFIGURATION_ID, "Intel Configuration"}, + { md_type::META_DATA_INTEL_STAT_ID, "Intel Statistics"}, + { md_type::META_DATA_INTEL_FISH_EYE_CONTROL_ID, "Intel Fisheye Control"}, + { md_type::META_DATA_INTEL_RGB_CONTROL_ID, "Intel RGB Control"}, + { md_type::META_DATA_INTEl_FE_FOV_MODEL_ID, "Intel Fisheye FOV Model"}, + { md_type::META_DATA_CAPTURE_STATS_ID, "Capture Statistics"}, + { md_type::META_DATA_CAMERA_EXTRINSICS_ID, "Camera Extrinsic"}, + { md_type::META_DATA_CAMERA_INTRINSICS_ID, "Camera Intrinsic"}, + { md_type::META_DATA_CAMERA_DEBUG_ID, "Camera Debug"}, + { md_type::META_DATA_INTEL_L500_CAPTURE_TIMING_ID, "Intel Capture timing"}, + { md_type::META_DATA_INTEL_L500_DEPTH_CONTROL_ID, "Intel Depth Control"}, }; /**\brief md_capture_timing_attributes - enumerate the bit offset to check @@ -101,6 +105,14 @@ namespace librealsense preset_attribute = (1u << 6), }; + /**\brief md_depth_control_attributes - bit mask to find active attributes, + * md_depth_control struct */ + enum class md_l500_depth_control_attributes : uint32_t + { + laser_power = (1u << 0), + preset_id = (1u << 1), + laser_power_mode = (1u << 2), + }; /**\brief md_fisheye_control_attributes - bit mask to find active attributes, * md_fisheye_control struct */ enum class md_fisheye_control_attributes : uint32_t @@ -271,6 +283,20 @@ namespace librealsense REGISTER_MD_TYPE(md_capture_timing, md_type::META_DATA_INTEL_CAPTURE_TIMING_ID) + struct l500_md_capture_timing + { + md_header header; + uint32_t version; + uint32_t flags; // Bit array to specify attributes that are valid + uint32_t frame_counter; + uint32_t sensor_timestamp; //In microsecond unit + uint32_t readout_time; //The readout time in microsecond unit + uint32_t exposure_time; //The exposure time in microsecond unit + uint32_t frame_interval; //The frame interval in microsecond unit + uint32_t pipe_latency; //The latency between start of frame to frame ready in USB buffer + }; + REGISTER_MD_TYPE(l500_md_capture_timing, md_type::META_DATA_INTEL_L500_CAPTURE_TIMING_ID) + /**\brief md_capture_stats - properties associated with optical sensor * during video streaming. Corresponds to FW STMetaDataCaptureStats object*/ struct md_capture_stats @@ -316,6 +342,19 @@ namespace librealsense REGISTER_MD_TYPE(md_depth_control, md_type::META_DATA_INTEL_DEPTH_CONTROL_ID) + /**\brief md_depth_control - depth data-related parameters. + * Corresponds to FW's STMetaDataIntelDepthControl object*/ + struct md_l500_depth_control + { + md_header header; + uint32_t version; + uint32_t flags; + uint32_t laser_power; //value between 1 to 12 + uint32_t preset_id; + uint32_t laser_power_mode; //Auto or Manual laser power + }; + + REGISTER_MD_TYPE(md_l500_depth_control, md_type::META_DATA_INTEL_L500_DEPTH_CONTROL_ID) /**\brief md_fisheye_control - fisheye-related parameters. * Corresponds to FW's STMetaDataIntelFishEyeControl object*/ @@ -478,6 +517,14 @@ namespace librealsense md_configuration intel_configuration; }; + struct md_l500_depth + { + md_capture_timing intel_capture_timing; + md_capture_stats intel_capture_stats; + md_l500_depth_control intel_depth_control; + md_configuration intel_configuration; + }; + struct md_fisheye_normal_mode { md_capture_timing intel_capture_timing; @@ -543,7 +590,7 @@ namespace librealsense * layout as transmitted and received by backend */ struct metadata_raw { - platform::uvc_header header; + platform::uvc_header header; md_modes mode; }; From ecb7012dba6449d599d83556d41b88bde21b80a3 Mon Sep 17 00:00:00 2001 From: Evgeni Raikhel Date: Sun, 21 Apr 2019 11:15:41 +0300 Subject: [PATCH 2/3] L500 patch - HID will mapped if available on startup. This is required as a back-compatibility measure, as well as Android/Mac bypass. The drawback -The enum flow that is dependent on HID activation latency will not commit, resulting in partial functionality only. Will be added to known-issues Change-Id: Ib8c546741eedb37a040c7ba0d7a79bf804c4dfdc Signed-off-by: Evgeni Raikhel --- src/ds5/ds5-motion.cpp | 2 +- src/l500/l500-factory.cpp | 8 ++------ src/sensor.cpp | 10 +++++----- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/ds5/ds5-motion.cpp b/src/ds5/ds5-motion.cpp index 1b8cfd2681..7b190cd712 100644 --- a/src/ds5/ds5-motion.cpp +++ b/src/ds5/ds5-motion.cpp @@ -158,7 +158,7 @@ namespace librealsense { if (all_hid_infos.empty()) { - LOG_WARNING("HID device is missing!"); + LOG_WARNING("No HID info provided, IMU is disabled"); return nullptr; } diff --git a/src/l500/l500-factory.cpp b/src/l500/l500-factory.cpp index 343ec37b80..707a65f849 100644 --- a/src/l500/l500-factory.cpp +++ b/src/l500/l500-factory.cpp @@ -114,15 +114,11 @@ namespace librealsense if (!ivcam2::try_fetch_usb_device(group.usb_devices, depth, hwm)) LOG_WARNING("try_fetch_usb_device(...) failed."); - -#if defined( RS2_USE_WMF_BACKEND) || defined(RS2_USE_V4L2_BACKEND) //currently hid backend implemented only for windows and linux. if (g.second.size() < 2) { - LOG_WARNING("Skipping L500. " << g.second.size() << " HID devices were recognized, at least 2 required"); - continue; + LOG_WARNING("L500 partial enum: " << g.second.size() << " HID devices were recognized (2+ expected)"); } - -#endif + auto info = std::make_shared(ctx, g.first, hwm, g.second); chosen.push_back(depth); results.push_back(info); diff --git a/src/sensor.cpp b/src/sensor.cpp index 26a60a8760..d155225131 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -15,7 +15,7 @@ namespace librealsense { - sensor_base::sensor_base(std::string name, device* dev, + sensor_base::sensor_base(std::string name, device* dev, recommended_proccesing_blocks_interface* owner) : recommended_proccesing_blocks_base(owner), _is_streaming(false), @@ -1105,15 +1105,15 @@ namespace librealsense if (has_metadata(mode, fo.metadata, fo.metadata_size)) { - // The timestamps conversions path comprise of: - // FW TS (32bit) -> USB Phy Layer (no changes) -> Host Driver TS (Extend to 64bit) -> LRS read as 64 bit - // The flow introduces discrepancy with UVC stream which timestamps aer not extended to 64 bit by host driver both for Win and v4l backends. + // The timestamps conversions path comprise of: + // FW TS (32bit) -> USB Phy Layer (no changes) -> Host Driver TS (Extend to 64bit) -> LRS read as 64 bit + // The flow introduces discrepancy with UVC stream which timestamps aer not extended to 64 bit by host driver both for Win and v4l backends. // In order to allow for hw timestamp-based synchronization of Depth and IMU streams the latter will be trimmed to 32 bit. // To revert to the extended 64 bit TS uncomment the next line instead //auto timestamp = *((uint64_t*)((const uint8_t*)fo.metadata)); auto timestamp = *((uint32_t*)((const uint8_t*)fo.metadata)); - // HID timestamps are aligned to FW Default - usec units + // HID timestamps are aligned to FW Default - usec units return static_cast(timestamp * TIMESTAMP_USEC_TO_MSEC); } From f1676c64345478489ee5186e22d45eabd826ef13 Mon Sep 17 00:00:00 2001 From: Evgeni Raikhel Date: Sun, 21 Apr 2019 13:56:27 +0300 Subject: [PATCH 3/3] L500 Patch - disable Zero-Order. Requires zo_point_x integration Change-Id: Iae982b95509a65a5d1b0057728c45209c0c15d3e Signed-off-by: Evgeni Raikhel --- common/model-views.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/model-views.cpp b/common/model-views.cpp index 8f0189c978..137255152d 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -970,7 +970,7 @@ namespace rs2 if (shared_filter->is()) zero_order_artifact_fix = model; - if (shared_filter->is()) + if (shared_filter->is() || shared_filter->is()) model->enabled = false; post_processing.push_back(model);