Evaluate DeviceScaleFactor per captured frame
This is to ensure that the device_scale_factor stored per frame is the latest one according to the system settings and not an old value. Bug: chromium:383946052 Change-Id: I11e6342201678451554e6883ded48999fd996743 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/377541 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Palak Agarwal <agpalak@google.com> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43924}
This commit is contained in:
parent
04d06457f5
commit
9a2c408a1a
@ -189,12 +189,12 @@ DxgiDuplicatorController::Result DxgiDuplicatorController::DoDuplicate(
|
|||||||
return Result::INITIALIZATION_FAILED;
|
return Result::INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frame->Prepare(SelectedDesktopSize(monitor_id), monitor_id,
|
if (!frame->Prepare(SelectedDesktopSize(monitor_id), monitor_id)) {
|
||||||
GetDeviceScaleFactor(monitor_id))) {
|
|
||||||
return Result::FRAME_PREPARE_FAILED;
|
return Result::FRAME_PREPARE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->frame()->mutable_updated_region()->Clear();
|
frame->frame()->mutable_updated_region()->Clear();
|
||||||
|
frame->frame()->set_device_scale_factor(GetDeviceScaleFactor(monitor_id));
|
||||||
|
|
||||||
if (DoDuplicateUnlocked(frame->context(), monitor_id, frame->frame())) {
|
if (DoDuplicateUnlocked(frame->context(), monitor_id, frame->frame())) {
|
||||||
succeeded_duplications_++;
|
succeeded_duplications_++;
|
||||||
|
|||||||
@ -25,9 +25,7 @@ DxgiFrame::DxgiFrame(SharedMemoryFactory* factory) : factory_(factory) {}
|
|||||||
|
|
||||||
DxgiFrame::~DxgiFrame() = default;
|
DxgiFrame::~DxgiFrame() = default;
|
||||||
|
|
||||||
bool DxgiFrame::Prepare(DesktopSize size,
|
bool DxgiFrame::Prepare(DesktopSize size, DesktopCapturer::SourceId source_id) {
|
||||||
DesktopCapturer::SourceId source_id,
|
|
||||||
std::optional<float> device_scale_factor) {
|
|
||||||
if (source_id != source_id_) {
|
if (source_id != source_id_) {
|
||||||
// Once the source has been changed, the entire source should be copied.
|
// Once the source has been changed, the entire source should be copied.
|
||||||
source_id_ = source_id;
|
source_id_ = source_id;
|
||||||
@ -59,7 +57,6 @@ bool DxgiFrame::Prepare(DesktopSize size,
|
|||||||
} else {
|
} else {
|
||||||
frame.reset(new BasicDesktopFrame(size));
|
frame.reset(new BasicDesktopFrame(size));
|
||||||
}
|
}
|
||||||
frame->set_device_scale_factor(device_scale_factor);
|
|
||||||
frame_ = SharedDesktopFrame::Wrap(std::move(frame));
|
frame_ = SharedDesktopFrame::Wrap(std::move(frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,11 +45,8 @@ class DxgiFrame final {
|
|||||||
// as well as Context class.
|
// as well as Context class.
|
||||||
friend class DxgiDuplicatorController;
|
friend class DxgiDuplicatorController;
|
||||||
|
|
||||||
// Prepares current instance with desktop size, source id and device scale
|
// Prepares current instance with desktop size and source id.
|
||||||
// factor.
|
bool Prepare(DesktopSize size, DesktopCapturer::SourceId source_id);
|
||||||
bool Prepare(DesktopSize size,
|
|
||||||
DesktopCapturer::SourceId source_id,
|
|
||||||
std::optional<float> device_scale_factor);
|
|
||||||
|
|
||||||
// Should not be called if Prepare() is not executed or returns false.
|
// Should not be called if Prepare() is not executed or returns false.
|
||||||
Context* context();
|
Context* context();
|
||||||
|
|||||||
@ -68,18 +68,12 @@ DxgiOutputDuplicator::DxgiOutputDuplicator(const D3dDevice& device,
|
|||||||
: device_(device),
|
: device_(device),
|
||||||
output_(output),
|
output_(output),
|
||||||
device_name_(rtc::ToUtf8(desc.DeviceName)),
|
device_name_(rtc::ToUtf8(desc.DeviceName)),
|
||||||
desktop_rect_(RECTToDesktopRect(desc.DesktopCoordinates)) {
|
desktop_rect_(RECTToDesktopRect(desc.DesktopCoordinates)),
|
||||||
|
monitor_(desc.Monitor) {
|
||||||
RTC_DCHECK(output_);
|
RTC_DCHECK(output_);
|
||||||
RTC_DCHECK(!desktop_rect_.is_empty());
|
RTC_DCHECK(!desktop_rect_.is_empty());
|
||||||
RTC_DCHECK_GT(desktop_rect_.width(), 0);
|
RTC_DCHECK_GT(desktop_rect_.width(), 0);
|
||||||
RTC_DCHECK_GT(desktop_rect_.height(), 0);
|
RTC_DCHECK_GT(desktop_rect_.height(), 0);
|
||||||
DEVICE_SCALE_FACTOR device_scale_factor = DEVICE_SCALE_FACTOR_INVALID;
|
|
||||||
HRESULT hr = GetScaleFactorForMonitor(desc.Monitor, &device_scale_factor);
|
|
||||||
RTC_LOG_IF(LS_ERROR, FAILED(hr))
|
|
||||||
<< "Failed to get scale factor for monitor: " << hr;
|
|
||||||
if (device_scale_factor != DEVICE_SCALE_FACTOR_INVALID) {
|
|
||||||
device_scale_factor_ = static_cast<float>(device_scale_factor) / 100.0f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DxgiOutputDuplicator::DxgiOutputDuplicator(DxgiOutputDuplicator&& other) =
|
DxgiOutputDuplicator::DxgiOutputDuplicator(DxgiOutputDuplicator&& other) =
|
||||||
@ -425,6 +419,17 @@ int64_t DxgiOutputDuplicator::num_frames_captured() const {
|
|||||||
return num_frames_captured_;
|
return num_frames_captured_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<float> DxgiOutputDuplicator::device_scale_factor() const {
|
||||||
|
DEVICE_SCALE_FACTOR device_scale_factor = DEVICE_SCALE_FACTOR_INVALID;
|
||||||
|
HRESULT hr = GetScaleFactorForMonitor(monitor_, &device_scale_factor);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
RTC_LOG(LS_ERROR) << "Failed to get scale factor for monitor: " << hr;
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
RTC_DCHECK(device_scale_factor != DEVICE_SCALE_FACTOR_INVALID);
|
||||||
|
return static_cast<float>(device_scale_factor) / 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void DxgiOutputDuplicator::TranslateRect(const DesktopVector& position) {
|
void DxgiOutputDuplicator::TranslateRect(const DesktopVector& position) {
|
||||||
desktop_rect_.Translate(position);
|
desktop_rect_.Translate(position);
|
||||||
RTC_DCHECK_GE(desktop_rect_.left(), 0);
|
RTC_DCHECK_GE(desktop_rect_.left(), 0);
|
||||||
|
|||||||
@ -86,9 +86,7 @@ class DxgiOutputDuplicator {
|
|||||||
|
|
||||||
// Device scale factor of the monitor associated with this
|
// Device scale factor of the monitor associated with this
|
||||||
// DxigOutputDuplicator.
|
// DxigOutputDuplicator.
|
||||||
std::optional<float> device_scale_factor() const {
|
std::optional<float> device_scale_factor() const;
|
||||||
return device_scale_factor_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Moves `desktop_rect_`. See DxgiDuplicatorController::TranslateRect().
|
// Moves `desktop_rect_`. See DxgiDuplicatorController::TranslateRect().
|
||||||
void TranslateRect(const DesktopVector& position);
|
void TranslateRect(const DesktopVector& position);
|
||||||
@ -134,13 +132,13 @@ class DxgiOutputDuplicator {
|
|||||||
const Microsoft::WRL::ComPtr<IDXGIOutput1> output_;
|
const Microsoft::WRL::ComPtr<IDXGIOutput1> output_;
|
||||||
const std::string device_name_;
|
const std::string device_name_;
|
||||||
DesktopRect desktop_rect_;
|
DesktopRect desktop_rect_;
|
||||||
|
const HMONITOR monitor_;
|
||||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> duplication_;
|
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> duplication_;
|
||||||
DXGI_OUTDUPL_DESC desc_;
|
DXGI_OUTDUPL_DESC desc_;
|
||||||
std::vector<uint8_t> metadata_;
|
std::vector<uint8_t> metadata_;
|
||||||
std::unique_ptr<DxgiTexture> texture_;
|
std::unique_ptr<DxgiTexture> texture_;
|
||||||
Rotation rotation_;
|
Rotation rotation_;
|
||||||
DesktopSize unrotated_size_;
|
DesktopSize unrotated_size_;
|
||||||
std::optional<float> device_scale_factor_;
|
|
||||||
|
|
||||||
// After each AcquireNextFrame() function call, updated_region_(s) of all
|
// After each AcquireNextFrame() function call, updated_region_(s) of all
|
||||||
// active Context(s) need to be updated. Since they have missed the
|
// active Context(s) need to be updated. Since they have missed the
|
||||||
|
|||||||
@ -106,21 +106,9 @@ WgcCaptureSession::WgcCaptureSession(intptr_t source_id,
|
|||||||
ABI::Windows::Graphics::SizeInt32 size)
|
ABI::Windows::Graphics::SizeInt32 size)
|
||||||
: d3d11_device_(std::move(d3d11_device)),
|
: d3d11_device_(std::move(d3d11_device)),
|
||||||
item_(std::move(item)),
|
item_(std::move(item)),
|
||||||
size_(size) {
|
size_(size),
|
||||||
|
source_id_(source_id) {
|
||||||
RTC_CHECK(source_id);
|
RTC_CHECK(source_id);
|
||||||
HMONITOR monitor = 0;
|
|
||||||
if (!GetHmonitorFromDeviceIndex(source_id, &monitor)) {
|
|
||||||
monitor = MonitorFromWindow(reinterpret_cast<HWND>(source_id),
|
|
||||||
/*dwFlags=*/MONITOR_DEFAULTTONEAREST);
|
|
||||||
}
|
|
||||||
DEVICE_SCALE_FACTOR device_scale_factor = DEVICE_SCALE_FACTOR_INVALID;
|
|
||||||
HRESULT hr = GetScaleFactorForMonitor(monitor, &device_scale_factor);
|
|
||||||
RTC_LOG_IF(LS_ERROR, FAILED(hr))
|
|
||||||
<< "Failed to get scale factor for monitor: " << hr;
|
|
||||||
|
|
||||||
if (device_scale_factor != DEVICE_SCALE_FACTOR_INVALID) {
|
|
||||||
device_scale_factor_ = static_cast<float>(device_scale_factor) / 100.0f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WgcCaptureSession::~WgcCaptureSession() {
|
WgcCaptureSession::~WgcCaptureSession() {
|
||||||
@ -473,9 +461,31 @@ HRESULT WgcCaptureSession::ProcessFrame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DesktopFrame* current_frame = queue_.current_frame();
|
DesktopFrame* current_frame = queue_.current_frame();
|
||||||
current_frame->set_device_scale_factor(device_scale_factor_);
|
|
||||||
DesktopFrame* previous_frame = queue_.previous_frame();
|
DesktopFrame* previous_frame = queue_.previous_frame();
|
||||||
|
|
||||||
|
// If the captured window moves to another screen, the HMONITOR assosciated
|
||||||
|
// with the captured window will change. Therefore, we need to get the value
|
||||||
|
// of HMONITOR per frame.
|
||||||
|
HMONITOR monitor;
|
||||||
|
if (!GetHmonitorFromDeviceIndex(source_id_, &monitor)) {
|
||||||
|
monitor = MonitorFromWindow(reinterpret_cast<HWND>(source_id_),
|
||||||
|
/*dwFlags=*/MONITOR_DEFAULTTONEAREST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Captures the device scale factor of the monitor where the frame is captured
|
||||||
|
// from. This value is the same as the scale from windows settings. Valid
|
||||||
|
// values are some distinct numbers in the range of [1,5], for example,
|
||||||
|
// 1, 1.5, 2.5, etc.
|
||||||
|
DEVICE_SCALE_FACTOR device_scale_factor = DEVICE_SCALE_FACTOR_INVALID;
|
||||||
|
HRESULT scale_factor_hr =
|
||||||
|
GetScaleFactorForMonitor(monitor, &device_scale_factor);
|
||||||
|
RTC_LOG_IF(LS_ERROR, FAILED(scale_factor_hr))
|
||||||
|
<< "Failed to get scale factor for monitor: " << scale_factor_hr;
|
||||||
|
if (device_scale_factor != DEVICE_SCALE_FACTOR_INVALID) {
|
||||||
|
current_frame->set_device_scale_factor(
|
||||||
|
static_cast<float>(device_scale_factor) / 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
// Will be set to true while copying the frame data to the `current_frame` if
|
// Will be set to true while copying the frame data to the `current_frame` if
|
||||||
// we can already determine that the content of the new frame differs from the
|
// we can already determine that the content of the new frame differs from the
|
||||||
// previous. The idea is to get a low-complexity indication of if the content
|
// previous. The idea is to get a low-complexity indication of if the content
|
||||||
|
|||||||
@ -149,11 +149,8 @@ class WgcCaptureSession final {
|
|||||||
// false.
|
// false.
|
||||||
DesktopRegion damage_region_;
|
DesktopRegion damage_region_;
|
||||||
|
|
||||||
// Captures the device scale factor of the monitor where the frame is captured
|
// The unique id to represent a Source of current DesktopCapturer.
|
||||||
// from. This value is the same as the scale from windows settings. Valid
|
intptr_t source_id_;
|
||||||
// values are some distinct numbers in the range of [1,5], for example,
|
|
||||||
// 1, 1.5, 2.5, etc.
|
|
||||||
std::optional<float> device_scale_factor_;
|
|
||||||
|
|
||||||
SequenceChecker sequence_checker_;
|
SequenceChecker sequence_checker_;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user