Commit 0ba070fd authored by Christian Fremerey's avatar Christian Fremerey Committed by Commit Bot

[VideoCapture, Windows] Blacklist certain legacy Empia chips for MediaFoundation

Devices using certain legacy Empia chips appear to get listed and report valid
formats in both DirectShow and MediaFoundation but only work in DirectShow when
actually trying to open them.

This CL adds a blacklisting mechanism that forces device models known to exhibit
this issue to always get opened with DirectShow instead of MediaFoundation.

Test: capture_unittests.exe --gtest_filter=VideoCaptureDeviceFactoryMFWinTest*
Bug: 792640, 849636, 862395
Change-Id: Ia70d13a45eb49ed185f27630d0e544f3a484b6f2
Reviewed-on: https://chromium-review.googlesource.com/1174902Reviewed-by: default avatarEmircan Uysaler <emircan@chromium.org>
Commit-Queue: Christian Fremerey <chfremer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583068}
parent ac8b0d15
......@@ -18,6 +18,7 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/win/core_winrt_util.h"
......@@ -78,6 +79,11 @@ static_assert(arraysize(kBlacklistedCameraNames) == BLACKLISTED_CAMERA_MAX + 1,
"kBlacklistedCameraNames should be same size as "
"BlacklistedCameraNames enum");
const char* const kModelIdsBlacklistedForMediaFoundation[] = {
// Devices using Empia 2860 or 2820 chips, see https://crbug.com/849636.
"eb1a:2860", "eb1a:2820",
};
const std::pair<VideoCaptureApi, std::vector<std::pair<GUID, GUID>>>
kMfAttributes[] = {{VideoCaptureApi::WIN_MEDIA_FOUNDATION,
{
......@@ -95,6 +101,11 @@ bool IsDeviceBlacklistedForQueryingDetailedFrameRates(
return display_name.find("WebcamMax") != std::string::npos;
}
bool IsDeviceBlacklistedForMediaFoundationByModelId(
const std::string& model_id) {
return base::ContainsValue(kModelIdsBlacklistedForMediaFoundation, model_id);
}
bool LoadMediaFoundationDlls() {
static const wchar_t* const kMfDLLs[] = {
L"%WINDIR%\\system32\\mf.dll", L"%WINDIR%\\system32\\mfplat.dll",
......@@ -613,6 +624,8 @@ void VideoCaptureDeviceFactoryWin::GetDeviceDescriptorsMediaFoundation(
const std::string device_id =
base::SysWideToUTF8(std::wstring(id, id_size));
const std::string model_id = GetDeviceModelId(device_id);
if (IsDeviceBlacklistedForMediaFoundationByModelId(model_id))
continue;
if (list_was_empty ||
!DescriptorsContainDeviceId(*device_descriptors, device_id)) {
device_descriptors->emplace_back(
......
......@@ -33,8 +33,16 @@ const wchar_t* kMFDeviceName2 = L"Device 2";
const wchar_t* kMFDeviceId5 = L"\\\\?\\usb#vid_0005&pid_0005&mi_00";
const wchar_t* kMFDeviceName5 = L"Dazzle";
const wchar_t* kMFDeviceId6 = L"\\\\?\\usb#vid_eb1a&pid_2860&mi_00";
const wchar_t* kMFDeviceName6 = L"Empia Device";
void GetMFSupportedFormats(const VideoCaptureDeviceDescriptor& device,
VideoCaptureFormats* formats) {}
VideoCaptureFormats* formats) {
if (device.device_id == base::SysWideToUTF8(kMFDeviceId6)) {
VideoCaptureFormat arbitrary_format;
formats->emplace_back(arbitrary_format);
}
}
// DirectShow devices
const wchar_t* kDirectShowDeviceId0 = L"\\\\?\\usb#vid_0000&pid_0000&mi_00";
......@@ -52,6 +60,9 @@ const wchar_t* kDirectShowDeviceName4 = L"Virtual Camera";
const wchar_t* kDirectShowDeviceId5 = L"\\\\?\\usb#vid_0005&pid_0005&mi_00#5";
const wchar_t* kDirectShowDeviceName5 = L"Dazzle";
const wchar_t* kDirectShowDeviceId6 = L"\\\\?\\usb#vid_eb1a&pid_2860&mi_00";
const wchar_t* kDirectShowDeviceName6 = L"Empia Device";
void GetDirectShowSupportedFormats(const VideoCaptureDeviceDescriptor& device,
VideoCaptureFormats* formats) {
if (device.device_id == base::SysWideToUTF8(kDirectShowDeviceId5)) {
......@@ -426,7 +437,8 @@ HRESULT __stdcall MockMFEnumDeviceSources(IMFAttributes* attributes,
new MockMFActivate(kMFDeviceId0, kMFDeviceName0, true, false),
new MockMFActivate(kMFDeviceId1, kMFDeviceName1, true, true),
new MockMFActivate(kMFDeviceId2, kMFDeviceName2, false, true),
new MockMFActivate(kMFDeviceId5, kMFDeviceName5, true, false)};
new MockMFActivate(kMFDeviceId5, kMFDeviceName5, true, false),
new MockMFActivate(kMFDeviceId6, kMFDeviceName6, true, false)};
// Iterate once to get the match count and check for errors.
*count = 0U;
HRESULT hr;
......@@ -456,7 +468,8 @@ HRESULT EnumerateStubDirectShowDevices(IEnumMoniker** enum_moniker) {
new StubMoniker(kDirectShowDeviceId1, kDirectShowDeviceName1),
new StubMoniker(kDirectShowDeviceId3, kDirectShowDeviceName3),
new StubMoniker(kDirectShowDeviceId4, kDirectShowDeviceName4),
new StubMoniker(kDirectShowDeviceId5, kDirectShowDeviceName5)};
new StubMoniker(kDirectShowDeviceId5, kDirectShowDeviceName5),
new StubMoniker(kDirectShowDeviceId6, kDirectShowDeviceName6)};
StubEnumMoniker* stub_enum_moniker = new StubEnumMoniker();
for (StubMoniker* moniker : monikers)
......@@ -511,7 +524,7 @@ TEST_F(VideoCaptureDeviceFactoryMFWinTest, GetDeviceDescriptors) {
base::BindRepeating(&EnumerateStubDirectShowDevices));
VideoCaptureDeviceDescriptors descriptors;
factory_.GetDeviceDescriptors(&descriptors);
EXPECT_EQ(descriptors.size(), 6U);
EXPECT_EQ(descriptors.size(), 7U);
for (auto it = descriptors.begin(); it != descriptors.end(); it++) {
// Verify that there are no duplicates.
EXPECT_EQ(FindDescriptorInRange(descriptors.begin(), it, it->device_id),
......@@ -555,6 +568,15 @@ TEST_F(VideoCaptureDeviceFactoryMFWinTest, GetDeviceDescriptors) {
EXPECT_NE(it, descriptors.end());
EXPECT_EQ(it->capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
EXPECT_EQ(it->display_name(), base::SysWideToUTF8(kDirectShowDeviceName5));
// Devices that are listed in both MediaFoundation and DirectShow but are
// blacklisted for use with MediaFoundation are expected to get enumerated
// with VideoCaptureApi::WIN_DIRECT_SHOW.
it = FindDescriptorInRange(descriptors.begin(), descriptors.end(),
base::SysWideToUTF8(kDirectShowDeviceId6));
EXPECT_NE(it, descriptors.end());
EXPECT_EQ(it->capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
EXPECT_EQ(it->display_name(), base::SysWideToUTF8(kDirectShowDeviceName6));
}
} // namespace media
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment