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

Side by Side Diff: media/video/capture/screen/differ.cc

Issue 15692018: Remove screen capturers from media/video/capture/screen. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/video/capture/screen/differ.h ('k') | media/video/capture/screen/differ_block.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "media/video/capture/screen/differ.h"
6
7 #include "base/logging.h"
8 #include "media/video/capture/screen/differ_block.h"
9
10 namespace media {
11
12 Differ::Differ(int width, int height, int bpp, int stride) {
13 // Dimensions of screen.
14 width_ = width;
15 height_ = height;
16 bytes_per_pixel_ = bpp;
17 bytes_per_row_ = stride;
18
19 // Calc number of blocks (full and partial) required to cover entire image.
20 // One additional row/column is added as a boundary on the right & bottom.
21 diff_info_width_ = ((width_ + kBlockSize - 1) / kBlockSize) + 1;
22 diff_info_height_ = ((height_ + kBlockSize - 1) / kBlockSize) + 1;
23 diff_info_size_ = diff_info_width_ * diff_info_height_ * sizeof(DiffInfo);
24 diff_info_.reset(new DiffInfo[diff_info_size_]);
25 }
26
27 Differ::~Differ() {}
28
29 void Differ::CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer,
30 webrtc::DesktopRegion* region) {
31 // Identify all the blocks that contain changed pixels.
32 MarkDirtyBlocks(prev_buffer, curr_buffer);
33
34 // Now that we've identified the blocks that have changed, merge adjacent
35 // blocks to minimize the number of rects that we return.
36 MergeBlocks(region);
37 }
38
39 void Differ::MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer) {
40 memset(diff_info_.get(), 0, diff_info_size_);
41
42 // Calc number of full blocks.
43 int x_full_blocks = width_ / kBlockSize;
44 int y_full_blocks = height_ / kBlockSize;
45
46 // Calc size of partial blocks which may be present on right and bottom edge.
47 int partial_column_width = width_ - (x_full_blocks * kBlockSize);
48 int partial_row_height = height_ - (y_full_blocks * kBlockSize);
49
50 // Offset from the start of one block-column to the next.
51 int block_x_offset = bytes_per_pixel_ * kBlockSize;
52 // Offset from the start of one block-row to the next.
53 int block_y_stride = (width_ * bytes_per_pixel_) * kBlockSize;
54 // Offset from the start of one diff_info row to the next.
55 int diff_info_stride = diff_info_width_ * sizeof(DiffInfo);
56
57 const uint8* prev_block_row_start = static_cast<const uint8*>(prev_buffer);
58 const uint8* curr_block_row_start = static_cast<const uint8*>(curr_buffer);
59 DiffInfo* diff_info_row_start = static_cast<DiffInfo*>(diff_info_.get());
60
61 for (int y = 0; y < y_full_blocks; y++) {
62 const uint8* prev_block = prev_block_row_start;
63 const uint8* curr_block = curr_block_row_start;
64 DiffInfo* diff_info = diff_info_row_start;
65
66 for (int x = 0; x < x_full_blocks; x++) {
67 // Mark this block as being modified so that it gets incorporated into
68 // a dirty rect.
69 *diff_info = BlockDifference(prev_block, curr_block, bytes_per_row_);
70 prev_block += block_x_offset;
71 curr_block += block_x_offset;
72 diff_info += sizeof(DiffInfo);
73 }
74
75 // If there is a partial column at the end, handle it.
76 // This condition should rarely, if ever, occur.
77 if (partial_column_width != 0) {
78 *diff_info = DiffPartialBlock(prev_block, curr_block, bytes_per_row_,
79 partial_column_width, kBlockSize);
80 diff_info += sizeof(DiffInfo);
81 }
82
83 // Update pointers for next row.
84 prev_block_row_start += block_y_stride;
85 curr_block_row_start += block_y_stride;
86 diff_info_row_start += diff_info_stride;
87 }
88
89 // If the screen height is not a multiple of the block size, then this
90 // handles the last partial row. This situation is far more common than the
91 // 'partial column' case.
92 if (partial_row_height != 0) {
93 const uint8* prev_block = prev_block_row_start;
94 const uint8* curr_block = curr_block_row_start;
95 DiffInfo* diff_info = diff_info_row_start;
96 for (int x = 0; x < x_full_blocks; x++) {
97 *diff_info = DiffPartialBlock(prev_block, curr_block,
98 bytes_per_row_,
99 kBlockSize, partial_row_height);
100 prev_block += block_x_offset;
101 curr_block += block_x_offset;
102 diff_info += sizeof(DiffInfo);
103 }
104 if (partial_column_width != 0) {
105 *diff_info = DiffPartialBlock(prev_block, curr_block, bytes_per_row_,
106 partial_column_width, partial_row_height);
107 diff_info += sizeof(DiffInfo);
108 }
109 }
110 }
111
112 DiffInfo Differ::DiffPartialBlock(const uint8* prev_buffer,
113 const uint8* curr_buffer,
114 int stride, int width, int height) {
115 int width_bytes = width * bytes_per_pixel_;
116 for (int y = 0; y < height; y++) {
117 if (memcmp(prev_buffer, curr_buffer, width_bytes) != 0)
118 return 1;
119 prev_buffer += bytes_per_row_;
120 curr_buffer += bytes_per_row_;
121 }
122 return 0;
123 }
124
125 void Differ::MergeBlocks(webrtc::DesktopRegion* region) {
126 region->Clear();
127
128 uint8* diff_info_row_start = static_cast<uint8*>(diff_info_.get());
129 int diff_info_stride = diff_info_width_ * sizeof(DiffInfo);
130
131 for (int y = 0; y < diff_info_height_; y++) {
132 uint8* diff_info = diff_info_row_start;
133 for (int x = 0; x < diff_info_width_; x++) {
134 if (*diff_info != 0) {
135 // We've found a modified block. Look at blocks to the right and below
136 // to group this block with as many others as we can.
137 int left = x * kBlockSize;
138 int top = y * kBlockSize;
139 int width = 1;
140 int height = 1;
141 *diff_info = 0;
142
143 // Group with blocks to the right.
144 // We can keep looking until we find an unchanged block because we
145 // have a boundary block which is never marked as having diffs.
146 uint8* right = diff_info + 1;
147 while (*right) {
148 *right++ = 0;
149 width++;
150 }
151
152 // Group with blocks below.
153 // The entire width of blocks that we matched above much match for
154 // each row that we add.
155 uint8* bottom = diff_info;
156 bool found_new_row;
157 do {
158 found_new_row = true;
159 bottom += diff_info_stride;
160 right = bottom;
161 for (int x2 = 0; x2 < width; x2++) {
162 if (*right++ == 0) {
163 found_new_row = false;
164 }
165 }
166
167 if (found_new_row) {
168 height++;
169
170 // We need to go back and erase the diff markers so that we don't
171 // try to add these blocks a second time.
172 right = bottom;
173 for (int x2 = 0; x2 < width; x2++) {
174 *right++ = 0;
175 }
176 }
177 } while (found_new_row);
178
179 // Add rect to list of dirty rects.
180 width *= kBlockSize;
181 if (left + width > width_) {
182 width = width_ - left;
183 }
184 height *= kBlockSize;
185 if (top + height > height_) {
186 height = height_ - top;
187 }
188 region->AddRect(
189 webrtc::DesktopRect::MakeXYWH(left, top, width, height));
190 }
191
192 // Increment to next block in this row.
193 diff_info++;
194 }
195
196 // Go to start of next row.
197 diff_info_row_start += diff_info_stride;
198 }
199 }
200
201 } // namespace media
OLDNEW
« no previous file with comments | « media/video/capture/screen/differ.h ('k') | media/video/capture/screen/differ_block.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698