Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1328)

Unified Diff: remoting/client/dual_buffer_frame_consumer.cc

Issue 2156713002: [Chromoting] Implement DualBufferFrameConsumer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reviewer's Feedback Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/client/dual_buffer_frame_consumer.cc
diff --git a/remoting/client/dual_buffer_frame_consumer.cc b/remoting/client/dual_buffer_frame_consumer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..709f1bef788cb4e0e062572e593c10803640d00d
--- /dev/null
+++ b/remoting/client/dual_buffer_frame_consumer.cc
@@ -0,0 +1,112 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/client/dual_buffer_frame_consumer.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
+#include "third_party/webrtc/modules/desktop_capture/shared_desktop_frame.h"
+
+namespace remoting {
+
+DualBufferFrameConsumer::DualBufferFrameConsumer(
+ const RenderCallback& callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ protocol::FrameConsumer::PixelFormat format)
+ : callback_(callback),
+ task_runner_(task_runner),
+ pixel_format_(format),
+ weak_factory_(this) {
+ weak_ptr_ = weak_factory_.GetWeakPtr();
+ thread_checker_.DetachFromThread();
+}
+
+DualBufferFrameConsumer::~DualBufferFrameConsumer() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void DualBufferFrameConsumer::RequestFullDesktopFrame() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!buffers_[0]) {
+ return;
+ }
+ DCHECK(buffers_[0]->size().equals(buffers_[1]->size()));
+ // This creates a copy of buffers_[0] and merges area defined in
+ // |buffer_1_mask_| from buffers_[1] into the copy.
+ std::unique_ptr<webrtc::DesktopFrame> full_frame(
+ webrtc::BasicDesktopFrame::CopyOf(*buffers_[0]));
+ webrtc::DesktopRect desktop_rect =
+ webrtc::DesktopRect::MakeSize(buffers_[0]->size());
+ for (webrtc::DesktopRegion::Iterator i(buffer_1_mask_); !i.IsAtEnd();
+ i.Advance()) {
+ full_frame->CopyPixelsFrom(*buffers_[1], i.rect().top_left(),
+ i.rect());
+ }
+ full_frame->mutable_updated_region()->SetRect(desktop_rect);
+
+ RunRenderCallback(std::move(full_frame), base::Bind(&base::DoNothing));
+}
+
+std::unique_ptr<webrtc::DesktopFrame> DualBufferFrameConsumer::AllocateFrame(
+ const webrtc::DesktopSize& size) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // Both buffers are reallocated whenever screen size changes.
+ if (!buffers_[0] || !buffers_[0]->size().equals(size)) {
+ buffers_[0] = webrtc::SharedDesktopFrame::Wrap(
+ base::WrapUnique(new webrtc::BasicDesktopFrame(size)));
+ buffers_[1] = webrtc::SharedDesktopFrame::Wrap(
+ base::WrapUnique(new webrtc::BasicDesktopFrame(size)));
+ buffer_1_mask_.Clear();
+ current_buffer_ = 0;
+ } else {
+ current_buffer_ = (current_buffer_ + 1) % 2;
+ }
+ return buffers_[current_buffer_]->Share();
+}
+
+void DualBufferFrameConsumer::DrawFrame(
+ std::unique_ptr<webrtc::DesktopFrame> frame,
+ const base::Closure& done) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ webrtc::SharedDesktopFrame* shared_frame =
+ reinterpret_cast<webrtc::SharedDesktopFrame*> (frame.get());
+ if (shared_frame->GetUnderlyingFrame() == buffers_[1]->GetUnderlyingFrame()) {
+ buffer_1_mask_.AddRegion(frame->updated_region());
+ } else if (shared_frame->GetUnderlyingFrame() ==
+ buffers_[0]->GetUnderlyingFrame()) {
+ buffer_1_mask_.Subtract(frame->updated_region());
+ }
+ RunRenderCallback(std::move(frame), done);
+}
+
+protocol::FrameConsumer::PixelFormat
+DualBufferFrameConsumer::GetPixelFormat() {
+ return pixel_format_;
+}
+
+base::WeakPtr<DualBufferFrameConsumer> DualBufferFrameConsumer::GetWeakPtr() {
+ return weak_ptr_;
+}
+
+void DualBufferFrameConsumer::RunRenderCallback(
+ std::unique_ptr<webrtc::DesktopFrame> frame,
+ const base::Closure& done) {
+ if (!task_runner_) {
+ callback_.Run(std::move(frame), done);
+ return;
+ }
+
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(callback_, base::Passed(&frame), base::Bind(
+ base::IgnoreResult(&base::TaskRunner::PostTask),
+ base::ThreadTaskRunnerHandle::Get(), FROM_HERE, done)));
+}
+
+} // namespace remoting
« no previous file with comments | « remoting/client/dual_buffer_frame_consumer.h ('k') | remoting/client/dual_buffer_frame_consumer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698