diff options
74 files changed, 190 insertions, 5413 deletions
diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 4e5944a..0ebc992 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -1171,6 +1171,9 @@ ], }], ['enable_webrtc==1', { + 'dependencies': [ + '../third_party/webrtc/modules/modules.gyp:desktop_capture', + ], 'sources': [ 'browser/renderer_host/media/peer_connection_tracker_host.cc', 'browser/renderer_host/media/peer_connection_tracker_host.h', diff --git a/media/media.gyp b/media/media.gyp index 2b98fb1..b37d51e 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -22,6 +22,8 @@ 'media_use_libvpx%': 1, }], # Screen capturer works only on Windows, OSX and Linux (with X11). + # TODO(sergeyu): Remove this variable once screen_capture_device.cc is + # moved to content. ['OS=="win" or OS=="mac" or (OS=="linux" and use_x11==1)', { 'screen_capture_supported%': 1, }, { @@ -383,36 +385,11 @@ 'video/capture/mac/video_capture_device_mac.mm', 'video/capture/mac/video_capture_device_qtkit_mac.h', 'video/capture/mac/video_capture_device_qtkit_mac.mm', - 'video/capture/screen/differ.cc', - 'video/capture/screen/differ.h', - 'video/capture/screen/differ_block.cc', - 'video/capture/screen/differ_block.h', - 'video/capture/screen/mac/desktop_configuration.h', - 'video/capture/screen/mac/desktop_configuration.mm', - 'video/capture/screen/mac/scoped_pixel_buffer_object.cc', - 'video/capture/screen/mac/scoped_pixel_buffer_object.h', - 'video/capture/screen/mouse_cursor_shape.h', + + # TODO(sergeyu): Move screen_capture_device.cc to content and remove it + # from here. 'video/capture/screen/screen_capture_device.cc', 'video/capture/screen/screen_capture_device.h', - 'video/capture/screen/screen_capture_frame_queue.cc', - 'video/capture/screen/screen_capture_frame_queue.h', - 'video/capture/screen/screen_capturer.h', - 'video/capture/screen/screen_capturer_fake.cc', - 'video/capture/screen/screen_capturer_fake.h', - 'video/capture/screen/screen_capturer_helper.cc', - 'video/capture/screen/screen_capturer_helper.h', - 'video/capture/screen/screen_capturer_mac.mm', - 'video/capture/screen/screen_capturer_null.cc', - 'video/capture/screen/screen_capturer_win.cc', - 'video/capture/screen/screen_capturer_x11.cc', - 'video/capture/screen/shared_desktop_frame.cc', - 'video/capture/screen/shared_desktop_frame.h', - 'video/capture/screen/win/desktop.cc', - 'video/capture/screen/win/desktop.h', - 'video/capture/screen/win/scoped_thread_desktop.cc', - 'video/capture/screen/win/scoped_thread_desktop.h', - 'video/capture/screen/x11/x_server_pixel_buffer.cc', - 'video/capture/screen/x11/x_server_pixel_buffer.h', 'video/capture/video_capture.h', 'video/capture/video_capture_device.h', 'video/capture/video_capture_device_dummy.cc', @@ -475,11 +452,6 @@ 'USE_NEON' ], }], - ['OS!="linux" or use_x11==1', { - 'sources!': [ - 'video/capture/screen/screen_capturer_null.cc', - ] - }], ['OS!="ios"', { 'dependencies': [ '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', @@ -999,12 +971,7 @@ 'filters/video_decoder_selector_unittest.cc', 'filters/video_frame_stream_unittest.cc', 'filters/video_renderer_base_unittest.cc', - 'video/capture/screen/differ_block_unittest.cc', - 'video/capture/screen/differ_unittest.cc', 'video/capture/screen/screen_capture_device_unittest.cc', - 'video/capture/screen/screen_capturer_helper_unittest.cc', - 'video/capture/screen/screen_capturer_mac_unittest.cc', - 'video/capture/screen/screen_capturer_unittest.cc', 'video/capture/video_capture_device_unittest.cc', 'webm/cluster_builder.cc', 'webm/cluster_builder.h', @@ -1160,19 +1127,6 @@ 'base/mock_filters.h', 'base/test_helpers.cc', 'base/test_helpers.h', - 'video/capture/screen/screen_capturer_mock_objects.cc', - 'video/capture/screen/screen_capturer_mock_objects.h', - ], - 'conditions': [ - ['screen_capture_supported==1', { - 'dependencies': [ - '../third_party/webrtc/modules/modules.gyp:desktop_capture', - ], - }, { - 'sources/': [ - ['exclude', '^video/capture/screen/'], - ], - }], ], }, ], @@ -1317,8 +1271,6 @@ 'base/simd/convert_rgb_to_yuv_sse2.cc', 'base/simd/convert_rgb_to_yuv_ssse3.cc', 'base/simd/filter_yuv_sse2.cc', - 'video/capture/screen/differ_block_sse2.cc', - 'video/capture/screen/differ_block_sse2.h', ], }, { 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_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(®ion); - ASSERT_TRUE(region.is_empty()); -} - -TEST_F(ScreenCapturerHelperTest, InvalidateRegion) { - DesktopRegion region; - capturer_helper_.TakeInvalidRegion(®ion); - ASSERT_TRUE(region.is_empty()); - - region.SetRect(DesktopRect::MakeXYWH(1, 2, 3, 4)); - capturer_helper_.InvalidateRegion(region); - capturer_helper_.TakeInvalidRegion(®ion); - 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(®ion); - 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(®ion); - 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(®ion); - ASSERT_TRUE(Equals(RectToRegion(DesktopRect()), region)); - - capturer_helper_.InvalidateRegion( - RectToRegion(DesktopRect::MakeXYWH(7, 7, 1, 1))); - capturer_helper_.TakeInvalidRegion(®ion); - 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(®ion); - 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(®ion); - 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(®ion); - 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(®ion); - 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(®ion); - 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(®ion); - - // 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(), - ®ion); - 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_ diff --git a/remoting/codec/DEPS b/remoting/codec/DEPS index 913ea7d..8c70163 100644 --- a/remoting/codec/DEPS +++ b/remoting/codec/DEPS @@ -1,5 +1,4 @@ include_rules = [ - "+media/video/capture/screen", "+remoting/protocol", "+google/protobuf", diff --git a/remoting/host/DEPS b/remoting/host/DEPS index cadbcd3..ef945f3 100644 --- a/remoting/host/DEPS +++ b/remoting/host/DEPS @@ -1,5 +1,4 @@ include_rules = [ - "+media/video/capture/screen", "+net", "+remoting/codec", "+remoting/protocol", diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc index 2a05104..e6e2db3 100644 --- a/remoting/host/basic_desktop_environment.cc +++ b/remoting/host/basic_desktop_environment.cc @@ -7,11 +7,11 @@ #include "base/bind.h" #include "base/logging.h" #include "base/single_thread_task_runner.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/client_session_control.h" #include "remoting/host/input_injector.h" #include "remoting/host/screen_controls.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace remoting { @@ -44,13 +44,13 @@ std::string BasicDesktopEnvironment::GetCapabilities() const { void BasicDesktopEnvironment::SetCapabilities(const std::string& capabilities) { } -scoped_ptr<media::ScreenCapturer> +scoped_ptr<webrtc::ScreenCapturer> BasicDesktopEnvironment::CreateVideoCapturer() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); // The basic desktop environment does not use X DAMAGE, since it is // broken on many systems - see http://crbug.com/73423. - return media::ScreenCapturer::Create(); + return scoped_ptr<webrtc::ScreenCapturer>(webrtc::ScreenCapturer::Create()); } BasicDesktopEnvironment::BasicDesktopEnvironment( diff --git a/remoting/host/basic_desktop_environment.h b/remoting/host/basic_desktop_environment.h index 6d4a88a..10429d1 100644 --- a/remoting/host/basic_desktop_environment.h +++ b/remoting/host/basic_desktop_environment.h @@ -26,7 +26,7 @@ class BasicDesktopEnvironment : public DesktopEnvironment { virtual scoped_ptr<AudioCapturer> CreateAudioCapturer() OVERRIDE; virtual scoped_ptr<InputInjector> CreateInputInjector() OVERRIDE; virtual scoped_ptr<ScreenControls> CreateScreenControls() OVERRIDE; - virtual scoped_ptr<media::ScreenCapturer> CreateVideoCapturer() OVERRIDE; + virtual scoped_ptr<webrtc::ScreenCapturer> CreateVideoCapturer() OVERRIDE; virtual std::string GetCapabilities() const OVERRIDE; virtual void SetCapabilities(const std::string& capabilities) OVERRIDE; diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index a0dc3d0..614b466 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -48,7 +48,7 @@ class DesktopEnvironmentFactory; // // 2. We listen for incoming connection using libjingle. We will create // a ConnectionToClient object that wraps around linjingle for transport. -// A VideoScheduler is created with an Encoder and a media::ScreenCapturer. +// A VideoScheduler is created with an Encoder and a webrtc::ScreenCapturer. // A ConnectionToClient is added to the ScreenRecorder for transporting // the screen captures. An InputStub is created and registered with the // ConnectionToClient to receive mouse / keyboard events from the remote diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index f7b56e2..e780eda 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -6,13 +6,13 @@ #include "base/bind_helpers.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop_proxy.h" -#include "media/video/capture/screen/screen_capturer_fake.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/host_mock_objects.h" +#include "remoting/host/screen_capturer_fake.h" #include "remoting/jingle_glue/mock_objects.h" #include "remoting/proto/video.pb.h" #include "remoting/protocol/errors.h" @@ -231,7 +231,7 @@ class ChromotingHostTest : public testing::Test { host_->OnSessionRouteChange(get_client(0), channel_name, route); } - // Creates a DesktopEnvironment with a fake media::ScreenCapturer, to mock + // Creates a DesktopEnvironment with a fake webrtc::ScreenCapturer, to mock // DesktopEnvironmentFactory::Create(). DesktopEnvironment* CreateDesktopEnvironment() { MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment(); @@ -261,10 +261,10 @@ class ChromotingHostTest : public testing::Test { return input_injector; } - // Creates a fake media::ScreenCapturer, to mock + // Creates a fake webrtc::ScreenCapturer, to mock // DesktopEnvironment::CreateVideoCapturer(). - media::ScreenCapturer* CreateVideoCapturer() { - return new media::ScreenCapturerFake(); + webrtc::ScreenCapturer* CreateVideoCapturer() { + return new ScreenCapturerFake(); } void DisconnectAllClients() { diff --git a/remoting/host/chromoting_messages.h b/remoting/host/chromoting_messages.h index 96ff800..e56b0f3 100644 --- a/remoting/host/chromoting_messages.h +++ b/remoting/host/chromoting_messages.h @@ -6,12 +6,12 @@ #define REMOTING_HOST_CHROMOTING_MESSAGES_H_ #include "ipc/ipc_platform_file.h" -#include "media/video/capture/screen/mouse_cursor_shape.h" #include "net/base/ip_endpoint.h" #include "remoting/host/chromoting_param_traits.h" #include "remoting/host/screen_resolution.h" #include "remoting/protocol/transport.h" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" +#include "third_party/webrtc/modules/desktop_capture/mouse_cursor_shape.h" #endif // REMOTING_HOST_CHROMOTING_MESSAGES_H_ @@ -138,7 +138,7 @@ IPC_MESSAGE_CONTROL3(ChromotingDesktopNetworkMsg_CreateSharedBuffer, IPC_MESSAGE_CONTROL1(ChromotingDesktopNetworkMsg_ReleaseSharedBuffer, int /* id */) -IPC_STRUCT_TRAITS_BEGIN(media::MouseCursorShape) +IPC_STRUCT_TRAITS_BEGIN(webrtc::MouseCursorShape) IPC_STRUCT_TRAITS_MEMBER(size) IPC_STRUCT_TRAITS_MEMBER(hotspot) IPC_STRUCT_TRAITS_MEMBER(data) @@ -174,7 +174,7 @@ IPC_MESSAGE_CONTROL1(ChromotingDesktopNetworkMsg_CaptureCompleted, // Carries a cursor share update from the desktop session agent to the client. IPC_MESSAGE_CONTROL1(ChromotingDesktopNetworkMsg_CursorShapeChanged, - media::MouseCursorShape /* cursor_shape */ ) + webrtc::MouseCursorShape /* cursor_shape */ ) // Carries a clipboard event from the desktop session agent to the client. // |serialized_event| is a serialized protocol::ClipboardEvent. diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index f4b72c7..27cd910 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -7,7 +7,6 @@ #include <algorithm> #include "base/message_loop_proxy.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/base/capabilities.h" #include "remoting/codec/audio_encoder.h" #include "remoting/codec/audio_encoder_opus.h" @@ -28,6 +27,7 @@ #include "remoting/protocol/client_stub.h" #include "remoting/protocol/clipboard_thread_proxy.h" #include "remoting/protocol/pairing_registry.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" // Default DPI to assume for old clients that use notifyClientDimensions. const int kDefaultDPI = 96; diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index 4b55caf..99da514 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc @@ -3,17 +3,17 @@ // found in the LICENSE file. #include "base/message_loop.h" -#include "media/video/capture/screen/screen_capturer_fake.h" -#include "media/video/capture/screen/screen_capturer_mock_objects.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/constants.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/client_session.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/host_mock_objects.h" +#include "remoting/host/screen_capturer_fake.h" #include "remoting/protocol/protocol_mock_objects.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" namespace remoting { @@ -69,7 +69,7 @@ class ClientSessionTest : public testing::Test { void StopClientSession(); protected: - // Creates a DesktopEnvironment with a fake media::ScreenCapturer, to mock + // Creates a DesktopEnvironment with a fake webrtc::ScreenCapturer, to mock // DesktopEnvironmentFactory::Create(). DesktopEnvironment* CreateDesktopEnvironment(); @@ -77,9 +77,9 @@ class ClientSessionTest : public testing::Test { // DesktopEnvironment::CreateInputInjector(). InputInjector* CreateInputInjector(); - // Creates a fake media::ScreenCapturer, to mock + // Creates a fake webrtc::ScreenCapturer, to mock // DesktopEnvironment::CreateVideoCapturer(). - media::ScreenCapturer* CreateVideoCapturer(); + webrtc::ScreenCapturer* CreateVideoCapturer(); // Notifies the client session that the client connection has been // authenticated and channels have been connected. This effectively enables @@ -209,8 +209,8 @@ InputInjector* ClientSessionTest::CreateInputInjector() { return input_injector_.release(); } -media::ScreenCapturer* ClientSessionTest::CreateVideoCapturer() { - return new media::ScreenCapturerFake(); +webrtc::ScreenCapturer* ClientSessionTest::CreateVideoCapturer() { + return new ScreenCapturerFake(); } void ClientSessionTest::ConnectClientSession() { @@ -487,9 +487,9 @@ TEST_F(ClientSessionTest, ClampMouseEvents) { Expectation connected = authenticated; int input_x[3] = { -999, 100, 999 }; - int expected_x[3] = { 0, 100, media::ScreenCapturerFake::kWidth - 1 }; + int expected_x[3] = { 0, 100, ScreenCapturerFake::kWidth - 1 }; int input_y[3] = { -999, 50, 999 }; - int expected_y[3] = { 0, 50, media::ScreenCapturerFake::kHeight - 1 }; + int expected_y[3] = { 0, 50, ScreenCapturerFake::kHeight - 1 }; protocol::MouseEvent expected_event; for (int j = 0; j < 3; j++) { diff --git a/remoting/host/desktop_environment.h b/remoting/host/desktop_environment.h index 660744a..1fa9ccd 100644 --- a/remoting/host/desktop_environment.h +++ b/remoting/host/desktop_environment.h @@ -17,9 +17,9 @@ namespace base { class SingleThreadTaskRunner; } // namespace base -namespace media { +namespace webrtc { class ScreenCapturer; -} // namespace media +} // namespace webrtc namespace remoting { @@ -39,7 +39,7 @@ class DesktopEnvironment { virtual scoped_ptr<AudioCapturer> CreateAudioCapturer() = 0; virtual scoped_ptr<InputInjector> CreateInputInjector() = 0; virtual scoped_ptr<ScreenControls> CreateScreenControls() = 0; - virtual scoped_ptr<media::ScreenCapturer> CreateVideoCapturer() = 0; + virtual scoped_ptr<webrtc::ScreenCapturer> CreateVideoCapturer() = 0; // Returns the set of all capabilities supported by |this|. virtual std::string GetCapabilities() const = 0; diff --git a/remoting/host/desktop_process_unittest.cc b/remoting/host/desktop_process_unittest.cc index 6a7623c..71155e7 100644 --- a/remoting/host/desktop_process_unittest.cc +++ b/remoting/host/desktop_process_unittest.cc @@ -15,17 +15,17 @@ #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_message.h" -#include "media/video/capture/screen/screen_capturer_fake.h" #include "remoting/base/auto_thread.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/chromoting_messages.h" #include "remoting/host/desktop_process.h" #include "remoting/host/host_exit_codes.h" #include "remoting/host/host_mock_objects.h" +#include "remoting/host/screen_capturer_fake.h" #include "remoting/host/screen_resolution.h" #include "remoting/protocol/protocol_mock_objects.h" -#include "testing/gmock_mutant.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; @@ -105,7 +105,7 @@ class DesktopProcessTest : public testing::Test { void ConnectNetworkChannel(IPC::PlatformFileForTransit desktop_process); void OnDesktopAttached(IPC::PlatformFileForTransit desktop_process); - // Creates a DesktopEnvironment with a fake media::ScreenCapturer, to mock + // Creates a DesktopEnvironment with a fake webrtc::ScreenCapturer, to mock // DesktopEnvironmentFactory::Create(). DesktopEnvironment* CreateDesktopEnvironment(); @@ -113,9 +113,9 @@ class DesktopProcessTest : public testing::Test { // DesktopEnvironment::CreateInputInjector(). InputInjector* CreateInputInjector(); - // Creates a fake media::ScreenCapturer, to mock + // Creates a fake webrtc::ScreenCapturer, to mock // DesktopEnvironment::CreateVideoCapturer(). - media::ScreenCapturer* CreateVideoCapturer(); + webrtc::ScreenCapturer* CreateVideoCapturer(); // Disconnects the daemon-to-desktop channel causing the desktop process to // exit. @@ -219,8 +219,8 @@ InputInjector* DesktopProcessTest::CreateInputInjector() { return input_injector; } -media::ScreenCapturer* DesktopProcessTest::CreateVideoCapturer() { - return new media::ScreenCapturerFake(); +webrtc::ScreenCapturer* DesktopProcessTest::CreateVideoCapturer() { + return new ScreenCapturerFake(); } void DesktopProcessTest::DisconnectChannels() { diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc index 490ef90..581f2c1 100644 --- a/remoting/host/desktop_session_agent.cc +++ b/remoting/host/desktop_session_agent.cc @@ -320,9 +320,11 @@ void DesktopSessionAgent::OnCaptureCompleted(webrtc::DesktopFrame* frame) { } void DesktopSessionAgent::OnCursorShapeChanged( - scoped_ptr<media::MouseCursorShape> cursor_shape) { + webrtc::MouseCursorShape* cursor_shape) { DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); + scoped_ptr<webrtc::MouseCursorShape> owned_cursor(cursor_shape); + SendToNetwork(new ChromotingDesktopNetworkMsg_CursorShapeChanged( *cursor_shape)); } @@ -412,11 +414,11 @@ void DesktopSessionAgent::OnCaptureFrame() { return; } - // media::ScreenCapturer supports a very few (currently 2) outstanding capture - // requests. The requests are serialized on |video_capture_task_runner()| task - // runner. If the client issues more requests, pixel data in captured frames - // will likely be corrupted but stability of media::ScreenCapturer will not be - // affected. + // webrtc::ScreenCapturer supports a very few (currently 2) outstanding + // capture requests. The requests are serialized on + // |video_capture_task_runner()| task runner. If the client issues more + // requests, pixel data in captured frames will likely be corrupted but + // stability of webrtc::ScreenCapturer will not be affected. video_capturer_->Capture(webrtc::DesktopRegion()); } diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h index e121c94..55196db 100644 --- a/remoting/host/desktop_session_agent.h +++ b/remoting/host/desktop_session_agent.h @@ -15,10 +15,10 @@ #include "base/memory/weak_ptr.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_platform_file.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/host/client_session_control.h" #include "remoting/protocol/clipboard_stub.h" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace IPC { class ChannelProxy; @@ -47,7 +47,7 @@ class DesktopSessionAgent : public base::RefCountedThreadSafe<DesktopSessionAgent>, public IPC::Listener, public webrtc::DesktopCapturer::Callback, - public media::ScreenCapturer::MouseShapeObserver, + public webrtc::ScreenCapturer::MouseShapeObserver, public ClientSessionControl { public: class Delegate { @@ -78,9 +78,9 @@ class DesktopSessionAgent virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE; virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) OVERRIDE; - // media::ScreenCapturer::MouseShapeObserver implementation. + // webrtc::ScreenCapturer::MouseShapeObserver implementation. virtual void OnCursorShapeChanged( - scoped_ptr<media::MouseCursorShape> cursor_shape) OVERRIDE; + webrtc::MouseCursorShape* cursor_shape) OVERRIDE; // Forwards a local clipboard event though the IPC channel to the network // process. @@ -214,7 +214,7 @@ class DesktopSessionAgent bool started_; // Captures the screen. - scoped_ptr<media::ScreenCapturer> video_capturer_; + scoped_ptr<webrtc::ScreenCapturer> video_capturer_; // Keep reference to the last frame sent to make sure shared buffer is alive // before it's received. diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc index 1f2bbc5..c32c2bb 100644 --- a/remoting/host/desktop_session_proxy.cc +++ b/remoting/host/desktop_session_proxy.cc @@ -137,10 +137,10 @@ scoped_ptr<ScreenControls> DesktopSessionProxy::CreateScreenControls() { return scoped_ptr<ScreenControls>(new IpcScreenControls(this)); } -scoped_ptr<media::ScreenCapturer> DesktopSessionProxy::CreateVideoCapturer() { +scoped_ptr<webrtc::ScreenCapturer> DesktopSessionProxy::CreateVideoCapturer() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); - return scoped_ptr<media::ScreenCapturer>(new IpcVideoFrameCapturer(this)); + return scoped_ptr<webrtc::ScreenCapturer>(new IpcVideoFrameCapturer(this)); } std::string DesktopSessionProxy::GetCapabilities() const { @@ -487,10 +487,10 @@ void DesktopSessionProxy::OnCaptureCompleted( } void DesktopSessionProxy::OnCursorShapeChanged( - const media::MouseCursorShape& cursor_shape) { + const webrtc::MouseCursorShape& cursor_shape) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); - PostCursorShape(scoped_ptr<media::MouseCursorShape>( - new media::MouseCursorShape(cursor_shape))); + PostCursorShape(scoped_ptr<webrtc::MouseCursorShape>( + new webrtc::MouseCursorShape(cursor_shape))); } void DesktopSessionProxy::OnInjectClipboardEvent( @@ -519,7 +519,7 @@ void DesktopSessionProxy::PostCaptureCompleted( } void DesktopSessionProxy::PostCursorShape( - scoped_ptr<media::MouseCursorShape> cursor_shape) { + scoped_ptr<webrtc::MouseCursorShape> cursor_shape) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); video_capture_task_runner_->PostTask( diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h index 198bd6f..ae8cc4d 100644 --- a/remoting/host/desktop_session_proxy.h +++ b/remoting/host/desktop_session_proxy.h @@ -15,13 +15,13 @@ #include "base/sequenced_task_runner_helpers.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_platform_file.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/screen_resolution.h" #include "remoting/proto/event.pb.h" #include "remoting/protocol/clipboard_stub.h" #include "third_party/skia/include/core/SkRegion.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace base { class SingleThreadTaskRunner; @@ -77,7 +77,7 @@ class DesktopSessionProxy scoped_ptr<AudioCapturer> CreateAudioCapturer(); scoped_ptr<InputInjector> CreateInputInjector(); scoped_ptr<ScreenControls> CreateScreenControls(); - scoped_ptr<media::ScreenCapturer> CreateVideoCapturer(); + scoped_ptr<webrtc::ScreenCapturer> CreateVideoCapturer(); std::string GetCapabilities() const; void SetCapabilities(const std::string& capabilities); @@ -101,7 +101,7 @@ class DesktopSessionProxy // on the |audio_capture_task_runner_| thread. void SetAudioCapturer(const base::WeakPtr<IpcAudioCapturer>& audio_capturer); - // APIs used to implement the media::ScreenCapturer interface. These must be + // APIs used to implement the webrtc::ScreenCapturer interface. These must be // called on the |video_capture_task_runner_| thread. void InvalidateRegion(const SkRegion& invalid_region); void CaptureFrame(); @@ -148,7 +148,7 @@ class DesktopSessionProxy void OnCaptureCompleted(const SerializedDesktopFrame& serialized_frame); // Handles CursorShapeChanged notification from the desktop session agent. - void OnCursorShapeChanged(const media::MouseCursorShape& cursor_shape); + void OnCursorShapeChanged(const webrtc::MouseCursorShape& cursor_shape); // Handles InjectClipboardEvent request from the desktop integration process. void OnInjectClipboardEvent(const std::string& serialized_event); @@ -159,7 +159,7 @@ class DesktopSessionProxy // Posts OnCursorShapeChanged() to |video_capturer_| on the video thread, // passing |cursor_shape|. - void PostCursorShape(scoped_ptr<media::MouseCursorShape> cursor_shape); + void PostCursorShape(scoped_ptr<webrtc::MouseCursorShape> cursor_shape); // Sends a message to the desktop session agent. The message is silently // deleted if the channel is broken. diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc index c4739ee..ea1fabb 100644 --- a/remoting/host/host_mock_objects.cc +++ b/remoting/host/host_mock_objects.cc @@ -6,7 +6,6 @@ #include "base/message_loop_proxy.h" #include "base/single_thread_task_runner.h" -#include "media/video/capture/screen/screen_capturer.h" #include "net/base/ip_endpoint.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/codec/audio_encoder.h" @@ -15,6 +14,7 @@ #include "remoting/host/input_injector.h" #include "remoting/proto/event.pb.h" #include "remoting/protocol/transport.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace remoting { @@ -34,9 +34,9 @@ scoped_ptr<ScreenControls> MockDesktopEnvironment::CreateScreenControls() { return scoped_ptr<ScreenControls>(CreateScreenControlsPtr()); } -scoped_ptr<media::ScreenCapturer> +scoped_ptr<webrtc::ScreenCapturer> MockDesktopEnvironment::CreateVideoCapturer() { - return scoped_ptr<media::ScreenCapturer>(CreateVideoCapturerPtr()); + return scoped_ptr<webrtc::ScreenCapturer>(CreateVideoCapturerPtr()); } MockDesktopEnvironmentFactory::MockDesktopEnvironmentFactory() {} diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index 15bdc6d..32df6d2 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -31,7 +31,7 @@ class MockDesktopEnvironment : public DesktopEnvironment { MOCK_METHOD0(CreateAudioCapturerPtr, AudioCapturer*()); MOCK_METHOD0(CreateInputInjectorPtr, InputInjector*()); MOCK_METHOD0(CreateScreenControlsPtr, ScreenControls*()); - MOCK_METHOD0(CreateVideoCapturerPtr, media::ScreenCapturer*()); + MOCK_METHOD0(CreateVideoCapturerPtr, webrtc::ScreenCapturer*()); MOCK_CONST_METHOD0(GetCapabilities, std::string()); MOCK_METHOD1(SetCapabilities, void(const std::string&)); @@ -39,7 +39,7 @@ class MockDesktopEnvironment : public DesktopEnvironment { virtual scoped_ptr<AudioCapturer> CreateAudioCapturer() OVERRIDE; virtual scoped_ptr<InputInjector> CreateInputInjector() OVERRIDE; virtual scoped_ptr<ScreenControls> CreateScreenControls() OVERRIDE; - virtual scoped_ptr<media::ScreenCapturer> CreateVideoCapturer() OVERRIDE; + virtual scoped_ptr<webrtc::ScreenCapturer> CreateVideoCapturer() OVERRIDE; }; class MockClientSessionControl : public ClientSessionControl { diff --git a/remoting/host/input_injector_mac.cc b/remoting/host/input_injector_mac.cc index 8993e86..0fc0379 100644 --- a/remoting/host/input_injector_mac.cc +++ b/remoting/host/input_injector_mac.cc @@ -15,13 +15,13 @@ #include "base/mac/scoped_cftyperef.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" -#include "media/video/capture/screen/mac/desktop_configuration.h" #include "remoting/host/clipboard.h" #include "remoting/proto/internal.pb.h" #include "remoting/protocol/message_decoder.h" #include "skia/ext/skia_utils_mac.h" #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkRect.h" +#include "third_party/webrtc/modules/desktop_capture/mac/desktop_configuration.h" namespace remoting { @@ -191,9 +191,9 @@ void InputInjectorMac::Core::InjectMouseEvent(const MouseEvent& event) { // response to display-changed events. VideoFrameCapturer's VideoFrames // could be augmented to include native cursor coordinates for use by // MouseClampingFilter, removing the need for translation here. - media::MacDesktopConfiguration desktop_config = - media::MacDesktopConfiguration::GetCurrent( - media::MacDesktopConfiguration::TopLeftOrigin); + webrtc::MacDesktopConfiguration desktop_config = + webrtc::MacDesktopConfiguration::GetCurrent( + webrtc::MacDesktopConfiguration::TopLeftOrigin); // Translate the mouse position into desktop coordinates. mouse_pos_ += SkIPoint::Make(desktop_config.pixel_bounds.left(), diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc index 45de6d9..c0eaec3 100644 --- a/remoting/host/ipc_desktop_environment.cc +++ b/remoting/host/ipc_desktop_environment.cc @@ -11,7 +11,6 @@ #include "base/process_util.h" #include "base/single_thread_task_runner.h" #include "ipc/ipc_sender.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/chromoting_messages.h" #include "remoting/host/client_session_control.h" @@ -19,6 +18,7 @@ #include "remoting/host/desktop_session_proxy.h" #include "remoting/host/input_injector.h" #include "remoting/host/screen_controls.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace remoting { @@ -56,7 +56,8 @@ scoped_ptr<ScreenControls> IpcDesktopEnvironment::CreateScreenControls() { return desktop_session_proxy_->CreateScreenControls(); } -scoped_ptr<media::ScreenCapturer> IpcDesktopEnvironment::CreateVideoCapturer() { +scoped_ptr<webrtc::ScreenCapturer> +IpcDesktopEnvironment::CreateVideoCapturer() { return desktop_session_proxy_->CreateVideoCapturer(); } diff --git a/remoting/host/ipc_desktop_environment.h b/remoting/host/ipc_desktop_environment.h index f0d11b9..2dee387 100644 --- a/remoting/host/ipc_desktop_environment.h +++ b/remoting/host/ipc_desktop_environment.h @@ -51,7 +51,7 @@ class IpcDesktopEnvironment : public DesktopEnvironment { virtual scoped_ptr<AudioCapturer> CreateAudioCapturer() OVERRIDE; virtual scoped_ptr<InputInjector> CreateInputInjector() OVERRIDE; virtual scoped_ptr<ScreenControls> CreateScreenControls() OVERRIDE; - virtual scoped_ptr<media::ScreenCapturer> CreateVideoCapturer() OVERRIDE; + virtual scoped_ptr<webrtc::ScreenCapturer> CreateVideoCapturer() OVERRIDE; virtual std::string GetCapabilities() const OVERRIDE; virtual void SetCapabilities(const std::string& capabilities) OVERRIDE; diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc index 7c18610..47eb36b 100644 --- a/remoting/host/ipc_desktop_environment_unittest.cc +++ b/remoting/host/ipc_desktop_environment_unittest.cc @@ -16,8 +16,6 @@ #include "ipc/ipc_listener.h" #include "ipc/ipc_message.h" #include "ipc/ipc_platform_file.h" -#include "media/video/capture/screen/screen_capturer_fake.h" -#include "media/video/capture/screen/screen_capturer_mock_objects.h" #include "remoting/base/auto_thread.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/constants.h" @@ -28,12 +26,14 @@ #include "remoting/host/desktop_session_proxy.h" #include "remoting/host/host_mock_objects.h" #include "remoting/host/ipc_desktop_environment.h" +#include "remoting/host/screen_capturer_fake.h" #include "remoting/protocol/protocol_mock_objects.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.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" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" using testing::_; using testing::AnyNumber; @@ -130,7 +130,7 @@ class IpcDesktopEnvironmentTest : public testing::Test { bool virtual_terminal); void DisconnectTerminal(int terminal_id); - // Creates a DesktopEnvironment with a fake media::ScreenCapturer, to mock + // Creates a DesktopEnvironment with a fake webrtc::ScreenCapturer, to mock // DesktopEnvironmentFactory::Create(). DesktopEnvironment* CreateDesktopEnvironment(); @@ -138,9 +138,9 @@ class IpcDesktopEnvironmentTest : public testing::Test { // DesktopEnvironment::CreateInputInjector(). InputInjector* CreateInputInjector(); - // Creates a fake media::ScreenCapturer, to mock + // Creates a fake webrtc::ScreenCapturer, to mock // DesktopEnvironment::CreateVideoCapturer(). - media::ScreenCapturer* CreateVideoCapturer(); + webrtc::ScreenCapturer* CreateVideoCapturer(); void DeleteDesktopEnvironment(); @@ -198,7 +198,7 @@ class IpcDesktopEnvironmentTest : public testing::Test { scoped_ptr<ScreenControls> screen_controls_; // The IPC screen capturer. - scoped_ptr<media::ScreenCapturer> video_capturer_; + scoped_ptr<webrtc::ScreenCapturer> video_capturer_; // Represents the desktop process running in a user session. scoped_ptr<DesktopProcess> desktop_process_; @@ -209,7 +209,7 @@ class IpcDesktopEnvironmentTest : public testing::Test { // The last |terminal_id| passed to ConnectTermina(); int terminal_id_; - media::MockScreenCapturerCallback screen_capturer_callback_; + webrtc::MockScreenCapturerCallback screen_capturer_callback_; MockClientSessionControl client_session_control_; base::WeakPtrFactory<ClientSessionControl> client_session_control_factory_; @@ -345,8 +345,8 @@ InputInjector* IpcDesktopEnvironmentTest::CreateInputInjector() { return remote_input_injector_; } -media::ScreenCapturer* IpcDesktopEnvironmentTest::CreateVideoCapturer() { - return new media::ScreenCapturerFake(); +webrtc::ScreenCapturer* IpcDesktopEnvironmentTest::CreateVideoCapturer() { + return new ScreenCapturerFake(); } void IpcDesktopEnvironmentTest::DeleteDesktopEnvironment() { diff --git a/remoting/host/ipc_video_frame_capturer.cc b/remoting/host/ipc_video_frame_capturer.cc index 695bf3c..b4120e1 100644 --- a/remoting/host/ipc_video_frame_capturer.cc +++ b/remoting/host/ipc_video_frame_capturer.cc @@ -4,9 +4,9 @@ #include "remoting/host/ipc_video_frame_capturer.h" -#include "media/video/capture/screen/mouse_cursor_shape.h" #include "remoting/host/desktop_session_proxy.h" #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" +#include "third_party/webrtc/modules/desktop_capture/mouse_cursor_shape.h" namespace remoting { @@ -50,9 +50,9 @@ void IpcVideoFrameCapturer::OnCaptureCompleted( } void IpcVideoFrameCapturer::OnCursorShapeChanged( - scoped_ptr<media::MouseCursorShape> cursor_shape) { + scoped_ptr<webrtc::MouseCursorShape> cursor_shape) { if (mouse_shape_observer_) - mouse_shape_observer_->OnCursorShapeChanged(cursor_shape.Pass()); + mouse_shape_observer_->OnCursorShapeChanged(cursor_shape.release()); } } // namespace remoting diff --git a/remoting/host/ipc_video_frame_capturer.h b/remoting/host/ipc_video_frame_capturer.h index 48ed750..1014604 100644 --- a/remoting/host/ipc_video_frame_capturer.h +++ b/remoting/host/ipc_video_frame_capturer.h @@ -7,7 +7,8 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "media/video/capture/screen/screen_capturer.h" +#include "base/memory/scoped_ptr.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace IPC { class Message; @@ -21,9 +22,9 @@ namespace remoting { class DesktopSessionProxy; -// Routes media::ScreenCapturer calls though the IPC channel to the desktop +// Routes webrtc::ScreenCapturer calls though the IPC channel to the desktop // session agent running in the desktop integration process. -class IpcVideoFrameCapturer : public media::ScreenCapturer { +class IpcVideoFrameCapturer : public webrtc::ScreenCapturer { public: explicit IpcVideoFrameCapturer( scoped_refptr<DesktopSessionProxy> desktop_session_proxy); @@ -33,7 +34,7 @@ class IpcVideoFrameCapturer : public media::ScreenCapturer { virtual void Start(Callback* callback) OVERRIDE; virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE; - // media::ScreenCapturer interface. + // webrtc::ScreenCapturer interface. virtual void SetMouseShapeObserver( MouseShapeObserver* mouse_shape_observer) OVERRIDE; @@ -41,11 +42,11 @@ class IpcVideoFrameCapturer : public media::ScreenCapturer { void OnCaptureCompleted(scoped_ptr<webrtc::DesktopFrame> frame); // Called when the cursor shape has changed. - void OnCursorShapeChanged(scoped_ptr<media::MouseCursorShape> cursor_shape); + void OnCursorShapeChanged(scoped_ptr<webrtc::MouseCursorShape> cursor_shape); private: - // Points to the callback passed to media::ScreenCapturer::Start(). - media::ScreenCapturer::Callback* callback_; + // Points to the callback passed to webrtc::ScreenCapturer::Start(). + webrtc::ScreenCapturer::Callback* callback_; MouseShapeObserver* mouse_shape_observer_; diff --git a/remoting/host/me2me_desktop_environment.cc b/remoting/host/me2me_desktop_environment.cc index 9dc6d2f..6f55262 100644 --- a/remoting/host/me2me_desktop_environment.cc +++ b/remoting/host/me2me_desktop_environment.cc @@ -6,7 +6,6 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/host/client_session_control.h" #include "remoting/host/curtain_mode.h" #include "remoting/host/desktop_resizer.h" @@ -16,6 +15,7 @@ #include "remoting/host/local_input_monitor.h" #include "remoting/host/resizing_host_observer.h" #include "remoting/host/screen_controls.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" #if defined(OS_POSIX) #include <sys/types.h> @@ -35,14 +35,15 @@ scoped_ptr<ScreenControls> Me2MeDesktopEnvironment::CreateScreenControls() { new ResizingHostObserver(DesktopResizer::Create())); } -scoped_ptr<media::ScreenCapturer> +scoped_ptr<webrtc::ScreenCapturer> Me2MeDesktopEnvironment::CreateVideoCapturer() { DCHECK(caller_task_runner()->BelongsToCurrentThread()); #if defined(OS_LINUX) - return media::ScreenCapturer::CreateWithXDamage(true); + return scoped_ptr<webrtc::ScreenCapturer>( + webrtc::ScreenCapturer::CreateWithXDamage(true)); #else // !defined(OS_LINUX) - return media::ScreenCapturer::Create(); + return scoped_ptr<webrtc::ScreenCapturer>(webrtc::ScreenCapturer::Create()); #endif // !defined(OS_LINUX) } diff --git a/remoting/host/me2me_desktop_environment.h b/remoting/host/me2me_desktop_environment.h index 316d5c3..1153ec8 100644 --- a/remoting/host/me2me_desktop_environment.h +++ b/remoting/host/me2me_desktop_environment.h @@ -21,7 +21,7 @@ class Me2MeDesktopEnvironment : public BasicDesktopEnvironment { // DesktopEnvironment interface. virtual scoped_ptr<ScreenControls> CreateScreenControls() OVERRIDE; - virtual scoped_ptr<media::ScreenCapturer> CreateVideoCapturer() OVERRIDE; + virtual scoped_ptr<webrtc::ScreenCapturer> CreateVideoCapturer() OVERRIDE; protected: friend class Me2MeDesktopEnvironmentFactory; diff --git a/remoting/host/sas_injector_win.cc b/remoting/host/sas_injector_win.cc index 663c08d..a29d727 100644 --- a/remoting/host/sas_injector_win.cc +++ b/remoting/host/sas_injector_win.cc @@ -14,8 +14,8 @@ #include "base/utf_string_conversions.h" #include "base/win/registry.h" #include "base/win/windows_version.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/win/desktop.h" +#include "third_party/webrtc/modules/desktop_capture/win/scoped_thread_desktop.h" namespace remoting { @@ -190,16 +190,16 @@ bool SasInjectorXp::InjectSas() { const wchar_t kSasWindowClassName[] = L"SAS window class"; const wchar_t kSasWindowTitle[] = L"SAS window"; - scoped_ptr<media::Desktop> winlogon_desktop( - media::Desktop::GetDesktop(kWinlogonDesktopName)); + scoped_ptr<webrtc::Desktop> winlogon_desktop( + webrtc::Desktop::GetDesktop(kWinlogonDesktopName)); if (!winlogon_desktop.get()) { LOG_GETLASTERROR(ERROR) << "Failed to open '" << kWinlogonDesktopName << "' desktop"; return false; } - media::ScopedThreadDesktop desktop; - if (!desktop.SetThreadDesktop(winlogon_desktop.Pass())) { + webrtc::ScopedThreadDesktop desktop; + if (!desktop.SetThreadDesktop(winlogon_desktop.release())) { LOG_GETLASTERROR(ERROR) << "Failed to switch to '" << kWinlogonDesktopName << "' desktop"; return false; diff --git a/media/video/capture/screen/screen_capturer_fake.cc b/remoting/host/screen_capturer_fake.cc index 416bcbb..0a6707c 100644 --- a/media/video/capture/screen/screen_capturer_fake.cc +++ b/remoting/host/screen_capturer_fake.cc @@ -1,14 +1,14 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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/screen_capturer_fake.h" +#include "remoting/host/screen_capturer_fake.h" #include "base/logging.h" #include "base/time.h" #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" -namespace media { +namespace remoting { // ScreenCapturerFake generates a white picture of size kWidth x kHeight // with a rectangle of size kBoxWidth x kBoxHeight. The rectangle moves kSpeed @@ -61,7 +61,7 @@ void ScreenCapturerFake::Capture(const webrtc::DesktopRegion& region) { } else { frame.reset(new webrtc::BasicDesktopFrame(frame_size)); } - queue_.ReplaceCurrentFrame(frame.Pass()); + queue_.ReplaceCurrentFrame(frame.release()); } DCHECK(queue_.current_frame()); @@ -125,4 +125,4 @@ void ScreenCapturerFake::ScreenConfigurationChanged() { bytes_per_row_ = size_.width() * webrtc::DesktopFrame::kBytesPerPixel; } -} // namespace media +} // namespace remoting diff --git a/media/video/capture/screen/screen_capturer_fake.h b/remoting/host/screen_capturer_fake.h index de67fbd..ab99146 100644 --- a/media/video/capture/screen/screen_capturer_fake.h +++ b/remoting/host/screen_capturer_fake.h @@ -1,22 +1,22 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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_SCREEN_CAPTURER_FAKE_H_ -#define MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_FAKE_H_ +#ifndef REMOTING_HOST_SCREEN_CAPTURER_FAKE_H_ +#define REMOTING_HOST_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" +#include "third_party/webrtc/modules/desktop_capture/screen_capture_frame_queue.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" -namespace media { +namespace remoting { // A ScreenCapturerFake generates artificial image for testing purpose. // // ScreenCapturerFake is double-buffered as required by ScreenCapturer. -class MEDIA_EXPORT ScreenCapturerFake : public ScreenCapturer { +class ScreenCapturerFake : public webrtc::ScreenCapturer { public: // ScreenCapturerFake generates a picture of size kWidth x kHeight. static const int kWidth = 800; @@ -50,11 +50,11 @@ class MEDIA_EXPORT ScreenCapturerFake : public ScreenCapturer { int box_speed_x_; int box_speed_y_; - ScreenCaptureFrameQueue queue_; + webrtc::ScreenCaptureFrameQueue queue_; DISALLOW_COPY_AND_ASSIGN(ScreenCapturerFake); }; -} // namespace media +} // namespace remoting -#endif // MEDIA_VIDEO_CAPTURE_SCREEN_SCREEN_CAPTURER_FAKE_H_ +#endif // REMOTING_HOST_SCREEN_CAPTURER_FAKE_H_ diff --git a/remoting/host/video_scheduler.cc b/remoting/host/video_scheduler.cc index f7db4c2..f051363b 100644 --- a/remoting/host/video_scheduler.cc +++ b/remoting/host/video_scheduler.cc @@ -14,16 +14,16 @@ #include "base/stl_util.h" #include "base/sys_info.h" #include "base/time.h" -#include "media/video/capture/screen/mouse_cursor_shape.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/proto/control.pb.h" #include "remoting/proto/internal.pb.h" #include "remoting/proto/video.pb.h" #include "remoting/protocol/cursor_shape_stub.h" #include "remoting/protocol/message_decoder.h" -#include "remoting/protocol/video_stub.h" #include "remoting/protocol/util.h" +#include "remoting/protocol/video_stub.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 remoting { @@ -35,7 +35,7 @@ VideoScheduler::VideoScheduler( scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_ptr<media::ScreenCapturer> capturer, + scoped_ptr<webrtc::ScreenCapturer> capturer, scoped_ptr<VideoEncoder> encoder, protocol::CursorShapeStub* cursor_stub, protocol::VideoStub* video_stub) @@ -88,9 +88,11 @@ void VideoScheduler::OnCaptureCompleted(webrtc::DesktopFrame* frame) { } void VideoScheduler::OnCursorShapeChanged( - scoped_ptr<media::MouseCursorShape> cursor_shape) { + webrtc::MouseCursorShape* cursor_shape) { DCHECK(capture_task_runner_->BelongsToCurrentThread()); + scoped_ptr<webrtc::MouseCursorShape> owned_cursor(cursor_shape); + // Do nothing if the scheduler is being stopped. if (!capturer_) return; diff --git a/remoting/host/video_scheduler.h b/remoting/host/video_scheduler.h index 16f6247..aecc207 100644 --- a/remoting/host/video_scheduler.h +++ b/remoting/host/video_scheduler.h @@ -12,11 +12,11 @@ #include "base/memory/scoped_ptr.h" #include "base/time.h" #include "base/timer.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/codec/video_encoder.h" #include "remoting/host/capture_scheduler.h" #include "remoting/proto/video.pb.h" #include "third_party/skia/include/core/SkSize.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace base { class SingleThreadTaskRunner; @@ -36,9 +36,10 @@ class CursorShapeStub; class VideoStub; } // namespace protocol -// Class responsible for scheduling frame captures from a media::ScreenCapturer, -// delivering them to a VideoEncoder to encode, and finally passing the encoded -// video packets to the specified VideoStub to send on the network. +// Class responsible for scheduling frame captures from a +// webrtc::ScreenCapturer, delivering them to a VideoEncoder to encode, and +// finally passing the encoded video packets to the specified VideoStub to send +// on the network. // // THREADING // @@ -74,7 +75,7 @@ class VideoStub; class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, public webrtc::DesktopCapturer::Callback, - public media::ScreenCapturer::MouseShapeObserver { + public webrtc::ScreenCapturer::MouseShapeObserver { public: // Creates a VideoScheduler running capture, encode and network tasks on the // supplied TaskRunners. Video and cursor shape updates will be pumped to @@ -84,7 +85,7 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_ptr<media::ScreenCapturer> capturer, + scoped_ptr<webrtc::ScreenCapturer> capturer, scoped_ptr<VideoEncoder> encoder, protocol::CursorShapeStub* cursor_stub, protocol::VideoStub* video_stub); @@ -93,9 +94,9 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE; virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) OVERRIDE; - // media::ScreenCapturer::MouseShapeObserver implementation. + // webrtc::ScreenCapturer::MouseShapeObserver implementation. virtual void OnCursorShapeChanged( - scoped_ptr<media::MouseCursorShape> cursor_shape) OVERRIDE; + webrtc::MouseCursorShape* cursor_shape) OVERRIDE; // Starts scheduling frame captures. void Start(); @@ -160,7 +161,7 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; // Used to capture frames. Always accessed on the capture thread. - scoped_ptr<media::ScreenCapturer> capturer_; + scoped_ptr<webrtc::ScreenCapturer> capturer_; // Used to encode captured frames. Always accessed on the encode thread. scoped_ptr<VideoEncoder> encoder_; diff --git a/remoting/host/video_scheduler_unittest.cc b/remoting/host/video_scheduler_unittest.cc index 7bf17fc..e949942 100644 --- a/remoting/host/video_scheduler_unittest.cc +++ b/remoting/host/video_scheduler_unittest.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/message_loop.h" #include "base/run_loop.h" -#include "media/video/capture/screen/screen_capturer_mock_objects.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/codec/video_encoder.h" #include "remoting/proto/video.pb.h" @@ -15,6 +14,7 @@ #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/screen_capturer_mock_objects.h" using ::remoting::protocol::MockClientStub; using ::remoting::protocol::MockVideoStub; @@ -73,11 +73,11 @@ class VideoSchedulerTest : public testing::Test { virtual void SetUp() OVERRIDE; - void StartVideoScheduler(scoped_ptr<media::ScreenCapturer> capturer); + void StartVideoScheduler(scoped_ptr<webrtc::ScreenCapturer> capturer); void StopVideoScheduler(); - // media::ScreenCapturer mocks. - void OnCapturerStart(media::ScreenCapturer::Callback* callback); + // webrtc::ScreenCapturer mocks. + void OnCapturerStart(webrtc::ScreenCapturer::Callback* callback); void OnCaptureFrame(const webrtc::DesktopRegion& region); protected: @@ -94,8 +94,8 @@ class VideoSchedulerTest : public testing::Test { scoped_ptr<webrtc::DesktopFrame> frame_; - // Points to the callback passed to media::ScreenCapturer::Start(). - media::ScreenCapturer::Callback* capturer_callback_; + // Points to the callback passed to webrtc::ScreenCapturer::Start(). + webrtc::ScreenCapturer::Callback* capturer_callback_; private: DISALLOW_COPY_AND_ASSIGN(VideoSchedulerTest); @@ -114,7 +114,7 @@ void VideoSchedulerTest::SetUp() { } void VideoSchedulerTest::StartVideoScheduler( - scoped_ptr<media::ScreenCapturer> capturer) { + scoped_ptr<webrtc::ScreenCapturer> capturer) { scheduler_ = new VideoScheduler( task_runner_, // Capture task_runner_, // Encode @@ -132,7 +132,7 @@ void VideoSchedulerTest::StopVideoScheduler() { } void VideoSchedulerTest::OnCapturerStart( - media::ScreenCapturer::Callback* callback) { + webrtc::ScreenCapturer::Callback* callback) { EXPECT_FALSE(capturer_callback_); EXPECT_TRUE(callback); @@ -150,8 +150,8 @@ void VideoSchedulerTest::OnCaptureFrame(const webrtc::DesktopRegion& region) { // VideoScheduler is instructed to come to a complete stop. We expect the stop // sequence to be executed successfully. TEST_F(VideoSchedulerTest, StartAndStop) { - scoped_ptr<media::MockScreenCapturer> capturer( - new media::MockScreenCapturer()); + scoped_ptr<webrtc::MockScreenCapturer> capturer( + new webrtc::MockScreenCapturer()); Expectation capturer_start = EXPECT_CALL(*capturer, Start(_)) .WillOnce(Invoke(this, &VideoSchedulerTest::OnCapturerStart)); @@ -182,7 +182,7 @@ TEST_F(VideoSchedulerTest, StartAndStop) { .RetiresOnSaturation(); // Start video frame capture. - StartVideoScheduler(capturer.PassAs<media::ScreenCapturer>()); + StartVideoScheduler(capturer.PassAs<webrtc::ScreenCapturer>()); task_runner_ = NULL; run_loop_.Run(); diff --git a/remoting/host/win/session_desktop_environment.cc b/remoting/host/win/session_desktop_environment.cc index 33add388..0f4ffda 100644 --- a/remoting/host/win/session_desktop_environment.cc +++ b/remoting/host/win/session_desktop_environment.cc @@ -6,11 +6,11 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" -#include "media/video/capture/screen/screen_capturer.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/input_injector.h" #include "remoting/host/screen_controls.h" #include "remoting/host/win/session_input_injector.h" +#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" namespace remoting { diff --git a/remoting/host/win/session_input_injector.cc b/remoting/host/win/session_input_injector.cc index 4c763ee..8f7a366 100644 --- a/remoting/host/win/session_input_injector.cc +++ b/remoting/host/win/session_input_injector.cc @@ -13,10 +13,10 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/win/windows_version.h" -#include "media/video/capture/screen/win/desktop.h" -#include "media/video/capture/screen/win/scoped_thread_desktop.h" #include "remoting/host/sas_injector.h" #include "remoting/proto/event.pb.h" +#include "third_party/webrtc/modules/desktop_capture/win/desktop.h" +#include "third_party/webrtc/modules/desktop_capture/win/scoped_thread_desktop.h" namespace { @@ -80,7 +80,7 @@ class SessionInputInjectorWin::Core scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner_; - media::ScopedThreadDesktop desktop_; + webrtc::ScopedThreadDesktop desktop_; // Used to inject Secure Attention Sequence on Vista+. base::Closure inject_sas_; @@ -182,11 +182,12 @@ SessionInputInjectorWin::Core::~Core() { void SessionInputInjectorWin::Core::SwitchToInputDesktop() { // Switch to the desktop receiving user input if different from the current // one. - scoped_ptr<media::Desktop> input_desktop = media::Desktop::GetInputDesktop(); + scoped_ptr<webrtc::Desktop> input_desktop( + webrtc::Desktop::GetInputDesktop()); if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { // If SetThreadDesktop() fails, the thread is still assigned a desktop. // So we can continue capture screen bits, just from a diffected desktop. - desktop_.SetThreadDesktop(input_desktop.Pass()); + desktop_.SetThreadDesktop(input_desktop.release()); } } diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 1b21b38..aa574957 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -297,7 +297,6 @@ 'remoting_protocol', '../crypto/crypto.gyp:crypto', '../google_apis/google_apis.gyp:google_apis', - '../media/media.gyp:media', '../ipc/ipc.gyp:ipc', '../third_party/webrtc/modules/modules.gyp:desktop_capture', ], @@ -554,8 +553,8 @@ 'dependencies': [ '../base/base.gyp:base', '../base/base.gyp:base_i18n', - '../media/media.gyp:media', '../net/net.gyp:net', + '../third_party/webrtc/modules/modules.gyp:desktop_capture', 'remoting_base', 'remoting_breakpad', 'remoting_host', @@ -840,8 +839,8 @@ 'dependencies': [ '../base/base.gyp:base', '../base/base.gyp:base_i18n', - '../media/media.gyp:media', '../net/net.gyp:net', + '../third_party/webrtc/modules/modules.gyp:desktop_capture', 'remoting_base', 'remoting_breakpad', 'remoting_host', @@ -1427,8 +1426,8 @@ '../base/base.gyp:base_static', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../ipc/ipc.gyp:ipc', - '../media/media.gyp:media', '../net/net.gyp:net', + '../third_party/webrtc/modules/modules.gyp:desktop_capture', 'remoting_base', 'remoting_breakpad', 'remoting_host', @@ -1942,10 +1941,10 @@ 'remoting_base', 'remoting_client', 'remoting_jingle_glue', - '../media/media.gyp:media', '../net/net.gyp:net', '../ppapi/ppapi.gyp:ppapi_cpp_objects', '../skia/skia.gyp:skia', + '../third_party/webrtc/modules/modules.gyp:desktop_capture', ], 'sources': [ 'client/plugin/chromoting_instance.cc', @@ -2115,7 +2114,7 @@ ], 'target_conditions': [ # We cannot currently build the appsv2 version of WebApp on Windows as - # there isn't a version of the "patch" tool available on windows. We + # there isn't a version of the "patch" tool available on windows. We # should remove this condition when we remove the reliance on the 'patch'. # We define this in a 'target_conditions' section because 'plugin_path' @@ -2163,7 +2162,7 @@ '<@(remoting_webapp_locale_files)', '--patches', '<@(remoting_webapp_patch_files)', - ], + ], 'msvs_cygwin_shell': 1, }, ], @@ -2589,8 +2588,6 @@ '../base/base.gyp:base_i18n', '../base/base.gyp:test_support_base', '../ipc/ipc.gyp:ipc', - '../media/media.gyp:media', - '../media/media.gyp:media_test_support', '../net/net.gyp:net_test_support', '../ppapi/ppapi.gyp:ppapi_cpp', '../testing/gmock.gyp:gmock', @@ -2675,6 +2672,8 @@ 'host/register_support_host_request_unittest.cc', 'host/remote_input_filter_unittest.cc', 'host/resizing_host_observer_unittest.cc', + 'host/screen_capturer_fake.cc', + 'host/screen_capturer_fake.h', 'host/screen_resolution_unittest.cc', 'host/server_log_entry_unittest.cc', 'host/setup/native_messaging_host_unittest.cc', |