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

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

Issue 2202443002: [WebRTC] Add ScreenCapturerDifferWrapper to share Differ across ScreenCapturers (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: 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/differ.cc
diff --git a/webrtc/modules/desktop_capture/differ.cc b/webrtc/modules/desktop_capture/differ.cc
index 8140e612a1008c0359237904958779f9c4e795fe..9ddfe1b63c4891d133e4a70dbf067c30bdd9492a 100644
--- a/webrtc/modules/desktop_capture/differ.cc
+++ b/webrtc/modules/desktop_capture/differ.cc
@@ -12,50 +12,89 @@
#include "string.h"
+#include "webrtc/base/checks.h"
+#include "webrtc/modules/desktop_capture/desktop_region.h"
+#include "webrtc/modules/desktop_capture/desktop_geometry.h"
#include "webrtc/modules/desktop_capture/differ_block.h"
#include "webrtc/system_wrappers/include/logging.h"
namespace webrtc {
-Differ::Differ(int width, int height, int bpp, int stride) {
- // Dimensions of screen.
- width_ = width;
- height_ = height;
- bytes_per_pixel_ = bpp;
- bytes_per_row_ = stride;
-
- // Calc number of blocks (full and partial) required to cover entire image.
- // One additional row/column is added as a boundary on the right & bottom.
- diff_info_width_ = ((width_ + kBlockSize - 1) / kBlockSize) + 1;
- diff_info_height_ = ((height_ + kBlockSize - 1) / kBlockSize) + 1;
- diff_info_size_ = diff_info_width_ * diff_info_height_ * sizeof(bool);
- diff_info_.reset(new bool[diff_info_size_]);
-}
+Differ::Differ(int width, int height, int bpp, int stride) :
+ // Dimensions of screen.
+ width_(width),
+ height_(height),
+ bytes_per_pixel_(bpp),
+ bytes_per_row_(stride),
+ // Calc number of blocks (full and partial) required to cover entire image.
+ // One additional row/column is added as a boundary on the right & bottom.
+ diff_info_width_(((width_ + kBlockSize - 1) / kBlockSize) + 1),
+ diff_info_height_(((height_ + kBlockSize - 1) / kBlockSize) + 1),
+ diff_info_size_(diff_info_width_ * diff_info_height_ * sizeof(bool)),
+ diff_info_(new bool[diff_info_size_]) {}
Differ::~Differ() {}
void Differ::CalcDirtyRegion(const uint8_t* prev_buffer,
const uint8_t* curr_buffer,
DesktopRegion* region) {
Jamie 2016/08/03 23:52:25 Maybe just call through to CalcDirtyRegionWithHint
Hzj_jie 2016/08/04 02:28:07 If you do not have concern with the unnecessary fo
+ // Reset internal dirty state to false.
+ memset(diff_info_.get(), 0, diff_info_size_);
+
// Identify all the blocks that contain changed pixels.
- MarkDirtyBlocks(prev_buffer, curr_buffer);
+ MarkDirtyBlocks(prev_buffer,
+ curr_buffer,
+ DesktopRect::MakeWH(width_, height_));
// Now that we've identified the blocks that have changed, merge adjacent
// blocks to minimize the number of rects that we return.
MergeBlocks(region);
}
-void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
- const uint8_t* curr_buffer) {
+void Differ::CalcDirtyRegionWithHints(const uint8_t* prev_buffer,
+ const uint8_t* curr_buffer,
+ const DesktopRegion& hints,
+ DesktopRegion* region) {
+ // Reset internal dirty state to false.
memset(diff_info_.get(), 0, diff_info_size_);
- // Calc number of full blocks.
- int x_full_blocks = width_ / kBlockSize;
- int y_full_blocks = height_ / kBlockSize;
+ // Identify all the blocks that contain changed pixels.
+ for (auto it = DesktopRegion::Iterator(hints);
+ !it.IsAtEnd();
+ it.Advance()) {
+ MarkDirtyBlocks(prev_buffer, curr_buffer, it.rect());
+ }
+
+ // Now that we've identified the blocks that have changed, merge adjacent
+ // blocks to minimize the number of rects that we return.
+ MergeBlocks(region);
+}
+
+void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
+ const uint8_t* curr_buffer,
+ const DesktopRect& rect) {
+ RTC_DCHECK(rect.width() <= width_);
+ RTC_DCHECK(rect.height() <= height_);
+
+ if (rect.is_empty()) {
+ return;
+ }
+
+ // Calculate the range of blocks.
Jamie 2016/08/03 23:52:25 Since right and bottom are both past-the-end point
Hzj_jie 2016/08/04 02:28:07 This seems not correct to me, Case 1: considering
+ int x_start = rect.left() / kBlockSize;
+ int y_start = rect.top() / kBlockSize;
+ int x_end = (rect.right() + kBlockSize - 1) / kBlockSize;
+ int y_end = (rect.bottom() + kBlockSize - 1) / kBlockSize;
+ if (x_end * kBlockSize > width_) {
+ x_end--;
+ }
+ if (y_end * kBlockSize > height_) {
+ y_end--;
+ }
// Calc size of partial blocks which may be present on right and bottom edge.
- int partial_column_width = width_ - (x_full_blocks * kBlockSize);
- int partial_row_height = height_ - (y_full_blocks * kBlockSize);
+ int partial_column_width = rect.right() - (x_end * kBlockSize);
+ int partial_row_height = rect.bottom() - (y_end * kBlockSize);
// Offset from the start of one block-column to the next.
int block_x_offset = bytes_per_pixel_ * kBlockSize;
@@ -64,16 +103,19 @@ void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
// Offset from the start of one diff_info row to the next.
int diff_info_stride = diff_info_width_ * sizeof(bool);
- const uint8_t* prev_block_row_start = prev_buffer;
- const uint8_t* curr_block_row_start = curr_buffer;
- bool* diff_info_row_start = diff_info_.get();
+ const uint8_t* prev_block_row_start =
+ prev_buffer + y_start * block_y_stride + x_start * block_x_offset;
+ const uint8_t* curr_block_row_start =
+ curr_buffer + (prev_block_row_start - prev_buffer);
+ bool* diff_info_row_start =
+ diff_info_.get() + y_start * diff_info_width_ + x_start;
- for (int y = 0; y < y_full_blocks; y++) {
+ for (int y = y_start; y < y_end; y++) {
const uint8_t* prev_block = prev_block_row_start;
const uint8_t* curr_block = curr_block_row_start;
bool* diff_info = diff_info_row_start;
- for (int x = 0; x < x_full_blocks; x++) {
+ for (int x = x_start; x < x_end; x++) {
// Mark this block as being modified so that it gets incorporated into
// a dirty rect.
*diff_info = BlockDifference(prev_block, curr_block, bytes_per_row_);
@@ -84,7 +126,7 @@ void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
// If there is a partial column at the end, handle it.
// This condition should rarely, if ever, occur.
Jamie 2016/08/03 23:52:25 I suspect this is no longer true; it's rare when t
Hzj_jie 2016/08/04 02:28:06 We always try our best to cover the damage rectang
- if (partial_column_width != 0) {
+ if (partial_column_width > 0) {
*diff_info = !PartialBlocksEqual(prev_block, curr_block, bytes_per_row_,
partial_column_width, kBlockSize);
diff_info += sizeof(bool);
@@ -99,19 +141,18 @@ void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
// If the screen height is not a multiple of the block size, then this
// handles the last partial row. This situation is far more common than the
// 'partial column' case.
Jamie 2016/08/03 23:52:25 As above, this second sentence can be removed now.
Hzj_jie 2016/08/04 02:28:06 Done.
- if (partial_row_height != 0) {
+ if (partial_row_height > 0) {
const uint8_t* prev_block = prev_block_row_start;
const uint8_t* curr_block = curr_block_row_start;
bool* diff_info = diff_info_row_start;
- for (int x = 0; x < x_full_blocks; x++) {
- *diff_info = !PartialBlocksEqual(prev_block, curr_block,
- bytes_per_row_,
+ for (int x = x_start; x < x_end; x++) {
+ *diff_info = !PartialBlocksEqual(prev_block, curr_block, bytes_per_row_,
kBlockSize, partial_row_height);
prev_block += block_x_offset;
curr_block += block_x_offset;
diff_info += sizeof(bool);
}
- if (partial_column_width != 0) {
+ if (partial_column_width > 0) {
*diff_info = !PartialBlocksEqual(prev_block, curr_block, bytes_per_row_,
partial_column_width,
partial_row_height);
@@ -123,6 +164,7 @@ void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
bool Differ::PartialBlocksEqual(const uint8_t* prev_buffer,
const uint8_t* curr_buffer,
int stride, int width, int height) {
+ RTC_DCHECK(width > 0 && height > 0);
int width_bytes = width * bytes_per_pixel_;
for (int y = 0; y < height; y++) {
if (memcmp(prev_buffer, curr_buffer, width_bytes) != 0)
@@ -133,7 +175,7 @@ bool Differ::PartialBlocksEqual(const uint8_t* prev_buffer,
return true;
}
-void Differ::MergeBlocks(DesktopRegion* region) {
+void Differ::MergeBlocks(DesktopRegion* region) const {
region->Clear();
bool* diff_info_row_start = diff_info_.get();

Powered by Google App Engine
This is Rietveld 408576698