dxgi_frame.cc (2477B)
1 /* 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/desktop_capture/win/dxgi_frame.h" 12 13 #include <cstring> 14 #include <memory> 15 #include <utility> 16 17 #include "modules/desktop_capture/desktop_capturer.h" 18 #include "modules/desktop_capture/desktop_frame.h" 19 #include "modules/desktop_capture/desktop_geometry.h" 20 #include "modules/desktop_capture/shared_desktop_frame.h" 21 #include "modules/desktop_capture/shared_memory.h" 22 #include "rtc_base/checks.h" 23 #include "rtc_base/logging.h" 24 25 namespace webrtc { 26 27 DxgiFrame::DxgiFrame(SharedMemoryFactory* factory) : factory_(factory) {} 28 29 DxgiFrame::~DxgiFrame() = default; 30 31 bool DxgiFrame::Prepare(DesktopSize size, DesktopCapturer::SourceId source_id) { 32 if (source_id != source_id_) { 33 // Once the source has been changed, the entire source should be copied. 34 source_id_ = source_id; 35 context_.Reset(); 36 } 37 38 if (resolution_tracker_.SetResolution(size)) { 39 // Once the output size changed, recreate the SharedDesktopFrame. 40 frame_.reset(); 41 } 42 43 if (!frame_) { 44 std::unique_ptr<DesktopFrame> frame; 45 if (factory_) { 46 frame = SharedMemoryDesktopFrame::Create(size, FOURCC_ARGB, factory_); 47 48 if (!frame) { 49 RTC_LOG(LS_WARNING) << "DxgiFrame cannot create a new DesktopFrame."; 50 return false; 51 } 52 53 // DirectX capturer won't paint each pixel in the frame due to its one 54 // capturer per monitor design. So once the new frame is created, we 55 // should clear it to avoid the legacy image to be remained on it. See 56 // http://crbug.com/708766. 57 RTC_DCHECK_EQ(frame->stride(), 58 frame->size().width() * DesktopFrame::kBytesPerPixel); 59 memset(frame->data(), 0, frame->stride() * frame->size().height()); 60 } else { 61 frame.reset(new BasicDesktopFrame(size, FOURCC_ARGB)); 62 } 63 frame_ = SharedDesktopFrame::Wrap(std::move(frame)); 64 } 65 66 return !!frame_; 67 } 68 69 SharedDesktopFrame* DxgiFrame::frame() const { 70 RTC_DCHECK(frame_); 71 return frame_.get(); 72 } 73 74 DxgiFrame::Context* DxgiFrame::context() { 75 RTC_DCHECK(frame_); 76 return &context_; 77 } 78 79 } // namespace webrtc