16c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org/*
26c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
36c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *
46c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  Use of this source code is governed by a BSD-style license
56c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  that can be found in the LICENSE file in the root of the source
66c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  tree. An additional intellectual property rights grant can be found
76c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  in the file PATENTS.  All contributing project authors may
86c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org */
106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#define WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#include <vector>
156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#include "webrtc/modules/desktop_capture/desktop_region.h"
176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgnamespace webrtc {
206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgtypedef uint8_t DiffInfo;
226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// TODO(sergeyu): Simplify differ now that we are working with DesktopRegion.
246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// diff_info_ should no longer be needed, as we can put our data directly into
256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// the region that we are calculating.
266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// http://crbug.com/92379
276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// TODO(sergeyu): Rename this class to something more sensible, e.g.
286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// ScreenCaptureFrameDifferencer.
296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgclass Differ {
306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org public:
316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Create a differ that operates on bitmaps with the specified width, height
326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // and bytes_per_pixel.
336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  Differ(int width, int height, int bytes_per_pixel, int stride);
346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ~Differ();
356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int width() { return width_; }
376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int height() { return height_; }
386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int bytes_per_pixel() { return bytes_per_pixel_; }
396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int bytes_per_row() { return bytes_per_row_; }
406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Given the previous and current screen buffer, calculate the dirty region
426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // that encloses all of the changed pixels in the new screen.
436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer,
446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                       DesktopRegion* region);
456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org private:
476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Allow tests to access our private parts.
486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  friend class DifferTest;
496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Identify all of the blocks that contain changed pixels.
516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer);
526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
536c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // After the dirty blocks have been identified, this routine merges adjacent
546c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // blocks into a region.
556c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // The goal is to minimize the region that covers the dirty blocks.
566c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void MergeBlocks(DesktopRegion* region);
576c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
586c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Check for diffs in upper-left portion of the block. The size of the portion
596c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // to check is specified by the |width| and |height| values.
606c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Note that if we force the capturer to always return images whose width and
616c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // height are multiples of kBlockSize, then this will never be called.
626c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DiffInfo DiffPartialBlock(const uint8_t* prev_buffer,
636c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                            const uint8_t* curr_buffer,
646c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                            int stride,
656c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                            int width, int height);
666c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
676c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Dimensions of screen.
686c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int width_;
696c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int height_;
706c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
716c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Number of bytes for each pixel in source and dest bitmap.
726c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // (Yes, they must match.)
736c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int bytes_per_pixel_;
746c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
756c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Number of bytes in each row of the image (AKA: stride).
766c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int bytes_per_row_;
776c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
786c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Diff information for each block in the image.
79ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org  scoped_ptr<DiffInfo[]> diff_info_;
806c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
816c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Dimensions and total size of diff info array.
826c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int diff_info_width_;
836c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int diff_info_height_;
846c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int diff_info_size_;
856c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
866c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DISALLOW_COPY_AND_ASSIGN(Differ);
876c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org};
886c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
896c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}  // namespace webrtc
906c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
916c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
92