/* * Copyright (c) 2026 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/desktop_capture/win/dxgi_desktop_frame.h" #include #include #include #include #include "modules/desktop_capture/win/desktop_capture_utils.h" #include "rtc_base/logging.h" using Microsoft::WRL::ComPtr; namespace webrtc { namespace { class DXGIFrameTexture : public FrameTexture { public: DXGIFrameTexture(Handle handle, ComPtr prevent_release) : FrameTexture(handle), prevent_release_(std::move(prevent_release)) {} ~DXGIFrameTexture() override { if (handle_ != kInvalidHandle) { CloseHandle(handle_); } } private: // Prevents the WGC frame pool from recycling the captured texture. Typically // holds a reference to the IDirect3D11CaptureFrame. When this pointer (and // hence this DXGIFrameTexture) is destroyed, the capture frame is released // and the frame pool may reuse the underlying texture. ComPtr prevent_release_; }; } // namespace DXGIDesktopFrame::DXGIDesktopFrame(DesktopSize size, int stride, uint8_t* data, std::unique_ptr frame_texture) : DesktopFrame(size, stride, FOURCC_ARGB, data, /*shared_memory=*/nullptr, frame_texture.get()), owned_frame_texture_(std::move(frame_texture)) {} // static std::unique_ptr DXGIDesktopFrame::Create( DesktopSize size, ComPtr texture, ComPtr prevent_release) { ComPtr dxgi_resource; HRESULT hr = texture.As(&dxgi_resource); if (FAILED(hr)) { RTC_LOG(LS_ERROR) << "Failed to query IDXGIResource1: " << desktop_capture::utils::ComErrorToString(hr); return nullptr; } HANDLE texture_handle; hr = dxgi_resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &texture_handle); if (FAILED(hr)) { RTC_LOG(LS_ERROR) << "Failed to create shared handle for texture: " << desktop_capture::utils::ComErrorToString(hr); return nullptr; } auto frame_texture = std::make_unique( texture_handle, std::move(prevent_release)); return std::unique_ptr( new DXGIDesktopFrame(size, 0, nullptr, std::move(frame_texture))); } } // namespace webrtc