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

Unified Diff: webrtc/modules/desktop_capture/desktop_frame_generator.cc

Issue 2202443002: [WebRTC] Add ScreenCapturerDifferWrapper to share Differ across ScreenCapturers (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Resolve review comments Created 4 years, 4 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: webrtc/modules/desktop_capture/desktop_frame_generator.cc
diff --git a/webrtc/modules/desktop_capture/desktop_frame_generator.cc b/webrtc/modules/desktop_capture/desktop_frame_generator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..32ec3f4d92c1035a0ebf40429ac6c2fad157bb7e
--- /dev/null
+++ b/webrtc/modules/desktop_capture/desktop_frame_generator.cc
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2016 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 "webrtc/modules/desktop_capture/desktop_frame_generator.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include <memory>
+
+#include "webrtc/base/random.h"
+#include "webrtc/base/timeutils.h"
+
+namespace webrtc {
+
+namespace {
+
+// Sets |updated_region| to |frame|. If |enlarge_updated_region| is
+// true, this function will randomly enlarge each DesktopRect in
+// |updated_region|.
+// But the enlarged DesktopRegion won't excceed the frame->size(). If
+// |add_random_updated_region| is true, several random rectangles will also be
+// included in |frame|.
+void SetUpdatedRegion(DesktopFrame* frame,
+ const DesktopRegion& updated_region,
+ bool enlarge_updated_region,
+ int enlarge_range,
+ bool add_random_updated_region) {
+ const DesktopRect screen_rect = DesktopRect::MakeSize(frame->size());
+ Random random(rtc::TimeMicros());
+ frame->mutable_updated_region()->Clear();
+ for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
+ it.Advance()) {
+ DesktopRect rect = it.rect();
+ if (enlarge_updated_region && enlarge_range > 0) {
+ rect = DesktopRect::MakeLTRB(rect.left() - random.Rand(enlarge_range),
+ rect.top() - random.Rand(enlarge_range),
+ rect.right() + random.Rand(enlarge_range),
+ rect.bottom() + random.Rand(enlarge_range));
Sergey Ulanov 2016/08/18 05:07:58 There are several other places where we need the s
Hzj_jie 2016/08/23 00:54:58 Done.
+ rect.IntersectWith(screen_rect);
+ }
+ frame->mutable_updated_region()->AddRect(rect);
+ }
+
+ if (add_random_updated_region) {
+ for (int i = random.Rand(10); i >= 0; i--) {
+ // At least a 1 x 1 updated region.
+ const int left = random.Rand(0, frame->size().width() - 2);
+ const int top = random.Rand(0, frame->size().height() - 2);
+ const int right = random.Rand(left + 1, frame->size().width());
+ const int bottom = random.Rand(top + 1, frame->size().height());
+ frame->mutable_updated_region()->AddRect(
+ DesktopRect::MakeLTRB(left, top, right, bottom));
+ }
+ }
+}
+
+// Paints pixels in |rect| of |frame| to |color|.
+void PaintRect(DesktopFrame* frame, DesktopRect rect, uint32_t color) {
+ static_assert(DesktopFrame::kBytesPerPixel == sizeof(uint32_t),
+ "kBytesPerPixel should be 4.");
+ RTC_DCHECK(frame->size().width() >= rect.right() &&
+ frame->size().height() >= rect.bottom());
+ int row = rect.top() * frame->stride();
+ for (int i = 0; i < rect.height(); i++) {
+ int column = rect.left() * DesktopFrame::kBytesPerPixel;
+ for (int j = 0; j < rect.width(); j++) {
+ memcpy(&frame->data()[row + column], &color, sizeof(color));
Sergey Ulanov 2016/08/18 05:07:58 Instead of calling memcpy() for every pixel it wou
Hzj_jie 2016/08/23 00:54:58 Done.
Hzj_jie 2016/08/25 18:20:12 Seems both memcpy and uint32_t assignment will be
Sergey Ulanov 2016/09/01 19:27:56 Simple assignment will still be faster and clearer
Hzj_jie 2016/09/01 23:26:42 Yes, it will have a ToUInt32() function to handle
+ column += DesktopFrame::kBytesPerPixel;
+ }
+ row += frame->stride();
+ }
+}
+
+// Paints pixels in |region| of |frame| to |color|.
+void PaintRegion(DesktopFrame* frame, DesktopRegion* region, uint32_t color) {
+ region->IntersectWith(DesktopRect::MakeSize(frame->size()));
+ for (DesktopRegion::Iterator it(*region); !it.IsAtEnd(); it.Advance()) {
+ PaintRect(frame, it.rect(), color);
+ }
+}
+
+} // namespace
+
+DesktopFrameGenerator::DesktopFrameGenerator() {}
+DesktopFrameGenerator::~DesktopFrameGenerator() {}
+
+BaseDesktopFrameGenerator::BaseDesktopFrameGenerator()
+ : size_(1024, 768),
+ return_frame_(true),
+ provide_updated_region_hints_(false),
+ enlarge_updated_region_(false),
+ enlarge_range_(20),
+ add_random_updated_region_(false) {}
+BaseDesktopFrameGenerator::~BaseDesktopFrameGenerator() {}
+
+std::unique_ptr<DesktopFrame> BaseDesktopFrameGenerator::operator()(
+ SharedMemoryFactory* factory) {
+ if (return_frame_) {
+ std::unique_ptr<DesktopFrame> frame = std::unique_ptr<DesktopFrame>(
+ factory ? SharedMemoryDesktopFrame::Create(size_, factory).release()
+ : new BasicDesktopFrame(size_));
+ DesktopRegion updated_region;
+ if (!Paint(frame.get(), &updated_region)) {
+ return nullptr;
+ }
+
+ if (provide_updated_region_hints_) {
+ SetUpdatedRegion(frame.get(), updated_region, enlarge_updated_region_,
+ enlarge_range_, add_random_updated_region_);
+ }
+ return frame;
+ } else {
Sergey Ulanov 2016/08/18 05:07:58 Don't use else after return. Best to move the !ret
Hzj_jie 2016/08/23 00:54:58 Done.
+ return nullptr;
+ }
+}
+
+DesktopSize* BaseDesktopFrameGenerator::size() {
+ return &size_;
+}
+
+void BaseDesktopFrameGenerator::set_return_frame(bool return_frame) {
+ return_frame_ = return_frame;
+}
+
+void BaseDesktopFrameGenerator::set_provide_updated_region_hints(
+ bool provide_updated_region_hints) {
+ provide_updated_region_hints_ = provide_updated_region_hints;
+}
+
+void BaseDesktopFrameGenerator::set_enlarge_updated_region(
+ bool enlarge_updated_region) {
+ enlarge_updated_region_ = enlarge_updated_region;
+}
+
+void BaseDesktopFrameGenerator::set_enlarge_range(int enlarge_range) {
+ enlarge_range_ = enlarge_range;
+}
+
+void BaseDesktopFrameGenerator::set_add_random_updated_region(
+ bool add_random_updated_region) {
+ add_random_updated_region_ = add_random_updated_region;
+}
+
+BlackWhiteDesktopFrameGenerator::BlackWhiteDesktopFrameGenerator() {}
+BlackWhiteDesktopFrameGenerator::~BlackWhiteDesktopFrameGenerator() {}
+
+DesktopRegion* BlackWhiteDesktopFrameGenerator::updated_region() {
+ return &updated_region_;
+}
+
+bool BlackWhiteDesktopFrameGenerator::Paint(DesktopFrame* frame,
+ DesktopRegion* updated_region) {
+ RTC_DCHECK(updated_region->is_empty());
+ memset(frame->data(), 0, frame->stride() * frame->size().height());
+ PaintRegion(frame, &updated_region_, UINT32_MAX);
+ updated_region_.Swap(updated_region);
+ return true;
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698