13d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org/*
23d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
33d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *
43d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  Use of this source code is governed by a BSD-style license
53d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  that can be found in the LICENSE file in the root of the source
63d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  tree. An additional intellectual property rights grant can be found
73d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  in the file PATENTS.  All contributing project authors may
83d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  be found in the AUTHORS file in the root of the source tree.
93d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org */
103d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
113d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
123d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#define WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
133d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
143d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#include <vector>
153d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
1600b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h"
173d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#include "webrtc/modules/desktop_capture/desktop_region.h"
183d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
193d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgnamespace webrtc {
203d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
213d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// TODO(sergeyu): Simplify differ now that we are working with DesktopRegion.
223d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// diff_info_ should no longer be needed, as we can put our data directly into
233d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// the region that we are calculating.
243d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// http://crbug.com/92379
253d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// TODO(sergeyu): Rename this class to something more sensible, e.g.
263d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// ScreenCaptureFrameDifferencer.
273d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgclass Differ {
283d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org public:
293d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Create a differ that operates on bitmaps with the specified width, height
303d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // and bytes_per_pixel.
313d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  Differ(int width, int height, int bytes_per_pixel, int stride);
323d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  ~Differ();
333d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
343d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int width() { return width_; }
353d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int height() { return height_; }
363d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int bytes_per_pixel() { return bytes_per_pixel_; }
373d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int bytes_per_row() { return bytes_per_row_; }
383d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
393d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Given the previous and current screen buffer, calculate the dirty region
403d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // that encloses all of the changed pixels in the new screen.
4179b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting  void CalcDirtyRegion(const uint8_t* prev_buffer, const uint8_t* curr_buffer,
423d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org                       DesktopRegion* region);
433d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
443d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org private:
453d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Allow tests to access our private parts.
463d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  friend class DifferTest;
473d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
483d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Identify all of the blocks that contain changed pixels.
4979b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting  void MarkDirtyBlocks(const uint8_t* prev_buffer, const uint8_t* curr_buffer);
503d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
513d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // After the dirty blocks have been identified, this routine merges adjacent
523d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // blocks into a region.
533d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // The goal is to minimize the region that covers the dirty blocks.
543d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  void MergeBlocks(DesktopRegion* region);
553d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
5679b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting  // Checks whether the upper-left portions of the buffers are equal. The size
5779b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting  // of the portion to check is specified by the |width| and |height| values.
583d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Note that if we force the capturer to always return images whose width and
593d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // height are multiples of kBlockSize, then this will never be called.
6079b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting  bool PartialBlocksEqual(const uint8_t* prev_buffer,
6179b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting                          const uint8_t* curr_buffer,
6279b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting                          int stride,
6379b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting                          int width, int height);
643d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
653d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Dimensions of screen.
663d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int width_;
673d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int height_;
683d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
693d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Number of bytes for each pixel in source and dest bitmap.
703d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // (Yes, they must match.)
713d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int bytes_per_pixel_;
723d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
733d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Number of bytes in each row of the image (AKA: stride).
743d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int bytes_per_row_;
753d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
763d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Diff information for each block in the image.
7779b2e06782a4115ebc46d1d44ddbf7a63a405926Peter Kasting  rtc::scoped_ptr<bool[]> diff_info_;
783d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
793d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  // Dimensions and total size of diff info array.
803d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int diff_info_width_;
813d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int diff_info_height_;
823d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int diff_info_size_;
833d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
843c089d751ede283e21e186885eaf705c3257ccd2henrikg  RTC_DISALLOW_COPY_AND_ASSIGN(Differ);
853d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org};
863d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
873d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}  // namespace webrtc
883d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
893d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
90