Reland "Wait for frames to arrive in WgcCapturer instead of returning nothing."
This reverts commit dd32562f242b247aed8add4efecaf3e20c623b9a. Reason for revert: Updated the original change to dynamically load the CoreMessaging.dll instead of statically linking with the .lib. Original change's description: > Revert "Wait for frames to arrive in WgcCapturer instead of returning nothing." > > This reverts commit 93bb3051490253d56dc1cdab4701b91138a151c3. > > Reason for revert: It breaks a test while rolling into Chromium, > see https://webrtc-review.googlesource.com/c/src/+/261780/21#message-4a96e33bfb475f19a618be82bbe72951b23085ef for details. > > Original change's description: > > Wait for frames to arrive in WgcCapturer instead of returning nothing. > > > > We're seeing a high instance of "first capture failed" in Chromium when > > using WGC. We can reduce this by waiting for frames to arrive if there > > are none in the frame pool instead of returning a temporary error. > > > > I've set the maximum time to wait for a frame to 50ms. If no frame > > arrives before 50ms has elapsed, we will return a temporary error. > > Added a new test, FirstCaptureSucceeds, to verify that this is working > > as expected. > > > > As part of this I updated the name of the `kCreateFreeThreadedFailed` > > enum value to `kCreateFramePoolFailed`. The value remains the same > > since they both report failures in frame pool creation. > > > > I also increased `kNumBuffers` from 1 to 2, so that the frame pool can > > store two frames. This should prevent us from having to wait on the > > event as frequently. This will increase the latency between capture > > and display, however. High frame rate applications should not be > > noticeably affected. > > > > Additionally, we uncovered a bug in the OS that prevents window capture > > when there are displays attached, but none of them are active. Added > > a new check to `IsWgcSupported` to cover this scenario. > > > > Finally, some issues with other WGC tests blocked moving the TryBots > > to a newer version of Windows. This CL fixes those issues and updates > > the TryBot configuration. > > > > bug: chromium:1314868 > > Change-Id: Id9c4d5ee98621e682ef04864c3848d50e761cdb7 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261780 > > Reviewed-by: Alexander Cooper <alcooper@chromium.org> > > Reviewed-by: Jeremy Leconte <jleconte@webrtc.org> > > Commit-Queue: Austin Orion <auorion@microsoft.com> > > Reviewed-by: Jeremy Leconte <jleconte@google.com> > > Cr-Commit-Position: refs/heads/main@{#37404} > > Change-Id: If237df4826fe20b6fe2ca4b57253623321bf33c5 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/267460 > Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> > Owners-Override: Mirko Bonadei <mbonadei@webrtc.org> > Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> > Auto-Submit: Mirko Bonadei <mbonadei@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#37408} Change-Id: I6cc2becd9ed363782ab2f326f58d9401bc8fb820 Bug: chromium:1314868 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/267902 Reviewed-by: Jeremy Leconte <jleconte@webrtc.org> Reviewed-by: Alexander Cooper <alcooper@chromium.org> Commit-Queue: Austin Orion <auorion@microsoft.com> Cr-Commit-Position: refs/heads/main@{#37470}
This commit is contained in:
parent
298450eb73
commit
81797744fd
@ -8436,7 +8436,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -8464,7 +8464,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8485,7 +8485,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8506,7 +8506,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8527,7 +8527,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8551,7 +8551,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8572,7 +8572,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -8594,7 +8594,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -8616,7 +8616,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -8638,7 +8638,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8659,7 +8659,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8680,7 +8680,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8701,7 +8701,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -8723,7 +8723,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8744,7 +8744,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8765,7 +8765,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8786,7 +8786,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8807,7 +8807,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8850,7 +8850,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -8872,7 +8872,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8893,7 +8893,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8918,7 +8918,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8939,7 +8939,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8960,7 +8960,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -8981,7 +8981,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9005,7 +9005,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9026,7 +9026,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -9048,7 +9048,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -9070,7 +9070,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -9092,7 +9092,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9113,7 +9113,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9134,7 +9134,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9155,7 +9155,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -9177,7 +9177,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9198,7 +9198,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9219,7 +9219,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9240,7 +9240,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9261,7 +9261,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9282,7 +9282,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -9304,7 +9304,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -9325,7 +9325,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -322,17 +322,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
'win10-1703': {
|
||||
'win10': {
|
||||
'swarming': {
|
||||
'dimensions': {
|
||||
'os': 'Windows-10-15063'
|
||||
}
|
||||
}
|
||||
},
|
||||
'win7': {
|
||||
'swarming': {
|
||||
'dimensions': {
|
||||
'os': 'Windows-7-SP1'
|
||||
'os': 'Windows-10-19042'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -259,12 +259,5 @@
|
||||
'os': 'Windows'
|
||||
}
|
||||
}
|
||||
},
|
||||
'win10-1703': {
|
||||
'swarming': {
|
||||
'dimensions': {
|
||||
'os': 'Windows-10-15063',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,13 +220,11 @@
|
||||
},
|
||||
'win_video_capture_tests': {
|
||||
'video_capture_tests': {
|
||||
'remove_mixins': ['win7'],
|
||||
'mixins': ['win', 'baremetal-pool'],
|
||||
}
|
||||
},
|
||||
'win_video_capture_tests_tryserver': {
|
||||
'video_capture_tests': {
|
||||
'remove_mixins': ['win7'],
|
||||
'mixins': ['win', 'baremetal-try-pool'],
|
||||
}
|
||||
},
|
||||
|
||||
@ -12364,7 +12364,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12385,7 +12385,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12406,7 +12406,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12427,7 +12427,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12451,7 +12451,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12472,7 +12472,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -12494,7 +12494,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -12516,7 +12516,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -12538,7 +12538,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12559,7 +12559,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12580,7 +12580,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12601,7 +12601,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -12623,7 +12623,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12644,7 +12644,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12665,7 +12665,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12686,7 +12686,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12707,7 +12707,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12728,7 +12728,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -12750,7 +12750,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12771,7 +12771,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12800,7 +12800,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12821,7 +12821,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12842,7 +12842,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12863,7 +12863,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12887,7 +12887,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12908,7 +12908,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -12930,7 +12930,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -12952,7 +12952,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -12974,7 +12974,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -12995,7 +12995,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13016,7 +13016,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13037,7 +13037,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -13059,7 +13059,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13080,7 +13080,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13101,7 +13101,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13122,7 +13122,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13143,7 +13143,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13164,7 +13164,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -13186,7 +13186,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13207,7 +13207,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13232,7 +13232,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13253,7 +13253,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13274,7 +13274,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13295,7 +13295,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13319,7 +13319,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13340,7 +13340,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -13362,7 +13362,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -13384,7 +13384,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -13406,7 +13406,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13427,7 +13427,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13448,7 +13448,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13469,7 +13469,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -13491,7 +13491,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13512,7 +13512,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13533,7 +13533,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13554,7 +13554,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13575,7 +13575,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13596,7 +13596,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -13618,7 +13618,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13639,7 +13639,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-10-15063"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13664,7 +13664,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13685,7 +13685,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13706,7 +13706,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13727,7 +13727,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13751,7 +13751,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13772,7 +13772,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -13794,7 +13794,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -13816,7 +13816,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -13838,7 +13838,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13859,7 +13859,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13880,7 +13880,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13901,7 +13901,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -13923,7 +13923,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13944,7 +13944,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13965,7 +13965,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -13986,7 +13986,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14007,7 +14007,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14028,7 +14028,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -14050,7 +14050,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14071,7 +14071,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14096,7 +14096,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14117,7 +14117,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14138,7 +14138,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14159,7 +14159,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14183,7 +14183,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14204,7 +14204,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -14226,7 +14226,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -14248,7 +14248,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -14270,7 +14270,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14291,7 +14291,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14312,7 +14312,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14333,7 +14333,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -14355,7 +14355,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14376,7 +14376,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14397,7 +14397,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14418,7 +14418,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14439,7 +14439,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14460,7 +14460,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -14482,7 +14482,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14503,7 +14503,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14528,7 +14528,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14549,7 +14549,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14570,7 +14570,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14591,7 +14591,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14615,7 +14615,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14636,7 +14636,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 2
|
||||
@ -14658,7 +14658,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -14680,7 +14680,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -14702,7 +14702,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14723,7 +14723,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14744,7 +14744,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14765,7 +14765,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 6
|
||||
@ -14787,7 +14787,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14808,7 +14808,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14829,7 +14829,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14850,7 +14850,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14871,7 +14871,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14914,7 +14914,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
@ -14936,7 +14936,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14957,7 +14957,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -14984,7 +14984,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -15009,7 +15009,7 @@
|
||||
"dimension_sets": [
|
||||
{
|
||||
"cpu": "x86-64",
|
||||
"os": "Windows-7-SP1"
|
||||
"os": "Windows-10-19042"
|
||||
}
|
||||
],
|
||||
"shards": 4
|
||||
|
||||
@ -179,7 +179,7 @@
|
||||
'MacArm64 Builder': {},
|
||||
'Win (more configs)': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win7', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'more_configs_tests',
|
||||
},
|
||||
@ -188,14 +188,14 @@
|
||||
'Win32 Debug (Clang)': {},
|
||||
'Win32 Release (Clang)': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win7', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'win_tests',
|
||||
},
|
||||
},
|
||||
'Win64 ASan': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win10-1703', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'desktop_tests',
|
||||
},
|
||||
@ -581,7 +581,7 @@
|
||||
},
|
||||
'win_asan': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win10-1703', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'desktop_tests',
|
||||
},
|
||||
@ -592,42 +592,42 @@
|
||||
'win_compile_x86_clang_rel': {},
|
||||
'win_x64_clang_dbg': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win7', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'desktop_tests',
|
||||
},
|
||||
},
|
||||
'win_x64_clang_dbg_win10': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win10-1703', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'desktop_tests',
|
||||
},
|
||||
},
|
||||
'win_x64_clang_rel': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win7', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'desktop_tests',
|
||||
},
|
||||
},
|
||||
'win_x86_clang_dbg': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win7', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'desktop_tests',
|
||||
},
|
||||
},
|
||||
'win_x86_clang_rel': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win7', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'win_tests_tryserver',
|
||||
},
|
||||
},
|
||||
'win_x86_more_configs': {
|
||||
'os_type': 'win',
|
||||
'mixins': ['win7', 'x86-64', 'resultdb-json-format'],
|
||||
'mixins': ['win10', 'x86-64', 'resultdb-json-format'],
|
||||
'test_suites': {
|
||||
'isolated_scripts': 'more_configs_tests',
|
||||
},
|
||||
|
||||
@ -636,7 +636,10 @@ rtc_library("desktop_capture") {
|
||||
"win/wgc_desktop_frame.h",
|
||||
]
|
||||
libs += [ "dwmapi.lib" ]
|
||||
deps += [ "../../rtc_base/win:hstring" ]
|
||||
deps += [
|
||||
"../../rtc_base:rtc_event",
|
||||
"../../rtc_base/win:hstring",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "modules/desktop_capture/win/wgc_capture_session.h"
|
||||
|
||||
#include <DispatcherQueue.h>
|
||||
#include <windows.graphics.capture.interop.h>
|
||||
#include <windows.graphics.directX.direct3d11.interop.h>
|
||||
#include <windows.graphics.h>
|
||||
@ -36,13 +37,13 @@ namespace {
|
||||
|
||||
// We must use a BGRA pixel format that has 4 bytes per pixel, as required by
|
||||
// the DesktopFrame interface.
|
||||
const auto kPixelFormat = ABI::Windows::Graphics::DirectX::DirectXPixelFormat::
|
||||
DirectXPixelFormat_B8G8R8A8UIntNormalized;
|
||||
constexpr auto kPixelFormat = ABI::Windows::Graphics::DirectX::
|
||||
DirectXPixelFormat::DirectXPixelFormat_B8G8R8A8UIntNormalized;
|
||||
|
||||
// We only want 1 buffer in our frame pool to reduce latency. If we had more,
|
||||
// they would sit in the pool for longer and be stale by the time we are asked
|
||||
// for a new frame.
|
||||
const int kNumBuffers = 1;
|
||||
// The maximum time `GetFrame` will wait for a frame to arrive, if we don't have
|
||||
// any in the pool.
|
||||
constexpr int kMaxWaitForFrameMs = 50;
|
||||
constexpr int kMaxWaitForFirstFrameMs = 500;
|
||||
|
||||
// These values are persisted to logs. Entries should not be renumbered and
|
||||
// numeric values should never be reused.
|
||||
@ -54,9 +55,9 @@ enum class StartCaptureResult {
|
||||
kD3dDelayLoadFailed = 4,
|
||||
kD3dDeviceCreationFailed = 5,
|
||||
kFramePoolActivationFailed = 6,
|
||||
kFramePoolCastFailed = 7,
|
||||
kGetItemSizeFailed = 8,
|
||||
kCreateFreeThreadedFailed = 9,
|
||||
// kFramePoolCastFailed = 7, (deprecated)
|
||||
// kGetItemSizeFailed = 8, (deprecated)
|
||||
kCreateFramePoolFailed = 9,
|
||||
kCreateCaptureSessionFailed = 10,
|
||||
kStartCaptureFailed = 11,
|
||||
kMaxValue = kStartCaptureFailed
|
||||
@ -100,7 +101,9 @@ WgcCaptureSession::WgcCaptureSession(ComPtr<ID3D11Device> d3d11_device,
|
||||
: d3d11_device_(std::move(d3d11_device)),
|
||||
item_(std::move(item)),
|
||||
size_(size) {}
|
||||
WgcCaptureSession::~WgcCaptureSession() = default;
|
||||
WgcCaptureSession::~WgcCaptureSession() {
|
||||
RemoveEventHandlers();
|
||||
}
|
||||
|
||||
HRESULT WgcCaptureSession::StartCapture() {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
@ -118,12 +121,13 @@ HRESULT WgcCaptureSession::StartCapture() {
|
||||
// Listen for the Closed event, to detect if the source we are capturing is
|
||||
// closed (e.g. application window is closed or monitor is disconnected). If
|
||||
// it is, we should abort the capture.
|
||||
item_closed_token_ = std::make_unique<EventRegistrationToken>();
|
||||
auto closed_handler =
|
||||
Microsoft::WRL::Callback<ABI::Windows::Foundation::ITypedEventHandler<
|
||||
WGC::GraphicsCaptureItem*, IInspectable*>>(
|
||||
this, &WgcCaptureSession::OnItemClosed);
|
||||
EventRegistrationToken item_closed_token;
|
||||
HRESULT hr = item_->add_Closed(closed_handler.Get(), &item_closed_token);
|
||||
HRESULT hr =
|
||||
item_->add_Closed(closed_handler.Get(), item_closed_token_.get());
|
||||
if (FAILED(hr)) {
|
||||
RecordStartCaptureResult(StartCaptureResult::kAddClosedFailed);
|
||||
return hr;
|
||||
@ -157,22 +161,25 @@ HRESULT WgcCaptureSession::StartCapture() {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Cast to FramePoolStatics2 so we can use CreateFreeThreaded and avoid the
|
||||
// need to have a DispatcherQueue. We don't listen for the FrameArrived event,
|
||||
// so there's no difference.
|
||||
ComPtr<WGC::IDirect3D11CaptureFramePoolStatics2> frame_pool_statics2;
|
||||
hr = frame_pool_statics->QueryInterface(IID_PPV_ARGS(&frame_pool_statics2));
|
||||
hr = frame_pool_statics->Create(direct3d_device_.Get(), kPixelFormat,
|
||||
kNumBuffers, size_, &frame_pool_);
|
||||
if (FAILED(hr)) {
|
||||
RecordStartCaptureResult(StartCaptureResult::kFramePoolCastFailed);
|
||||
RecordStartCaptureResult(StartCaptureResult::kCreateFramePoolFailed);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = frame_pool_statics2->CreateFreeThreaded(
|
||||
direct3d_device_.Get(), kPixelFormat, kNumBuffers, size_, &frame_pool_);
|
||||
if (FAILED(hr)) {
|
||||
RecordStartCaptureResult(StartCaptureResult::kCreateFreeThreadedFailed);
|
||||
return hr;
|
||||
}
|
||||
frames_in_pool_ = 0;
|
||||
|
||||
// Because `WgcCapturerWin` created a `DispatcherQueue`, and we created
|
||||
// `frame_pool_` via `Create`, the `FrameArrived` event will be delivered on
|
||||
// the current thread.
|
||||
frame_arrived_token_ = std::make_unique<EventRegistrationToken>();
|
||||
auto frame_arrived_handler =
|
||||
Microsoft::WRL::Callback<ABI::Windows::Foundation::ITypedEventHandler<
|
||||
WGC::Direct3D11CaptureFramePool*, IInspectable*>>(
|
||||
this, &WgcCaptureSession::OnFrameArrived);
|
||||
hr = frame_pool_->add_FrameArrived(frame_arrived_handler.Get(),
|
||||
frame_arrived_token_.get());
|
||||
|
||||
hr = frame_pool_->CreateCaptureSession(item_.Get(), &session_);
|
||||
if (FAILED(hr)) {
|
||||
@ -205,6 +212,10 @@ HRESULT WgcCaptureSession::GetFrame(
|
||||
|
||||
RTC_DCHECK(is_capture_started_);
|
||||
|
||||
if (frames_in_pool_ < 1)
|
||||
wait_for_frame_event_.Wait(first_frame_ ? kMaxWaitForFirstFrameMs
|
||||
: kMaxWaitForFrameMs);
|
||||
|
||||
ComPtr<WGC::IDirect3D11CaptureFrame> capture_frame;
|
||||
HRESULT hr = frame_pool_->TryGetNextFrame(&capture_frame);
|
||||
if (FAILED(hr)) {
|
||||
@ -218,6 +229,9 @@ HRESULT WgcCaptureSession::GetFrame(
|
||||
return hr;
|
||||
}
|
||||
|
||||
first_frame_ = false;
|
||||
--frames_in_pool_;
|
||||
|
||||
// We need to get `capture_frame` as an `ID3D11Texture2D` so that we can get
|
||||
// the raw image data in the format required by the `DesktopFrame` interface.
|
||||
ComPtr<ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface>
|
||||
@ -358,6 +372,16 @@ HRESULT WgcCaptureSession::CreateMappedTexture(
|
||||
return d3d11_device_->CreateTexture2D(&map_desc, nullptr, &mapped_texture_);
|
||||
}
|
||||
|
||||
HRESULT WgcCaptureSession::OnFrameArrived(
|
||||
WGC::IDirect3D11CaptureFramePool* sender,
|
||||
IInspectable* event_args) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_DCHECK_LT(frames_in_pool_, kNumBuffers);
|
||||
++frames_in_pool_;
|
||||
wait_for_frame_event_.Set();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender,
|
||||
IInspectable* event_args) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
@ -366,6 +390,8 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender,
|
||||
item_closed_ = true;
|
||||
is_capture_started_ = false;
|
||||
|
||||
RemoveEventHandlers();
|
||||
|
||||
mapped_texture_ = nullptr;
|
||||
session_ = nullptr;
|
||||
frame_pool_ = nullptr;
|
||||
@ -376,4 +402,22 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void WgcCaptureSession::RemoveEventHandlers() {
|
||||
HRESULT hr;
|
||||
if (frame_pool_ && frame_arrived_token_) {
|
||||
hr = frame_pool_->remove_FrameArrived(*frame_arrived_token_);
|
||||
frame_arrived_token_.reset();
|
||||
if (FAILED(hr)) {
|
||||
RTC_LOG(LS_WARNING) << "Failed to remove FrameArrived event handler: "
|
||||
<< hr;
|
||||
}
|
||||
}
|
||||
if (item_ && item_closed_token_) {
|
||||
hr = item_->remove_Closed(*item_closed_token_);
|
||||
item_closed_token_.reset();
|
||||
if (FAILED(hr))
|
||||
RTC_LOG(LS_WARNING) << "Failed to remove Closed event handler: " << hr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "api/sequence_checker.h"
|
||||
#include "modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "modules/desktop_capture/win/wgc_capture_source.h"
|
||||
#include "rtc_base/event.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -48,6 +49,12 @@ class WgcCaptureSession final {
|
||||
return is_capture_started_;
|
||||
}
|
||||
|
||||
// We keep 2 buffers in the frame pool to balance the staleness of the frame
|
||||
// with having to wait for frames to arrive too frequently. Too many buffers
|
||||
// will lead to a high latency, and too few will lead to poor performance.
|
||||
// We make this public for tests.
|
||||
static constexpr int kNumBuffers = 2;
|
||||
|
||||
private:
|
||||
// Initializes `mapped_texture_` with the properties of the `src_texture`,
|
||||
// overrides the values of some necessary properties like the
|
||||
@ -64,6 +71,24 @@ class WgcCaptureSession final {
|
||||
ABI::Windows::Graphics::Capture::IGraphicsCaptureItem* sender,
|
||||
IInspectable* event_args);
|
||||
|
||||
// Event handler for `frame_pool_`'s FrameArrived event.
|
||||
HRESULT OnFrameArrived(
|
||||
ABI::Windows::Graphics::Capture::IDirect3D11CaptureFramePool* sender,
|
||||
IInspectable* event_args);
|
||||
|
||||
void RemoveEventHandlers();
|
||||
|
||||
// We wait on this event in `GetFrame` if there are no frames in the pool.
|
||||
// `OnFrameArrived` will set the event so we can proceed.
|
||||
rtc::Event wait_for_frame_event_;
|
||||
int frames_in_pool_;
|
||||
|
||||
// We're willing to wait for a frame a little longer if it's the first one.
|
||||
bool first_frame_ = true;
|
||||
|
||||
std::unique_ptr<EventRegistrationToken> frame_arrived_token_;
|
||||
std::unique_ptr<EventRegistrationToken> item_closed_token_;
|
||||
|
||||
// A Direct3D11 Device provided by the caller. We use this to create an
|
||||
// IDirect3DDevice, and also to create textures that will hold the image data.
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "modules/desktop_capture/win/wgc_capturer_win.h"
|
||||
|
||||
#include <DispatcherQueue.h>
|
||||
#include <windows.foundation.metadata.h>
|
||||
#include <windows.graphics.capture.h>
|
||||
|
||||
@ -32,10 +33,12 @@ namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kWgcSessionType[] =
|
||||
constexpr wchar_t kCoreMessagingDll[] = L"CoreMessaging.dll";
|
||||
|
||||
constexpr wchar_t kWgcSessionType[] =
|
||||
L"Windows.Graphics.Capture.GraphicsCaptureSession";
|
||||
const wchar_t kApiContract[] = L"Windows.Foundation.UniversalApiContract";
|
||||
const UINT16 kRequiredApiContractVersion = 8;
|
||||
constexpr wchar_t kApiContract[] = L"Windows.Foundation.UniversalApiContract";
|
||||
constexpr UINT16 kRequiredApiContractVersion = 8;
|
||||
|
||||
enum class WgcCapturerResult {
|
||||
kSuccess = 0,
|
||||
@ -45,7 +48,8 @@ enum class WgcCapturerResult {
|
||||
kSessionStartFailure = 4,
|
||||
kGetFrameFailure = 5,
|
||||
kFrameDropped = 6,
|
||||
kMaxValue = kFrameDropped
|
||||
kCreateDispatcherQueueFailure = 7,
|
||||
kMaxValue = kCreateDispatcherQueueFailure
|
||||
};
|
||||
|
||||
void RecordWgcCapturerResult(WgcCapturerResult error) {
|
||||
@ -57,20 +61,34 @@ void RecordWgcCapturerResult(WgcCapturerResult error) {
|
||||
} // namespace
|
||||
|
||||
bool IsWgcSupported(CaptureType capture_type) {
|
||||
if (capture_type == CaptureType::kScreen) {
|
||||
// A bug in the WGC API `CreateForMonitor` was fixed in 20H1.
|
||||
if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN10_20H1)
|
||||
if (!HasActiveDisplay()) {
|
||||
// There is a bug in `CreateForMonitor` that causes a crash if there are no
|
||||
// active displays. The crash was fixed in Win11, but we are still unable
|
||||
// to capture screens without an active display.
|
||||
if (capture_type == CaptureType::kScreen)
|
||||
return false;
|
||||
|
||||
// There is another bug in `CreateForMonitor` that causes a crash if there
|
||||
// are no active displays.
|
||||
if (!HasActiveDisplay())
|
||||
// There is a bug in the DWM (Desktop Window Manager) that prevents it from
|
||||
// providing image data if there are no displays attached. This was fixed in
|
||||
// Windows 11.
|
||||
if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN11)
|
||||
return false;
|
||||
}
|
||||
|
||||
// A bug in the WGC API `CreateForMonitor` prevents capturing the entire
|
||||
// virtual screen (all monitors simultaneously), this was fixed in 20H1. Since
|
||||
// we can't assert that we won't be asked to capture the entire virtual
|
||||
// screen, we report unsupported so we can fallback to another capturer.
|
||||
if (capture_type == CaptureType::kScreen &&
|
||||
rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN10_20H1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ResolveCoreWinRTDelayload())
|
||||
return false;
|
||||
|
||||
// We need to check if the WGC APIs are presesnt on the system. Certain SKUs
|
||||
// of Windows ship without these APIs.
|
||||
ComPtr<ABI::Windows::Foundation::Metadata::IApiInformationStatics>
|
||||
api_info_statics;
|
||||
HRESULT hr = GetActivationFactory<
|
||||
@ -104,6 +122,7 @@ bool IsWgcSupported(CaptureType capture_type) {
|
||||
if (FAILED(hr) || !is_type_present)
|
||||
return false;
|
||||
|
||||
// If the APIs are present, we need to check that they are supported.
|
||||
ComPtr<WGC::IGraphicsCaptureSessionStatics> capture_session_statics;
|
||||
hr = GetActivationFactory<
|
||||
WGC::IGraphicsCaptureSessionStatics,
|
||||
@ -126,8 +145,21 @@ WgcCapturerWin::WgcCapturerWin(
|
||||
bool allow_delayed_capturable_check)
|
||||
: source_factory_(std::move(source_factory)),
|
||||
source_enumerator_(std::move(source_enumerator)),
|
||||
allow_delayed_capturable_check_(allow_delayed_capturable_check) {}
|
||||
WgcCapturerWin::~WgcCapturerWin() = default;
|
||||
allow_delayed_capturable_check_(allow_delayed_capturable_check) {
|
||||
if (!core_messaging_library_)
|
||||
core_messaging_library_ = LoadLibraryW(kCoreMessagingDll);
|
||||
|
||||
if (core_messaging_library_) {
|
||||
create_dispatcher_queue_controller_func_ =
|
||||
reinterpret_cast<CreateDispatcherQueueControllerFunc>(GetProcAddress(
|
||||
core_messaging_library_, "CreateDispatcherQueueController"));
|
||||
}
|
||||
}
|
||||
|
||||
WgcCapturerWin::~WgcCapturerWin() {
|
||||
if (core_messaging_library_)
|
||||
FreeLibrary(core_messaging_library_);
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<DesktopCapturer> WgcCapturerWin::CreateRawWindowCapturer(
|
||||
@ -224,9 +256,32 @@ void WgcCapturerWin::CaptureFrame() {
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
if (!dispatcher_queue_created_) {
|
||||
// Set the apartment type to NONE because this thread should already be COM
|
||||
// initialized.
|
||||
DispatcherQueueOptions options{
|
||||
sizeof(DispatcherQueueOptions),
|
||||
DISPATCHERQUEUE_THREAD_TYPE::DQTYPE_THREAD_CURRENT,
|
||||
DISPATCHERQUEUE_THREAD_APARTMENTTYPE::DQTAT_COM_NONE};
|
||||
ComPtr<ABI::Windows::System::IDispatcherQueueController> queue_controller;
|
||||
hr = create_dispatcher_queue_controller_func_(options, &queue_controller);
|
||||
|
||||
// If there is already a DispatcherQueue on this thread, that is fine. Its
|
||||
// lifetime is tied to the thread's, and as long as the thread has one, even
|
||||
// if we didn't create it, the capture session's events will be delivered on
|
||||
// this thread.
|
||||
if (FAILED(hr) && hr != RPC_E_WRONG_THREAD) {
|
||||
RecordWgcCapturerResult(WgcCapturerResult::kCreateDispatcherQueueFailure);
|
||||
callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT,
|
||||
/*frame=*/nullptr);
|
||||
} else {
|
||||
dispatcher_queue_created_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t capture_start_time_nanos = rtc::TimeNanos();
|
||||
|
||||
HRESULT hr;
|
||||
WgcCaptureSession* capture_session = nullptr;
|
||||
std::map<SourceId, WgcCaptureSession>::iterator session_iter =
|
||||
ongoing_captures_.find(capture_source_->GetSourceId());
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#ifndef MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_
|
||||
#define MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_
|
||||
|
||||
#include <DispatcherQueue.h>
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
@ -109,6 +110,23 @@ class WgcCapturerWin : public DesktopCapturer {
|
||||
bool IsSourceBeingCaptured(SourceId id);
|
||||
|
||||
private:
|
||||
typedef HRESULT(WINAPI* CreateDispatcherQueueControllerFunc)(
|
||||
DispatcherQueueOptions,
|
||||
ABI::Windows::System::IDispatcherQueueController**);
|
||||
|
||||
// We need to either create or ensure that someone else created a
|
||||
// `DispatcherQueue` on the current thread so that events will be delivered
|
||||
// on the current thread rather than an arbitrary thread. A
|
||||
// `DispatcherQueue`'s lifetime is tied to the thread's, and we don't post
|
||||
// any work to it, so we don't need to hold a reference.
|
||||
bool dispatcher_queue_created_ = false;
|
||||
|
||||
// Statically linking to CoreMessaging.lib is disallowed in Chromium, so we
|
||||
// load it at runtime.
|
||||
HMODULE core_messaging_library_ = NULL;
|
||||
CreateDispatcherQueueControllerFunc create_dispatcher_queue_controller_func_ =
|
||||
nullptr;
|
||||
|
||||
// Factory to create a WgcCaptureSource for us whenever SelectSource is
|
||||
// called. Initialized at construction with a source-specific implementation.
|
||||
std::unique_ptr<WgcCaptureSourceFactory> source_factory_;
|
||||
|
||||
@ -18,12 +18,14 @@
|
||||
#include "modules/desktop_capture/desktop_capture_types.h"
|
||||
#include "modules/desktop_capture/desktop_capturer.h"
|
||||
#include "modules/desktop_capture/win/test_support/test_window.h"
|
||||
#include "modules/desktop_capture/win/wgc_capture_session.h"
|
||||
#include "modules/desktop_capture/win/window_capture_utils.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/thread.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
#include "rtc_base/win/scoped_com_initializer.h"
|
||||
#include "rtc_base/win/windows_version.h"
|
||||
#include "system_wrappers/include/metrics.h"
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
#include "test/gtest.h"
|
||||
@ -31,40 +33,54 @@
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
const char kWindowThreadName[] = "wgc_capturer_test_window_thread";
|
||||
const WCHAR kWindowTitle[] = L"WGC Capturer Test Window";
|
||||
constexpr char kWindowThreadName[] = "wgc_capturer_test_window_thread";
|
||||
constexpr WCHAR kWindowTitle[] = L"WGC Capturer Test Window";
|
||||
|
||||
const char kCapturerImplHistogram[] =
|
||||
constexpr char kCapturerImplHistogram[] =
|
||||
"WebRTC.DesktopCapture.Win.DesktopCapturerImpl";
|
||||
|
||||
const char kCapturerResultHistogram[] =
|
||||
constexpr char kCapturerResultHistogram[] =
|
||||
"WebRTC.DesktopCapture.Win.WgcCapturerResult";
|
||||
const int kSuccess = 0;
|
||||
const int kSessionStartFailure = 4;
|
||||
constexpr int kSuccess = 0;
|
||||
constexpr int kSessionStartFailure = 4;
|
||||
|
||||
const char kCaptureSessionResultHistogram[] =
|
||||
constexpr char kCaptureSessionResultHistogram[] =
|
||||
"WebRTC.DesktopCapture.Win.WgcCaptureSessionStartResult";
|
||||
const int kSourceClosed = 1;
|
||||
constexpr int kSourceClosed = 1;
|
||||
|
||||
const char kCaptureTimeHistogram[] =
|
||||
constexpr char kCaptureTimeHistogram[] =
|
||||
"WebRTC.DesktopCapture.Win.WgcCapturerFrameTime";
|
||||
|
||||
const int kSmallWindowWidth = 200;
|
||||
const int kSmallWindowHeight = 100;
|
||||
const int kMediumWindowWidth = 300;
|
||||
const int kMediumWindowHeight = 200;
|
||||
const int kLargeWindowWidth = 400;
|
||||
const int kLargeWindowHeight = 500;
|
||||
// The capturer keeps `kNumBuffers` in its frame pool, so we need to request
|
||||
// that many frames to clear those out. The next frame will have the new size
|
||||
// (if the size has changed) so we will resize the frame pool at this point.
|
||||
// Then, we need to clear any frames that may have delivered to the frame pool
|
||||
// before the resize. Finally, the next frame will be guaranteed to be the new
|
||||
// size.
|
||||
constexpr int kNumCapturesToFlushBuffers =
|
||||
WgcCaptureSession::kNumBuffers * 2 + 1;
|
||||
|
||||
constexpr int kSmallWindowWidth = 200;
|
||||
constexpr int kSmallWindowHeight = 100;
|
||||
constexpr int kMediumWindowWidth = 300;
|
||||
constexpr int kMediumWindowHeight = 200;
|
||||
constexpr int kLargeWindowWidth = 400;
|
||||
constexpr int kLargeWindowHeight = 500;
|
||||
|
||||
// The size of the image we capture is slightly smaller than the actual size of
|
||||
// the window.
|
||||
const int kWindowWidthSubtrahend = 14;
|
||||
const int kWindowHeightSubtrahend = 7;
|
||||
constexpr int kWindowWidthSubtrahend = 14;
|
||||
constexpr int kWindowHeightSubtrahend = 7;
|
||||
|
||||
// Custom message constants so we can direct our thread to close windows
|
||||
// and quit running.
|
||||
const UINT kDestroyWindow = WM_APP;
|
||||
const UINT kQuitRunning = WM_APP + 1;
|
||||
// Custom message constants so we can direct our thread to close windows and
|
||||
// quit running.
|
||||
constexpr UINT kDestroyWindow = WM_APP;
|
||||
constexpr UINT kQuitRunning = WM_APP + 1;
|
||||
|
||||
// When testing changes to real windows, sometimes the effects (close or resize)
|
||||
// don't happen immediately, we want to keep trying until we see the effect but
|
||||
// only for a reasonable amount of time.
|
||||
constexpr int kMaxTries = 50;
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -185,20 +201,26 @@ class WgcCapturerWinTest : public ::testing::TestWithParam<CaptureType>,
|
||||
return sources[0].id;
|
||||
}
|
||||
|
||||
void DoCapture() {
|
||||
// Sometimes the first few frames are empty becaues the capture engine is
|
||||
// still starting up. We also may drop a few frames when the window is
|
||||
// resized or un-minimized.
|
||||
do {
|
||||
void DoCapture(int num_captures = 1) {
|
||||
// Capture the requested number of frames. We expect the first capture to
|
||||
// always succeed. If we're asked for multiple frames, we do expect to see a
|
||||
// a couple dropped frames due to resizing the window.
|
||||
const int max_tries = num_captures == 1 ? 1 : kMaxTries;
|
||||
int success_count = 0;
|
||||
for (int i = 0; success_count < num_captures && i < max_tries; i++) {
|
||||
capturer_->CaptureFrame();
|
||||
} while (result_ == DesktopCapturer::Result::ERROR_TEMPORARY);
|
||||
if (result_ == DesktopCapturer::Result::ERROR_PERMANENT)
|
||||
break;
|
||||
if (result_ == DesktopCapturer::Result::SUCCESS)
|
||||
success_count++;
|
||||
}
|
||||
|
||||
total_successful_captures_ += success_count;
|
||||
EXPECT_EQ(success_count, num_captures);
|
||||
EXPECT_EQ(result_, DesktopCapturer::Result::SUCCESS);
|
||||
EXPECT_TRUE(frame_);
|
||||
|
||||
EXPECT_GT(metrics::NumEvents(kCapturerResultHistogram, kSuccess),
|
||||
successful_captures_);
|
||||
++successful_captures_;
|
||||
EXPECT_GE(metrics::NumEvents(kCapturerResultHistogram, kSuccess),
|
||||
total_successful_captures_);
|
||||
}
|
||||
|
||||
void ValidateFrame(int expected_width, int expected_height) {
|
||||
@ -206,8 +228,7 @@ class WgcCapturerWinTest : public ::testing::TestWithParam<CaptureType>,
|
||||
EXPECT_EQ(frame_->size().height(),
|
||||
expected_height - kWindowHeightSubtrahend);
|
||||
|
||||
// Verify the buffer contains as much data as it should, and that the right
|
||||
// colors are found.
|
||||
// Verify the buffer contains as much data as it should.
|
||||
int data_length = frame_->stride() * frame_->size().height();
|
||||
|
||||
// The first and last pixel should have the same color because they will be
|
||||
@ -219,7 +240,7 @@ class WgcCapturerWinTest : public ::testing::TestWithParam<CaptureType>,
|
||||
EXPECT_EQ(first_pixel, last_pixel);
|
||||
|
||||
// Let's also check a pixel from the middle of the content area, which the
|
||||
// TestWindow will paint a consistent color for us to verify.
|
||||
// test window will paint a consistent color for us to verify.
|
||||
uint8_t* middle_pixel = frame_->data() + (data_length / 2);
|
||||
|
||||
int sub_pixel_offset = DesktopFrame::kBytesPerPixel / 4;
|
||||
@ -251,7 +272,7 @@ class WgcCapturerWinTest : public ::testing::TestWithParam<CaptureType>,
|
||||
intptr_t source_id_;
|
||||
bool window_open_ = false;
|
||||
DesktopCapturer::Result result_;
|
||||
int successful_captures_ = 0;
|
||||
int total_successful_captures_ = 0;
|
||||
std::unique_ptr<DesktopFrame> frame_;
|
||||
std::unique_ptr<DesktopCapturer> capturer_;
|
||||
};
|
||||
@ -310,13 +331,12 @@ TEST_P(WgcCapturerWinTest, CaptureTime) {
|
||||
capturer_->Start(this);
|
||||
|
||||
int64_t start_time;
|
||||
do {
|
||||
start_time = rtc::TimeNanos();
|
||||
capturer_->CaptureFrame();
|
||||
} while (result_ == DesktopCapturer::Result::ERROR_TEMPORARY);
|
||||
start_time = rtc::TimeNanos();
|
||||
capturer_->CaptureFrame();
|
||||
|
||||
int capture_time_ms =
|
||||
(rtc::TimeNanos() - start_time) / rtc::kNumNanosecsPerMillisec;
|
||||
EXPECT_EQ(result_, DesktopCapturer::Result::SUCCESS);
|
||||
EXPECT_TRUE(frame_);
|
||||
|
||||
// The test may measure the time slightly differently than the capturer. So we
|
||||
@ -332,6 +352,8 @@ INSTANTIATE_TEST_SUITE_P(SourceAgnostic,
|
||||
CaptureType::kScreen));
|
||||
|
||||
TEST(WgcCapturerNoMonitorTest, NoMonitors) {
|
||||
ScopedCOMInitializer com_initializer(ScopedCOMInitializer::kMTA);
|
||||
EXPECT_TRUE(com_initializer.Succeeded());
|
||||
if (HasActiveDisplay()) {
|
||||
RTC_LOG(LS_INFO) << "Skip WgcCapturerWinTest designed specifically for "
|
||||
"systems with no monitors";
|
||||
@ -341,6 +363,13 @@ TEST(WgcCapturerNoMonitorTest, NoMonitors) {
|
||||
// A bug in `CreateForMonitor` prevents screen capture when no displays are
|
||||
// attached.
|
||||
EXPECT_FALSE(IsWgcSupported(CaptureType::kScreen));
|
||||
|
||||
// A bug in the DWM (Desktop Window Manager) prevents it from providing image
|
||||
// data if there are no displays attached. This was fixed in Windows 11.
|
||||
if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN11)
|
||||
EXPECT_FALSE(IsWgcSupported(CaptureType::kWindow));
|
||||
else
|
||||
EXPECT_TRUE(IsWgcSupported(CaptureType::kWindow));
|
||||
}
|
||||
|
||||
class WgcCapturerMonitorTest : public WgcCapturerWinTest {
|
||||
@ -452,15 +481,11 @@ TEST_F(WgcCapturerWindowTest, IncreaseWindowSizeMidCapture) {
|
||||
ValidateFrame(kSmallWindowWidth, kSmallWindowHeight);
|
||||
|
||||
ResizeTestWindow(window_info_.hwnd, kSmallWindowWidth, kMediumWindowHeight);
|
||||
DoCapture();
|
||||
// We don't expect to see the new size until the next capture, as the frame
|
||||
// pool hadn't had a chance to resize yet to fit the new, larger image.
|
||||
DoCapture();
|
||||
DoCapture(kNumCapturesToFlushBuffers);
|
||||
ValidateFrame(kSmallWindowWidth, kMediumWindowHeight);
|
||||
|
||||
ResizeTestWindow(window_info_.hwnd, kLargeWindowWidth, kMediumWindowHeight);
|
||||
DoCapture();
|
||||
DoCapture();
|
||||
DoCapture(kNumCapturesToFlushBuffers);
|
||||
ValidateFrame(kLargeWindowWidth, kMediumWindowHeight);
|
||||
}
|
||||
|
||||
@ -473,13 +498,11 @@ TEST_F(WgcCapturerWindowTest, ReduceWindowSizeMidCapture) {
|
||||
ValidateFrame(kLargeWindowWidth, kLargeWindowHeight);
|
||||
|
||||
ResizeTestWindow(window_info_.hwnd, kLargeWindowWidth, kMediumWindowHeight);
|
||||
// We expect to see the new size immediately because the image data has shrunk
|
||||
// and will fit in the existing buffer.
|
||||
DoCapture();
|
||||
DoCapture(kNumCapturesToFlushBuffers);
|
||||
ValidateFrame(kLargeWindowWidth, kMediumWindowHeight);
|
||||
|
||||
ResizeTestWindow(window_info_.hwnd, kSmallWindowWidth, kMediumWindowHeight);
|
||||
DoCapture();
|
||||
DoCapture(kNumCapturesToFlushBuffers);
|
||||
ValidateFrame(kSmallWindowWidth, kMediumWindowHeight);
|
||||
}
|
||||
|
||||
@ -491,7 +514,7 @@ TEST_F(WgcCapturerWindowTest, MinimizeWindowMidCapture) {
|
||||
|
||||
// Minmize the window and capture should continue but return temporary errors.
|
||||
MinimizeTestWindow(window_info_.hwnd);
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
capturer_->CaptureFrame();
|
||||
EXPECT_EQ(result_, DesktopCapturer::Result::ERROR_TEMPORARY);
|
||||
}
|
||||
@ -520,19 +543,24 @@ TEST_F(WgcCapturerWindowTest, CloseWindowMidCapture) {
|
||||
// stops.
|
||||
auto* wgc_capturer = static_cast<WgcCapturerWin*>(capturer_.get());
|
||||
MSG msg;
|
||||
while (wgc_capturer->IsSourceBeingCaptured(source_id_)) {
|
||||
for (int i = 0;
|
||||
wgc_capturer->IsSourceBeingCaptured(source_id_) && i < kMaxTries; ++i) {
|
||||
// Unlike GetMessage, PeekMessage will not hang if there are no messages in
|
||||
// the queue.
|
||||
PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
|
||||
SleepMs(1);
|
||||
}
|
||||
|
||||
// Occasionally, one last frame will have made it into the frame pool before
|
||||
// the window closed. The first call will consume it, and in that case we need
|
||||
// to make one more call to CaptureFrame.
|
||||
capturer_->CaptureFrame();
|
||||
if (result_ == DesktopCapturer::Result::SUCCESS)
|
||||
EXPECT_FALSE(wgc_capturer->IsSourceBeingCaptured(source_id_));
|
||||
|
||||
// The frame pool can buffer `kNumBuffers` frames. We must consume these
|
||||
// and then make one more call to CaptureFrame before we expect to see the
|
||||
// failure.
|
||||
int num_tries = 0;
|
||||
do {
|
||||
capturer_->CaptureFrame();
|
||||
} while (result_ == DesktopCapturer::Result::SUCCESS &&
|
||||
++num_tries <= WgcCaptureSession::kNumBuffers);
|
||||
|
||||
EXPECT_GE(metrics::NumEvents(kCapturerResultHistogram, kSessionStartFailure),
|
||||
1);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user