1/*
2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
12#define WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
13
14#include <vector>
15
16#include "webrtc/modules/desktop_capture/desktop_region.h"
17#include "webrtc/system_wrappers/interface/scoped_ptr.h"
18
19namespace webrtc {
20
21typedef uint8_t DiffInfo;
22
23// TODO(sergeyu): Simplify differ now that we are working with DesktopRegion.
24// diff_info_ should no longer be needed, as we can put our data directly into
25// the region that we are calculating.
26// http://crbug.com/92379
27// TODO(sergeyu): Rename this class to something more sensible, e.g.
28// ScreenCaptureFrameDifferencer.
29class Differ {
30 public:
31  // Create a differ that operates on bitmaps with the specified width, height
32  // and bytes_per_pixel.
33  Differ(int width, int height, int bytes_per_pixel, int stride);
34  ~Differ();
35
36  int width() { return width_; }
37  int height() { return height_; }
38  int bytes_per_pixel() { return bytes_per_pixel_; }
39  int bytes_per_row() { return bytes_per_row_; }
40
41  // Given the previous and current screen buffer, calculate the dirty region
42  // that encloses all of the changed pixels in the new screen.
43  void CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer,
44                       DesktopRegion* region);
45
46 private:
47  // Allow tests to access our private parts.
48  friend class DifferTest;
49
50  // Identify all of the blocks that contain changed pixels.
51  void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer);
52
53  // After the dirty blocks have been identified, this routine merges adjacent
54  // blocks into a region.
55  // The goal is to minimize the region that covers the dirty blocks.
56  void MergeBlocks(DesktopRegion* region);
57
58  // Check for diffs in upper-left portion of the block. The size of the portion
59  // to check is specified by the |width| and |height| values.
60  // Note that if we force the capturer to always return images whose width and
61  // height are multiples of kBlockSize, then this will never be called.
62  DiffInfo DiffPartialBlock(const uint8_t* prev_buffer,
63                            const uint8_t* curr_buffer,
64                            int stride,
65                            int width, int height);
66
67  // Dimensions of screen.
68  int width_;
69  int height_;
70
71  // Number of bytes for each pixel in source and dest bitmap.
72  // (Yes, they must match.)
73  int bytes_per_pixel_;
74
75  // Number of bytes in each row of the image (AKA: stride).
76  int bytes_per_row_;
77
78  // Diff information for each block in the image.
79  scoped_ptr<DiffInfo[]> diff_info_;
80
81  // Dimensions and total size of diff info array.
82  int diff_info_width_;
83  int diff_info_height_;
84  int diff_info_size_;
85
86  DISALLOW_COPY_AND_ASSIGN(Differ);
87};
88
89}  // namespace webrtc
90
91#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
92