Skip to content

Enable metadata with a single click on Windows - #5678

Merged
dorodnic merged 4 commits into
realsenseai:developmentfrom
dorodnic:install_metadata
Jan 23, 2020
Merged

dorodnic merged 4 commits into
realsenseai:developmentfrom
dorodnic:install_metadata

Conversation

@dorodnic

Copy link
Copy Markdown
Contributor

UVC frame metadata on Windows is causing a lot of questions and confusion, adding a single click solution that would be applicable from within the Viewer.
Alternative solution is to download and install Intel-RealSense-D400-Series-Universal-Windows-Platform-UWP-Driver-for-Windows but from our experience a lot of users don't do this.
Related to #5669

@maloel
maloel self-requested a review January 20, 2020 09:31
Comment thread common/notifications.cpp Outdated
"software synchronization between different\n"
"camera streams.\n"
"It must be explicitly enabled on Windows OS\n";
last_progress_time = system_clock::now();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is draw_progress_bar() called at all? Where is this last_progress_time being used? If not used, is the inheritance from process_notification_model needed? Maybe inherit directly from notification_model?

Comment thread common/notifications.cpp Outdated
enable_dismiss = true;
update_state = 0;
pinned = true;
message = "Frame Metadata is device feature allowing\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a device feature

Comment thread common/metadata-helper.cpp Outdated

bool operator==(const device_id& a, const device_id& b)
{
return (to_lower(a.pid) == to_lower(b.pid) &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strcasecmp() would compare just as well without all the extra allocations/transformations

Comment thread common/metadata-helper.cpp Outdated
public:
static bool parse_device_id(std::string id, device_id* res)
{
static const std::regex regex("[\\s\\S]*pid_([0-9a-fA-F]+)&mi_([0-9]+)#[0-9]&([0-9a-fA-F]+)&[\\s\\S]*\\{([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\\}[\\s\\S]*");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't "[\s\S]" the same as "."? And is not needed at the beginning/end of the regex if we use regex_search() instead of regex_match()?
If we're using a-fA-F, then no need to use to_lower(), and then can pass the string in with 'const &'?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't "[\s\S]" the same as "."?

Apparently no, I had problems matching special symbols with .*

And is not needed at the beginning/end of the regex if we use regex_search() instead of regex_match()

Make sense, I'll give it a try

If we're using a-fA-F, then no need to use to_lower()

Ultimately, to_lower is only used for comparisons. If we switch all comparisons to strcasecmp as you suggested it may be redundant

@maloel maloel Jan 21, 2020 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't "[\s\S]" the same as "."?

Apparently no, I had problems matching special symbols with .*

According to this, ". doesn't catch line terminators (like new line) by default" but I don't think that would cover your difficulties. I wonder what kind of special characters...

But OK, keep it at [/s/S] but please comment so the next wise-guy like me won't try to "optimize" :)

Comment thread common/metadata-helper.cpp Outdated
return false;
}

static void do_foreach_device(std::vector<device_id> devices,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass devices by 'const &'

NULL,
NULL,
&ftLastWriteTime);
if (retCode == ERROR_SUCCESS)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of errors, do we usually LOG_DEBUG() it?
What about the successes? Do we want to debug-log any of this so we can see what happened?

Comment thread common/metadata-helper.cpp Outdated
if (rdid == did)
{
std::wstringstream ss;
ss << ws << "\\" << ke << "\\#GLOBAL\\Device Parameters";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can build the whole key path here instead of building ws ahead of time, so it'll be:

ss << "SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{" << guid << "}"
   << "\\" << ke << "\\#GLOBAL\\Device Parameters";

That way it's clearer (and ws doesn't get re-defined inside this block).

Comment thread common/metadata-helper.cpp Outdated
{
std::wstringstream ss;
ss << ws << "\\" << ke << "\\#GLOBAL\\Device Parameters";
auto s = ss.str();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a wstring? Why do we need ws on the next line?

// Heuristic that determines how many media-pins UVC device is expected to have
static int number_of_mediapins(std::string pid, std::string mi)
{
if (mi == "00")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole function is very confusing unless you know things by heart.

Isn't there a way to programmatically get all these magic numbers (which could conceivably change in the future)?
If not programmatically, isn't there a header somewhere with constants that will make this both more understandable and easier to maintain?
The way I understand it, "media pins" is the same as the streams that a device sensor exposes?

Comment thread common/metadata-helper.cpp Resolved
Comment thread common/metadata-helper.cpp Outdated
std::wstring wcmd(cmd_line.begin(), cmd_line.end());
sei.lpParameters = wcmd.c_str();

ShellExecuteEx(&sei); // not checking return code - what you are going to do? retry? why?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the very least, I think this should be logged somehow?

Comment thread common/metadata-helper.cpp Outdated
}

static void do_foreach_device(std::vector<device_id> devices,
std::function<void(device_id&, std::wstring)> action)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear what the wstring is representing... it's a device path, right? Can we name the argument? There might be an issue with the compiler (it's ambiguous in the standard, so depends on the compiler)...

Maybe name the function 'foreach_device_path'?

The device_id should be passed as 'const &'.

Comment thread common/metadata-helper.cpp Outdated
DWORD MetadataBufferSizeInKB = 5;
RegSetValueEx(key, metadatakey.c_str(), 0, REG_DWORD,
(const BYTE*)&MetadataBufferSizeInKB, sizeof(DWORD));
// What to do if failed???

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log it, at the very least.

Comment thread common/metadata-helper.h
// Enable metadata for all connected devices
virtual void enable_metadata() { }

static std::string get_command_line_param() { return "--enable_metadata"; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// This is the command-line parameter that gets passed to another process (running as admin) in order to enable metadata -- see WinMain

Comment thread common/metadata-helper.h
virtual bool is_enabled(std::string id) const { return true; }

// Enable metadata for all connected devices
virtual void enable_metadata() { }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, it could fail, so I'd suggest to return a bool, even if the implementation always "succeeds"

Comment thread common/windows-app-bootstrap.cpp Outdated
if (s == rs2::metadata_helper::get_command_line_param())
{
rs2::metadata_helper::instance().enable_metadata();
exit(0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exit 1 on failure (if you change the return value)

Comment thread common/windows-app-bootstrap.cpp Resolved
Comment thread common/metadata-helper.h
public:
static metadata_helper& instance();

// Check if metadata is enabled using Physical Port ID

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd help readability if we gave an example of a port ID string here, and explained is can be retrieved with device::get_info(RS2_CAMERA_INFO_PHYSICAL_PORT)

Comment thread common/model-views.cpp Outdated
std::string product = dev.get_info(RS2_CAMERA_INFO_PRODUCT_LINE);
std::string id = dev.get_info(RS2_CAMERA_INFO_PHYSICAL_PORT);
bool has_metadata = rs2::metadata_helper::instance().is_enabled(id) ||
!(product == "D400" || product == "SR300" || product == "L500");

@maloel maloel Jan 21, 2020 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we abstract these product names into the metadata_helper class, such that we can simply ask:

auto & metadata = rs2::metadata_helper::instance();
bool has_metadata = metadata.is_enabled( dev );

That way, the product names will be local to the helper class and this information is contained centrally.

(LPBYTE)(&MetadataBufferSizeInKB),
&len);
&len) != ERROR_SUCCESS)
rs2::log(RS2_LOG_SEVERITY_DEBUG, "Unable to read metadata registry key!");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to include the key path in the message, otherwise it lacks context and will be repetitive if it happens multiple times

Comment thread common/metadata-helper.cpp Outdated
}

static void foreach_device_path(const std::vector<device_id>& devices,
std::function<void(device_id&, /* matched device */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any special reason device_id is not const?

Comment thread common/windows-app-bootstrap.cpp Outdated
{
try
{
DebugBreak();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to remove :)

Comment thread common/notifications.cpp Outdated

if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("%s", "You will be prompted to enabled metadata on the device");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"to enable" (there's an extra d in there)

May I suggest:

"Enables metadata on connected devices (you may be prompted for administrator privileges)"

Comment thread common/metadata-helper.h
// (can be retrieved with device::get_info(RS2_CAMERA_INFO_PHYSICAL_PORT))
virtual bool is_enabled(std::string id) const { return true; }

// Enable metadata for all connected devices

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add that it will throw a runtime_error on failure

@maloel maloel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, see comments above

@dorodnic
dorodnic merged commit 6006739 into realsenseai:development Jan 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants