Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "remoting/client/dual_buffer_frame_consumer.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/bind_helpers.h" | |
| 9 #include "base/location.h" | |
| 10 #include "base/memory/ptr_util.h" | |
| 11 #include "remoting/base/util.h" | |
| 12 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | |
| 13 #include "third_party/webrtc/modules/desktop_capture/shared_desktop_frame.h" | |
| 14 | |
| 15 namespace remoting { | |
| 16 | |
| 17 DualBufferFrameConsumer::DualBufferFrameConsumer( | |
| 18 base::Callback<void(std::unique_ptr<webrtc::DesktopFrame>)> callback, | |
| 19 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 20 protocol::FrameConsumer::PixelFormat format) | |
| 21 : callback_(callback), | |
| 22 task_runner_(task_runner), | |
| 23 pixel_format_(format), | |
| 24 weak_factory_(this) { | |
| 25 weak_ptr_ = weak_factory_.GetWeakPtr(); | |
| 26 thread_checker_.DetachFromThread(); | |
| 27 } | |
| 28 | |
| 29 DualBufferFrameConsumer::~DualBufferFrameConsumer() { | |
| 30 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 31 } | |
| 32 | |
| 33 void DualBufferFrameConsumer::RequestFullDesktopFrame() { | |
| 34 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 35 if (!buffer_0_) { | |
| 36 return; | |
| 37 } | |
| 38 DCHECK(buffer_0_->size().equals(buffer_1_->size())); | |
| 39 std::unique_ptr<webrtc::DesktopFrame> full_frame( | |
| 40 webrtc::BasicDesktopFrame::CopyOf(*buffer_0_)); | |
| 41 webrtc::DesktopRect desktop_rect = | |
| 42 webrtc::DesktopRect::MakeSize(buffer_0_->size()); | |
| 43 for (webrtc::DesktopRegion::Iterator i(buffer_1_mask_); !i.IsAtEnd(); | |
| 44 i.Advance()) { | |
| 45 CopyRGB32Rect(buffer_1_->data(), buffer_1_->stride(), desktop_rect, | |
| 46 full_frame->data(), full_frame->stride(), desktop_rect, | |
| 47 i.rect()); | |
| 48 } | |
| 49 full_frame->mutable_updated_region()->SetRect(desktop_rect); | |
| 50 | |
| 51 RunRenderCallback(std::move(full_frame), base::Closure()); | |
| 52 } | |
| 53 | |
| 54 std::unique_ptr<webrtc::DesktopFrame> DualBufferFrameConsumer::AllocateFrame( | |
| 55 const webrtc::DesktopSize& size) { | |
| 56 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 57 if (!buffer_0_ || !buffer_0_->size().equals(size)) { | |
| 58 buffer_0_ = webrtc::SharedDesktopFrame::Wrap( | |
|
Sergey Ulanov
2016/07/20 18:39:26
add comment that both buffers are reallocated when
Yuwei
2016/07/21 00:07:32
Done.
| |
| 59 base::WrapUnique(new webrtc::BasicDesktopFrame(size))); | |
| 60 buffer_1_ = webrtc::SharedDesktopFrame::Wrap( | |
| 61 base::WrapUnique(new webrtc::BasicDesktopFrame(size))); | |
| 62 buffer_1_mask_.Clear(); | |
| 63 next_buffer_ = 0; | |
| 64 } | |
| 65 next_buffer_ = (next_buffer_ + 1) % 2; | |
|
Sergey Ulanov
2016/07/20 18:39:26
I think you want to synchronize buffers here (or m
Yuwei
2016/07/20 19:12:43
Do you mean that when rendering is slower than dec
| |
| 66 if (next_buffer_ == 0) { | |
|
Sergey Ulanov
2016/07/20 18:39:26
If you replace buffer_?_ with buffers_[] then this
Yuwei
2016/07/21 00:07:32
Done.
| |
| 67 return buffer_1_->Share(); | |
| 68 } else { | |
| 69 return buffer_0_->Share(); | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 void DualBufferFrameConsumer::DrawFrame( | |
| 74 std::unique_ptr<webrtc::DesktopFrame> frame, | |
| 75 const base::Closure& done) { | |
| 76 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 77 if ((reinterpret_cast<webrtc::SharedDesktopFrame*> (frame.get())) | |
|
Yuwei
2016/07/18 22:38:35
This assumes |frame| must come from AllocateFrame.
Sergey Ulanov
2016/07/20 18:39:26
Yes, this is a valid assumption. Caller must use A
Yuwei
2016/07/21 00:07:32
Acknowledged.
| |
| 78 ->GetUnderlyingFrame() == buffer_1_->GetUnderlyingFrame()) { | |
| 79 buffer_1_mask_.AddRegion(frame->updated_region()); | |
| 80 } else { | |
| 81 buffer_1_mask_.Subtract(frame->updated_region()); | |
| 82 } | |
| 83 RunRenderCallback(std::move(frame), done); | |
| 84 } | |
| 85 | |
| 86 protocol::FrameConsumer::PixelFormat | |
| 87 DualBufferFrameConsumer::GetPixelFormat() { | |
| 88 return pixel_format_; | |
| 89 } | |
| 90 | |
| 91 base::WeakPtr<DualBufferFrameConsumer> DualBufferFrameConsumer::GetWeakPtr() { | |
| 92 return weak_ptr_; | |
| 93 } | |
| 94 | |
| 95 void DualBufferFrameConsumer::RunRenderCallback( | |
| 96 std::unique_ptr<webrtc::DesktopFrame> frame, | |
| 97 const base::Closure& done) { | |
| 98 if (!task_runner_) { | |
| 99 callback_.Run(std::move(frame)); | |
| 100 done.Run(); | |
| 101 return; | |
| 102 } | |
| 103 task_runner_->PostTaskAndReply( | |
| 104 FROM_HERE, base::Bind(callback_, base::Passed(&frame)), | |
| 105 base::Bind(&DualBufferFrameConsumer::OnFrameRendered, GetWeakPtr(), | |
| 106 done)); | |
| 107 } | |
| 108 | |
| 109 void DualBufferFrameConsumer::OnFrameRendered(const base::Closure& done) { | |
| 110 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 111 if (done) { | |
| 112 done.Run(); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 } // namespace remoting | |
| OLD | NEW |