summaryrefslogtreecommitdiffstats
path: root/media/video/capture/screen
diff options
context:
space:
mode:
Diffstat (limited to 'media/video/capture/screen')
-rw-r--r--media/video/capture/screen/differ.cc201
-rw-r--r--media/video/capture/screen/differ.h85
-rw-r--r--media/video/capture/screen/differ_block.cc49
-rw-r--r--media/video/capture/screen/differ_block.h28
-rw-r--r--media/video/capture/screen/differ_block_sse2.cc112
-rw-r--r--media/video/capture/screen/differ_block_sse2.h25
-rw-r--r--media/video/capture/screen/differ_block_unittest.cc81
-rw-r--r--media/video/capture/screen/differ_unittest.cc646
-rw-r--r--media/video/capture/screen/mac/desktop_configuration.h65
-rw-r--r--media/video/capture/screen/mac/desktop_configuration.mm140
-rw-r--r--media/video/capture/screen/mac/scoped_pixel_buffer_object.cc47
-rw-r--r--media/video/capture/screen/mac/scoped_pixel_buffer_object.h33
-rw-r--r--media/video/capture/screen/mouse_cursor_shape.h30
-rw-r--r--media/video/capture/screen/screen_capture_device.cc34
-rw-r--r--media/video/capture/screen/screen_capture_device.h4
-rw-r--r--media/video/capture/screen/screen_capture_device_unittest.cc4
-rw-r--r--media/video/capture/screen/screen_capture_frame_queue.cc39
-rw-r--r--media/video/capture/screen/screen_capture_frame_queue.h68
-rw-r--r--media/video/capture/screen/screen_capturer.h77
-rw-r--r--media/video/capture/screen/screen_capturer_fake.cc128
-rw-r--r--media/video/capture/screen/screen_capturer_fake.h60
-rw-r--r--media/video/capture/screen/screen_capturer_helper.cc128
-rw-r--r--media/video/capture/screen/screen_capturer_helper.h83
-rw-r--r--media/video/capture/screen/screen_capturer_helper_unittest.cc225
-rw-r--r--media/video/capture/screen/screen_capturer_mac.mm859
-rw-r--r--media/video/capture/screen/screen_capturer_mac_unittest.cc95
-rw-r--r--media/video/capture/screen/screen_capturer_mock_objects.cc28
-rw-r--r--media/video/capture/screen/screen_capturer_mock_objects.h58
-rw-r--r--media/video/capture/screen/screen_capturer_null.cc29
-rw-r--r--media/video/capture/screen/screen_capturer_unittest.cc120
-rw-r--r--media/video/capture/screen/screen_capturer_win.cc524
-rw-r--r--media/video/capture/screen/screen_capturer_x11.cc613
-rw-r--r--media/video/capture/screen/shared_desktop_frame.cc56
-rw-r--r--media/video/capture/screen/shared_desktop_frame.h43
-rw-r--r--media/video/capture/screen/win/desktop.cc104
-rw-r--r--media/video/capture/screen/win/desktop.h59
-rw-r--r--media/video/capture/screen/win/scoped_thread_desktop.cc49
-rw-r--r--media/video/capture/screen/win/scoped_thread_desktop.h48
-rw-r--r--media/video/capture/screen/x11/x_server_pixel_buffer.cc261
-rw-r--r--media/video/capture/screen/x11/x_server_pixel_buffer.h78
40 files changed, 22 insertions, 5394 deletions
diff --git a/media/video/capture/screen/differ.cc b/media/video/capture/screen/differ.cc
deleted file mode 100644
index addaea1..0000000
--- a/media/video/capture/screen/differ.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/differ.h"
-
-#include "base/logging.h"
-#include "media/video/capture/screen/differ_block.h"
-
-namespace media {
-
-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(DiffInfo);
- diff_info_.reset(new DiffInfo[diff_info_size_]);
-}
-
-Differ::~Differ() {}
-
-void Differ::CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer,
- webrtc::DesktopRegion* region) {
- // Identify all the blocks that contain changed pixels.
- MarkDirtyBlocks(prev_buffer, curr_buffer);
-
- // 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 void* prev_buffer, const void* curr_buffer) {
- 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;
-
- // 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);
-
- // Offset from the start of one block-column to the next.
- int block_x_offset = bytes_per_pixel_ * kBlockSize;
- // Offset from the start of one block-row to the next.
- int block_y_stride = (width_ * bytes_per_pixel_) * kBlockSize;
- // Offset from the start of one diff_info row to the next.
- int diff_info_stride = diff_info_width_ * sizeof(DiffInfo);
-
- const uint8* prev_block_row_start = static_cast<const uint8*>(prev_buffer);
- const uint8* curr_block_row_start = static_cast<const uint8*>(curr_buffer);
- DiffInfo* diff_info_row_start = static_cast<DiffInfo*>(diff_info_.get());
-
- for (int y = 0; y < y_full_blocks; y++) {
- const uint8* prev_block = prev_block_row_start;
- const uint8* curr_block = curr_block_row_start;
- DiffInfo* diff_info = diff_info_row_start;
-
- for (int x = 0; x < x_full_blocks; 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_);
- prev_block += block_x_offset;
- curr_block += block_x_offset;
- diff_info += sizeof(DiffInfo);
- }
-
- // If there is a partial column at the end, handle it.
- // This condition should rarely, if ever, occur.
- if (partial_column_width != 0) {
- *diff_info = DiffPartialBlock(prev_block, curr_block, bytes_per_row_,
- partial_column_width, kBlockSize);
- diff_info += sizeof(DiffInfo);
- }
-
- // Update pointers for next row.
- prev_block_row_start += block_y_stride;
- curr_block_row_start += block_y_stride;
- diff_info_row_start += diff_info_stride;
- }
-
- // 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.
- if (partial_row_height != 0) {
- const uint8* prev_block = prev_block_row_start;
- const uint8* curr_block = curr_block_row_start;
- DiffInfo* diff_info = diff_info_row_start;
- for (int x = 0; x < x_full_blocks; x++) {
- *diff_info = DiffPartialBlock(prev_block, curr_block,
- bytes_per_row_,
- kBlockSize, partial_row_height);
- prev_block += block_x_offset;
- curr_block += block_x_offset;
- diff_info += sizeof(DiffInfo);
- }
- if (partial_column_width != 0) {
- *diff_info = DiffPartialBlock(prev_block, curr_block, bytes_per_row_,
- partial_column_width, partial_row_height);
- diff_info += sizeof(DiffInfo);
- }
- }
-}
-
-DiffInfo Differ::DiffPartialBlock(const uint8* prev_buffer,
- const uint8* curr_buffer,
- int stride, int width, int height) {
- int width_bytes = width * bytes_per_pixel_;
- for (int y = 0; y < height; y++) {
- if (memcmp(prev_buffer, curr_buffer, width_bytes) != 0)
- return 1;
- prev_buffer += bytes_per_row_;
- curr_buffer += bytes_per_row_;
- }
- return 0;
-}
-
-void Differ::MergeBlocks(webrtc::DesktopRegion* region) {
- region->Clear();
-
- uint8* diff_info_row_start = static_cast<uint8*>(diff_info_.get());
- int diff_info_stride = diff_info_width_ * sizeof(DiffInfo);
-
- for (int y = 0; y < diff_info_height_; y++) {
- uint8* diff_info = diff_info_row_start;
- for (int x = 0; x < diff_info_width_; x++) {
- if (*diff_info != 0) {
- // We've found a modified block. Look at blocks to the right and below
- // to group this block with as many others as we can.
- int left = x * kBlockSize;
- int top = y * kBlockSize;
- int width = 1;
- int height = 1;
- *diff_info = 0;
-
- // Group with blocks to the right.
- // We can keep looking until we find an unchanged block because we
- // have a boundary block which is never marked as having diffs.
- uint8* right = diff_info + 1;
- while (*right) {
- *right++ = 0;
- width++;
- }
-
- // Group with blocks below.
- // The entire width of blocks that we matched above much match for
- // each row that we add.
- uint8* bottom = diff_info;
- bool found_new_row;
- do {
- found_new_row = true;
- bottom += diff_info_stride;
- right = bottom;
- for (int x2 = 0; x2 < width; x2++) {
- if (*right++ == 0) {
- found_new_row = false;
- }
- }
-
- if (found_new_row) {
- height++;
-
- // We need to go back and erase the diff markers so that we don't
- // try to add these blocks a second time.
- right = bottom;
- for (int x2 = 0; x2 < width; x2++) {
- *right++ = 0;
- }
- }
- } while (found_new_row);
-
- // Add rect to list of dirty rects.
- width *= kBlockSize;
- if (left + width > width_) {
- width = width_ - left;
- }
- height *= kBlockSize;
- if (top + height > height_) {
- height = height_ - top;
- }
- region->AddRect(
- webrtc::DesktopRect::MakeXYWH(left, top, width, height));
- }
-
- // Increment to next block in this row.
- diff_info++;
- }
-
- // Go to start of next row.
- diff_info_row_start += diff_info_stride;
- }
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/differ.h b/media/video/capture/screen/differ.h
deleted file mode 100644
index 1676ecb..0000000
--- a/media/video/capture/screen/differ.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "media/base/media_export.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
-
-namespace media {
-
-typedef uint8 DiffInfo;
-
-// TODO: Simplify differ now that we are working with webrtc::DesktopRegion.
-// diff_info_ should no longer be needed, as we can put our data directly into
-// the region that we are calculating.
-// http://crbug.com/92379
-// TODO(sergeyu): Rename this class to something more sensible, e.g.
-// ScreenCaptureFrameDifferencer.
-class MEDIA_EXPORT Differ {
- public:
- // Create a differ that operates on bitmaps with the specified width, height
- // and bytes_per_pixel.
- Differ(int width, int height, int bytes_per_pixel, int stride);
- ~Differ();
-
- int width() { return width_; }
- int height() { return height_; }
- int bytes_per_pixel() { return bytes_per_pixel_; }
- int bytes_per_row() { return bytes_per_row_; }
-
- // Given the previous and current screen buffer, calculate the dirty region
- // that encloses all of the changed pixels in the new screen.
- void CalcDirtyRegion(const void* prev_buffer, const void* curr_buffer,
- webrtc::DesktopRegion* region);
-
- private:
- // Allow tests to access our private parts.
- friend class DifferTest;
-
- // Identify all of the blocks that contain changed pixels.
- void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer);
-
- // After the dirty blocks have been identified, this routine merges adjacent
- // blocks into a region.
- // The goal is to minimize the region that covers the dirty blocks.
- void MergeBlocks(webrtc::DesktopRegion* region);
-
- // Check for diffs in upper-left portion of the block. The size of the portion
- // to check is specified by the |width| and |height| values.
- // Note that if we force the capturer to always return images whose width and
- // height are multiples of kBlockSize, then this will never be called.
- DiffInfo DiffPartialBlock(const uint8* prev_buffer, const uint8* curr_buffer,
- int stride, int width, int height);
-
- // Dimensions of screen.
- int width_;
- int height_;
-
- // Number of bytes for each pixel in source and dest bitmap.
- // (Yes, they must match.)
- int bytes_per_pixel_;
-
- // Number of bytes in each row of the image (AKA: stride).
- int bytes_per_row_;
-
- // Diff information for each block in the image.
- scoped_ptr<DiffInfo[]> diff_info_;
-
- // Dimensions and total size of diff info array.
- int diff_info_width_;
- int diff_info_height_;
- int diff_info_size_;
-
- DISALLOW_COPY_AND_ASSIGN(Differ);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_H_
diff --git a/media/video/capture/screen/differ_block.cc b/media/video/capture/screen/differ_block.cc
deleted file mode 100644
index d263ac4..0000000
--- a/media/video/capture/screen/differ_block.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/differ_block.h"
-
-#include "base/cpu.h"
-#include "build/build_config.h"
-#include "media/video/capture/screen/differ_block_sse2.h"
-
-namespace media {
-
-int BlockDifference_C(const uint8* image1, const uint8* image2, int stride) {
- int width_bytes = kBlockSize * kBytesPerPixel;
-
- for (int y = 0; y < kBlockSize; y++) {
- if (memcmp(image1, image2, width_bytes) != 0)
- return 1;
- image1 += stride;
- image2 += stride;
- }
- return 0;
-}
-
-int BlockDifference(const uint8* image1, const uint8* image2, int stride) {
- static int (*diff_proc)(const uint8*, const uint8*, int) = NULL;
-
- if (!diff_proc) {
-#if defined(ARCH_CPU_ARM_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
- // For ARM and MIPS processors, always use C version.
- // TODO(hclam): Implement a NEON version.
- diff_proc = &BlockDifference_C;
-#else
- base::CPU cpu;
- // For x86 processors, check if SSE2 is supported.
- if (cpu.has_sse2() && kBlockSize == 32) {
- diff_proc = &BlockDifference_SSE2_W32;
- } else if (cpu.has_sse2() && kBlockSize == 16) {
- diff_proc = &BlockDifference_SSE2_W16;
- } else {
- diff_proc = &BlockDifference_C;
- }
-#endif
- }
-
- return diff_proc(image1, image2, stride);
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/differ_block.h b/media/video/capture/screen/differ_block.h
deleted file mode 100644
index 8b211e2..0000000
--- a/media/video/capture/screen/differ_block.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_BLOCK_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_BLOCK_H_
-
-#include "base/basictypes.h"
-#include "media/base/media_export.h"
-
-namespace media {
-
-// Size (in pixels) of each square block used for diffing. This must be a
-// multiple of sizeof(uint64)/8.
-const int kBlockSize = 32;
-
-// Format: BGRA 32 bit.
-const int kBytesPerPixel = 4;
-
-// Low level functions to compare 2 blocks of pixels. Zero means the blocks
-// are identical. One - the blocks are different.
-MEDIA_EXPORT int BlockDifference(const uint8* image1,
- const uint8* image2,
- int stride);
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_BLOCK_H_
diff --git a/media/video/capture/screen/differ_block_sse2.cc b/media/video/capture/screen/differ_block_sse2.cc
deleted file mode 100644
index abe7ced..0000000
--- a/media/video/capture/screen/differ_block_sse2.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/differ_block_sse2.h"
-
-#if defined(_MSC_VER)
-#include <intrin.h>
-#else
-#include <mmintrin.h>
-#include <emmintrin.h>
-#endif
-
-#include "media/video/capture/screen/differ_block.h"
-
-namespace media {
-
-extern int BlockDifference_SSE2_W16(const uint8* image1, const uint8* image2,
- int stride) {
- __m128i acc = _mm_setzero_si128();
- __m128i v0;
- __m128i v1;
- __m128i sad;
- for (int y = 0; y < kBlockSize; ++y) {
- const __m128i* i1 = reinterpret_cast<const __m128i*>(image1);
- const __m128i* i2 = reinterpret_cast<const __m128i*>(image2);
- v0 = _mm_loadu_si128(i1);
- v1 = _mm_loadu_si128(i2);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 1);
- v1 = _mm_loadu_si128(i2 + 1);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 2);
- v1 = _mm_loadu_si128(i2 + 2);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 3);
- v1 = _mm_loadu_si128(i2 + 3);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
-
- // This essential means sad = acc >> 64. We only care about the lower 16
- // bits.
- sad = _mm_shuffle_epi32(acc, 0xEE);
- sad = _mm_adds_epu16(sad, acc);
- int diff = _mm_cvtsi128_si32(sad);
- if (diff)
- return 1;
- image1 += stride;
- image2 += stride;
- }
- return 0;
-}
-
-extern int BlockDifference_SSE2_W32(const uint8* image1, const uint8* image2,
- int stride) {
- __m128i acc = _mm_setzero_si128();
- __m128i v0;
- __m128i v1;
- __m128i sad;
- for (int y = 0; y < kBlockSize; ++y) {
- const __m128i* i1 = reinterpret_cast<const __m128i*>(image1);
- const __m128i* i2 = reinterpret_cast<const __m128i*>(image2);
- v0 = _mm_loadu_si128(i1);
- v1 = _mm_loadu_si128(i2);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 1);
- v1 = _mm_loadu_si128(i2 + 1);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 2);
- v1 = _mm_loadu_si128(i2 + 2);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 3);
- v1 = _mm_loadu_si128(i2 + 3);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 4);
- v1 = _mm_loadu_si128(i2 + 4);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 5);
- v1 = _mm_loadu_si128(i2 + 5);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 6);
- v1 = _mm_loadu_si128(i2 + 6);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
- v0 = _mm_loadu_si128(i1 + 7);
- v1 = _mm_loadu_si128(i2 + 7);
- sad = _mm_sad_epu8(v0, v1);
- acc = _mm_adds_epu16(acc, sad);
-
- // This essential means sad = acc >> 64. We only care about the lower 16
- // bits.
- sad = _mm_shuffle_epi32(acc, 0xEE);
- sad = _mm_adds_epu16(sad, acc);
- int diff = _mm_cvtsi128_si32(sad);
- if (diff)
- return 1;
- image1 += stride;
- image2 += stride;
- }
- return 0;
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/differ_block_sse2.h b/media/video/capture/screen/differ_block_sse2.h
deleted file mode 100644
index 08d4d47..0000000
--- a/media/video/capture/screen/differ_block_sse2.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This header file is used only differ_block.h. It defines the SSE2 rountines
-// for finding block difference.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_BLOCK_SSE2_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_BLOCK_SSE2_H_
-
-#include "base/basictypes.h"
-
-namespace media {
-
-// Find block difference of dimension 16x16.
-extern int BlockDifference_SSE2_W16(const uint8* image1, const uint8* image2,
- int stride);
-
-// Find block difference of dimension 32x32.
-extern int BlockDifference_SSE2_W32(const uint8* image1, const uint8* image2,
- int stride);
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_DIFFER_BLOCK_SSE2_H_
diff --git a/media/video/capture/screen/differ_block_unittest.cc b/media/video/capture/screen/differ_block_unittest.cc
deleted file mode 100644
index 45694a0..0000000
--- a/media/video/capture/screen/differ_block_unittest.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/memory/ref_counted.h"
-#include "media/video/capture/screen/differ_block.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace media {
-
-// Run 900 times to mimic 1280x720.
-// TODO(fbarchard): Remove benchmark once performance is non-issue.
-static const int kTimesToRun = 900;
-
-static void GenerateData(uint8* data, int size) {
- for (int i = 0; i < size; ++i) {
- data[i] = i;
- }
-}
-
-// Memory buffer large enough for 2 blocks aligned to 16 bytes.
-static const int kSizeOfBlock = kBlockSize * kBlockSize * kBytesPerPixel;
-uint8 block_buffer[kSizeOfBlock * 2 + 16];
-
-void PrepareBuffers(uint8* &block1, uint8* &block2) {
- block1 = reinterpret_cast<uint8*>
- ((reinterpret_cast<uintptr_t>(&block_buffer[0]) + 15) & ~15);
- GenerateData(block1, kSizeOfBlock);
- block2 = block1 + kSizeOfBlock;
- memcpy(block2, block1, kSizeOfBlock);
-}
-
-TEST(BlockDifferenceTestSame, BlockDifference) {
- uint8* block1;
- uint8* block2;
- PrepareBuffers(block1, block2);
-
- // These blocks should match.
- for (int i = 0; i < kTimesToRun; ++i) {
- int result = BlockDifference(block1, block2, kBlockSize * kBytesPerPixel);
- EXPECT_EQ(0, result);
- }
-}
-
-TEST(BlockDifferenceTestLast, BlockDifference) {
- uint8* block1;
- uint8* block2;
- PrepareBuffers(block1, block2);
- block2[kSizeOfBlock-2] += 1;
-
- for (int i = 0; i < kTimesToRun; ++i) {
- int result = BlockDifference(block1, block2, kBlockSize * kBytesPerPixel);
- EXPECT_EQ(1, result);
- }
-}
-
-TEST(BlockDifferenceTestMid, BlockDifference) {
- uint8* block1;
- uint8* block2;
- PrepareBuffers(block1, block2);
- block2[kSizeOfBlock/2+1] += 1;
-
- for (int i = 0; i < kTimesToRun; ++i) {
- int result = BlockDifference(block1, block2, kBlockSize * kBytesPerPixel);
- EXPECT_EQ(1, result);
- }
-}
-
-TEST(BlockDifferenceTestFirst, BlockDifference) {
- uint8* block1;
- uint8* block2;
- PrepareBuffers(block1, block2);
- block2[0] += 1;
-
- for (int i = 0; i < kTimesToRun; ++i) {
- int result = BlockDifference(block1, block2, kBlockSize * kBytesPerPixel);
- EXPECT_EQ(1, result);
- }
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/differ_unittest.cc b/media/video/capture/screen/differ_unittest.cc
deleted file mode 100644
index dab540d..0000000
--- a/media/video/capture/screen/differ_unittest.cc
+++ /dev/null
@@ -1,646 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/memory/scoped_ptr.h"
-#include "media/video/capture/screen/differ.h"
-#include "media/video/capture/screen/differ_block.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace media {
-
-// 96x96 screen gives a 4x4 grid of blocks.
-const int kScreenWidth= 96;
-const int kScreenHeight = 96;
-
-// To test partial blocks, we need a width and height that are not multiples
-// of 16 (or 32, depending on current block size).
-const int kPartialScreenWidth = 70;
-const int kPartialScreenHeight = 70;
-
-class DifferTest : public testing::Test {
- public:
- DifferTest() {
- }
-
- protected:
- void InitDiffer(int width, int height) {
- width_ = width;
- height_ = height;
- bytes_per_pixel_ = kBytesPerPixel;
- stride_ = (kBytesPerPixel * width);
- buffer_size_ = width_ * height_ * bytes_per_pixel_;
-
- differ_.reset(new Differ(width_, height_, bytes_per_pixel_, stride_));
-
- prev_.reset(new uint8[buffer_size_]);
- memset(prev_.get(), 0, buffer_size_);
-
- curr_.reset(new uint8[buffer_size_]);
- memset(curr_.get(), 0, buffer_size_);
- }
-
- void ClearBuffer(uint8* buffer) {
- memset(buffer, 0, buffer_size_);
- }
-
- // Here in DifferTest so that tests can access private methods of Differ.
- void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer) {
- differ_->MarkDirtyBlocks(prev_buffer, curr_buffer);
- }
-
- void MergeBlocks(webrtc::DesktopRegion* dirty) {
- differ_->MergeBlocks(dirty);
- }
-
- // Convenience method to count rectangles in a region.
- int RegionRectCount(const webrtc::DesktopRegion& region) {
- int count = 0;
- for (webrtc::DesktopRegion::Iterator iter(region);
- !iter.IsAtEnd(); iter.Advance()) {
- ++count;
- }
- return count;
- }
-
- // Convenience wrapper for Differ's DiffBlock that calculates the appropriate
- // offset to the start of the desired block.
- DiffInfo DiffBlock(int block_x, int block_y) {
- // Offset from upper-left of buffer to upper-left of requested block.
- int block_offset = ((block_y * stride_) + (block_x * bytes_per_pixel_))
- * kBlockSize;
- return BlockDifference(prev_.get() + block_offset,
- curr_.get() + block_offset,
- stride_);
- }
-
- // Write the pixel |value| into the specified block in the |buffer|.
- // This is a convenience wrapper around WritePixel().
- void WriteBlockPixel(uint8* buffer, int block_x, int block_y,
- int pixel_x, int pixel_y, uint32 value) {
- WritePixel(buffer, (block_x * kBlockSize) + pixel_x,
- (block_y * kBlockSize) + pixel_y, value);
- }
-
- // Write the test pixel |value| into the |buffer| at the specified |x|,|y|
- // location.
- // Only the low-order bytes from |value| are written (assuming little-endian).
- // So, for |value| = 0xaabbccdd:
- // If bytes_per_pixel = 4, then ddccbbaa will be written as the pixel value.
- // If = 3, ddccbb
- // If = 2, ddcc
- // If = 1, dd
- void WritePixel(uint8* buffer, int x, int y, uint32 value) {
- uint8* pixel = reinterpret_cast<uint8*>(&value);
- buffer += (y * stride_) + (x * bytes_per_pixel_);
- for (int b = bytes_per_pixel_ - 1; b >= 0; b--) {
- *buffer++ = pixel[b];
- }
- }
-
- // DiffInfo utility routines.
- // These are here so that we don't have to make each DifferText_Xxx_Test
- // class a friend class to Differ.
-
- // Clear out the entire |diff_info_| buffer.
- void ClearDiffInfo() {
- memset(differ_->diff_info_.get(), 0, differ_->diff_info_size_);
- }
-
- // Get the value in the |diff_info_| array at (x,y).
- DiffInfo GetDiffInfo(int x, int y) {
- DiffInfo* diff_info = differ_->diff_info_.get();
- return diff_info[(y * GetDiffInfoWidth()) + x];
- }
-
- // Width of |diff_info_| array.
- int GetDiffInfoWidth() {
- return differ_->diff_info_width_;
- }
-
- // Height of |diff_info_| array.
- int GetDiffInfoHeight() {
- return differ_->diff_info_height_;
- }
-
- // Size of |diff_info_| array.
- int GetDiffInfoSize() {
- return differ_->diff_info_size_;
- }
-
- void SetDiffInfo(int x, int y, const DiffInfo& value) {
- DiffInfo* diff_info = differ_->diff_info_.get();
- diff_info[(y * GetDiffInfoWidth()) + x] = value;
- }
-
- // Mark the range of blocks specified.
- void MarkBlocks(int x_origin, int y_origin, int width, int height) {
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- SetDiffInfo(x_origin + x, y_origin + y, 1);
- }
- }
- }
-
- // Verify that |region| contains a rectangle defined by |x|, |y|, |width| and
- // |height|.
- // |x|, |y|, |width| and |height| are specified in block (not pixel) units.
- bool CheckDirtyRegionContainsRect(const webrtc::DesktopRegion& region,
- int x, int y,
- int width, int height) {
- webrtc::DesktopRect r =
- webrtc::DesktopRect::MakeXYWH(x * kBlockSize, y * kBlockSize,
- width * kBlockSize, height * kBlockSize);
- for (webrtc::DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) {
- if (i.rect().equals(r))
- return true;
- }
- return false;
- }
-
- // Mark the range of blocks specified and then verify that they are
- // merged correctly.
- // Only one rectangular region of blocks can be checked with this routine.
- bool MarkBlocksAndCheckMerge(int x_origin, int y_origin,
- int width, int height) {
- ClearDiffInfo();
- MarkBlocks(x_origin, y_origin, width, height);
-
- webrtc::DesktopRegion dirty;
- MergeBlocks(&dirty);
-
-
- webrtc::DesktopRect expected_rect = webrtc::DesktopRect::MakeXYWH(
- x_origin * kBlockSize, y_origin * kBlockSize,
- width * kBlockSize, height * kBlockSize);
-
- // Verify that the region contains expected_rect and it's the only
- // rectangle.
- webrtc::DesktopRegion::Iterator it(dirty);
- return !it.IsAtEnd() && expected_rect.equals(it.rect()) &&
- (it.Advance(), it.IsAtEnd());
- }
-
- // The differ class we're testing.
- scoped_ptr<Differ> differ_;
-
- // Screen/buffer info.
- int width_;
- int height_;
- int bytes_per_pixel_;
- int stride_;
-
- // Size of each screen buffer.
- int buffer_size_;
-
- // Previous and current screen buffers.
- scoped_ptr<uint8[]> prev_;
- scoped_ptr<uint8[]> curr_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DifferTest);
-};
-
-TEST_F(DifferTest, Setup) {
- InitDiffer(kScreenWidth, kScreenHeight);
- // 96x96 pixels results in 3x3 array. Add 1 to each dimension as boundary.
- // +---+---+---+---+
- // | o | o | o | _ |
- // +---+---+---+---+ o = blocks mapped to screen pixels
- // | o | o | o | _ |
- // +---+---+---+---+ _ = boundary blocks
- // | o | o | o | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- EXPECT_EQ(4, GetDiffInfoWidth());
- EXPECT_EQ(4, GetDiffInfoHeight());
- EXPECT_EQ(16, GetDiffInfoSize());
-}
-
-TEST_F(DifferTest, MarkDirtyBlocks_All) {
- InitDiffer(kScreenWidth, kScreenHeight);
- ClearDiffInfo();
-
- // Update a pixel in each block.
- for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
- for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
- WriteBlockPixel(curr_.get(), x, y, 10, 10, 0xff00ff);
- }
- }
-
- MarkDirtyBlocks(prev_.get(), curr_.get());
-
- // Make sure each block is marked as dirty.
- for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
- for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
- EXPECT_EQ(1, GetDiffInfo(x, y))
- << "when x = " << x << ", and y = " << y;
- }
- }
-}
-
-TEST_F(DifferTest, MarkDirtyBlocks_Sampling) {
- InitDiffer(kScreenWidth, kScreenHeight);
- ClearDiffInfo();
-
- // Update some pixels in image.
- WriteBlockPixel(curr_.get(), 1, 0, 10, 10, 0xff00ff);
- WriteBlockPixel(curr_.get(), 2, 1, 10, 10, 0xff00ff);
- WriteBlockPixel(curr_.get(), 0, 2, 10, 10, 0xff00ff);
-
- MarkDirtyBlocks(prev_.get(), curr_.get());
-
- // Make sure corresponding blocks are updated.
- EXPECT_EQ(0, GetDiffInfo(0, 0));
- EXPECT_EQ(0, GetDiffInfo(0, 1));
- EXPECT_EQ(1, GetDiffInfo(0, 2));
- EXPECT_EQ(1, GetDiffInfo(1, 0));
- EXPECT_EQ(0, GetDiffInfo(1, 1));
- EXPECT_EQ(0, GetDiffInfo(1, 2));
- EXPECT_EQ(0, GetDiffInfo(2, 0));
- EXPECT_EQ(1, GetDiffInfo(2, 1));
- EXPECT_EQ(0, GetDiffInfo(2, 2));
-}
-
-TEST_F(DifferTest, DiffBlock) {
- InitDiffer(kScreenWidth, kScreenHeight);
-
- // Verify no differences at start.
- EXPECT_EQ(0, DiffBlock(0, 0));
- EXPECT_EQ(0, DiffBlock(1, 1));
-
- // Write new data into the 4 corners of the middle block and verify that
- // neighboring blocks are not affected.
- int max = kBlockSize - 1;
- WriteBlockPixel(curr_.get(), 1, 1, 0, 0, 0xffffff);
- WriteBlockPixel(curr_.get(), 1, 1, 0, max, 0xffffff);
- WriteBlockPixel(curr_.get(), 1, 1, max, 0, 0xffffff);
- WriteBlockPixel(curr_.get(), 1, 1, max, max, 0xffffff);
- EXPECT_EQ(0, DiffBlock(0, 0));
- EXPECT_EQ(0, DiffBlock(0, 1));
- EXPECT_EQ(0, DiffBlock(0, 2));
- EXPECT_EQ(0, DiffBlock(1, 0));
- EXPECT_EQ(1, DiffBlock(1, 1)); // Only this block should change.
- EXPECT_EQ(0, DiffBlock(1, 2));
- EXPECT_EQ(0, DiffBlock(2, 0));
- EXPECT_EQ(0, DiffBlock(2, 1));
- EXPECT_EQ(0, DiffBlock(2, 2));
-}
-
-TEST_F(DifferTest, Partial_Setup) {
- InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
- // 70x70 pixels results in 3x3 array: 2x2 full blocks + partials around
- // the edge. One more is added to each dimension as a boundary.
- // +---+---+---+---+
- // | o | o | + | _ |
- // +---+---+---+---+ o = blocks mapped to screen pixels
- // | o | o | + | _ |
- // +---+---+---+---+ + = partial blocks (top/left mapped to screen pixels)
- // | + | + | + | _ |
- // +---+---+---+---+ _ = boundary blocks
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- EXPECT_EQ(4, GetDiffInfoWidth());
- EXPECT_EQ(4, GetDiffInfoHeight());
- EXPECT_EQ(16, GetDiffInfoSize());
-}
-
-TEST_F(DifferTest, Partial_FirstPixel) {
- InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
- ClearDiffInfo();
-
- // Update the first pixel in each block.
- for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
- for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
- WriteBlockPixel(curr_.get(), x, y, 0, 0, 0xff00ff);
- }
- }
-
- MarkDirtyBlocks(prev_.get(), curr_.get());
-
- // Make sure each block is marked as dirty.
- for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
- for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
- EXPECT_EQ(1, GetDiffInfo(x, y))
- << "when x = " << x << ", and y = " << y;
- }
- }
-}
-
-TEST_F(DifferTest, Partial_BorderPixel) {
- InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
- ClearDiffInfo();
-
- // Update the right/bottom border pixels.
- for (int y = 0; y < height_; y++) {
- WritePixel(curr_.get(), width_ - 1, y, 0xff00ff);
- }
- for (int x = 0; x < width_; x++) {
- WritePixel(curr_.get(), x, height_ - 1, 0xff00ff);
- }
-
- MarkDirtyBlocks(prev_.get(), curr_.get());
-
- // Make sure last (partial) block in each row/column is marked as dirty.
- int x_last = GetDiffInfoWidth() - 2;
- for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
- EXPECT_EQ(1, GetDiffInfo(x_last, y))
- << "when x = " << x_last << ", and y = " << y;
- }
- int y_last = GetDiffInfoHeight() - 2;
- for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
- EXPECT_EQ(1, GetDiffInfo(x, y_last))
- << "when x = " << x << ", and y = " << y_last;
- }
- // All other blocks are clean.
- for (int y = 0; y < GetDiffInfoHeight() - 2; y++) {
- for (int x = 0; x < GetDiffInfoWidth() - 2; x++) {
- EXPECT_EQ(0, GetDiffInfo(x, y)) << "when x = " << x << ", and y = " << y;
- }
- }
-}
-
-TEST_F(DifferTest, MergeBlocks_Empty) {
- InitDiffer(kScreenWidth, kScreenHeight);
-
- // No blocks marked:
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ClearDiffInfo();
-
- webrtc::DesktopRegion dirty;
- MergeBlocks(&dirty);
-
- EXPECT_TRUE(dirty.is_empty());
-}
-
-TEST_F(DifferTest, MergeBlocks_SingleBlock) {
- InitDiffer(kScreenWidth, kScreenHeight);
- // Mark a single block and make sure that there is a single merged
- // rect with the correct bounds.
- for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
- for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
- ASSERT_TRUE(MarkBlocksAndCheckMerge(x, y, 1, 1)) << "x: " << x
- << "y: " << y;
- }
- }
-}
-
-TEST_F(DifferTest, MergeBlocks_BlockRow) {
- InitDiffer(kScreenWidth, kScreenHeight);
-
- // +---+---+---+---+
- // | X | X | | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 1));
-
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | X | X | X | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 1));
-
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | | X | X | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 2, 2, 1));
-}
-
-TEST_F(DifferTest, MergeBlocks_BlockColumn) {
- InitDiffer(kScreenWidth, kScreenHeight);
-
- // +---+---+---+---+
- // | X | | | _ |
- // +---+---+---+---+
- // | X | | | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 1, 2));
-
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | | X | | _ |
- // +---+---+---+---+
- // | | X | | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 1, 2));
-
- // +---+---+---+---+
- // | | | X | _ |
- // +---+---+---+---+
- // | | | X | _ |
- // +---+---+---+---+
- // | | | X | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(2, 0, 1, 3));
-}
-
-TEST_F(DifferTest, MergeBlocks_BlockRect) {
- InitDiffer(kScreenWidth, kScreenHeight);
-
- // +---+---+---+---+
- // | X | X | | _ |
- // +---+---+---+---+
- // | X | X | | _ |
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 2));
-
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | | X | X | _ |
- // +---+---+---+---+
- // | | X | X | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 2, 2));
-
- // +---+---+---+---+
- // | | X | X | _ |
- // +---+---+---+---+
- // | | X | X | _ |
- // +---+---+---+---+
- // | | X | X | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 0, 2, 3));
-
- // +---+---+---+---+
- // | | | | _ |
- // +---+---+---+---+
- // | X | X | X | _ |
- // +---+---+---+---+
- // | X | X | X | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 2));
-
- // +---+---+---+---+
- // | X | X | X | _ |
- // +---+---+---+---+
- // | X | X | X | _ |
- // +---+---+---+---+
- // | X | X | X | _ |
- // +---+---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 3, 3));
-}
-
-// This tests marked regions that require more than 1 single dirty rect.
-// The exact rects returned depend on the current implementation, so these
-// may need to be updated if we modify how we merge blocks.
-TEST_F(DifferTest, MergeBlocks_MultiRect) {
- InitDiffer(kScreenWidth, kScreenHeight);
- webrtc::DesktopRegion dirty;
-
- // +---+---+---+---+ +---+---+---+
- // | | X | | _ | | | 0 | |
- // +---+---+---+---+ +---+---+---+
- // | X | | | _ | | 1 | | |
- // +---+---+---+---+ => +---+---+---+
- // | | | X | _ | | | | 2 |
- // +---+---+---+---+ +---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ClearDiffInfo();
- MarkBlocks(1, 0, 1, 1);
- MarkBlocks(0, 1, 1, 1);
- MarkBlocks(2, 2, 1, 1);
-
- dirty.Clear();
- MergeBlocks(&dirty);
-
- ASSERT_EQ(3, RegionRectCount(dirty));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 0, 1, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1));
-
- // +---+---+---+---+ +---+---+---+
- // | | | X | _ | | | | 0 |
- // +---+---+---+---+ +---+---+---+
- // | X | X | X | _ | | 1 1 1 |
- // +---+---+---+---+ => + +
- // | X | X | X | _ | | 1 1 1 |
- // +---+---+---+---+ +---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ClearDiffInfo();
- MarkBlocks(2, 0, 1, 1);
- MarkBlocks(0, 1, 3, 2);
-
- dirty.Clear();
- MergeBlocks(&dirty);
-
- ASSERT_EQ(2, RegionRectCount(dirty));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 0, 1, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 3, 2));
-
- // +---+---+---+---+ +---+---+---+
- // | | | | _ | | | | |
- // +---+---+---+---+ +---+---+---+
- // | X | | X | _ | | 0 | | 1 |
- // +---+---+---+---+ => +---+---+---+
- // | X | X | X | _ | | 2 2 2 |
- // +---+---+---+---+ +---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ClearDiffInfo();
- MarkBlocks(0, 1, 1, 1);
- MarkBlocks(2, 1, 1, 1);
- MarkBlocks(0, 2, 3, 1);
-
- dirty.Clear();
- MergeBlocks(&dirty);
-
- ASSERT_EQ(3, RegionRectCount(dirty));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1));
-
- // +---+---+---+---+ +---+---+---+
- // | X | X | X | _ | | 0 0 0 |
- // +---+---+---+---+ +---+---+---+
- // | X | | X | _ | | 1 | | 2 |
- // +---+---+---+---+ => +---+---+---+
- // | X | X | X | _ | | 3 3 3 |
- // +---+---+---+---+ +---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ClearDiffInfo();
- MarkBlocks(0, 0, 3, 1);
- MarkBlocks(0, 1, 1, 1);
- MarkBlocks(2, 1, 1, 1);
- MarkBlocks(0, 2, 3, 1);
-
- dirty.Clear();
- MergeBlocks(&dirty);
-
- ASSERT_EQ(4, RegionRectCount(dirty));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 3, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1));
-
- // +---+---+---+---+ +---+---+---+
- // | X | X | | _ | | 0 0 | |
- // +---+---+---+---+ + +---+
- // | X | X | | _ | | 0 0 | |
- // +---+---+---+---+ => +---+---+---+
- // | | X | | _ | | | 1 | |
- // +---+---+---+---+ +---+---+---+
- // | _ | _ | _ | _ |
- // +---+---+---+---+
- ClearDiffInfo();
- MarkBlocks(0, 0, 2, 2);
- MarkBlocks(1, 2, 1, 1);
-
- dirty.Clear();
- MergeBlocks(&dirty);
-
- ASSERT_EQ(2, RegionRectCount(dirty));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 2, 2));
- ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 2, 1, 1));
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/mac/desktop_configuration.h b/media/video/capture/screen/mac/desktop_configuration.h
deleted file mode 100644
index dfa563f..0000000
--- a/media/video/capture/screen/mac/desktop_configuration.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_MAC_DESKTOP_CONFIGURATION_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_MAC_DESKTOP_CONFIGURATION_H_
-
-#include <ApplicationServices/ApplicationServices.h>
-#include <Carbon/Carbon.h>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "media/base/media_export.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-
-namespace media {
-
-// Describes the configuration of a specific display.
-struct MEDIA_EXPORT MacDisplayConfiguration {
- MacDisplayConfiguration();
-
- // Cocoa identifier for this display.
- CGDirectDisplayID id;
-
- // Bounds of this display in Density-Independent Pixels (DIPs).
- webrtc::DesktopRect bounds;
-
- // Bounds of this display in physical pixels.
- webrtc::DesktopRect pixel_bounds;
-
- // Scale factor from DIPs to physical pixels.
- float dip_to_pixel_scale;
-};
-
-typedef std::vector<MacDisplayConfiguration> MacDisplayConfigurations;
-
-// Describes the configuration of the whole desktop.
-struct MEDIA_EXPORT MacDesktopConfiguration {
- // Used to request bottom-up or top-down coordinates.
- enum Origin { BottomLeftOrigin, TopLeftOrigin };
-
- MacDesktopConfiguration();
- ~MacDesktopConfiguration();
-
- // Returns the desktop & display configurations in Cocoa-style "bottom-up"
- // (the origin is the bottom-left of the primary monitor, and coordinates
- // increase as you move up the screen) or Carbon-style "top-down" coordinates.
- MEDIA_EXPORT static MacDesktopConfiguration GetCurrent(Origin origin);
-
- // Bounds of the desktop in Density-Independent Pixels (DIPs).
- webrtc::DesktopRect bounds;
-
- // Bounds of the desktop in physical pixels.
- webrtc::DesktopRect pixel_bounds;
-
- // Scale factor from DIPs to physical pixels.
- float dip_to_pixel_scale;
-
- // Configurations of the displays making up the desktop area.
- MacDisplayConfigurations displays;
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_MAC_DESKTOP_CONFIGURATION_H_
diff --git a/media/video/capture/screen/mac/desktop_configuration.mm b/media/video/capture/screen/mac/desktop_configuration.mm
deleted file mode 100644
index 53b8e13..0000000
--- a/media/video/capture/screen/mac/desktop_configuration.mm
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/mac/desktop_configuration.h"
-
-#include <math.h>
-#include <algorithm>
-#include <Cocoa/Cocoa.h>
-
-#include "base/logging.h"
-
-#if !defined(MAC_OS_X_VERSION_10_7) || \
- MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
-
-@interface NSScreen (LionAPI)
-- (CGFloat)backingScaleFactor;
-- (NSRect)convertRectToBacking:(NSRect)aRect;
-@end
-
-#endif // 10.7
-
-namespace media {
-
-namespace {
-
-webrtc::DesktopRect NSRectToDesktopRect(const NSRect& ns_rect) {
- return webrtc::DesktopRect::MakeLTRB(
- static_cast<int>(floor(ns_rect.origin.x)),
- static_cast<int>(floor(ns_rect.origin.y)),
- static_cast<int>(ceil(ns_rect.origin.x + ns_rect.size.width)),
- static_cast<int>(ceil(ns_rect.origin.y + ns_rect.size.height)));
-}
-
-webrtc::DesktopRect JoinRects(const webrtc::DesktopRect& a,
- const webrtc::DesktopRect& b) {
- return webrtc::DesktopRect::MakeLTRB(
- std::min(a.left(), b.left()),
- std::min(a.top(), b.top()),
- std::max(a.right(), b.right()),
- std::max(a.bottom(), b.bottom()));
-}
-
-// Inverts the position of |rect| from bottom-up coordinates to top-down,
-// relative to |bounds|.
-void InvertRectYOrigin(const webrtc::DesktopRect& bounds,
- webrtc::DesktopRect* rect) {
- DCHECK_EQ(0, bounds.top());
- *rect = webrtc::DesktopRect::MakeXYWH(
- rect->left(), bounds.bottom() - rect->bottom(),
- rect->width(), rect->height());
-}
-
-MacDisplayConfiguration GetConfigurationForScreen(NSScreen* screen) {
- MacDisplayConfiguration display_config;
-
- // Fetch the NSScreenNumber, which is also the CGDirectDisplayID.
- NSDictionary* device_description = [screen deviceDescription];
- display_config.id = static_cast<CGDirectDisplayID>(
- [[device_description objectForKey:@"NSScreenNumber"] intValue]);
-
- // Determine the display's logical & physical dimensions.
- NSRect ns_bounds = [screen frame];
- display_config.bounds = NSRectToDesktopRect(ns_bounds);
-
- // If the host is running Mac OS X 10.7+ or later, query the scaling factor
- // between logical and physical (aka "backing") pixels, otherwise assume 1:1.
- if ([screen respondsToSelector:@selector(backingScaleFactor)] &&
- [screen respondsToSelector:@selector(convertRectToBacking:)]) {
- display_config.dip_to_pixel_scale = [screen backingScaleFactor];
- NSRect ns_pixel_bounds = [screen convertRectToBacking: ns_bounds];
- display_config.pixel_bounds = NSRectToDesktopRect(ns_pixel_bounds);
- } else {
- display_config.pixel_bounds = display_config.bounds;
- }
-
- return display_config;
-}
-
-} // namespace
-
-MacDisplayConfiguration::MacDisplayConfiguration()
- : id(0),
- dip_to_pixel_scale(1.0f) {
-}
-
-MacDesktopConfiguration::MacDesktopConfiguration()
- : dip_to_pixel_scale(1.0f) {
-}
-
-MacDesktopConfiguration::~MacDesktopConfiguration() {
-}
-
-// static
-MacDesktopConfiguration MacDesktopConfiguration::GetCurrent(Origin origin) {
- MacDesktopConfiguration desktop_config;
-
- NSArray* screens = [NSScreen screens];
- CHECK(screens != NULL);
-
- // Iterator over the monitors, adding the primary monitor and monitors whose
- // DPI match that of the primary monitor.
- for (NSUInteger i = 0; i < [screens count]; ++i) {
- MacDisplayConfiguration display_config =
- GetConfigurationForScreen([screens objectAtIndex: i]);
-
- // Handling mixed-DPI is hard, so we only return displays that match the
- // "primary" display's DPI. The primary display is always the first in the
- // list returned by [NSScreen screens].
- if (i == 0) {
- desktop_config.dip_to_pixel_scale = display_config.dip_to_pixel_scale;
- } else if (desktop_config.dip_to_pixel_scale !=
- display_config.dip_to_pixel_scale) {
- continue;
- }
-
- // Cocoa uses bottom-up coordinates, so if the caller wants top-down then
- // we need to invert the positions of secondary monitors relative to the
- // primary one (the primary monitor's position is (0,0) in both systems).
- if (i > 0 && origin == TopLeftOrigin) {
- InvertRectYOrigin(desktop_config.displays[0].bounds,
- &display_config.bounds);
- InvertRectYOrigin(desktop_config.displays[0].pixel_bounds,
- &display_config.pixel_bounds);
- }
-
- // Add the display to the configuration.
- desktop_config.displays.push_back(display_config);
-
- // Update the desktop bounds to account for this display.
- desktop_config.bounds =
- JoinRects(desktop_config.bounds, display_config.bounds);
- desktop_config.pixel_bounds =
- JoinRects(desktop_config.pixel_bounds, display_config.pixel_bounds);
- }
-
- return desktop_config;
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/mac/scoped_pixel_buffer_object.cc b/media/video/capture/screen/mac/scoped_pixel_buffer_object.cc
deleted file mode 100644
index 29adf6f..0000000
--- a/media/video/capture/screen/mac/scoped_pixel_buffer_object.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/mac/scoped_pixel_buffer_object.h"
-
-namespace media {
-
-ScopedPixelBufferObject::ScopedPixelBufferObject()
- : cgl_context_(NULL),
- pixel_buffer_object_(0) {
-}
-
-ScopedPixelBufferObject::~ScopedPixelBufferObject() {
- Release();
-}
-
-bool ScopedPixelBufferObject::Init(CGLContextObj cgl_context,
- int size_in_bytes) {
- cgl_context_ = cgl_context;
- CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
- glGenBuffersARB(1, &pixel_buffer_object_);
- if (glGetError() == GL_NO_ERROR) {
- glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_);
- glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, size_in_bytes, NULL,
- GL_STREAM_READ_ARB);
- glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
- if (glGetError() != GL_NO_ERROR) {
- Release();
- }
- } else {
- cgl_context_ = NULL;
- pixel_buffer_object_ = 0;
- }
- return pixel_buffer_object_ != 0;
-}
-
-void ScopedPixelBufferObject::Release() {
- if (pixel_buffer_object_) {
- CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
- glDeleteBuffersARB(1, &pixel_buffer_object_);
- cgl_context_ = NULL;
- pixel_buffer_object_ = 0;
- }
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/mac/scoped_pixel_buffer_object.h b/media/video/capture/screen/mac/scoped_pixel_buffer_object.h
deleted file mode 100644
index 0c06278..0000000
--- a/media/video/capture/screen/mac/scoped_pixel_buffer_object.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_SCOPED_PIXEL_BUFFER_OBJECT_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_SCOPED_PIXEL_BUFFER_OBJECT_H_
-
-#include <OpenGL/CGLMacro.h>
-#include <OpenGL/OpenGL.h>
-#include "base/basictypes.h"
-
-namespace media {
-
-class ScopedPixelBufferObject {
- public:
- ScopedPixelBufferObject();
- ~ScopedPixelBufferObject();
-
- bool Init(CGLContextObj cgl_context, int size_in_bytes);
- void Release();
-
- GLuint get() const { return pixel_buffer_object_; }
-
- private:
- CGLContextObj cgl_context_;
- GLuint pixel_buffer_object_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedPixelBufferObject);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SCOPED_PIXEL_BUFFER_OBJECT_H_
diff --git a/media/video/capture/screen/mouse_cursor_shape.h b/media/video/capture/screen/mouse_cursor_shape.h
deleted file mode 100644
index 1e540562..0000000
--- a/media/video/capture/screen/mouse_cursor_shape.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_MOUSE_CURSOR_SHAPE_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_MOUSE_CURSOR_SHAPE_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "media/base/media_export.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-
-namespace media {
-
-// Type used to return mouse cursor shape from video capturers.
-struct MEDIA_EXPORT MouseCursorShape {
- // Size of the cursor in screen pixels.
- webrtc::DesktopSize size;
-
- // Coordinates of the cursor hotspot relative to upper-left corner.
- webrtc::DesktopVector hotspot;
-
- // Cursor pixmap data in 32-bit BGRA format.
- std::string data;
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_MOUSE_CURSOR_SHAPE_H_
diff --git a/media/video/capture/screen/screen_capture_device.cc b/media/video/capture/screen/screen_capture_device.cc
index 546112b..03c9128 100644
--- a/media/video/capture/screen/screen_capture_device.cc
+++ b/media/video/capture/screen/screen_capture_device.cc
@@ -9,10 +9,11 @@
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
-#include "media/video/capture/screen/mouse_cursor_shape.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDevice.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
+#include "third_party/webrtc/modules/desktop_capture/mouse_cursor_shape.h"
+#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
namespace media {
@@ -27,7 +28,7 @@ class ScreenCaptureDevice::Core
explicit Core(scoped_refptr<base::SequencedTaskRunner> task_runner);
// Helper used in tests to supply a fake capturer.
- void SetScreenCapturerForTest(scoped_ptr<ScreenCapturer> capturer) {
+ void SetScreenCapturerForTest(scoped_ptr<webrtc::ScreenCapturer> capturer) {
screen_capturer_ = capturer.Pass();
}
@@ -77,7 +78,7 @@ class ScreenCaptureDevice::Core
int frame_rate_;
// The underlying ScreenCapturer instance used to capture frames.
- scoped_ptr<ScreenCapturer> screen_capturer_;
+ scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
// After Allocate() is called we need to call OnFrameInfo() method of the
// |event_handler_| to specify the size of the frames this capturer will
@@ -273,22 +274,23 @@ void ScreenCaptureDevice::Core::DoAllocate(int frame_rate) {
frame_rate_ = frame_rate;
// Create and start frame capturer.
+ if (!screen_capturer_) {
#if defined(OS_CHROMEOS) && !defined(ARCH_CPU_ARMEL)
- // ScreenCapturerX11 polls by default, due to poor driver support for DAMAGE.
- // ChromeOS' drivers [can be patched to] support DAMAGE properly, so use it.
- // However ARM driver seems to not support this properly, so disable it for
- // ARM. See http://crbug.com/230105.
- if (!screen_capturer_)
- screen_capturer_ = ScreenCapturer::CreateWithXDamage(true);
+ // ScreenCapturerX11 polls by default, due to poor driver support for
+ // DAMAGE. ChromeOS' drivers [can be patched to] support DAMAGE properly, so
+ // use it. However ARM driver seems to not support this properly, so disable
+ // it for ARM. See http://crbug.com/230105.
+ screen_capturer_.reset(webrtc::ScreenCapturer::CreateWithXDamage(true));
#elif defined(OS_WIN)
- // ScreenCapturerWin disables Aero by default. We don't want it disabled for
- // WebRTC screen capture, though.
- if (!screen_capturer_)
- screen_capturer_ = ScreenCapturer::CreateWithDisableAero(false);
+ // ScreenCapturerWin disables Aero by default. We don't want it disabled for
+ // WebRTC screen capture, though.
+ screen_capturer_.reset(
+ webrtc::ScreenCapturer::CreateWithDisableAero(false));
#else
- if (!screen_capturer_)
- screen_capturer_ = ScreenCapturer::Create();
+ screen_capturer_.reset(webrtc::ScreenCapturer::Create());
#endif
+ }
+
if (screen_capturer_)
screen_capturer_->Start(this);
@@ -362,7 +364,7 @@ ScreenCaptureDevice::~ScreenCaptureDevice() {
}
void ScreenCaptureDevice::SetScreenCapturerForTest(
- scoped_ptr<ScreenCapturer> capturer) {
+ scoped_ptr<webrtc::ScreenCapturer> capturer) {
core_->SetScreenCapturerForTest(capturer.Pass());
}
diff --git a/media/video/capture/screen/screen_capture_device.h b/media/video/capture/screen/screen_capture_device.h
index f1cee98..94e4d9c 100644
--- a/media/video/capture/screen/screen_capture_device.h
+++ b/media/video/capture/screen/screen_capture_device.h
@@ -8,9 +8,9 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/media_export.h"
-#include "media/video/capture/screen/screen_capturer.h"
#include "media/video/capture/video_capture_device.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
namespace base {
class SequencedTaskRunner;
@@ -28,7 +28,7 @@ class MEDIA_EXPORT ScreenCaptureDevice : public VideoCaptureDevice {
// Helper used in tests to supply a fake capturer.
void SetScreenCapturerForTest(
- scoped_ptr<media::ScreenCapturer> capturer);
+ scoped_ptr<webrtc::ScreenCapturer> capturer);
// VideoCaptureDevice interface.
virtual void Allocate(int width, int height,
diff --git a/media/video/capture/screen/screen_capture_device_unittest.cc b/media/video/capture/screen/screen_capture_device_unittest.cc
index 0247bb9..04f4201 100644
--- a/media/video/capture/screen/screen_capture_device_unittest.cc
+++ b/media/video/capture/screen/screen_capture_device_unittest.cc
@@ -49,7 +49,7 @@ class MockFrameObserver : public VideoCaptureDevice::EventHandler {
};
// TODO(sergeyu): Move this to a separate file where it can be reused.
-class FakeScreenCapturer : public ScreenCapturer {
+class FakeScreenCapturer : public webrtc::ScreenCapturer {
public:
FakeScreenCapturer()
: callback_(NULL),
@@ -133,7 +133,7 @@ TEST_F(ScreenCaptureDeviceTest, ScreenResolutionChange) {
ScreenCaptureDevice capture_device(
worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()));
capture_device.SetScreenCapturerForTest(
- scoped_ptr<ScreenCapturer>(mock_capturer));
+ scoped_ptr<webrtc::ScreenCapturer>(mock_capturer));
VideoCaptureCapability caps;
base::WaitableEvent done_event(false, false);
diff --git a/media/video/capture/screen/screen_capture_frame_queue.cc b/media/video/capture/screen/screen_capture_frame_queue.cc
deleted file mode 100644
index 5402acf..0000000
--- a/media/video/capture/screen/screen_capture_frame_queue.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capture_frame_queue.h"
-
-#include <algorithm>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/threading/non_thread_safe.h"
-#include "media/video/capture/screen/shared_desktop_frame.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-
-namespace media {
-
-ScreenCaptureFrameQueue::ScreenCaptureFrameQueue() : current_(0) {}
-
-ScreenCaptureFrameQueue::~ScreenCaptureFrameQueue() {}
-
-void ScreenCaptureFrameQueue::MoveToNextFrame() {
- current_ = (current_ + 1) % kQueueLength;
-
- // Verify that the frame is not shared, i.e. that consumer has released it
- // before attempting to capture again.
- DCHECK(!frames_[current_] || !frames_[current_]->IsShared());
-}
-
-void ScreenCaptureFrameQueue::ReplaceCurrentFrame(
- scoped_ptr<webrtc::DesktopFrame> frame) {
- frames_[current_].reset(SharedDesktopFrame::Wrap(frame.release()));
-}
-
-void ScreenCaptureFrameQueue::Reset() {
- for (int i = 0; i < kQueueLength; ++i)
- frames_[i].reset();
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capture_frame_queue.h b/media/video/capture/screen/screen_capture_frame_queue.h
deleted file mode 100644
index c51c563..0000000
--- a/media/video/capture/screen/screen_capture_frame_queue.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURE_FRAME_QUEUE_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURE_FRAME_QUEUE_H_
-
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "media/video/capture/screen/shared_desktop_frame.h"
-
-namespace webrtc {
-class DesktopFrame;
-} // namespace webrtc
-
-namespace media {
-
-// Represents a queue of reusable video frames. Provides access to the 'current'
-// frame - the frame that the caller is working with at the moment, and to the
-// 'previous' frame - the predecessor of the current frame swapped by
-// MoveToNextFrame() call, if any.
-//
-// The caller is expected to (re)allocate frames if current_frame() returns
-// NULL. The caller can mark all frames in the queue for reallocation (when,
-// say, frame dimensions change). The queue records which frames need updating
-// which the caller can query.
-//
-// Frame consumer is expected to never hold more than kQueueLength frames
-// created by this function and it should release the earliest one before trying
-// to capture a new frame (i.e. before MoveToNextFrame() is called).
-class ScreenCaptureFrameQueue {
- public:
- ScreenCaptureFrameQueue();
- ~ScreenCaptureFrameQueue();
-
- // Moves to the next frame in the queue, moving the 'current' frame to become
- // the 'previous' one.
- void MoveToNextFrame();
-
- // Replaces the current frame with a new one allocated by the caller.
- // The existing frame (if any) is destroyed.
- void ReplaceCurrentFrame(scoped_ptr<webrtc::DesktopFrame> frame);
-
- // Marks all frames obsolete and resets the previous frame pointer. No
- // frames are freed though as the caller can still access them.
- void Reset();
-
- SharedDesktopFrame* current_frame() const {
- return frames_[current_].get();
- }
-
- SharedDesktopFrame* previous_frame() const {
- return frames_[(current_ + kQueueLength - 1) % kQueueLength].get();
- }
-
- private:
- // Index of the current frame.
- int current_;
-
- static const int kQueueLength = 2;
- scoped_ptr<SharedDesktopFrame> frames_[kQueueLength];
-
- DISALLOW_COPY_AND_ASSIGN(ScreenCaptureFrameQueue);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURE_FRAME_QUEUE_H_
diff --git a/media/video/capture/screen/screen_capturer.h b/media/video/capture/screen/screen_capturer.h
deleted file mode 100644
index 5fef2a1..0000000
--- a/media/video/capture/screen/screen_capturer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_H_
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "media/base/media_export.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
-
-namespace media {
-
-struct MouseCursorShape;
-
-// Class used to capture video frames asynchronously.
-//
-// The full capture sequence is as follows:
-//
-// (1) Start
-// This is when pre-capture steps are executed, such as flagging the
-// display to prevent it from sleeping during a session.
-//
-// (2) CaptureFrame
-// This is where the bits for the invalid rects are packaged up and sent
-// to the encoder.
-// A screen capture is performed if needed. For example, Windows requires
-// a capture to calculate the diff from the previous screen, whereas the
-// Mac version does not.
-//
-// Implementation has to ensure the following guarantees:
-// 1. Double buffering
-// Since data can be read while another capture action is happening.
-class MEDIA_EXPORT ScreenCapturer
- : public NON_EXPORTED_BASE(webrtc::DesktopCapturer) {
- public:
- // Provides callbacks used by the capturer to pass captured video frames and
- // mouse cursor shapes to the processing pipeline.
- //
- // TODO(sergeyu): Move cursor shape capturing to a separate class because it's
- // unrelated.
- class MEDIA_EXPORT MouseShapeObserver {
- public:
- // Called when the cursor shape has changed.
- virtual void OnCursorShapeChanged(
- scoped_ptr<MouseCursorShape> cursor_shape) = 0;
-
- protected:
- virtual ~MouseShapeObserver() {}
- };
-
- virtual ~ScreenCapturer() {}
-
- // Creates platform-specific capturer.
- static scoped_ptr<ScreenCapturer> Create();
-
-#if defined(OS_LINUX)
- // Creates platform-specific capturer and instructs it whether it should use
- // X DAMAGE support.
- static scoped_ptr<ScreenCapturer> CreateWithXDamage(bool use_x_damage);
-#elif defined(OS_WIN)
- // Creates Windows-specific capturer and instructs it whether or not to
- // disable desktop compositing.
- static scoped_ptr<ScreenCapturer> CreateWithDisableAero(bool disable_aero);
-#endif // defined(OS_WIN)
-
- // Called at the beginning of a capturing session. |mouse_shape_observer| must
- // remain valid until the capturer is destroyed.
- virtual void SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) = 0;
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_H_
diff --git a/media/video/capture/screen/screen_capturer_fake.cc b/media/video/capture/screen/screen_capturer_fake.cc
deleted file mode 100644
index 416bcbb..0000000
--- a/media/video/capture/screen/screen_capturer_fake.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer_fake.h"
-
-#include "base/logging.h"
-#include "base/time.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-
-namespace media {
-
-// ScreenCapturerFake generates a white picture of size kWidth x kHeight
-// with a rectangle of size kBoxWidth x kBoxHeight. The rectangle moves kSpeed
-// pixels per frame along both axes, and bounces off the sides of the screen.
-static const int kWidth = ScreenCapturerFake::kWidth;
-static const int kHeight = ScreenCapturerFake::kHeight;
-static const int kBoxWidth = 140;
-static const int kBoxHeight = 140;
-static const int kSpeed = 20;
-
-COMPILE_ASSERT(kBoxWidth < kWidth && kBoxHeight < kHeight, bad_box_size);
-COMPILE_ASSERT((kBoxWidth % kSpeed == 0) && (kWidth % kSpeed == 0) &&
- (kBoxHeight % kSpeed == 0) && (kHeight % kSpeed == 0),
- sizes_must_be_multiple_of_kSpeed);
-
-ScreenCapturerFake::ScreenCapturerFake()
- : callback_(NULL),
- mouse_shape_observer_(NULL),
- bytes_per_row_(0),
- box_pos_x_(0),
- box_pos_y_(0),
- box_speed_x_(kSpeed),
- box_speed_y_(kSpeed) {
- ScreenConfigurationChanged();
-}
-
-ScreenCapturerFake::~ScreenCapturerFake() {
-}
-
-void ScreenCapturerFake::Start(Callback* callback) {
- DCHECK(!callback_);
- DCHECK(callback);
- callback_ = callback;
-}
-
-void ScreenCapturerFake::Capture(const webrtc::DesktopRegion& region) {
- base::Time capture_start_time = base::Time::Now();
-
- queue_.MoveToNextFrame();
-
- if (!queue_.current_frame()) {
- int buffer_size = size_.height() * bytes_per_row_;
- webrtc::SharedMemory* shared_memory =
- callback_->CreateSharedMemory(buffer_size);
- scoped_ptr<webrtc::DesktopFrame> frame;
- webrtc::DesktopSize frame_size(size_.width(), size_.height());
- if (shared_memory) {
- frame.reset(new webrtc::SharedMemoryDesktopFrame(
- frame_size, bytes_per_row_, shared_memory));
- } else {
- frame.reset(new webrtc::BasicDesktopFrame(frame_size));
- }
- queue_.ReplaceCurrentFrame(frame.Pass());
- }
-
- DCHECK(queue_.current_frame());
- GenerateImage();
-
- queue_.current_frame()->mutable_updated_region()->SetRect(
- webrtc::DesktopRect::MakeSize(size_));
- queue_.current_frame()->set_capture_time_ms(
- (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp());
-
- callback_->OnCaptureCompleted(queue_.current_frame()->Share());
-}
-
-void ScreenCapturerFake::SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) {
- DCHECK(!mouse_shape_observer_);
- DCHECK(mouse_shape_observer);
- mouse_shape_observer_ = mouse_shape_observer;
-}
-
-void ScreenCapturerFake::GenerateImage() {
- webrtc::DesktopFrame* frame = queue_.current_frame();
-
- const int kBytesPerPixel = webrtc::DesktopFrame::kBytesPerPixel;
-
- memset(frame->data(), 0xff,
- size_.width() * size_.height() * kBytesPerPixel);
-
- uint8* row = frame->data() +
- (box_pos_y_ * size_.width() + box_pos_x_) * kBytesPerPixel;
-
- box_pos_x_ += box_speed_x_;
- if (box_pos_x_ + kBoxWidth >= size_.width() || box_pos_x_ == 0)
- box_speed_x_ = -box_speed_x_;
-
- box_pos_y_ += box_speed_y_;
- if (box_pos_y_ + kBoxHeight >= size_.height() || box_pos_y_ == 0)
- box_speed_y_ = -box_speed_y_;
-
- // Draw rectangle with the following colors in its corners:
- // cyan....yellow
- // ..............
- // blue.......red
- for (int y = 0; y < kBoxHeight; ++y) {
- for (int x = 0; x < kBoxWidth; ++x) {
- int r = x * 255 / kBoxWidth;
- int g = y * 255 / kBoxHeight;
- int b = 255 - (x * 255 / kBoxWidth);
- row[x * kBytesPerPixel] = r;
- row[x * kBytesPerPixel + 1] = g;
- row[x * kBytesPerPixel + 2] = b;
- row[x * kBytesPerPixel + 3] = 0xff;
- }
- row += bytes_per_row_;
- }
-}
-
-void ScreenCapturerFake::ScreenConfigurationChanged() {
- size_.set(kWidth, kHeight);
- queue_.Reset();
- bytes_per_row_ = size_.width() * webrtc::DesktopFrame::kBytesPerPixel;
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_fake.h b/media/video/capture/screen/screen_capturer_fake.h
deleted file mode 100644
index de67fbd..0000000
--- a/media/video/capture/screen/screen_capturer_fake.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_FAKE_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_FAKE_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "media/base/media_export.h"
-#include "media/video/capture/screen/screen_capture_frame_queue.h"
-#include "media/video/capture/screen/screen_capturer.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-
-namespace media {
-
-// A ScreenCapturerFake generates artificial image for testing purpose.
-//
-// ScreenCapturerFake is double-buffered as required by ScreenCapturer.
-class MEDIA_EXPORT ScreenCapturerFake : public ScreenCapturer {
- public:
- // ScreenCapturerFake generates a picture of size kWidth x kHeight.
- static const int kWidth = 800;
- static const int kHeight = 600;
-
- ScreenCapturerFake();
- virtual ~ScreenCapturerFake();
-
- // webrtc::DesktopCapturer interface.
- virtual void Start(Callback* callback) OVERRIDE;
- virtual void Capture(const webrtc::DesktopRegion& rect) OVERRIDE;
-
- // ScreenCapturer interface.
- virtual void SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) OVERRIDE;
-
- private:
- // Generates an image in the front buffer.
- void GenerateImage();
-
- // Called when the screen configuration is changed.
- void ScreenConfigurationChanged();
-
- Callback* callback_;
- MouseShapeObserver* mouse_shape_observer_;
-
- webrtc::DesktopSize size_;
- int bytes_per_row_;
- int box_pos_x_;
- int box_pos_y_;
- int box_speed_x_;
- int box_speed_y_;
-
- ScreenCaptureFrameQueue queue_;
-
- DISALLOW_COPY_AND_ASSIGN(ScreenCapturerFake);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_FAKE_H_
diff --git a/media/video/capture/screen/screen_capturer_helper.cc b/media/video/capture/screen/screen_capturer_helper.cc
deleted file mode 100644
index e85cf3b..0000000
--- a/media/video/capture/screen/screen_capturer_helper.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer_helper.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace media {
-
-ScreenCapturerHelper::ScreenCapturerHelper() :
- log_grid_size_(0) {
-}
-
-ScreenCapturerHelper::~ScreenCapturerHelper() {
-}
-
-void ScreenCapturerHelper::ClearInvalidRegion() {
- base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
- invalid_region_.setEmpty();
-}
-
-void ScreenCapturerHelper::InvalidateRegion(
- const webrtc::DesktopRegion& invalid_region) {
- base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
- for (webrtc::DesktopRegion::Iterator it(invalid_region);
- !it.IsAtEnd(); it.Advance()) {
- invalid_region_.op(SkIRect::MakeLTRB(it.rect().left(), it.rect().top(),
- it.rect().right(), it.rect().bottom()),
- SkRegion::kUnion_Op);
- }
-}
-
-void ScreenCapturerHelper::InvalidateScreen(const webrtc::DesktopSize& size) {
- base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
- invalid_region_.op(SkIRect::MakeWH(size.width(), size.height()),
- SkRegion::kUnion_Op);
-}
-
-void ScreenCapturerHelper::TakeInvalidRegion(
- webrtc::DesktopRegion* invalid_region) {
- SkRegion sk_invalid_region;
- {
- base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
- sk_invalid_region.swap(invalid_region_);
- }
-
- if (log_grid_size_ > 0) {
- scoped_ptr<SkRegion> expanded_region(
- ExpandToGrid(sk_invalid_region, log_grid_size_));
- sk_invalid_region.swap(*expanded_region);
- sk_invalid_region.op(SkIRect::MakeWH(size_most_recent_.width(),
- size_most_recent_.height()),
- SkRegion::kIntersect_Op);
- }
- invalid_region->Clear();
- for (SkRegion::Iterator it(sk_invalid_region); !it.done(); it.next()) {
- invalid_region->AddRect(webrtc::DesktopRect::MakeLTRB(
- it.rect().left(), it.rect().top(),
- it.rect().right(), it.rect().bottom()));
- }
-}
-
-void ScreenCapturerHelper::SetLogGridSize(int log_grid_size) {
- log_grid_size_ = log_grid_size;
-}
-
-const webrtc::DesktopSize& ScreenCapturerHelper::size_most_recent() const {
- return size_most_recent_;
-}
-
-void ScreenCapturerHelper::set_size_most_recent(
- const webrtc::DesktopSize& size) {
- size_most_recent_ = size;
-}
-
-// Returns the largest multiple of |n| that is <= |x|.
-// |n| must be a power of 2. |nMask| is ~(|n| - 1).
-static int DownToMultiple(int x, int nMask) {
- return (x & nMask);
-}
-
-// Returns the smallest multiple of |n| that is >= |x|.
-// |n| must be a power of 2. |nMask| is ~(|n| - 1).
-static int UpToMultiple(int x, int n, int nMask) {
- return ((x + n - 1) & nMask);
-}
-
-scoped_ptr<SkRegion> ScreenCapturerHelper::ExpandToGrid(
- const SkRegion& region,
- int log_grid_size) {
- DCHECK(log_grid_size >= 1);
- int grid_size = 1 << log_grid_size;
- int grid_size_mask = ~(grid_size - 1);
- // Count the rects in the region.
- int rectNum = 0;
- SkRegion::Iterator iter(region);
- while (!iter.done()) {
- iter.next();
- ++rectNum;
- }
- // Expand each rect.
- scoped_ptr<SkIRect[]> rects(new SkIRect[rectNum]);
- iter.rewind();
- int rectI = 0;
- while (!iter.done()) {
- SkIRect rect = iter.rect();
- iter.next();
- int left = std::min(rect.left(), rect.right());
- int right = std::max(rect.left(), rect.right());
- int top = std::min(rect.top(), rect.bottom());
- int bottom = std::max(rect.top(), rect.bottom());
- left = DownToMultiple(left, grid_size_mask);
- right = UpToMultiple(right, grid_size, grid_size_mask);
- top = DownToMultiple(top, grid_size_mask);
- bottom = UpToMultiple(bottom, grid_size, grid_size_mask);
- rects[rectI++] = SkIRect::MakeLTRB(left, top, right, bottom);
- }
- // Make the union of the expanded rects.
- scoped_ptr<SkRegion> regionNew(new SkRegion());
- regionNew->setRects(rects.get(), rectNum);
- return regionNew.Pass();
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_helper.h b/media/video/capture/screen/screen_capturer_helper.h
deleted file mode 100644
index 35260b2..0000000
--- a/media/video/capture/screen/screen_capturer_helper.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_HELPER_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_HELPER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
-#include "media/base/media_export.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
-
-namespace media {
-
-// ScreenCapturerHelper is intended to be used by an implementation of the
-// ScreenCapturer interface. It maintains a thread-safe invalid region, and
-// the size of the most recently captured screen, on behalf of the
-// ScreenCapturer that owns it.
-class MEDIA_EXPORT ScreenCapturerHelper {
- public:
- ScreenCapturerHelper();
- ~ScreenCapturerHelper();
-
- // Clear out the invalid region.
- void ClearInvalidRegion();
-
- // Invalidate the specified region.
- void InvalidateRegion(const webrtc::DesktopRegion& invalid_region);
-
- // Invalidate the entire screen, of a given size.
- void InvalidateScreen(const webrtc::DesktopSize& size);
-
- // Copies current invalid region to |invalid_region| clears invalid region
- // storage for the next frame.
- void TakeInvalidRegion(webrtc::DesktopRegion* invalid_region);
-
- // Access the size of the most recently captured screen.
- const webrtc::DesktopSize& size_most_recent() const;
- void set_size_most_recent(const webrtc::DesktopSize& size);
-
- // Lossy compression can result in color values leaking between pixels in one
- // block. If part of a block changes, then unchanged parts of that block can
- // be changed in the compressed output. So we need to re-render an entire
- // block whenever part of the block changes.
- //
- // If |log_grid_size| is >= 1, then this function makes TakeInvalidRegion()
- // produce an invalid region expanded so that its vertices lie on a grid of
- // size 2 ^ |log_grid_size|. The expanded region is then clipped to the size
- // of the most recently captured screen, as previously set by
- // set_size_most_recent().
- // If |log_grid_size| is <= 0, then the invalid region is not expanded.
- void SetLogGridSize(int log_grid_size);
-
- // Expands a region so that its vertices all lie on a grid.
- // The grid size must be >= 2, so |log_grid_size| must be >= 1.
- static scoped_ptr<SkRegion> ExpandToGrid(const SkRegion& region,
- int log_grid_size);
-
- private:
- // A region that has been manually invalidated (through InvalidateRegion).
- // These will be returned as dirty_region in the capture data during the next
- // capture.
- SkRegion invalid_region_;
-
- // A lock protecting |invalid_region_| across threads.
- base::Lock invalid_region_lock_;
-
- // The size of the most recently captured screen.
- webrtc::DesktopSize size_most_recent_;
-
- // The log (base 2) of the size of the grid to which the invalid region is
- // expanded.
- // If the value is <= 0, then the invalid region is not expanded to a grid.
- int log_grid_size_;
-
- DISALLOW_COPY_AND_ASSIGN(ScreenCapturerHelper);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_HELPER_H_
diff --git a/media/video/capture/screen/screen_capturer_helper_unittest.cc b/media/video/capture/screen/screen_capturer_helper_unittest.cc
deleted file mode 100644
index 7477786..0000000
--- a/media/video/capture/screen/screen_capturer_helper_unittest.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer_helper.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using webrtc::DesktopRect;
-using webrtc::DesktopRegion;
-using webrtc::DesktopSize;
-
-namespace media {
-
-class ScreenCapturerHelperTest : public testing::Test {
- protected:
- ScreenCapturerHelper capturer_helper_;
-};
-
-bool Equals(const DesktopRegion& region1, const DesktopRegion& region2) {
- DesktopRegion::Iterator iter1(region1);
- DesktopRegion::Iterator iter2(region2);
- while (!iter1.IsAtEnd() && !iter1.IsAtEnd()) {
- if (!iter1.rect().equals(iter2.rect())) {
- return false;
- }
- iter1.Advance();
- iter2.Advance();
- }
- return iter1.IsAtEnd() && iter2.IsAtEnd();
-}
-
-bool Equals(const SkRegion& region1, const SkRegion& region2) {
- SkRegion::Iterator iter1(region1);
- SkRegion::Iterator iter2(region2);
- while (!iter1.done() && !iter2.done()) {
- if (iter1.rect() != iter2.rect()) {
- return false;
- }
- iter1.next();
- iter2.next();
- }
- return iter1.done() && iter2.done();
-}
-
-DesktopRegion RectToRegion(const DesktopRect& rect) {
- webrtc::DesktopRegion result;
- result.SetRect(rect);
- return result;
-}
-
-TEST_F(ScreenCapturerHelperTest, ClearInvalidRegion) {
- DesktopRegion region;
- region.SetRect(DesktopRect::MakeXYWH(1, 2, 3, 4));
- capturer_helper_.InvalidateRegion(region);
- capturer_helper_.ClearInvalidRegion();
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(region.is_empty());
-}
-
-TEST_F(ScreenCapturerHelperTest, InvalidateRegion) {
- DesktopRegion region;
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(region.is_empty());
-
- region.SetRect(DesktopRect::MakeXYWH(1, 2, 3, 4));
- capturer_helper_.InvalidateRegion(region);
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(1, 2, 3, 4)), region));
-
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(1, 2, 3, 4)));
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(4, 2, 3, 4)));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(1, 2, 6, 4)), region));
-}
-
-TEST_F(ScreenCapturerHelperTest, InvalidateScreen) {
- DesktopRegion region;
- capturer_helper_.InvalidateScreen(DesktopSize(12, 34));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeWH(12, 34)), region));
-}
-
-TEST_F(ScreenCapturerHelperTest, SizeMostRecent) {
- ASSERT_TRUE(capturer_helper_.size_most_recent().is_empty());
- capturer_helper_.set_size_most_recent(DesktopSize(12, 34));
- ASSERT_TRUE(
- DesktopSize(12, 34).equals(capturer_helper_.size_most_recent()));
-}
-
-TEST_F(ScreenCapturerHelperTest, SetLogGridSize) {
- capturer_helper_.set_size_most_recent(DesktopSize(10, 10));
-
- DesktopRegion region;
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect()), region));
-
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)), region));
-
- capturer_helper_.SetLogGridSize(-1);
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)), region));
-
- capturer_helper_.SetLogGridSize(0);
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)), region));
-
- capturer_helper_.SetLogGridSize(1);
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(6, 6, 2, 2)), region));
-
- capturer_helper_.SetLogGridSize(2);
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(4, 4, 4, 4)), region));
-
- capturer_helper_.SetLogGridSize(0);
- capturer_helper_.InvalidateRegion(
- RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
- capturer_helper_.TakeInvalidRegion(&region);
- ASSERT_TRUE(Equals(RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)), region));
-}
-
-void TestExpandRegionToGrid(const SkRegion& region, int log_grid_size,
- const SkRegion& expandedRegionExpected) {
- scoped_ptr<SkRegion> expandedRegion1(
- ScreenCapturerHelper::ExpandToGrid(region, log_grid_size));
- ASSERT_TRUE(Equals(expandedRegionExpected, *expandedRegion1));
- scoped_ptr<SkRegion> expandedRegion2(
- ScreenCapturerHelper::ExpandToGrid(*expandedRegion1, log_grid_size));
- ASSERT_TRUE(Equals(*expandedRegion1, *expandedRegion2));
-}
-
-void TestExpandRectToGrid(int l, int t, int r, int b, int log_grid_size,
- int lExpanded, int tExpanded,
- int rExpanded, int bExpanded) {
- TestExpandRegionToGrid(SkRegion(SkIRect::MakeLTRB(l, t, r, b)), log_grid_size,
- SkRegion(SkIRect::MakeLTRB(lExpanded, tExpanded,
- rExpanded, bExpanded)));
-}
-
-TEST_F(ScreenCapturerHelperTest, ExpandToGrid) {
- const int LOG_GRID_SIZE = 4;
- const int GRID_SIZE = 1 << LOG_GRID_SIZE;
- for (int i = -2; i <= 2; i++) {
- int x = i * GRID_SIZE;
- for (int j = -2; j <= 2; j++) {
- int y = j * GRID_SIZE;
- TestExpandRectToGrid(x + 0, y + 0, x + 1, y + 1, LOG_GRID_SIZE,
- x + 0, y + 0, x + GRID_SIZE, y + GRID_SIZE);
- TestExpandRectToGrid(x + 0, y + GRID_SIZE - 1, x + 1, y + GRID_SIZE,
- LOG_GRID_SIZE,
- x + 0, y + 0, x + GRID_SIZE, y + GRID_SIZE);
- TestExpandRectToGrid(x + GRID_SIZE - 1, y + GRID_SIZE - 1,
- x + GRID_SIZE, y + GRID_SIZE, LOG_GRID_SIZE,
- x + 0, y + 0, x + GRID_SIZE, y + GRID_SIZE);
- TestExpandRectToGrid(x + GRID_SIZE - 1, y + 0,
- x + GRID_SIZE, y + 1, LOG_GRID_SIZE,
- x + 0, y + 0, x + GRID_SIZE, y + GRID_SIZE);
- TestExpandRectToGrid(x - 1, y + 0, x + 1, y + 1, LOG_GRID_SIZE,
- x - GRID_SIZE, y + 0, x + GRID_SIZE, y + GRID_SIZE);
- TestExpandRectToGrid(x - 1, y - 1, x + 1, y + 0, LOG_GRID_SIZE,
- x - GRID_SIZE, y - GRID_SIZE, x + GRID_SIZE, y);
- TestExpandRectToGrid(x + 0, y - 1, x + 1, y + 1, LOG_GRID_SIZE,
- x, y - GRID_SIZE, x + GRID_SIZE, y + GRID_SIZE);
- TestExpandRectToGrid(x - 1, y - 1, x + 0, y + 1, LOG_GRID_SIZE,
- x - GRID_SIZE, y - GRID_SIZE, x, y + GRID_SIZE);
-
- SkRegion region(SkIRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1));
- region.op(SkIRect::MakeLTRB(x - 1, y - 1, x + 0, y + 0),
- SkRegion::kDifference_Op);
- SkRegion expandedRegionExpected(SkIRect::MakeLTRB(
- x - GRID_SIZE, y - GRID_SIZE, x + GRID_SIZE, y + GRID_SIZE));
- expandedRegionExpected.op(
- SkIRect::MakeLTRB(x - GRID_SIZE, y - GRID_SIZE, x + 0, y + 0),
- SkRegion::kDifference_Op);
- TestExpandRegionToGrid(region, LOG_GRID_SIZE, expandedRegionExpected);
-
- region.setRect(SkIRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1));
- region.op(SkIRect::MakeLTRB(x - 1, y + 0, x + 0, y + 1),
- SkRegion::kDifference_Op);
- expandedRegionExpected.setRect(SkIRect::MakeLTRB(
- x - GRID_SIZE, y - GRID_SIZE, x + GRID_SIZE, y + GRID_SIZE));
- expandedRegionExpected.op(
- SkIRect::MakeLTRB(x - GRID_SIZE, y + 0, x + 0, y + GRID_SIZE),
- SkRegion::kDifference_Op);
- TestExpandRegionToGrid(region, LOG_GRID_SIZE, expandedRegionExpected);
-
- region.setRect(SkIRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1));
- region.op(SkIRect::MakeLTRB(x + 0, y + 0, x + 1, y + 1),
- SkRegion::kDifference_Op);
- expandedRegionExpected.setRect(SkIRect::MakeLTRB(
- x - GRID_SIZE, y - GRID_SIZE, x + GRID_SIZE, y + GRID_SIZE));
- expandedRegionExpected.op(
- SkIRect::MakeLTRB(x + 0, y + 0, x + GRID_SIZE, y + GRID_SIZE),
- SkRegion::kDifference_Op);
- TestExpandRegionToGrid(region, LOG_GRID_SIZE, expandedRegionExpected);
-
- region.setRect(SkIRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1));
- region.op(SkIRect::MakeLTRB(x + 0, y - 1, x + 1, y + 0),
- SkRegion::kDifference_Op);
- expandedRegionExpected.setRect(SkIRect::MakeLTRB(
- x - GRID_SIZE, y - GRID_SIZE, x + GRID_SIZE, y + GRID_SIZE));
- expandedRegionExpected.op(
- SkIRect::MakeLTRB(x + 0, y - GRID_SIZE, x + GRID_SIZE, y + 0),
- SkRegion::kDifference_Op);
- TestExpandRegionToGrid(region, LOG_GRID_SIZE, expandedRegionExpected);
- }
- }
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_mac.mm b/media/video/capture/screen/screen_capturer_mac.mm
deleted file mode 100644
index 158775a..0000000
--- a/media/video/capture/screen/screen_capturer_mac.mm
+++ /dev/null
@@ -1,859 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer.h"
-
-#include <ApplicationServices/ApplicationServices.h>
-#include <Cocoa/Cocoa.h>
-#include <dlfcn.h>
-#include <IOKit/pwr_mgt/IOPMLib.h>
-#include <OpenGL/CGLMacro.h>
-#include <OpenGL/OpenGL.h>
-#include <sys/utsname.h>
-#include <stddef.h>
-#include <set>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/waitable_event.h"
-#include "media/video/capture/screen/mac/desktop_configuration.h"
-#include "media/video/capture/screen/mac/scoped_pixel_buffer_object.h"
-#include "media/video/capture/screen/mouse_cursor_shape.h"
-#include "media/video/capture/screen/screen_capture_frame_queue.h"
-#include "media/video/capture/screen/screen_capturer_helper.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
-
-namespace media {
-
-namespace {
-
-// Definitions used to dynamic-link to deprecated OS 10.6 functions.
-const char* kApplicationServicesLibraryName =
- "/System/Library/Frameworks/ApplicationServices.framework/"
- "ApplicationServices";
-typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID);
-typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID);
-typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID);
-const char* kOpenGlLibraryName =
- "/System/Library/Frameworks/OpenGL.framework/OpenGL";
-typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj);
-
-// Standard Mac displays have 72dpi, but we report 96dpi for
-// consistency with Windows and Linux.
-const int kStandardDPI = 96;
-
-// Scales all coordinates of a rect by a specified factor.
-webrtc::DesktopRect ScaleAndRoundCGRect(const CGRect& rect, float scale) {
- return webrtc::DesktopRect::MakeLTRB(
- static_cast<int>(floor(rect.origin.x * scale)),
- static_cast<int>(floor(rect.origin.y * scale)),
- static_cast<int>(ceil((rect.origin.x + rect.size.width) * scale)),
- static_cast<int>(ceil((rect.origin.y + rect.size.height) * scale)));
-}
-
-// Copy pixels in the |rect| from |src_place| to |dest_plane|.
-void CopyRect(const uint8* src_plane,
- int src_plane_stride,
- uint8* dest_plane,
- int dest_plane_stride,
- int bytes_per_pixel,
- const webrtc::DesktopRect& rect) {
- // Get the address of the starting point.
- const int src_y_offset = src_plane_stride * rect.top();
- const int dest_y_offset = dest_plane_stride * rect.top();
- const int x_offset = bytes_per_pixel * rect.left();
- src_plane += src_y_offset + x_offset;
- dest_plane += dest_y_offset + x_offset;
-
- // Copy pixels in the rectangle line by line.
- const int bytes_per_line = bytes_per_pixel * rect.width();
- const int height = rect.height();
- for (int i = 0 ; i < height; ++i) {
- memcpy(dest_plane, src_plane, bytes_per_line);
- src_plane += src_plane_stride;
- dest_plane += dest_plane_stride;
- }
-}
-
-int GetDarwinVersion() {
- struct utsname uname_info;
- if (uname(&uname_info) != 0) {
- LOG(ERROR) << "uname failed";
- return 0;
- }
-
- if (strcmp(uname_info.sysname, "Darwin") != 0)
- return 0;
-
- char* dot;
- int result = strtol(uname_info.release, &dot, 10);
- if (*dot != '.') {
- LOG(ERROR) << "Failed to parse version";
- return 0;
- }
-
- return result;
-}
-
-bool IsOSLionOrLater() {
- static int darwin_version = GetDarwinVersion();
-
- // Verify that the version has been parsed correctly.
- CHECK(darwin_version >= 6);
-
- // Darwin major version 11 corresponds to OSX 10.7.
- return darwin_version >= 11;
-}
-
-// The amount of time allowed for displays to reconfigure.
-const int64 kDisplayConfigurationEventTimeoutInSeconds = 10;
-
-// A class to perform video frame capturing for mac.
-class ScreenCapturerMac : public ScreenCapturer {
- public:
- ScreenCapturerMac();
- virtual ~ScreenCapturerMac();
-
- bool Init();
-
- // Overridden from ScreenCapturer:
- virtual void Start(Callback* callback) OVERRIDE;
- virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE;
- virtual void SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) OVERRIDE;
-
- private:
- void CaptureCursor();
-
- void GlBlitFast(const webrtc::DesktopFrame& frame,
- const webrtc::DesktopRegion& region);
- void GlBlitSlow(const webrtc::DesktopFrame& frame);
- void CgBlitPreLion(const webrtc::DesktopFrame& frame,
- const webrtc::DesktopRegion& region);
- void CgBlitPostLion(const webrtc::DesktopFrame& frame,
- const webrtc::DesktopRegion& region);
-
- // Called when the screen configuration is changed.
- void ScreenConfigurationChanged();
-
- bool RegisterRefreshAndMoveHandlers();
- void UnregisterRefreshAndMoveHandlers();
-
- void ScreenRefresh(CGRectCount count, const CGRect *rect_array);
- void ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
- size_t count,
- const CGRect *rect_array);
- void DisplaysReconfigured(CGDirectDisplayID display,
- CGDisplayChangeSummaryFlags flags);
- static void ScreenRefreshCallback(CGRectCount count,
- const CGRect *rect_array,
- void *user_parameter);
- static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta,
- size_t count,
- const CGRect *rect_array,
- void *user_parameter);
- static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
- CGDisplayChangeSummaryFlags flags,
- void *user_parameter);
-
- void ReleaseBuffers();
-
- Callback* callback_;
- MouseShapeObserver* mouse_shape_observer_;
-
- CGLContextObj cgl_context_;
- ScopedPixelBufferObject pixel_buffer_object_;
-
- // Queue of the frames buffers.
- ScreenCaptureFrameQueue queue_;
-
- // Current display configuration.
- MacDesktopConfiguration desktop_config_;
-
- // A thread-safe list of invalid rectangles, and the size of the most
- // recently captured screen.
- ScreenCapturerHelper helper_;
-
- // The last cursor that we sent to the client.
- MouseCursorShape last_cursor_;
-
- // Contains an invalid region from the previous capture.
- webrtc::DesktopRegion last_invalid_region_;
-
- // Used to ensure that frame captures do not take place while displays
- // are being reconfigured.
- base::WaitableEvent display_configuration_capture_event_;
-
- // Records the Ids of attached displays which are being reconfigured.
- // Accessed on the thread on which we are notified of display events.
- std::set<CGDirectDisplayID> reconfiguring_displays_;
-
- // Power management assertion to prevent the screen from sleeping.
- IOPMAssertionID power_assertion_id_display_;
-
- // Power management assertion to indicate that the user is active.
- IOPMAssertionID power_assertion_id_user_;
-
- // Dynamically link to deprecated APIs for Mac OS X 10.6 support.
- void* app_services_library_;
- CGDisplayBaseAddressFunc cg_display_base_address_;
- CGDisplayBytesPerRowFunc cg_display_bytes_per_row_;
- CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_;
- void* opengl_library_;
- CGLSetFullScreenFunc cgl_set_full_screen_;
-
- DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac);
-};
-
-scoped_ptr<webrtc::DesktopFrame> CreateFrame(
- const MacDesktopConfiguration& desktop_config) {
-
- webrtc::DesktopSize size(desktop_config.pixel_bounds.width(),
- desktop_config.pixel_bounds.height());
- scoped_ptr<webrtc::DesktopFrame> frame(new webrtc::BasicDesktopFrame(size));
-
- frame->set_dpi(webrtc::DesktopVector(
- kStandardDPI * desktop_config.dip_to_pixel_scale,
- kStandardDPI * desktop_config.dip_to_pixel_scale));
- return frame.Pass();
-}
-
-ScreenCapturerMac::ScreenCapturerMac()
- : callback_(NULL),
- mouse_shape_observer_(NULL),
- cgl_context_(NULL),
- display_configuration_capture_event_(false, true),
- power_assertion_id_display_(kIOPMNullAssertionID),
- power_assertion_id_user_(kIOPMNullAssertionID),
- app_services_library_(NULL),
- cg_display_base_address_(NULL),
- cg_display_bytes_per_row_(NULL),
- cg_display_bits_per_pixel_(NULL),
- opengl_library_(NULL),
- cgl_set_full_screen_(NULL) {
-}
-
-ScreenCapturerMac::~ScreenCapturerMac() {
- if (power_assertion_id_display_ != kIOPMNullAssertionID) {
- IOPMAssertionRelease(power_assertion_id_display_);
- power_assertion_id_display_ = kIOPMNullAssertionID;
- }
- if (power_assertion_id_user_ != kIOPMNullAssertionID) {
- IOPMAssertionRelease(power_assertion_id_user_);
- power_assertion_id_user_ = kIOPMNullAssertionID;
- }
-
- ReleaseBuffers();
- UnregisterRefreshAndMoveHandlers();
- CGError err = CGDisplayRemoveReconfigurationCallback(
- ScreenCapturerMac::DisplaysReconfiguredCallback, this);
- if (err != kCGErrorSuccess)
- LOG(ERROR) << "CGDisplayRemoveReconfigurationCallback " << err;
-
- dlclose(app_services_library_);
- dlclose(opengl_library_);
-}
-
-bool ScreenCapturerMac::Init() {
- if (!RegisterRefreshAndMoveHandlers()) {
- return false;
- }
-
- CGError err = CGDisplayRegisterReconfigurationCallback(
- ScreenCapturerMac::DisplaysReconfiguredCallback, this);
- if (err != kCGErrorSuccess) {
- LOG(ERROR) << "CGDisplayRegisterReconfigurationCallback " << err;
- return false;
- }
-
- ScreenConfigurationChanged();
- return true;
-}
-
-void ScreenCapturerMac::ReleaseBuffers() {
- if (cgl_context_) {
- pixel_buffer_object_.Release();
- CGLDestroyContext(cgl_context_);
- cgl_context_ = NULL;
- }
- // The buffers might be in use by the encoder, so don't delete them here.
- // Instead, mark them as "needs update"; next time the buffers are used by
- // the capturer, they will be recreated if necessary.
- queue_.Reset();
-}
-
-void ScreenCapturerMac::Start(Callback* callback) {
- DCHECK(!callback_);
- DCHECK(callback);
-
- callback_ = callback;
-
- // Create power management assertions to wake the display and prevent it from
- // going to sleep on user idle.
- // TODO(jamiewalch): Use IOPMAssertionDeclareUserActivity on 10.7.3 and above
- // instead of the following two assertions.
- IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
- kIOPMAssertionLevelOn,
- CFSTR("Chrome Remote Desktop connection active"),
- &power_assertion_id_display_);
- // This assertion ensures that the display is woken up if it already asleep
- // (as used by Apple Remote Desktop).
- IOPMAssertionCreateWithName(CFSTR("UserIsActive"),
- kIOPMAssertionLevelOn,
- CFSTR("Chrome Remote Desktop connection active"),
- &power_assertion_id_user_);
-}
-
-void ScreenCapturerMac::Capture(
- const webrtc::DesktopRegion& region_to_capture) {
- base::Time capture_start_time = base::Time::Now();
-
- queue_.MoveToNextFrame();
-
- // Wait until the display configuration is stable. If one or more displays
- // are reconfiguring then |display_configuration_capture_event_| will not be
- // set until the reconfiguration completes.
- // TODO(wez): Replace this with an early-exit (See crbug.com/104542).
- CHECK(display_configuration_capture_event_.TimedWait(
- base::TimeDelta::FromSeconds(
- kDisplayConfigurationEventTimeoutInSeconds)));
-
- webrtc::DesktopRegion region;
- helper_.TakeInvalidRegion(&region);
-
- // If the current buffer is from an older generation then allocate a new one.
- // Note that we can't reallocate other buffers at this point, since the caller
- // may still be reading from them.
- if (!queue_.current_frame())
- queue_.ReplaceCurrentFrame(CreateFrame(desktop_config_));
-
- webrtc::DesktopFrame* current_frame = queue_.current_frame();
-
- bool flip = false; // GL capturers need flipping.
- if (IsOSLionOrLater()) {
- // Lion requires us to use their new APIs for doing screen capture. These
- // APIS currently crash on 10.6.8 if there is no monitor attached.
- CgBlitPostLion(*current_frame, region);
- } else if (cgl_context_) {
- flip = true;
- if (pixel_buffer_object_.get() != 0) {
- GlBlitFast(*current_frame, region);
- } else {
- // See comment in ScopedPixelBufferObject::Init about why the slow
- // path is always used on 10.5.
- GlBlitSlow(*current_frame);
- }
- } else {
- CgBlitPreLion(*current_frame, region);
- }
-
- uint8* buffer = current_frame->data();
- int stride = current_frame->stride();
- if (flip) {
- stride = -stride;
- buffer += (current_frame->size().height() - 1) * current_frame->stride();
- }
-
- webrtc::DesktopFrame* new_frame = queue_.current_frame()->Share();
- *new_frame->mutable_updated_region() = region;
-
- helper_.set_size_most_recent(new_frame->size());
-
- // Signal that we are done capturing data from the display framebuffer,
- // and accessing display structures.
- display_configuration_capture_event_.Signal();
-
- // Capture the current cursor shape and notify |callback_| if it has changed.
- CaptureCursor();
-
- new_frame->set_capture_time_ms(
- (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp());
- callback_->OnCaptureCompleted(new_frame);
-}
-
-void ScreenCapturerMac::SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) {
- DCHECK(!mouse_shape_observer_);
- DCHECK(mouse_shape_observer);
- mouse_shape_observer_ = mouse_shape_observer;
-}
-
-void ScreenCapturerMac::CaptureCursor() {
- if (!mouse_shape_observer_)
- return;
-
- NSCursor* cursor = [NSCursor currentSystemCursor];
- if (cursor == nil)
- return;
-
- NSImage* nsimage = [cursor image];
- NSPoint hotspot = [cursor hotSpot];
- NSSize size = [nsimage size];
- CGImageRef image = [nsimage CGImageForProposedRect:NULL
- context:nil
- hints:nil];
- if (image == nil)
- return;
-
- if (CGImageGetBitsPerPixel(image) != 32 ||
- CGImageGetBytesPerRow(image) != (size.width * 4) ||
- CGImageGetBitsPerComponent(image) != 8) {
- return;
- }
-
- CGDataProviderRef provider = CGImageGetDataProvider(image);
- CFDataRef image_data_ref = CGDataProviderCopyData(provider);
- if (image_data_ref == NULL)
- return;
-
- const char* cursor_src_data =
- reinterpret_cast<const char*>(CFDataGetBytePtr(image_data_ref));
- int data_size = CFDataGetLength(image_data_ref);
-
- // Create a MouseCursorShape that describes the cursor and pass it to
- // the client.
- scoped_ptr<MouseCursorShape> cursor_shape(new MouseCursorShape());
- cursor_shape->size.set(size.width, size.height);
- cursor_shape->hotspot.set(hotspot.x, hotspot.y);
- cursor_shape->data.assign(cursor_src_data, cursor_src_data + data_size);
-
- CFRelease(image_data_ref);
-
- // Compare the current cursor with the last one we sent to the client. If
- // they're the same, then don't bother sending the cursor again.
- if (last_cursor_.size.equals(cursor_shape->size) &&
- last_cursor_.hotspot.equals(cursor_shape->hotspot) &&
- last_cursor_.data == cursor_shape->data) {
- return;
- }
-
- // Record the last cursor image that we sent to the client.
- last_cursor_ = *cursor_shape;
-
- VLOG(3) << "Sending cursor: " << size.width << "x" << size.height;
- mouse_shape_observer_->OnCursorShapeChanged(cursor_shape.Pass());
-}
-
-void ScreenCapturerMac::GlBlitFast(const webrtc::DesktopFrame& frame,
- const webrtc::DesktopRegion& region) {
- // Clip to the size of our current screen.
- webrtc::DesktopRect clip_rect = webrtc::DesktopRect::MakeSize(frame.size());
- if (queue_.previous_frame()) {
- // We are doing double buffer for the capture data so we just need to copy
- // the invalid region from the previous capture in the current buffer.
- // TODO(hclam): We can reduce the amount of copying here by subtracting
- // |capturer_helper_|s region from |last_invalid_region_|.
- // http://crbug.com/92354
-
- // Since the image obtained from OpenGL is upside-down, need to do some
- // magic here to copy the correct rectangle.
- const int y_offset = (frame.size().width() - 1) * frame.stride();
- for (webrtc::DesktopRegion::Iterator i(last_invalid_region_);
- !i.IsAtEnd(); i.Advance()) {
- webrtc::DesktopRect copy_rect = i.rect();
- copy_rect.IntersectWith(clip_rect);
- if (!copy_rect.is_empty()) {
- CopyRect(queue_.previous_frame()->data() + y_offset,
- -frame.stride(),
- frame.data() + y_offset,
- -frame.stride(),
- webrtc::DesktopFrame::kBytesPerPixel,
- copy_rect);
- }
- }
- }
- last_invalid_region_ = region;
-
- CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
- glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_.get());
- glReadPixels(0, 0, frame.size().height(), frame.size().width(), GL_BGRA,
- GL_UNSIGNED_BYTE, 0);
- GLubyte* ptr = static_cast<GLubyte*>(
- glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB));
- if (ptr == NULL) {
- // If the buffer can't be mapped, assume that it's no longer valid and
- // release it.
- pixel_buffer_object_.Release();
- } else {
- // Copy only from the dirty rects. Since the image obtained from OpenGL is
- // upside-down we need to do some magic here to copy the correct rectangle.
- const int y_offset = (frame.size().height() - 1) * frame.stride();
- for (webrtc::DesktopRegion::Iterator i(region);
- !i.IsAtEnd(); i.Advance()) {
- webrtc::DesktopRect copy_rect = i.rect();
- copy_rect.IntersectWith(clip_rect);
- if (!copy_rect.is_empty()) {
- CopyRect(ptr + y_offset,
- -frame.stride(),
- frame.data() + y_offset,
- -frame.stride(),
- webrtc::DesktopFrame::kBytesPerPixel,
- copy_rect);
- }
- }
- }
- if (!glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB)) {
- // If glUnmapBuffer returns false, then the contents of the data store are
- // undefined. This might be because the screen mode has changed, in which
- // case it will be recreated in ScreenConfigurationChanged, but releasing
- // the object here is the best option. Capturing will fall back on
- // GlBlitSlow until such time as the pixel buffer object is recreated.
- pixel_buffer_object_.Release();
- }
- glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
-}
-
-void ScreenCapturerMac::GlBlitSlow(const webrtc::DesktopFrame& frame) {
- CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
- glReadBuffer(GL_FRONT);
- glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
- glPixelStorei(GL_PACK_ALIGNMENT, 4); // Force 4-byte alignment.
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_SKIP_ROWS, 0);
- glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
- // Read a block of pixels from the frame buffer.
- glReadPixels(0, 0, frame.size().width(), frame.size().height(),
- GL_BGRA, GL_UNSIGNED_BYTE, frame.data());
- glPopClientAttrib();
-}
-
-void ScreenCapturerMac::CgBlitPreLion(const webrtc::DesktopFrame& frame,
- const webrtc::DesktopRegion& region) {
- // Copy the entire contents of the previous capture buffer, to capture over.
- // TODO(wez): Get rid of this as per crbug.com/145064, or implement
- // crbug.com/92354.
- if (queue_.previous_frame()) {
- memcpy(frame.data(),
- queue_.previous_frame()->data(),
- frame.stride() * frame.size().height());
- }
-
- for (size_t i = 0; i < desktop_config_.displays.size(); ++i) {
- const MacDisplayConfiguration& display_config = desktop_config_.displays[i];
-
- // Use deprecated APIs to determine the display buffer layout.
- DCHECK(cg_display_base_address_ && cg_display_bytes_per_row_ &&
- cg_display_bits_per_pixel_);
- uint8* display_base_address =
- reinterpret_cast<uint8*>((*cg_display_base_address_)(display_config.id));
- CHECK(display_base_address);
- int src_bytes_per_row = (*cg_display_bytes_per_row_)(display_config.id);
- int src_bytes_per_pixel =
- (*cg_display_bits_per_pixel_)(display_config.id) / 8;
-
- // Determine the display's position relative to the desktop, in pixels.
- webrtc::DesktopRect display_bounds = display_config.pixel_bounds;
- display_bounds.Translate(-desktop_config_.pixel_bounds.left(),
- -desktop_config_.pixel_bounds.top());
-
- // Determine which parts of the blit region, if any, lay within the monitor.
- webrtc::DesktopRegion copy_region = region;
- copy_region.IntersectWith(display_bounds);
- if (copy_region.is_empty())
- continue;
-
- // Translate the region to be copied into display-relative coordinates.
- copy_region.Translate(-display_bounds.left(), -display_bounds.top());
-
- // Calculate where in the output buffer the display's origin is.
- uint8* out_ptr = frame.data() +
- (display_bounds.left() * src_bytes_per_pixel) +
- (display_bounds.top() * frame.stride());
-
- // Copy the dirty region from the display buffer into our desktop buffer.
- for (webrtc::DesktopRegion::Iterator i(copy_region);
- !i.IsAtEnd(); i.Advance()) {
- CopyRect(display_base_address,
- src_bytes_per_row,
- out_ptr,
- frame.stride(),
- src_bytes_per_pixel,
- i.rect());
- }
- }
-}
-
-void ScreenCapturerMac::CgBlitPostLion(const webrtc::DesktopFrame& frame,
- const webrtc::DesktopRegion& region) {
- // Copy the entire contents of the previous capture buffer, to capture over.
- // TODO(wez): Get rid of this as per crbug.com/145064, or implement
- // crbug.com/92354.
- if (queue_.previous_frame()) {
- memcpy(frame.data(),
- queue_.previous_frame()->data(),
- frame.stride() * frame.size().height());
- }
-
- for (size_t i = 0; i < desktop_config_.displays.size(); ++i) {
- const MacDisplayConfiguration& display_config = desktop_config_.displays[i];
-
- // Determine the display's position relative to the desktop, in pixels.
- webrtc::DesktopRect display_bounds = display_config.pixel_bounds;
- display_bounds.Translate(-desktop_config_.pixel_bounds.left(),
- -desktop_config_.pixel_bounds.top());
-
- // Determine which parts of the blit region, if any, lay within the monitor.
- webrtc::DesktopRegion copy_region = region;
- copy_region.IntersectWith(display_bounds);
- if (copy_region.is_empty())
- continue;
-
- // Translate the region to be copied into display-relative coordinates.
- copy_region.Translate(-display_bounds.left(), -display_bounds.top());
-
- // Create an image containing a snapshot of the display.
- CGImageRef image = CGDisplayCreateImage(display_config.id);
- if (image == NULL)
- continue;
-
- // Request access to the raw pixel data via the image's DataProvider.
- CGDataProviderRef provider = CGImageGetDataProvider(image);
- CFDataRef data = CGDataProviderCopyData(provider);
- CHECK(data);
-
- const uint8* display_base_address = CFDataGetBytePtr(data);
- int src_bytes_per_row = CGImageGetBytesPerRow(image);
- int src_bytes_per_pixel = CGImageGetBitsPerPixel(image) / 8;
-
- // Calculate where in the output buffer the display's origin is.
- uint8* out_ptr = frame.data() +
- (display_bounds.left() * src_bytes_per_pixel) +
- (display_bounds.top() * frame.stride());
-
- // Copy the dirty region from the display buffer into our desktop buffer.
- for (webrtc::DesktopRegion::Iterator i(copy_region);
- !i.IsAtEnd(); i.Advance()) {
- CopyRect(display_base_address,
- src_bytes_per_row,
- out_ptr,
- frame.stride(),
- src_bytes_per_pixel,
- i.rect());
- }
-
- CFRelease(data);
- CFRelease(image);
- }
-}
-
-void ScreenCapturerMac::ScreenConfigurationChanged() {
- // Release existing buffers, which will be of the wrong size.
- ReleaseBuffers();
-
- // Clear the dirty region, in case the display is down-sizing.
- helper_.ClearInvalidRegion();
-
- // Refresh the cached desktop configuration.
- desktop_config_ = MacDesktopConfiguration::GetCurrent(
- MacDesktopConfiguration::TopLeftOrigin);
-
- // Re-mark the entire desktop as dirty.
- helper_.InvalidateScreen(
- webrtc::DesktopSize(desktop_config_.pixel_bounds.width(),
- desktop_config_.pixel_bounds.height()));
-
- // Make sure the frame buffers will be reallocated.
- queue_.Reset();
-
- // CgBlitPostLion uses CGDisplayCreateImage() to snapshot each display's
- // contents. Although the API exists in OS 10.6, it crashes the caller if
- // the machine has no monitor connected, so we fall back to depcreated APIs
- // when running on 10.6.
- if (IsOSLionOrLater()) {
- LOG(INFO) << "Using CgBlitPostLion.";
- // No need for any OpenGL support on Lion
- return;
- }
-
- // Dynamically link to the deprecated pre-Lion capture APIs.
- app_services_library_ = dlopen(kApplicationServicesLibraryName,
- RTLD_LAZY);
- CHECK(app_services_library_)
- << "Failed to open " << kApplicationServicesLibraryName;
-
- opengl_library_ = dlopen(kOpenGlLibraryName, RTLD_LAZY);
- CHECK(opengl_library_) << "Failed to open " << kOpenGlLibraryName;
-
- cg_display_base_address_ = reinterpret_cast<CGDisplayBaseAddressFunc>(
- dlsym(app_services_library_, "CGDisplayBaseAddress"));
- cg_display_bytes_per_row_ = reinterpret_cast<CGDisplayBytesPerRowFunc>(
- dlsym(app_services_library_, "CGDisplayBytesPerRow"));
- cg_display_bits_per_pixel_ = reinterpret_cast<CGDisplayBitsPerPixelFunc>(
- dlsym(app_services_library_, "CGDisplayBitsPerPixel"));
- cgl_set_full_screen_ = reinterpret_cast<CGLSetFullScreenFunc>(
- dlsym(opengl_library_, "CGLSetFullScreen"));
- CHECK(cg_display_base_address_ && cg_display_bytes_per_row_ &&
- cg_display_bits_per_pixel_ && cgl_set_full_screen_);
-
- if (desktop_config_.displays.size() > 1) {
- LOG(INFO) << "Using CgBlitPreLion (Multi-monitor).";
- return;
- }
-
- CGDirectDisplayID mainDevice = CGMainDisplayID();
- if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) {
- LOG(INFO) << "Using CgBlitPreLion (OpenGL unavailable).";
- return;
- }
-
- LOG(INFO) << "Using GlBlit";
-
- CGLPixelFormatAttribute attributes[] = {
- kCGLPFAFullScreen,
- kCGLPFADisplayMask,
- (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice),
- (CGLPixelFormatAttribute)0
- };
- CGLPixelFormatObj pixel_format = NULL;
- GLint matching_pixel_format_count = 0;
- CGLError err = CGLChoosePixelFormat(attributes,
- &pixel_format,
- &matching_pixel_format_count);
- DCHECK_EQ(err, kCGLNoError);
- err = CGLCreateContext(pixel_format, NULL, &cgl_context_);
- DCHECK_EQ(err, kCGLNoError);
- CGLDestroyPixelFormat(pixel_format);
- (*cgl_set_full_screen_)(cgl_context_);
- CGLSetCurrentContext(cgl_context_);
-
- size_t buffer_size = desktop_config_.pixel_bounds.width() *
- desktop_config_.pixel_bounds.height() *
- sizeof(uint32_t);
- pixel_buffer_object_.Init(cgl_context_, buffer_size);
-}
-
-bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() {
- CGError err = CGRegisterScreenRefreshCallback(
- ScreenCapturerMac::ScreenRefreshCallback, this);
- if (err != kCGErrorSuccess) {
- LOG(ERROR) << "CGRegisterScreenRefreshCallback " << err;
- return false;
- }
-
- err = CGScreenRegisterMoveCallback(
- ScreenCapturerMac::ScreenUpdateMoveCallback, this);
- if (err != kCGErrorSuccess) {
- LOG(ERROR) << "CGScreenRegisterMoveCallback " << err;
- return false;
- }
-
- return true;
-}
-
-void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() {
- CGUnregisterScreenRefreshCallback(
- ScreenCapturerMac::ScreenRefreshCallback, this);
- CGScreenUnregisterMoveCallback(
- ScreenCapturerMac::ScreenUpdateMoveCallback, this);
-}
-
-void ScreenCapturerMac::ScreenRefresh(CGRectCount count,
- const CGRect* rect_array) {
- if (desktop_config_.pixel_bounds.is_empty())
- return;
-
- webrtc::DesktopRegion region;
-
- for (CGRectCount i = 0; i < count; ++i) {
- // Convert from Density-Independent Pixel to physical pixel coordinates.
- webrtc::DesktopRect rect =
- ScaleAndRoundCGRect(rect_array[i], desktop_config_.dip_to_pixel_scale);
-
- // Translate from local desktop to capturer framebuffer coordinates.
- rect.Translate(-desktop_config_.pixel_bounds.left(),
- -desktop_config_.pixel_bounds.top());
-
- region.AddRect(rect);
- }
-
- helper_.InvalidateRegion(region);
-}
-
-void ScreenCapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
- size_t count,
- const CGRect* rect_array) {
- // Translate |rect_array| to identify the move's destination.
- CGRect refresh_rects[count];
- for (CGRectCount i = 0; i < count; ++i) {
- refresh_rects[i] = CGRectOffset(rect_array[i], delta.dX, delta.dY);
- }
-
- // Currently we just treat move events the same as refreshes.
- ScreenRefresh(count, refresh_rects);
-}
-
-void ScreenCapturerMac::DisplaysReconfigured(
- CGDirectDisplayID display,
- CGDisplayChangeSummaryFlags flags) {
- if (flags & kCGDisplayBeginConfigurationFlag) {
- if (reconfiguring_displays_.empty()) {
- // If this is the first display to start reconfiguring then wait on
- // |display_configuration_capture_event_| to block the capture thread
- // from accessing display memory until the reconfiguration completes.
- CHECK(display_configuration_capture_event_.TimedWait(
- base::TimeDelta::FromSeconds(
- kDisplayConfigurationEventTimeoutInSeconds)));
- }
-
- reconfiguring_displays_.insert(display);
- } else {
- reconfiguring_displays_.erase(display);
-
- if (reconfiguring_displays_.empty()) {
- // If no other displays are reconfiguring then refresh capturer data
- // structures and un-block the capturer thread. Occasionally, the
- // refresh and move handlers are lost when the screen mode changes,
- // so re-register them here (the same does not appear to be true for
- // the reconfiguration handler itself).
- UnregisterRefreshAndMoveHandlers();
- RegisterRefreshAndMoveHandlers();
- ScreenConfigurationChanged();
- display_configuration_capture_event_.Signal();
- }
- }
-}
-
-void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count,
- const CGRect* rect_array,
- void* user_parameter) {
- ScreenCapturerMac* capturer = reinterpret_cast<ScreenCapturerMac*>(
- user_parameter);
- if (capturer->desktop_config_.pixel_bounds.is_empty()) {
- capturer->ScreenConfigurationChanged();
- }
- capturer->ScreenRefresh(count, rect_array);
-}
-
-void ScreenCapturerMac::ScreenUpdateMoveCallback(
- CGScreenUpdateMoveDelta delta,
- size_t count,
- const CGRect* rect_array,
- void* user_parameter) {
- ScreenCapturerMac* capturer = reinterpret_cast<ScreenCapturerMac*>(
- user_parameter);
- capturer->ScreenUpdateMove(delta, count, rect_array);
-}
-
-void ScreenCapturerMac::DisplaysReconfiguredCallback(
- CGDirectDisplayID display,
- CGDisplayChangeSummaryFlags flags,
- void* user_parameter) {
- ScreenCapturerMac* capturer = reinterpret_cast<ScreenCapturerMac*>(
- user_parameter);
- capturer->DisplaysReconfigured(display, flags);
-}
-
-} // namespace
-
-// static
-scoped_ptr<ScreenCapturer> ScreenCapturer::Create() {
- scoped_ptr<ScreenCapturerMac> capturer(new ScreenCapturerMac());
- if (!capturer->Init())
- capturer.reset();
- return capturer.PassAs<ScreenCapturer>();
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_mac_unittest.cc b/media/video/capture/screen/screen_capturer_mac_unittest.cc
deleted file mode 100644
index 72f2d69..0000000
--- a/media/video/capture/screen/screen_capturer_mac_unittest.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer.h"
-
-#include <ApplicationServices/ApplicationServices.h>
-
-#include <ostream>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "media/video/capture/screen/mac/desktop_configuration.h"
-#include "media/video/capture/screen/screen_capturer_mock_objects.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Return;
-
-namespace media {
-
-class ScreenCapturerMacTest : public testing::Test {
- public:
- // Verifies that the whole screen is initially dirty.
- void CaptureDoneCallback1(webrtc::DesktopFrame* frame);
-
- // Verifies that a rectangle explicitly marked as dirty is propagated
- // correctly.
- void CaptureDoneCallback2(webrtc::DesktopFrame* frame);
-
- protected:
- virtual void SetUp() OVERRIDE {
- capturer_ = ScreenCapturer::Create();
- }
-
- scoped_ptr<ScreenCapturer> capturer_;
- MockScreenCapturerCallback callback_;
-};
-
-void ScreenCapturerMacTest::CaptureDoneCallback1(
- webrtc::DesktopFrame* frame) {
- scoped_ptr<webrtc::DesktopFrame> owned_frame(frame);
-
- MacDesktopConfiguration config = MacDesktopConfiguration::GetCurrent(
- MacDesktopConfiguration::BottomLeftOrigin);
-
- // Verify that the region contains full frame.
- webrtc::DesktopRegion::Iterator it(frame->updated_region());
- EXPECT_TRUE(!it.IsAtEnd() && it.rect().equals(config.pixel_bounds));
-}
-
-void ScreenCapturerMacTest::CaptureDoneCallback2(
- webrtc::DesktopFrame* frame) {
- scoped_ptr<webrtc::DesktopFrame> owned_frame(frame);
-
- MacDesktopConfiguration config = MacDesktopConfiguration::GetCurrent(
- MacDesktopConfiguration::BottomLeftOrigin);
- int width = config.pixel_bounds.width();
- int height = config.pixel_bounds.height();
-
- EXPECT_EQ(width, frame->size().width());
- EXPECT_EQ(height, frame->size().height());
- EXPECT_TRUE(frame->data() != NULL);
- // Depending on the capture method, the screen may be flipped or not, so
- // the stride may be positive or negative.
- EXPECT_EQ(static_cast<int>(sizeof(uint32_t) * width),
- abs(frame->stride()));
-}
-
-TEST_F(ScreenCapturerMacTest, Capture) {
- EXPECT_CALL(callback_, OnCaptureCompleted(_))
- .Times(2)
- .WillOnce(Invoke(this, &ScreenCapturerMacTest::CaptureDoneCallback1))
- .WillOnce(Invoke(this, &ScreenCapturerMacTest::CaptureDoneCallback2));
-
- EXPECT_CALL(callback_, CreateSharedMemory(_))
- .Times(AnyNumber())
- .WillRepeatedly(Return(static_cast<webrtc::SharedMemory*>(NULL)));
-
- SCOPED_TRACE("");
- capturer_->Start(&callback_);
-
- // Check that we get an initial full-screen updated.
- capturer_->Capture(webrtc::DesktopRegion());
-
- // Check that subsequent dirty rects are propagated correctly.
- capturer_->Capture(webrtc::DesktopRegion());
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_mock_objects.cc b/media/video/capture/screen/screen_capturer_mock_objects.cc
deleted file mode 100644
index 9e365ff..0000000
--- a/media/video/capture/screen/screen_capturer_mock_objects.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer_mock_objects.h"
-
-#include "media/video/capture/screen/screen_capturer.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
-
-namespace media {
-
-MockScreenCapturer::MockScreenCapturer() {}
-MockScreenCapturer::~MockScreenCapturer() {}
-
-MockScreenCapturerCallback::MockScreenCapturerCallback() {}
-MockScreenCapturerCallback::~MockScreenCapturerCallback() {}
-
-MockMouseShapeObserver::MockMouseShapeObserver() {}
-MockMouseShapeObserver::~MockMouseShapeObserver() {}
-
-void MockMouseShapeObserver::OnCursorShapeChanged(
- scoped_ptr<MouseCursorShape> cursor_shape) {
- // Notify the mock method.
- OnCursorShapeChangedPtr(cursor_shape.get());
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_mock_objects.h b/media/video/capture/screen/screen_capturer_mock_objects.h
deleted file mode 100644
index 95f0152..0000000
--- a/media/video/capture/screen/screen_capturer_mock_objects.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_MOCK_OBJECTS_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_MOCK_OBJECTS_H_
-
-#include "media/video/capture/screen/mouse_cursor_shape.h"
-#include "media/video/capture/screen/screen_capturer.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace media {
-
-class MockScreenCapturer : public ScreenCapturer {
- public:
- MockScreenCapturer();
- virtual ~MockScreenCapturer();
-
- MOCK_METHOD1(Start, void(Callback* callback));
- MOCK_METHOD1(Capture, void(const webrtc::DesktopRegion& region));
- MOCK_METHOD1(SetMouseShapeObserver, void(
- MouseShapeObserver* mouse_shape_observer));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockScreenCapturer);
-};
-
-class MockScreenCapturerCallback : public ScreenCapturer::Callback {
- public:
- MockScreenCapturerCallback();
- virtual ~MockScreenCapturerCallback();
-
- MOCK_METHOD1(CreateSharedMemory, webrtc::SharedMemory*(size_t));
- MOCK_METHOD1(OnCaptureCompleted, void(webrtc::DesktopFrame*));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockScreenCapturerCallback);
-};
-
-class MockMouseShapeObserver : public ScreenCapturer::MouseShapeObserver {
- public:
- MockMouseShapeObserver();
- virtual ~MockMouseShapeObserver();
-
- void OnCursorShapeChanged(scoped_ptr<MouseCursorShape> cursor_shape) OVERRIDE;
-
- MOCK_METHOD1(OnCursorShapeChangedPtr,
- void(MouseCursorShape* cursor_shape));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockMouseShapeObserver);
-
-};
-
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_MOCK_OBJECTS_H_
diff --git a/media/video/capture/screen/screen_capturer_null.cc b/media/video/capture/screen/screen_capturer_null.cc
deleted file mode 100644
index 19c9fca..0000000
--- a/media/video/capture/screen/screen_capturer_null.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer.h"
-
-namespace media {
-
-scoped_refptr<SharedBuffer> ScreenCapturer::Delegate::CreateSharedBuffer(
- uint32 size) {
- return scoped_refptr<SharedBuffer>();
-}
-
-void ScreenCapturer::Delegate::ReleaseSharedBuffer(
- scoped_refptr<SharedBuffer> buffer) {
-}
-
-// static
-scoped_ptr<ScreenCapturer> ScreenCapturer::Create() {
- return scoped_ptr<ScreenCapturer>();
-}
-
-// static
-scoped_ptr<ScreenCapturer> ScreenCapturer::CreateWithXDamage(
- bool use_x_damage) {
- return scoped_ptr<ScreenCapturer>();
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_unittest.cc b/media/video/capture/screen/screen_capturer_unittest.cc
deleted file mode 100644
index 7be07db..0000000
--- a/media/video/capture/screen/screen_capturer_unittest.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer.h"
-
-#include "base/bind.h"
-#if defined(OS_MACOSX)
-#include "base/mac/mac_util.h"
-#endif // defined(OS_MACOSX)
-#include "media/video/capture/screen/screen_capturer_mock_objects.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Return;
-using ::testing::SaveArg;
-
-const int kTestSharedMemoryId = 123;
-
-namespace media {
-
-class ScreenCapturerTest : public testing::Test {
- public:
- webrtc::SharedMemory* CreateSharedMemory(size_t size);
-
- protected:
- scoped_ptr<ScreenCapturer> capturer_;
- MockMouseShapeObserver mouse_observer_;
- MockScreenCapturerCallback callback_;
-};
-
-class FakeSharedMemory : public webrtc::SharedMemory {
- public:
- FakeSharedMemory(char* buffer, size_t size)
- : SharedMemory(buffer, size, 0, kTestSharedMemoryId),
- buffer_(buffer) {
- }
- virtual ~FakeSharedMemory() {
- delete[] buffer_;
- }
- private:
- char* buffer_;
- DISALLOW_COPY_AND_ASSIGN(FakeSharedMemory);
-};
-
-webrtc::SharedMemory* ScreenCapturerTest::CreateSharedMemory(size_t size) {
- return new FakeSharedMemory(new char[size], size);
-}
-
-TEST_F(ScreenCapturerTest, StartCapturer) {
- capturer_ = ScreenCapturer::Create();
- capturer_->SetMouseShapeObserver(&mouse_observer_);
- capturer_->Start(&callback_);
-}
-
-TEST_F(ScreenCapturerTest, Capture) {
- // Assume that Start() treats the screen as invalid initially.
- webrtc::DesktopFrame* frame = NULL;
- EXPECT_CALL(callback_, OnCaptureCompleted(_))
- .WillOnce(SaveArg<0>(&frame));
- EXPECT_CALL(mouse_observer_, OnCursorShapeChangedPtr(_))
- .Times(AnyNumber());
-
- EXPECT_CALL(callback_, CreateSharedMemory(_))
- .Times(AnyNumber())
- .WillRepeatedly(Return(static_cast<webrtc::SharedMemory*>(NULL)));
-
- capturer_ = ScreenCapturer::Create();
- capturer_->Start(&callback_);
- capturer_->Capture(webrtc::DesktopRegion());
-
- ASSERT_TRUE(frame);
- EXPECT_GT(frame->size().width(), 0);
- EXPECT_GT(frame->size().height(), 0);
- EXPECT_GE(frame->stride(),
- frame->size().width() * webrtc::DesktopFrame::kBytesPerPixel);
- EXPECT_TRUE(frame->shared_memory() == NULL);
-
- // Verify that the region contains whole screen.
- EXPECT_FALSE(frame->updated_region().is_empty());
- webrtc::DesktopRegion::Iterator it(frame->updated_region());
- ASSERT_TRUE(!it.IsAtEnd());
- EXPECT_TRUE(it.rect().equals(webrtc::DesktopRect::MakeSize(frame->size())));
- it.Advance();
- EXPECT_TRUE(it.IsAtEnd());
-
- delete frame;
-}
-
-#if defined(OS_WIN)
-
-TEST_F(ScreenCapturerTest, UseSharedBuffers) {
- webrtc::DesktopFrame* frame = NULL;
- EXPECT_CALL(callback_, OnCaptureCompleted(_))
- .WillOnce(SaveArg<0>(&frame));
- EXPECT_CALL(mouse_observer_, OnCursorShapeChangedPtr(_))
- .Times(AnyNumber());
-
- EXPECT_CALL(callback_, CreateSharedMemory(_))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(this, &ScreenCapturerTest::CreateSharedMemory));
-
- capturer_ = ScreenCapturer::Create();
- capturer_->Start(&callback_);
- capturer_->Capture(webrtc::DesktopRegion());
-
- ASSERT_TRUE(frame);
- ASSERT_TRUE(frame->shared_memory());
- EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
-
- delete frame;
-}
-
-#endif // defined(OS_WIN)
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_win.cc b/media/video/capture/screen/screen_capturer_win.cc
deleted file mode 100644
index 9ba115f..0000000
--- a/media/video/capture/screen/screen_capturer_win.cc
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer.h"
-
-#include <windows.h>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time.h"
-#include "media/video/capture/screen/differ.h"
-#include "media/video/capture/screen/mouse_cursor_shape.h"
-#include "media/video/capture/screen/screen_capture_frame_queue.h"
-#include "media/video/capture/screen/screen_capturer_helper.h"
-#include "media/video/capture/screen/win/desktop.h"
-#include "media/video/capture/screen/win/scoped_thread_desktop.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame_win.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
-
-namespace media {
-
-namespace {
-
-// Constants from dwmapi.h.
-const UINT DWM_EC_DISABLECOMPOSITION = 0;
-const UINT DWM_EC_ENABLECOMPOSITION = 1;
-
-typedef HRESULT (WINAPI * DwmEnableCompositionFunc)(UINT);
-
-const wchar_t kDwmapiLibraryName[] = L"dwmapi.dll";
-
-// Pixel colors used when generating cursor outlines.
-const uint32 kPixelBgraBlack = 0xff000000;
-const uint32 kPixelBgraWhite = 0xffffffff;
-const uint32 kPixelBgraTransparent = 0x00000000;
-
-uint8_t AlphaMul(uint8_t v, uint8_t alpha) {
- return (static_cast<uint16_t>(v) * alpha) >> 8;
-}
-
-// ScreenCapturerWin captures 32bit RGB using GDI.
-//
-// ScreenCapturerWin is double-buffered as required by ScreenCapturer.
-class ScreenCapturerWin : public ScreenCapturer {
- public:
- ScreenCapturerWin(bool disable_aero);
- virtual ~ScreenCapturerWin();
-
- // Overridden from ScreenCapturer:
- virtual void Start(Callback* callback) OVERRIDE;
- virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE;
- virtual void SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) OVERRIDE;
-
- private:
- // Make sure that the device contexts match the screen configuration.
- void PrepareCaptureResources();
-
- // Captures the current screen contents into the current buffer.
- void CaptureImage();
-
- // Expand the cursor shape to add a white outline for visibility against
- // dark backgrounds.
- void AddCursorOutline(int width, int height, uint32* dst);
-
- // Capture the current cursor shape.
- void CaptureCursor();
-
- Callback* callback_;
- MouseShapeObserver* mouse_shape_observer_;
-
- // A thread-safe list of invalid rectangles, and the size of the most
- // recently captured screen.
- ScreenCapturerHelper helper_;
-
- // Snapshot of the last cursor bitmap we sent to the client. This is used
- // to diff against the current cursor so we only send a cursor-change
- // message when the shape has changed.
- MouseCursorShape last_cursor_;
-
- ScopedThreadDesktop desktop_;
-
- // GDI resources used for screen capture.
- HDC desktop_dc_;
- HDC memory_dc_;
-
- // Queue of the frames buffers.
- ScreenCaptureFrameQueue queue_;
-
- // Rectangle describing the bounds of the desktop device context.
- webrtc::DesktopRect desktop_dc_rect_;
-
- // Class to calculate the difference between two screen bitmaps.
- scoped_ptr<Differ> differ_;
-
- HMODULE dwmapi_library_;
- DwmEnableCompositionFunc composition_func_;
-
- // Used to suppress duplicate logging of SetThreadExecutionState errors.
- bool set_thread_execution_state_failed_;
-
- DISALLOW_COPY_AND_ASSIGN(ScreenCapturerWin);
-};
-
-ScreenCapturerWin::ScreenCapturerWin(bool disable_aero)
- : callback_(NULL),
- mouse_shape_observer_(NULL),
- desktop_dc_(NULL),
- memory_dc_(NULL),
- dwmapi_library_(NULL),
- composition_func_(NULL),
- set_thread_execution_state_failed_(false) {
- if (disable_aero) {
- // Load dwmapi.dll dynamically since it is not available on XP.
- if (!dwmapi_library_)
- dwmapi_library_ = LoadLibrary(kDwmapiLibraryName);
-
- if (dwmapi_library_) {
- composition_func_ = reinterpret_cast<DwmEnableCompositionFunc>(
- GetProcAddress(dwmapi_library_, "DwmEnableComposition"));
- }
- }
-}
-
-ScreenCapturerWin::~ScreenCapturerWin() {
- if (desktop_dc_)
- ReleaseDC(NULL, desktop_dc_);
- if (memory_dc_)
- DeleteDC(memory_dc_);
-
- // Restore Aero.
- if (composition_func_)
- (*composition_func_)(DWM_EC_ENABLECOMPOSITION);
-
- if (dwmapi_library_)
- FreeLibrary(dwmapi_library_);
-}
-
-void ScreenCapturerWin::Capture(const webrtc::DesktopRegion& region) {
- base::Time capture_start_time = base::Time::Now();
-
- queue_.MoveToNextFrame();
-
- // Request that the system not power-down the system, or the display hardware.
- if (!SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED)) {
- if (!set_thread_execution_state_failed_) {
- set_thread_execution_state_failed_ = true;
- LOG_GETLASTERROR(WARNING)
- << "Failed to make system & display power assertion";
- }
- }
-
- // Make sure the GDI capture resources are up-to-date.
- PrepareCaptureResources();
-
- // Copy screen bits to the current buffer.
- CaptureImage();
-
- const webrtc::DesktopFrame* current_frame = queue_.current_frame();
- const webrtc::DesktopFrame* last_frame = queue_.previous_frame();
- if (last_frame) {
- // Make sure the differencer is set up correctly for these previous and
- // current screens.
- if (!differ_.get() ||
- (differ_->width() != current_frame->size().width()) ||
- (differ_->height() != current_frame->size().height()) ||
- (differ_->bytes_per_row() != current_frame->stride())) {
- differ_.reset(new Differ(current_frame->size().width(),
- current_frame->size().height(),
- webrtc::DesktopFrame::kBytesPerPixel,
- current_frame->stride()));
- }
-
- // Calculate difference between the two last captured frames.
- webrtc::DesktopRegion region;
- differ_->CalcDirtyRegion(last_frame->data(), current_frame->data(),
- &region);
- helper_.InvalidateRegion(region);
- } else {
- // No previous frame is available. Invalidate the whole screen.
- helper_.InvalidateScreen(current_frame->size());
- }
-
- helper_.set_size_most_recent(current_frame->size());
-
- // Emit the current frame.
- webrtc::DesktopFrame* frame = queue_.current_frame()->Share();
- frame->set_dpi(webrtc::DesktopVector(
- GetDeviceCaps(desktop_dc_, LOGPIXELSX),
- GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
- frame->mutable_updated_region()->Clear();
- helper_.TakeInvalidRegion(frame->mutable_updated_region());
- frame->set_capture_time_ms(
- (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp());
- callback_->OnCaptureCompleted(frame);
-
- // Check for cursor shape update.
- CaptureCursor();
-}
-
-void ScreenCapturerWin::SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) {
- DCHECK(!mouse_shape_observer_);
- DCHECK(mouse_shape_observer);
-
- mouse_shape_observer_ = mouse_shape_observer;
-}
-
-void ScreenCapturerWin::Start(Callback* callback) {
- DCHECK(!callback_);
- DCHECK(callback);
-
- callback_ = callback;
-
- // Vote to disable Aero composited desktop effects while capturing. Windows
- // will restore Aero automatically if the process exits. This has no effect
- // under Windows 8 or higher. See crbug.com/124018.
- if (composition_func_)
- (*composition_func_)(DWM_EC_DISABLECOMPOSITION);
-}
-
-void ScreenCapturerWin::PrepareCaptureResources() {
- // Switch to the desktop receiving user input if different from the current
- // one.
- scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop();
- if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
- // Release GDI resources otherwise SetThreadDesktop will fail.
- if (desktop_dc_) {
- ReleaseDC(NULL, desktop_dc_);
- desktop_dc_ = NULL;
- }
-
- if (memory_dc_) {
- DeleteDC(memory_dc_);
- memory_dc_ = NULL;
- }
-
- // If SetThreadDesktop() fails, the thread is still assigned a desktop.
- // So we can continue capture screen bits, just from the wrong desktop.
- desktop_.SetThreadDesktop(input_desktop.Pass());
-
- // Re-assert our vote to disable Aero.
- // See crbug.com/124018 and crbug.com/129906.
- if (composition_func_ != NULL) {
- (*composition_func_)(DWM_EC_DISABLECOMPOSITION);
- }
- }
-
- // If the display bounds have changed then recreate GDI resources.
- // TODO(wez): Also check for pixel format changes.
- webrtc::DesktopRect screen_rect(webrtc::DesktopRect::MakeXYWH(
- GetSystemMetrics(SM_XVIRTUALSCREEN),
- GetSystemMetrics(SM_YVIRTUALSCREEN),
- GetSystemMetrics(SM_CXVIRTUALSCREEN),
- GetSystemMetrics(SM_CYVIRTUALSCREEN)));
- if (!screen_rect.equals(desktop_dc_rect_)) {
- if (desktop_dc_) {
- ReleaseDC(NULL, desktop_dc_);
- desktop_dc_ = NULL;
- }
- if (memory_dc_) {
- DeleteDC(memory_dc_);
- memory_dc_ = NULL;
- }
- desktop_dc_rect_ = webrtc::DesktopRect();
- }
-
- if (desktop_dc_ == NULL) {
- DCHECK(memory_dc_ == NULL);
-
- // Create GDI device contexts to capture from the desktop into memory.
- desktop_dc_ = GetDC(NULL);
- CHECK(desktop_dc_);
- memory_dc_ = CreateCompatibleDC(desktop_dc_);
- CHECK(memory_dc_);
- desktop_dc_rect_ = screen_rect;
-
- // Make sure the frame buffers will be reallocated.
- queue_.Reset();
-
- helper_.ClearInvalidRegion();
- }
-}
-
-void ScreenCapturerWin::CaptureImage() {
- // If the current buffer is from an older generation then allocate a new one.
- // Note that we can't reallocate other buffers at this point, since the caller
- // may still be reading from them.
- if (!queue_.current_frame()) {
- DCHECK(desktop_dc_ != NULL);
- DCHECK(memory_dc_ != NULL);
-
- webrtc::DesktopSize size = webrtc::DesktopSize(
- desktop_dc_rect_.width(), desktop_dc_rect_.height());
-
- size_t buffer_size = size.width() * size.height() *
- webrtc::DesktopFrame::kBytesPerPixel;
- webrtc::SharedMemory* shared_memory =
- callback_->CreateSharedMemory(buffer_size);
- scoped_ptr<webrtc::DesktopFrameWin> buffer(
- webrtc::DesktopFrameWin::Create(size, shared_memory, desktop_dc_));
- queue_.ReplaceCurrentFrame(buffer.PassAs<webrtc::DesktopFrame>());
- }
-
- // Select the target bitmap into the memory dc and copy the rect from desktop
- // to memory.
- webrtc::DesktopFrameWin* current = static_cast<webrtc::DesktopFrameWin*>(
- queue_.current_frame()->GetUnderlyingFrame());
- HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap());
- if (previous_object != NULL) {
- BitBlt(memory_dc_,
- 0, 0, desktop_dc_rect_.width(), desktop_dc_rect_.height(),
- desktop_dc_,
- desktop_dc_rect_.left(), desktop_dc_rect_.top(),
- SRCCOPY | CAPTUREBLT);
-
- // Select back the previously selected object to that the device contect
- // could be destroyed independently of the bitmap if needed.
- SelectObject(memory_dc_, previous_object);
- }
-}
-
-void ScreenCapturerWin::AddCursorOutline(int width,
- int height,
- uint32* dst) {
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- // If this is a transparent pixel (bgr == 0 and alpha = 0), check the
- // neighbor pixels to see if this should be changed to an outline pixel.
- if (*dst == kPixelBgraTransparent) {
- // Change to white pixel if any neighbors (top, bottom, left, right)
- // are black.
- if ((y > 0 && dst[-width] == kPixelBgraBlack) ||
- (y < height - 1 && dst[width] == kPixelBgraBlack) ||
- (x > 0 && dst[-1] == kPixelBgraBlack) ||
- (x < width - 1 && dst[1] == kPixelBgraBlack)) {
- *dst = kPixelBgraWhite;
- }
- }
- dst++;
- }
- }
-}
-
-void ScreenCapturerWin::CaptureCursor() {
- CURSORINFO cursor_info;
- cursor_info.cbSize = sizeof(CURSORINFO);
- if (!GetCursorInfo(&cursor_info)) {
- VLOG(3) << "Unable to get cursor info. Error = " << GetLastError();
- return;
- }
-
- // Note that this does not need to be freed.
- HCURSOR hcursor = cursor_info.hCursor;
- ICONINFO iinfo;
- if (!GetIconInfo(hcursor, &iinfo)) {
- VLOG(3) << "Unable to get cursor icon info. Error = " << GetLastError();
- return;
- }
- int hotspot_x = iinfo.xHotspot;
- int hotspot_y = iinfo.yHotspot;
-
- // Get the cursor bitmap.
- HBITMAP hbitmap;
- BITMAP bitmap;
- bool color_bitmap;
- if (iinfo.hbmColor) {
- // Color cursor bitmap.
- color_bitmap = true;
- hbitmap = reinterpret_cast<HBITMAP>(
- CopyImage(iinfo.hbmColor, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION));
- if (!hbitmap) {
- VLOG(3) << "Unable to copy color cursor image. Error = "
- << GetLastError();
- return;
- }
-
- // Free the color and mask bitmaps since we only need our copy.
- DeleteObject(iinfo.hbmColor);
- DeleteObject(iinfo.hbmMask);
- } else {
- // Black and white (xor) cursor.
- color_bitmap = false;
- hbitmap = iinfo.hbmMask;
- }
-
- if (!GetObject(hbitmap, sizeof(BITMAP), &bitmap)) {
- VLOG(3) << "Unable to get cursor bitmap. Error = " << GetLastError();
- DeleteObject(hbitmap);
- return;
- }
-
- int width = bitmap.bmWidth;
- int height = bitmap.bmHeight;
- // For non-color cursors, the mask contains both an AND and an XOR mask and
- // the height includes both. Thus, the width is correct, but we need to
- // divide by 2 to get the correct mask height.
- if (!color_bitmap) {
- height /= 2;
- }
- int data_size = height * width * webrtc::DesktopFrame::kBytesPerPixel;
-
- scoped_ptr<MouseCursorShape> cursor(new MouseCursorShape());
- cursor->data.resize(data_size);
- uint8* cursor_dst_data =
- reinterpret_cast<uint8*>(&*(cursor->data.begin()));
-
- // Copy/convert cursor bitmap into format needed by chromotocol.
- int row_bytes = bitmap.bmWidthBytes;
- if (color_bitmap) {
- if (bitmap.bmPlanes != 1 || bitmap.bmBitsPixel != 32) {
- VLOG(3) << "Unsupported color cursor format. Error = " << GetLastError();
- DeleteObject(hbitmap);
- return;
- }
-
- // Copy across colour cursor imagery.
- // MouseCursorShape stores imagery top-down, and premultiplied
- // by the alpha channel, whereas windows stores them bottom-up
- // and not premultiplied.
- uint8* cursor_src_data = reinterpret_cast<uint8*>(bitmap.bmBits);
- uint8* src = cursor_src_data + ((height - 1) * row_bytes);
- uint8* dst = cursor_dst_data;
- for (int row = 0; row < height; ++row) {
- for (int column = 0; column < width; ++column) {
- dst[0] = AlphaMul(src[0], src[3]);
- dst[1] = AlphaMul(src[1], src[3]);
- dst[2] = AlphaMul(src[2], src[3]);
- dst[3] = src[3];
- dst += webrtc::DesktopFrame::kBytesPerPixel;
- src += webrtc::DesktopFrame::kBytesPerPixel;
- }
- src -= row_bytes + (width * webrtc::DesktopFrame::kBytesPerPixel);
- }
- } else {
- if (bitmap.bmPlanes != 1 || bitmap.bmBitsPixel != 1) {
- VLOG(3) << "Unsupported cursor mask format. Error = " << GetLastError();
- DeleteObject(hbitmap);
- return;
- }
-
- // x2 because there are 2 masks in the bitmap: AND and XOR.
- int mask_bytes = height * row_bytes * 2;
- scoped_ptr<uint8[]> mask(new uint8[mask_bytes]);
- if (!GetBitmapBits(hbitmap, mask_bytes, mask.get())) {
- VLOG(3) << "Unable to get cursor mask bits. Error = " << GetLastError();
- DeleteObject(hbitmap);
- return;
- }
- uint8* and_mask = mask.get();
- uint8* xor_mask = mask.get() + height * row_bytes;
- uint8* dst = cursor_dst_data;
- bool add_outline = false;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- int byte = y * row_bytes + x / 8;
- int bit = 7 - x % 8;
- int and_bit = and_mask[byte] & (1 << bit);
- int xor_bit = xor_mask[byte] & (1 << bit);
-
- // The two cursor masks combine as follows:
- // AND XOR Windows Result Our result RGB Alpha
- // 0 0 Black Black 00 ff
- // 0 1 White White ff ff
- // 1 0 Screen Transparent 00 00
- // 1 1 Reverse-screen Black 00 ff
- // Since we don't support XOR cursors, we replace the "Reverse Screen"
- // with black. In this case, we also add an outline around the cursor
- // so that it is visible against a dark background.
- int rgb = (!and_bit && xor_bit) ? 0xff : 0x00;
- int alpha = (and_bit && !xor_bit) ? 0x00 : 0xff;
- *dst++ = rgb;
- *dst++ = rgb;
- *dst++ = rgb;
- *dst++ = alpha;
- if (and_bit && xor_bit) {
- add_outline = true;
- }
- }
- }
- if (add_outline) {
- AddCursorOutline(width, height,
- reinterpret_cast<uint32*>(cursor_dst_data));
- }
- }
-
- DeleteObject(hbitmap);
-
- cursor->size.set(width, height);
- cursor->hotspot.set(hotspot_x, hotspot_y);
-
- // Compare the current cursor with the last one we sent to the client. If
- // they're the same, then don't bother sending the cursor again.
- if (last_cursor_.size.equals(cursor->size) &&
- last_cursor_.hotspot.equals(cursor->hotspot) &&
- last_cursor_.data == cursor->data) {
- return;
- }
-
- VLOG(3) << "Sending updated cursor: " << width << "x" << height;
-
- // Record the last cursor image that we sent to the client.
- last_cursor_ = *cursor;
-
- if (mouse_shape_observer_)
- mouse_shape_observer_->OnCursorShapeChanged(cursor.Pass());
-}
-
-} // namespace
-
-// static
-scoped_ptr<ScreenCapturer> ScreenCapturer::Create() {
- return CreateWithDisableAero(true);
-}
-
-// static
-scoped_ptr<ScreenCapturer> ScreenCapturer::CreateWithDisableAero(
- bool disable_aero) {
- return scoped_ptr<ScreenCapturer>(new ScreenCapturerWin(disable_aero));
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/screen_capturer_x11.cc b/media/video/capture/screen/screen_capturer_x11.cc
deleted file mode 100644
index 775151c..0000000
--- a/media/video/capture/screen/screen_capturer_x11.cc
+++ /dev/null
@@ -1,613 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/screen_capturer.h"
-
-#include <X11/extensions/Xdamage.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include <set>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "media/video/capture/screen/differ.h"
-#include "media/video/capture/screen/mouse_cursor_shape.h"
-#include "media/video/capture/screen/screen_capture_frame_queue.h"
-#include "media/video/capture/screen/screen_capturer_helper.h"
-#include "media/video/capture/screen/x11/x_server_pixel_buffer.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-
-namespace media {
-
-namespace {
-
-// A class to perform video frame capturing for Linux.
-class ScreenCapturerLinux : public ScreenCapturer {
- public:
- ScreenCapturerLinux();
- virtual ~ScreenCapturerLinux();
-
- // TODO(ajwong): Do we really want this to be synchronous?
- bool Init(bool use_x_damage);
-
- // DesktopCapturer interface.
- virtual void Start(Callback* delegate) OVERRIDE;
- virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE;
-
- // ScreenCapturer interface.
- virtual void SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) OVERRIDE;
-
- private:
- void InitXDamage();
-
- // Read and handle all currently-pending XEvents.
- // In the DAMAGE case, process the XDamage events and store the resulting
- // damage rectangles in the ScreenCapturerHelper.
- // In all cases, call ScreenConfigurationChanged() in response to any
- // ConfigNotify events.
- void ProcessPendingXEvents();
-
- // Capture the cursor image and notify the delegate if it was captured.
- void CaptureCursor();
-
- // Capture screen pixels to the current buffer in the queue. In the DAMAGE
- // case, the ScreenCapturerHelper already holds the list of invalid rectangles
- // from ProcessPendingXEvents(). In the non-DAMAGE case, this captures the
- // whole screen, then calculates some invalid rectangles that include any
- // differences between this and the previous capture.
- webrtc::DesktopFrame* CaptureScreen();
-
- // Called when the screen configuration is changed. |root_window_size|
- // specifies the most recent size of the root window.
- void ScreenConfigurationChanged(const webrtc::DesktopSize& root_window_size);
-
- // Synchronize the current buffer with |last_buffer_|, by copying pixels from
- // the area of |last_invalid_rects|.
- // Note this only works on the assumption that kNumBuffers == 2, as
- // |last_invalid_rects| holds the differences from the previous buffer and
- // the one prior to that (which will then be the current buffer).
- void SynchronizeFrame();
-
- void DeinitXlib();
-
- // Capture a rectangle from |x_server_pixel_buffer_|, and copy the data into
- // |frame|.
- void CaptureRect(const webrtc::DesktopRect& rect,
- webrtc::DesktopFrame* frame);
-
- // We expose two forms of blitting to handle variations in the pixel format.
- // In FastBlit, the operation is effectively a memcpy.
- void FastBlit(uint8* image,
- const webrtc::DesktopRect& rect,
- webrtc::DesktopFrame* frame);
- void SlowBlit(uint8* image,
- const webrtc::DesktopRect& rect,
- webrtc::DesktopFrame* frame);
-
- // Returns the number of bits |mask| has to be shifted left so its last
- // (most-significant) bit set becomes the most-significant bit of the word.
- // When |mask| is 0 the function returns 31.
- static uint32 GetRgbShift(uint32 mask);
-
- Callback* callback_;
- MouseShapeObserver* mouse_shape_observer_;
-
- // X11 graphics context.
- Display* display_;
- GC gc_;
- Window root_window_;
-
- // Last known dimensions of the root window.
- webrtc::DesktopSize root_window_size_;
-
- // XFixes.
- bool has_xfixes_;
- int xfixes_event_base_;
- int xfixes_error_base_;
-
- // XDamage information.
- bool use_damage_;
- Damage damage_handle_;
- int damage_event_base_;
- int damage_error_base_;
- XserverRegion damage_region_;
-
- // Access to the X Server's pixel buffer.
- XServerPixelBuffer x_server_pixel_buffer_;
-
- // A thread-safe list of invalid rectangles, and the size of the most
- // recently captured screen.
- ScreenCapturerHelper helper_;
-
- // Queue of the frames buffers.
- ScreenCaptureFrameQueue queue_;
-
- // Invalid region from the previous capture. This is used to synchronize the
- // current with the last buffer used.
- webrtc::DesktopRegion last_invalid_region_;
-
- // |Differ| for use when polling for changes.
- scoped_ptr<Differ> differ_;
-
- DISALLOW_COPY_AND_ASSIGN(ScreenCapturerLinux);
-};
-
-ScreenCapturerLinux::ScreenCapturerLinux()
- : callback_(NULL),
- mouse_shape_observer_(NULL),
- display_(NULL),
- gc_(NULL),
- root_window_(BadValue),
- has_xfixes_(false),
- xfixes_event_base_(-1),
- xfixes_error_base_(-1),
- use_damage_(false),
- damage_handle_(0),
- damage_event_base_(-1),
- damage_error_base_(-1),
- damage_region_(0) {
- helper_.SetLogGridSize(4);
-}
-
-ScreenCapturerLinux::~ScreenCapturerLinux() {
- DeinitXlib();
-}
-
-bool ScreenCapturerLinux::Init(bool use_x_damage) {
- // TODO(ajwong): We should specify the display string we are attaching to
- // in the constructor.
- display_ = XOpenDisplay(NULL);
- if (!display_) {
- LOG(ERROR) << "Unable to open display";
- return false;
- }
-
- root_window_ = RootWindow(display_, DefaultScreen(display_));
- if (root_window_ == BadValue) {
- LOG(ERROR) << "Unable to get the root window";
- DeinitXlib();
- return false;
- }
-
- gc_ = XCreateGC(display_, root_window_, 0, NULL);
- if (gc_ == NULL) {
- LOG(ERROR) << "Unable to get graphics context";
- DeinitXlib();
- return false;
- }
-
- // Check for XFixes extension. This is required for cursor shape
- // notifications, and for our use of XDamage.
- if (XFixesQueryExtension(display_, &xfixes_event_base_,
- &xfixes_error_base_)) {
- has_xfixes_ = true;
- } else {
- LOG(INFO) << "X server does not support XFixes.";
- }
-
- // Register for changes to the dimensions of the root window.
- XSelectInput(display_, root_window_, StructureNotifyMask);
-
- root_window_size_ = XServerPixelBuffer::GetRootWindowSize(display_);
- x_server_pixel_buffer_.Init(display_, root_window_size_);
-
- if (has_xfixes_) {
- // Register for changes to the cursor shape.
- XFixesSelectCursorInput(display_, root_window_,
- XFixesDisplayCursorNotifyMask);
- }
-
- if (use_x_damage) {
- InitXDamage();
- }
-
- return true;
-}
-
-void ScreenCapturerLinux::InitXDamage() {
- // Our use of XDamage requires XFixes.
- if (!has_xfixes_) {
- return;
- }
-
- // Check for XDamage extension.
- if (!XDamageQueryExtension(display_, &damage_event_base_,
- &damage_error_base_)) {
- LOG(INFO) << "X server does not support XDamage.";
- return;
- }
-
- // TODO(lambroslambrou): Disable DAMAGE in situations where it is known
- // to fail, such as when Desktop Effects are enabled, with graphics
- // drivers (nVidia, ATI) that fail to report DAMAGE notifications
- // properly.
-
- // Request notifications every time the screen becomes damaged.
- damage_handle_ = XDamageCreate(display_, root_window_,
- XDamageReportNonEmpty);
- if (!damage_handle_) {
- LOG(ERROR) << "Unable to initialize XDamage.";
- return;
- }
-
- // Create an XFixes server-side region to collate damage into.
- damage_region_ = XFixesCreateRegion(display_, 0, 0);
- if (!damage_region_) {
- XDamageDestroy(display_, damage_handle_);
- LOG(ERROR) << "Unable to create XFixes region.";
- return;
- }
-
- use_damage_ = true;
- LOG(INFO) << "Using XDamage extension.";
-}
-
-void ScreenCapturerLinux::Start(Callback* callback) {
- DCHECK(!callback_);
- DCHECK(callback);
-
- callback_ = callback;
-}
-
-void ScreenCapturerLinux::Capture(const webrtc::DesktopRegion& region) {
- base::Time capture_start_time = base::Time::Now();
-
- queue_.MoveToNextFrame();
-
- // Process XEvents for XDamage and cursor shape tracking.
- ProcessPendingXEvents();
-
- // If the current frame is from an older generation then allocate a new one.
- // Note that we can't reallocate other buffers at this point, since the caller
- // may still be reading from them.
- if (!queue_.current_frame()) {
- scoped_ptr<webrtc::DesktopFrame> frame(
- new webrtc::BasicDesktopFrame(root_window_size_));
- queue_.ReplaceCurrentFrame(frame.Pass());
- }
-
- // Refresh the Differ helper used by CaptureFrame(), if needed.
- webrtc::DesktopFrame* frame = queue_.current_frame();
- if (!use_damage_ && (
- !differ_.get() ||
- (differ_->width() != frame->size().width()) ||
- (differ_->height() != frame->size().height()) ||
- (differ_->bytes_per_row() != frame->stride()))) {
- differ_.reset(new Differ(frame->size().width(), frame->size().height(),
- webrtc::DesktopFrame::kBytesPerPixel,
- frame->stride()));
- }
-
- webrtc::DesktopFrame* result = CaptureScreen();
- last_invalid_region_ = result->updated_region();
- result->set_capture_time_ms(
- (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp());
- callback_->OnCaptureCompleted(result);
-}
-
-void ScreenCapturerLinux::SetMouseShapeObserver(
- MouseShapeObserver* mouse_shape_observer) {
- DCHECK(!mouse_shape_observer_);
- DCHECK(mouse_shape_observer);
-
- mouse_shape_observer_ = mouse_shape_observer;
-}
-
-void ScreenCapturerLinux::ProcessPendingXEvents() {
- // Find the number of events that are outstanding "now." We don't just loop
- // on XPending because we want to guarantee this terminates.
- int events_to_process = XPending(display_);
- XEvent e;
-
- for (int i = 0; i < events_to_process; i++) {
- XNextEvent(display_, &e);
- if (use_damage_ && (e.type == damage_event_base_ + XDamageNotify)) {
- XDamageNotifyEvent* event = reinterpret_cast<XDamageNotifyEvent*>(&e);
- DCHECK(event->level == XDamageReportNonEmpty);
- } else if (e.type == ConfigureNotify) {
- const XConfigureEvent& event = e.xconfigure;
- ScreenConfigurationChanged(
- webrtc::DesktopSize(event.width, event.height));
- } else if (has_xfixes_ &&
- e.type == xfixes_event_base_ + XFixesCursorNotify) {
- XFixesCursorNotifyEvent* cne;
- cne = reinterpret_cast<XFixesCursorNotifyEvent*>(&e);
- if (cne->subtype == XFixesDisplayCursorNotify) {
- CaptureCursor();
- }
- } else {
- LOG(WARNING) << "Got unknown event type: " << e.type;
- }
- }
-}
-
-void ScreenCapturerLinux::CaptureCursor() {
- DCHECK(has_xfixes_);
-
- XFixesCursorImage* img = XFixesGetCursorImage(display_);
- if (!img) {
- return;
- }
-
- scoped_ptr<MouseCursorShape> cursor(new MouseCursorShape());
- cursor->size = webrtc::DesktopSize(img->width, img->height);
- cursor->hotspot = webrtc::DesktopVector(img->xhot, img->yhot);
-
- int total_bytes = cursor->size.width ()* cursor->size.height() *
- webrtc::DesktopFrame::kBytesPerPixel;
- cursor->data.resize(total_bytes);
-
- // Xlib stores 32-bit data in longs, even if longs are 64-bits long.
- unsigned long* src = img->pixels;
- uint32* dst = reinterpret_cast<uint32*>(&*(cursor->data.begin()));
- uint32* dst_end = dst + (img->width * img->height);
- while (dst < dst_end) {
- *dst++ = static_cast<uint32>(*src++);
- }
- XFree(img);
-
- if (mouse_shape_observer_)
- mouse_shape_observer_->OnCursorShapeChanged(cursor.Pass());
-}
-
-webrtc::DesktopFrame* ScreenCapturerLinux::CaptureScreen() {
- webrtc::DesktopFrame* frame = queue_.current_frame()->Share();
-
- // Pass the screen size to the helper, so it can clip the invalid region if it
- // expands that region to a grid.
- helper_.set_size_most_recent(frame->size());
-
- // In the DAMAGE case, ensure the frame is up-to-date with the previous frame
- // if any. If there isn't a previous frame, that means a screen-resolution
- // change occurred, and |invalid_rects| will be updated to include the whole
- // screen.
- if (use_damage_ && queue_.previous_frame())
- SynchronizeFrame();
-
- webrtc::DesktopRegion* updated_region = frame->mutable_updated_region();
-
- x_server_pixel_buffer_.Synchronize();
- if (use_damage_ && queue_.previous_frame()) {
- // Atomically fetch and clear the damage region.
- XDamageSubtract(display_, damage_handle_, None, damage_region_);
- int rects_num = 0;
- XRectangle bounds;
- XRectangle* rects = XFixesFetchRegionAndBounds(display_, damage_region_,
- &rects_num, &bounds);
- for (int i = 0; i < rects_num; ++i) {
- updated_region->AddRect(webrtc::DesktopRect::MakeXYWH(
- rects[i].x, rects[i].y, rects[i].width, rects[i].height));
- }
- XFree(rects);
- helper_.InvalidateRegion(*updated_region);
-
- // Capture the damaged portions of the desktop.
- helper_.TakeInvalidRegion(updated_region);
-
- // Clip the damaged portions to the current screen size, just in case some
- // spurious XDamage notifications were received for a previous (larger)
- // screen size.
- updated_region->IntersectWith(
- webrtc::DesktopRect::MakeSize(root_window_size_));
- for (webrtc::DesktopRegion::Iterator it(*updated_region);
- !it.IsAtEnd(); it.Advance()) {
- CaptureRect(it.rect(), frame);
- }
- } else {
- // Doing full-screen polling, or this is the first capture after a
- // screen-resolution change. In either case, need a full-screen capture.
- webrtc::DesktopRect screen_rect =
- webrtc::DesktopRect::MakeSize(frame->size());
- CaptureRect(screen_rect, frame);
-
- if (queue_.previous_frame()) {
- // Full-screen polling, so calculate the invalid rects here, based on the
- // changed pixels between current and previous buffers.
- DCHECK(differ_ != NULL);
- DCHECK(queue_.previous_frame()->data());
- differ_->CalcDirtyRegion(queue_.previous_frame()->data(),
- frame->data(), updated_region);
- } else {
- // No previous buffer, so always invalidate the whole screen, whether
- // or not DAMAGE is being used. DAMAGE doesn't necessarily send a
- // full-screen notification after a screen-resolution change, so
- // this is done here.
- updated_region->SetRect(screen_rect);
- }
- }
-
- return frame;
-}
-
-void ScreenCapturerLinux::ScreenConfigurationChanged(
- const webrtc::DesktopSize& root_window_size) {
- root_window_size_ = root_window_size;
-
- // Make sure the frame buffers will be reallocated.
- queue_.Reset();
-
- helper_.ClearInvalidRegion();
- x_server_pixel_buffer_.Init(display_, root_window_size_);
-}
-
-void ScreenCapturerLinux::SynchronizeFrame() {
- // Synchronize the current buffer with the previous one since we do not
- // capture the entire desktop. Note that encoder may be reading from the
- // previous buffer at this time so thread access complaints are false
- // positives.
-
- // TODO(hclam): We can reduce the amount of copying here by subtracting
- // |capturer_helper_|s region from |last_invalid_region_|.
- // http://crbug.com/92354
- DCHECK(queue_.previous_frame());
-
- webrtc::DesktopFrame* current = queue_.current_frame();
- webrtc::DesktopFrame* last = queue_.previous_frame();
- DCHECK_NE(current, last);
- for (webrtc::DesktopRegion::Iterator it(last_invalid_region_);
- !it.IsAtEnd(); it.Advance()) {
- const webrtc::DesktopRect& r = it.rect();
- int offset = r.top() * current->stride() +
- r.left() * webrtc::DesktopFrame::kBytesPerPixel;
- for (int i = 0; i < r.height(); ++i) {
- memcpy(current->data() + offset, last->data() + offset,
- r.width() * webrtc::DesktopFrame::kBytesPerPixel);
- offset += current->size().width() * webrtc::DesktopFrame::kBytesPerPixel;
- }
- }
-}
-
-void ScreenCapturerLinux::DeinitXlib() {
- if (gc_) {
- XFreeGC(display_, gc_);
- gc_ = NULL;
- }
-
- x_server_pixel_buffer_.Release();
-
- if (display_) {
- if (damage_handle_)
- XDamageDestroy(display_, damage_handle_);
- if (damage_region_)
- XFixesDestroyRegion(display_, damage_region_);
- XCloseDisplay(display_);
- display_ = NULL;
- damage_handle_ = 0;
- damage_region_ = 0;
- }
-}
-
-void ScreenCapturerLinux::CaptureRect(const webrtc::DesktopRect& rect,
- webrtc::DesktopFrame* frame) {
- uint8* image = x_server_pixel_buffer_.CaptureRect(rect);
- int depth = x_server_pixel_buffer_.GetDepth();
- if ((depth == 24 || depth == 32) &&
- x_server_pixel_buffer_.GetBitsPerPixel() == 32 &&
- x_server_pixel_buffer_.GetRedMask() == 0xff0000 &&
- x_server_pixel_buffer_.GetGreenMask() == 0xff00 &&
- x_server_pixel_buffer_.GetBlueMask() == 0xff) {
- DVLOG(3) << "Fast blitting";
- FastBlit(image, rect, frame);
- } else {
- DVLOG(3) << "Slow blitting";
- SlowBlit(image, rect, frame);
- }
-}
-
-void ScreenCapturerLinux::FastBlit(uint8* image,
- const webrtc::DesktopRect& rect,
- webrtc::DesktopFrame* frame) {
- uint8* src_pos = image;
- int src_stride = x_server_pixel_buffer_.GetStride();
- int dst_x = rect.left(), dst_y = rect.top();
-
- uint8* dst_pos = frame->data() + frame->stride() * dst_y;
- dst_pos += dst_x * webrtc::DesktopFrame::kBytesPerPixel;
-
- int height = rect.height();
- int row_bytes = rect.width() * webrtc::DesktopFrame::kBytesPerPixel;
- for (int y = 0; y < height; ++y) {
- memcpy(dst_pos, src_pos, row_bytes);
- src_pos += src_stride;
- dst_pos += frame->stride();
- }
-}
-
-void ScreenCapturerLinux::SlowBlit(uint8* image,
- const webrtc::DesktopRect& rect,
- webrtc::DesktopFrame* frame) {
- int src_stride = x_server_pixel_buffer_.GetStride();
- int dst_x = rect.left(), dst_y = rect.top();
- int width = rect.width(), height = rect.height();
-
- uint32 red_mask = x_server_pixel_buffer_.GetRedMask();
- uint32 green_mask = x_server_pixel_buffer_.GetGreenMask();
- uint32 blue_mask = x_server_pixel_buffer_.GetBlueMask();
-
- uint32 red_shift = GetRgbShift(red_mask);
- uint32 green_shift = GetRgbShift(green_mask);
- uint32 blue_shift = GetRgbShift(blue_mask);
-
- unsigned int bits_per_pixel = x_server_pixel_buffer_.GetBitsPerPixel();
-
- uint8* dst_pos = frame->data() + frame->stride() * dst_y;
- uint8* src_pos = image;
- dst_pos += dst_x * webrtc::DesktopFrame::kBytesPerPixel;
- // TODO(hclam): Optimize, perhaps using MMX code or by converting to
- // YUV directly
- for (int y = 0; y < height; y++) {
- uint32* dst_pos_32 = reinterpret_cast<uint32*>(dst_pos);
- uint32* src_pos_32 = reinterpret_cast<uint32*>(src_pos);
- uint16* src_pos_16 = reinterpret_cast<uint16*>(src_pos);
- for (int x = 0; x < width; x++) {
- // Dereference through an appropriately-aligned pointer.
- uint32 pixel;
- if (bits_per_pixel == 32)
- pixel = src_pos_32[x];
- else if (bits_per_pixel == 16)
- pixel = src_pos_16[x];
- else
- pixel = src_pos[x];
- uint32 r = (pixel & red_mask) << red_shift;
- uint32 g = (pixel & green_mask) << green_shift;
- uint32 b = (pixel & blue_mask) << blue_shift;
-
- // Write as 32-bit RGB.
- dst_pos_32[x] = ((r >> 8) & 0xff0000) | ((g >> 16) & 0xff00) |
- ((b >> 24) & 0xff);
- }
- dst_pos += frame->stride();
- src_pos += src_stride;
- }
-}
-
-// static
-uint32 ScreenCapturerLinux::GetRgbShift(uint32 mask) {
- int shift = 0;
- if ((mask & 0xffff0000u) == 0) {
- mask <<= 16;
- shift += 16;
- }
- if ((mask & 0xff000000u) == 0) {
- mask <<= 8;
- shift += 8;
- }
- if ((mask & 0xf0000000u) == 0) {
- mask <<= 4;
- shift += 4;
- }
- if ((mask & 0xc0000000u) == 0) {
- mask <<= 2;
- shift += 2;
- }
- if ((mask & 0x80000000u) == 0)
- shift += 1;
-
- return shift;
-}
-
-} // namespace
-
-// static
-scoped_ptr<ScreenCapturer> ScreenCapturer::Create() {
- scoped_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux());
- if (!capturer->Init(false))
- capturer.reset();
- return capturer.PassAs<ScreenCapturer>();
-}
-
-// static
-scoped_ptr<ScreenCapturer> ScreenCapturer::CreateWithXDamage(
- bool use_x_damage) {
- scoped_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux());
- if (!capturer->Init(use_x_damage))
- capturer.reset();
- return capturer.PassAs<ScreenCapturer>();
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/shared_desktop_frame.cc b/media/video/capture/screen/shared_desktop_frame.cc
deleted file mode 100644
index b0a6f14..0000000
--- a/media/video/capture/screen/shared_desktop_frame.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/shared_desktop_frame.h"
-
-#include "base/memory/scoped_ptr.h"
-
-namespace media {
-
-class SharedDesktopFrame::Core : public base::RefCountedThreadSafe<Core> {
- public:
- Core(webrtc::DesktopFrame* frame) : frame_(frame) {}
-
- webrtc::DesktopFrame* frame() { return frame_.get(); }
-
- private:
- friend class base::RefCountedThreadSafe<Core>;
- virtual ~Core() {}
-
- scoped_ptr<webrtc::DesktopFrame> frame_;
-
- DISALLOW_COPY_AND_ASSIGN(Core);
-};
-
-SharedDesktopFrame::~SharedDesktopFrame() {}
-
-// static
-SharedDesktopFrame* SharedDesktopFrame::Wrap(
- webrtc::DesktopFrame* desktop_frame) {
- return new SharedDesktopFrame(new Core(desktop_frame));
-}
-
-webrtc::DesktopFrame* SharedDesktopFrame::GetUnderlyingFrame() {
- return core_->frame();
-}
-
-SharedDesktopFrame* SharedDesktopFrame::Share() {
- SharedDesktopFrame* result = new SharedDesktopFrame(core_);
- result->set_dpi(dpi());
- result->set_capture_time_ms(capture_time_ms());
- *result->mutable_updated_region() = updated_region();
- return result;
-}
-
-bool SharedDesktopFrame::IsShared() {
- return !core_->HasOneRef();
-}
-
-SharedDesktopFrame::SharedDesktopFrame(scoped_refptr<Core> core)
- : DesktopFrame(core->frame()->size(), core->frame()->stride(),
- core->frame()->data(), core->frame()->shared_memory()),
- core_(core) {
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/shared_desktop_frame.h b/media/video/capture/screen/shared_desktop_frame.h
deleted file mode 100644
index 861b5f0..0000000
--- a/media/video/capture/screen/shared_desktop_frame.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_SHARED_DESKTOP_FRAME_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_SHARED_DESKTOP_FRAME_H_
-
-#include "base/memory/ref_counted.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-
-namespace media {
-
-// SharedDesktopFrame is a DesktopFrame that may have multiple instances all
-// sharing the same buffer.
-class SharedDesktopFrame : public webrtc::DesktopFrame {
- public:
- virtual ~SharedDesktopFrame();
-
- static SharedDesktopFrame* Wrap(webrtc::DesktopFrame* desktop_frame);
-
- // Returns the underlying instance of DesktopFrame.
- webrtc::DesktopFrame* GetUnderlyingFrame();
-
- // Creates a clone of this object.
- SharedDesktopFrame* Share();
-
- // Checks if the frame is currently shared. If it returns false it's
- // guaranteed that there are no clones of the object.
- bool IsShared();
-
- private:
- class Core;
-
- SharedDesktopFrame(scoped_refptr<Core> core);
-
- scoped_refptr<Core> core_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedDesktopFrame);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SHARED_DESKTOP_FRAME_H_
diff --git a/media/video/capture/screen/win/desktop.cc b/media/video/capture/screen/win/desktop.cc
deleted file mode 100644
index 2b6cbb7..0000000
--- a/media/video/capture/screen/win/desktop.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/win/desktop.h"
-
-#include <vector>
-
-#include "base/logging.h"
-
-namespace media {
-
-Desktop::Desktop(HDESK desktop, bool own) : desktop_(desktop), own_(own) {
-}
-
-Desktop::~Desktop() {
- if (own_ && desktop_ != NULL) {
- if (!::CloseDesktop(desktop_)) {
- LOG_GETLASTERROR(ERROR)
- << "Failed to close the owned desktop handle";
- }
- }
-}
-
-bool Desktop::GetName(string16* desktop_name_out) const {
- if (desktop_ == NULL)
- return false;
-
- DWORD length;
- CHECK(!GetUserObjectInformationW(desktop_, UOI_NAME, NULL, 0, &length));
- CHECK(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
-
- length /= sizeof(char16);
- std::vector<char16> buffer(length);
- if (!GetUserObjectInformationW(desktop_, UOI_NAME, &buffer[0],
- length * sizeof(char16), &length)) {
- LOG_GETLASTERROR(ERROR)
- << "Failed to query the desktop name";
- return false;
- }
-
- desktop_name_out->assign(&buffer[0], length / sizeof(char16));
- return true;
-}
-
-bool Desktop::IsSame(const Desktop& other) const {
- string16 name;
- if (!GetName(&name))
- return false;
-
- string16 other_name;
- if (!other.GetName(&other_name))
- return false;
-
- return name == other_name;
-}
-
-bool Desktop::SetThreadDesktop() const {
- if (!::SetThreadDesktop(desktop_)) {
- LOG_GETLASTERROR(ERROR)
- << "Failed to assign the desktop to the current thread";
- return false;
- }
-
- return true;
-}
-
-scoped_ptr<Desktop> Desktop::GetDesktop(const wchar_t* desktop_name) {
- ACCESS_MASK desired_access =
- DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE |
- DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
- DESKTOP_SWITCHDESKTOP | GENERIC_WRITE;
- HDESK desktop = OpenDesktop(desktop_name, 0, FALSE, desired_access);
- if (desktop == NULL) {
- LOG_GETLASTERROR(ERROR)
- << "Failed to open the desktop '" << desktop_name << "'";
- return scoped_ptr<Desktop>();
- }
-
- return scoped_ptr<Desktop>(new Desktop(desktop, true));
-}
-
-scoped_ptr<Desktop> Desktop::GetInputDesktop() {
- HDESK desktop = OpenInputDesktop(
- 0, FALSE, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE);
- if (desktop == NULL)
- return scoped_ptr<Desktop>();
-
- return scoped_ptr<Desktop>(new Desktop(desktop, true));
-}
-
-scoped_ptr<Desktop> Desktop::GetThreadDesktop() {
- HDESK desktop = ::GetThreadDesktop(GetCurrentThreadId());
- if (desktop == NULL) {
- LOG_GETLASTERROR(ERROR)
- << "Failed to retrieve the handle of the desktop assigned to "
- "the current thread";
- return scoped_ptr<Desktop>();
- }
-
- return scoped_ptr<Desktop>(new Desktop(desktop, false));
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/win/desktop.h b/media/video/capture/screen/win/desktop.h
deleted file mode 100644
index 69c83b4..0000000
--- a/media/video/capture/screen/win/desktop.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_WIN_DESKTOP_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_WIN_DESKTOP_H_
-
-#include <windows.h>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/string16.h"
-#include "media/base/media_export.h"
-
-namespace media {
-
-class MEDIA_EXPORT Desktop {
- public:
- ~Desktop();
-
- // Returns the name of the desktop represented by the object. Return false if
- // quering the name failed for any reason.
- bool GetName(string16* desktop_name_out) const;
-
- // Returns true if |other| has the same name as this desktop. Returns false
- // in any other case including failing Win32 APIs and uninitialized desktop
- // handles.
- bool IsSame(const Desktop& other) const;
-
- // Assigns the desktop to the current thread. Returns false is the operation
- // failed for any reason.
- bool SetThreadDesktop() const;
-
- // Returns the desktop by its name or NULL if an error occurs.
- static scoped_ptr<Desktop> GetDesktop(const wchar_t* desktop_name);
-
- // Returns the desktop currently receiving user input or NULL if an error
- // occurs.
- static scoped_ptr<Desktop> GetInputDesktop();
-
- // Returns the desktop currently assigned to the calling thread or NULL if
- // an error occurs.
- static scoped_ptr<Desktop> GetThreadDesktop();
-
- private:
- Desktop(HDESK desktop, bool own);
-
- // The desktop handle.
- HDESK desktop_;
-
- // True if |desktop_| must be closed on teardown.
- bool own_;
-
- DISALLOW_COPY_AND_ASSIGN(Desktop);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_WIN_DESKTOP_H_
diff --git a/media/video/capture/screen/win/scoped_thread_desktop.cc b/media/video/capture/screen/win/scoped_thread_desktop.cc
deleted file mode 100644
index 8e9a80a..0000000
--- a/media/video/capture/screen/win/scoped_thread_desktop.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/win/scoped_thread_desktop.h"
-
-#include "base/logging.h"
-
-#include "media/video/capture/screen/win/desktop.h"
-
-namespace media {
-
-ScopedThreadDesktop::ScopedThreadDesktop()
- : initial_(Desktop::GetThreadDesktop()) {
-}
-
-ScopedThreadDesktop::~ScopedThreadDesktop() {
- Revert();
-}
-
-bool ScopedThreadDesktop::IsSame(const Desktop& desktop) {
- if (assigned_.get() != NULL) {
- return assigned_->IsSame(desktop);
- } else {
- return initial_->IsSame(desktop);
- }
-}
-
-void ScopedThreadDesktop::Revert() {
- if (assigned_.get() != NULL) {
- initial_->SetThreadDesktop();
- assigned_.reset();
- }
-}
-
-bool ScopedThreadDesktop::SetThreadDesktop(scoped_ptr<Desktop> desktop) {
- Revert();
-
- if (initial_->IsSame(*desktop))
- return true;
-
- if (!desktop->SetThreadDesktop())
- return false;
-
- assigned_ = desktop.Pass();
- return true;
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/win/scoped_thread_desktop.h b/media/video/capture/screen/win/scoped_thread_desktop.h
deleted file mode 100644
index 1a9259f..0000000
--- a/media/video/capture/screen/win/scoped_thread_desktop.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_WIN_SCOPED_THREAD_DESKTOP_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_WIN_SCOPED_THREAD_DESKTOP_H_
-
-#include <windows.h>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "media/base/media_export.h"
-
-namespace media {
-
-class Desktop;
-
-class MEDIA_EXPORT ScopedThreadDesktop {
- public:
- ScopedThreadDesktop();
- ~ScopedThreadDesktop();
-
- // Returns true if |desktop| has the same desktop name as the currently
- // assigned desktop (if assigned) or as the initial desktop (if not assigned).
- // Returns false in any other case including failing Win32 APIs and
- // uninitialized desktop handles.
- bool IsSame(const Desktop& desktop);
-
- // Reverts the calling thread to use the initial desktop.
- void Revert();
-
- // Assigns |desktop| to be the calling thread. Returns true if the thread has
- // been switched to |desktop| successfully.
- bool SetThreadDesktop(scoped_ptr<Desktop> desktop);
-
- private:
- // The desktop handle assigned to the calling thread by Set
- scoped_ptr<Desktop> assigned_;
-
- // The desktop handle assigned to the calling thread at creation.
- scoped_ptr<Desktop> initial_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedThreadDesktop);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_WIN_SCOPED_THREAD_DESKTOP_H_
diff --git a/media/video/capture/screen/x11/x_server_pixel_buffer.cc b/media/video/capture/screen/x11/x_server_pixel_buffer.cc
deleted file mode 100644
index 4941666..0000000
--- a/media/video/capture/screen/x11/x_server_pixel_buffer.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/capture/screen/x11/x_server_pixel_buffer.h"
-
-#include <sys/shm.h>
-
-#include "base/logging.h"
-
-#if defined(TOOLKIT_GTK)
-#include <gdk/gdk.h>
-#else // !defined(TOOLKIT_GTK)
-#include <X11/Xlib.h>
-#endif // !defined(TOOLKIT_GTK)
-
-namespace {
-
-#if defined(TOOLKIT_GTK)
-// GDK sets error handler for Xlib errors, so we need to use it to
-// trap X errors when this code is compiled with GTK.
-void EnableXServerErrorTrap() {
- gdk_error_trap_push();
-}
-
-int GetLastXServerError() {
- return gdk_error_trap_pop();
-}
-
-#else // !defined(TOOLKIT_GTK)
-
-static bool g_xserver_error_trap_enabled = false;
-static int g_last_xserver_error_code = 0;
-
-int XServerErrorHandler(Display* display, XErrorEvent* error_event) {
- DCHECK(g_xserver_error_trap_enabled);
- g_last_xserver_error_code = error_event->error_code;
- return 0;
-}
-
-void EnableXServerErrorTrap() {
- DCHECK(!g_xserver_error_trap_enabled);
- XSetErrorHandler(&XServerErrorHandler);
- g_xserver_error_trap_enabled = true;
- g_last_xserver_error_code = 0;
-}
-
-int GetLastXServerError() {
- DCHECK(g_xserver_error_trap_enabled);
- XSetErrorHandler(NULL);
- g_xserver_error_trap_enabled = false;
- return g_last_xserver_error_code;
-}
-
-#endif // !defined(TOOLKIT_GTK)
-
-} // namespace
-
-namespace media {
-
-XServerPixelBuffer::XServerPixelBuffer()
- : display_(NULL), root_window_(0),
- x_image_(NULL),
- shm_segment_info_(NULL), shm_pixmap_(0), shm_gc_(NULL) {
-}
-
-XServerPixelBuffer::~XServerPixelBuffer() {
- Release();
-}
-
-void XServerPixelBuffer::Release() {
- if (x_image_) {
- XDestroyImage(x_image_);
- x_image_ = NULL;
- }
- if (shm_pixmap_) {
- XFreePixmap(display_, shm_pixmap_);
- shm_pixmap_ = 0;
- }
- if (shm_gc_) {
- XFreeGC(display_, shm_gc_);
- shm_gc_ = NULL;
- }
- if (shm_segment_info_) {
- if (shm_segment_info_->shmaddr != reinterpret_cast<char*>(-1))
- shmdt(shm_segment_info_->shmaddr);
- if (shm_segment_info_->shmid != -1)
- shmctl(shm_segment_info_->shmid, IPC_RMID, 0);
- delete shm_segment_info_;
- shm_segment_info_ = NULL;
- }
-}
-
-void XServerPixelBuffer::Init(Display* display,
- const webrtc::DesktopSize& screen_size) {
- Release();
- display_ = display;
- root_window_size_ = screen_size;
- int default_screen = DefaultScreen(display_);
- root_window_ = RootWindow(display_, default_screen);
- InitShm(default_screen);
-}
-
-// static
-webrtc::DesktopSize XServerPixelBuffer::GetRootWindowSize(Display* display) {
- XWindowAttributes root_attr;
- XGetWindowAttributes(display, DefaultRootWindow(display), &root_attr);
- return webrtc::DesktopSize(root_attr.width, root_attr.height);
-}
-
-void XServerPixelBuffer::InitShm(int screen) {
- Visual* default_visual = DefaultVisual(display_, screen);
- int default_depth = DefaultDepth(display_, screen);
-
- int major, minor;
- Bool havePixmaps;
- if (!XShmQueryVersion(display_, &major, &minor, &havePixmaps))
- // Shared memory not supported. CaptureRect will use the XImage API instead.
- return;
-
- bool using_shm = false;
- shm_segment_info_ = new XShmSegmentInfo;
- shm_segment_info_->shmid = -1;
- shm_segment_info_->shmaddr = reinterpret_cast<char*>(-1);
- shm_segment_info_->readOnly = False;
- x_image_ = XShmCreateImage(display_, default_visual, default_depth, ZPixmap,
- 0, shm_segment_info_, root_window_size_.width(),
- root_window_size_.height());
- if (x_image_) {
- shm_segment_info_->shmid = shmget(
- IPC_PRIVATE, x_image_->bytes_per_line * x_image_->height,
- IPC_CREAT | 0600);
- if (shm_segment_info_->shmid != -1) {
- shm_segment_info_->shmaddr = x_image_->data =
- reinterpret_cast<char*>(shmat(shm_segment_info_->shmid, 0, 0));
- if (x_image_->data != reinterpret_cast<char*>(-1)) {
- EnableXServerErrorTrap();
- using_shm = XShmAttach(display_, shm_segment_info_);
- XSync(display_, False);
- if (GetLastXServerError() != 0)
- using_shm = false;
- if (using_shm) {
- VLOG(1) << "Using X shared memory segment "
- << shm_segment_info_->shmid;
- }
- }
- } else {
- LOG(WARNING) << "Failed to get shared memory segment. "
- "Performance may be degraded.";
- }
- }
-
- if (!using_shm) {
- LOG(WARNING) << "Not using shared memory. Performance may be degraded.";
- Release();
- return;
- }
-
- if (havePixmaps)
- havePixmaps = InitPixmaps(default_depth);
-
- shmctl(shm_segment_info_->shmid, IPC_RMID, 0);
- shm_segment_info_->shmid = -1;
-
- VLOG(1) << "Using X shared memory extension v" << major << "." << minor
- << " with" << (havePixmaps?"":"out") << " pixmaps.";
-}
-
-bool XServerPixelBuffer::InitPixmaps(int depth) {
- if (XShmPixmapFormat(display_) != ZPixmap)
- return false;
-
- EnableXServerErrorTrap();
- shm_pixmap_ = XShmCreatePixmap(display_, root_window_,
- shm_segment_info_->shmaddr,
- shm_segment_info_,
- root_window_size_.width(),
- root_window_size_.height(), depth);
- XSync(display_, False);
- if (GetLastXServerError() != 0) {
- // |shm_pixmap_| is not not valid because the request was not processed
- // by the X Server, so zero it.
- shm_pixmap_ = 0;
- return false;
- }
-
- EnableXServerErrorTrap();
- XGCValues shm_gc_values;
- shm_gc_values.subwindow_mode = IncludeInferiors;
- shm_gc_values.graphics_exposures = False;
- shm_gc_ = XCreateGC(display_, root_window_,
- GCSubwindowMode | GCGraphicsExposures,
- &shm_gc_values);
- XSync(display_, False);
- if (GetLastXServerError() != 0) {
- XFreePixmap(display_, shm_pixmap_);
- shm_pixmap_ = 0;
- shm_gc_ = 0; // See shm_pixmap_ comment above.
- return false;
- }
-
- return true;
-}
-
-void XServerPixelBuffer::Synchronize() {
- if (shm_segment_info_ && !shm_pixmap_) {
- // XShmGetImage can fail if the display is being reconfigured.
- EnableXServerErrorTrap();
- XShmGetImage(display_, root_window_, x_image_, 0, 0, AllPlanes);
- GetLastXServerError();
- }
-}
-
-uint8* XServerPixelBuffer::CaptureRect(const webrtc::DesktopRect& rect) {
- DCHECK_LE(rect.right(), root_window_size_.width());
- DCHECK_LE(rect.bottom(), root_window_size_.height());
-
- if (shm_segment_info_) {
- if (shm_pixmap_) {
- XCopyArea(display_, root_window_, shm_pixmap_, shm_gc_,
- rect.left(), rect.top(), rect.width(), rect.height(),
- rect.left(), rect.top());
- XSync(display_, False);
- }
- return reinterpret_cast<uint8*>(x_image_->data) +
- rect.top() * x_image_->bytes_per_line +
- rect.left() * x_image_->bits_per_pixel / 8;
- } else {
- if (x_image_)
- XDestroyImage(x_image_);
- x_image_ = XGetImage(display_, root_window_, rect.left(), rect.top(),
- rect.width(), rect.height(), AllPlanes, ZPixmap);
- return reinterpret_cast<uint8*>(x_image_->data);
- }
-}
-
-int XServerPixelBuffer::GetStride() const {
- return x_image_->bytes_per_line;
-}
-
-int XServerPixelBuffer::GetDepth() const {
- return x_image_->depth;
-}
-
-int XServerPixelBuffer::GetBitsPerPixel() const {
- return x_image_->bits_per_pixel;
-}
-
-int XServerPixelBuffer::GetRedMask() const {
- return x_image_->red_mask;
-}
-
-int XServerPixelBuffer::GetBlueMask() const {
- return x_image_->blue_mask;
-}
-
-int XServerPixelBuffer::GetGreenMask() const {
- return x_image_->green_mask;
-}
-
-} // namespace media
diff --git a/media/video/capture/screen/x11/x_server_pixel_buffer.h b/media/video/capture/screen/x11/x_server_pixel_buffer.h
deleted file mode 100644
index 40a1678..0000000
--- a/media/video/capture/screen/x11/x_server_pixel_buffer.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Don't include this file in any .h files because it pulls in some X headers.
-
-#ifndef MEDIA_VIDEO_CAPTURE_SCREEN_X11_X_SERVER_PIXEL_BUFFER_H_
-#define MEDIA_VIDEO_CAPTURE_SCREEN_X11_X_SERVER_PIXEL_BUFFER_H_
-
-#include "base/basictypes.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
-
-namespace media {
-
-// A class to allow the X server's pixel buffer to be accessed as efficiently
-// as possible.
-class XServerPixelBuffer {
- public:
- XServerPixelBuffer();
- ~XServerPixelBuffer();
-
- void Release();
-
- // Allocate (or reallocate) the pixel buffer with the given size, which is
- // assumed to be the current size of the root window.
- // |screen_size| should either come from GetRootWindowSize(), or
- // from a recent ConfigureNotify event on the root window.
- void Init(Display* display, const webrtc::DesktopSize& screen_size);
-
- // Request the current size of the root window from the X Server.
- static webrtc::DesktopSize GetRootWindowSize(Display* display);
-
- // If shared memory is being used without pixmaps, synchronize this pixel
- // buffer with the root window contents (otherwise, this is a no-op).
- // This is to avoid doing a full-screen capture for each individual
- // rectangle in the capture list, when it only needs to be done once at the
- // beginning.
- void Synchronize();
-
- // Capture the specified rectangle and return a pointer to its top-left pixel
- // or NULL if capture fails. The returned pointer remains valid until the next
- // call to CaptureRect.
- // In the case where the full-screen data is captured by Synchronize(), this
- // simply returns the pointer without doing any more work.
- // The caller must ensure that |rect| is no larger than the screen size
- // supplied to Init().
- uint8* CaptureRect(const webrtc::DesktopRect& rect);
-
- // Return information about the most recent capture. This is only guaranteed
- // to be valid between CaptureRect calls.
- int GetStride() const;
- int GetDepth() const;
- int GetBitsPerPixel() const;
- int GetRedMask() const;
- int GetBlueMask() const;
- int GetGreenMask() const;
-
- private:
- void InitShm(int screen);
- bool InitPixmaps(int depth);
-
- Display* display_;
- Window root_window_;
- webrtc::DesktopSize root_window_size_;
- XImage* x_image_;
- XShmSegmentInfo* shm_segment_info_;
- Pixmap shm_pixmap_;
- GC shm_gc_;
-
- DISALLOW_COPY_AND_ASSIGN(XServerPixelBuffer);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_CAPTURE_SCREEN_X11_X_SERVER_PIXEL_BUFFER_H_