l1npengtul / nokhwa

Cross Platform Rust Library for Powerful Webcam/Camera Capture
Apache License 2.0
533 stars 137 forks source link

msmf backend - mf_device.compatible_format_list() deadlocks but does not panic after 333 device enumerations. #87

Closed JosephCatrambone closed 1 year ago

JosephCatrambone commented 1 year ago

This was a strange one.

Inside the MediaFoundationCaptureDevice, there's the following call let availible = mf_device.compatible_format_list()?;. Compatible format list generates all possible combinations of frame rates and resolutions, then returns them. On my system, this method spins and deadlocks. If I try and break the process, I can step through until index 334.

I think this is caused by the following chunk:

let frame_fmt = match guid_to_frameformat(fourcc) {
                    Some(fcc) => fcc,
                    None => continue,
                };

In my case, frame_fmt does not match anything and triggers a 'continue', but the index is not incremented, leading to an endless loop while evaluating the same fourcc value.

EDIT: I made a patch, but I defer to the owner if it's better to increment index in this part or at the top of the block. Both are good.

===

Complete digression:

It feels slightly wasteful (though cleaner) to exhaustively enumerate camera formats before passing them in to the fulfill method on camera_fmt. Perhaps it's possible to do one of the following to speed up the detection process?

  1. Create a method get_compatible_format_list that takes the requested format and breaks on a match.
  2. Use some kind of callback to check for valid formats?

Obviously, this is inconceivable if the user requests the MAX_WHATEVER. In that case we need to enumerate the formats no matter what, but it's possible we can still do some early-out by skipping the later parts of the inner loop if the resolution is less than the min or the framerate is less than the best we've found.