Index: chrome/browser/media/desktop_media_picker_model.cc |
diff --git a/chrome/browser/media/desktop_media_picker_model.cc b/chrome/browser/media/desktop_media_picker_model.cc |
deleted file mode 100644 |
index 4ce788aba4c3396b7ec76a7972140d30c6e8fe47..0000000000000000000000000000000000000000 |
--- a/chrome/browser/media/desktop_media_picker_model.cc |
+++ /dev/null |
@@ -1,337 +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 "chrome/browser/media/desktop_media_picker_model.h" |
- |
-#include <map> |
- |
-#include "base/hash.h" |
-#include "base/logging.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "base/threading/sequenced_worker_pool.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "grit/generated_resources.h" |
-#include "media/base/video_util.h" |
-#include "third_party/libyuv/include/libyuv/scale_argb.h" |
-#include "third_party/skia/include/core/SkBitmap.h" |
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
-#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" |
-#include "third_party/webrtc/modules/desktop_capture/window_capturer.h" |
-#include "ui/base/l10n/l10n_util.h" |
-#include "ui/gfx/skia_util.h" |
- |
-using content::BrowserThread; |
-using content::DesktopMediaID; |
- |
-namespace { |
- |
-// Update the list every second. |
-const int kDefaultUpdatePeriod = 1000; |
- |
-// Returns a hash of a DesktopFrame content to detect when image for a desktop |
-// media source has changed. |
-uint32 GetFrameHash(webrtc::DesktopFrame* frame) { |
- int data_size = frame->stride() * frame->size().height(); |
- return base::SuperFastHash(reinterpret_cast<char*>(frame->data()), data_size); |
-} |
- |
-gfx::ImageSkia ScaleDesktopFrame(scoped_ptr<webrtc::DesktopFrame> frame, |
- gfx::Size size) { |
- gfx::Rect scaled_rect = media::ComputeLetterboxRegion( |
- gfx::Rect(0, 0, size.width(), size.height()), |
- gfx::Size(frame->size().width(), frame->size().height())); |
- |
- SkBitmap result; |
- result.setConfig(SkBitmap::kARGB_8888_Config, |
- scaled_rect.width(), scaled_rect.height(), 0, |
- kOpaque_SkAlphaType); |
- result.allocPixels(); |
- result.lockPixels(); |
- |
- uint8* pixels_data = reinterpret_cast<uint8*>(result.getPixels()); |
- libyuv::ARGBScale(frame->data(), frame->stride(), |
- frame->size().width(), frame->size().height(), |
- pixels_data, result.rowBytes(), |
- scaled_rect.width(), scaled_rect.height(), |
- libyuv::kFilterBilinear); |
- |
- // Set alpha channel values to 255 for all pixels. |
- // TODO(sergeyu): Fix screen/window capturers to capture alpha channel and |
- // remove this code. Currently screen/window capturers (at least some |
- // implementations) only capture R, G and B channels and set Alpha to 0. |
- // crbug.com/264424 |
- for (int y = 0; y < result.height(); ++y) { |
- for (int x = 0; x < result.width(); ++x) { |
- pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] = |
- 0xff; |
- } |
- } |
- |
- result.unlockPixels(); |
- |
- return gfx::ImageSkia::CreateFrom1xBitmap(result); |
-} |
- |
-} // namespace |
- |
-DesktopMediaPickerModel::Source::Source(DesktopMediaID id, const string16& name) |
- : id(id), |
- name(name) { |
-} |
- |
-DesktopMediaPickerModelImpl::SourceDescription::SourceDescription( |
- DesktopMediaID id, |
- const string16& name) |
- : id(id), |
- name(name) { |
-} |
- |
-class DesktopMediaPickerModelImpl::Worker |
- : public webrtc::DesktopCapturer::Callback { |
- public: |
- Worker(base::WeakPtr<DesktopMediaPickerModelImpl> model, |
- scoped_ptr<webrtc::ScreenCapturer> screen_capturer, |
- scoped_ptr<webrtc::WindowCapturer> window_capturer); |
- virtual ~Worker(); |
- |
- void Refresh(const gfx::Size& thumbnail_size, |
- content::DesktopMediaID::Id view_dialog_id); |
- |
- private: |
- typedef std::map<DesktopMediaID, uint32> ImageHashesMap; |
- |
- // webrtc::DesktopCapturer::Callback interface. |
- virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE; |
- virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) OVERRIDE; |
- |
- base::WeakPtr<DesktopMediaPickerModelImpl> model_; |
- |
- scoped_ptr<webrtc::ScreenCapturer> screen_capturer_; |
- scoped_ptr<webrtc::WindowCapturer> window_capturer_; |
- |
- scoped_ptr<webrtc::DesktopFrame> current_frame_; |
- |
- ImageHashesMap image_hashes_; |
- |
- DISALLOW_COPY_AND_ASSIGN(Worker); |
-}; |
- |
-DesktopMediaPickerModelImpl::Worker::Worker( |
- base::WeakPtr<DesktopMediaPickerModelImpl> model, |
- scoped_ptr<webrtc::ScreenCapturer> screen_capturer, |
- scoped_ptr<webrtc::WindowCapturer> window_capturer) |
- : model_(model), |
- screen_capturer_(screen_capturer.Pass()), |
- window_capturer_(window_capturer.Pass()) { |
- if (screen_capturer_) |
- screen_capturer_->Start(this); |
- if (window_capturer_) |
- window_capturer_->Start(this); |
-} |
- |
-DesktopMediaPickerModelImpl::Worker::~Worker() {} |
- |
-void DesktopMediaPickerModelImpl::Worker::Refresh( |
- const gfx::Size& thumbnail_size, |
- content::DesktopMediaID::Id view_dialog_id) { |
- std::vector<SourceDescription> sources; |
- |
- if (screen_capturer_) { |
- // TODO(sergeyu): Enumerate each screen when ScreenCapturer supports it. |
- sources.push_back(SourceDescription(DesktopMediaID( |
- DesktopMediaID::TYPE_SCREEN, 0), |
- l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_SCREEN_NAME))); |
- } |
- |
- if (window_capturer_) { |
- webrtc::WindowCapturer::WindowList windows; |
- if (window_capturer_->GetWindowList(&windows)) { |
- for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin(); |
- it != windows.end(); ++it) { |
- // Skip the picker dialog window. |
- if (it->id != view_dialog_id) { |
- sources.push_back(SourceDescription( |
- DesktopMediaID(DesktopMediaID::TYPE_WINDOW, it->id), |
- base::UTF8ToUTF16(it->title))); |
- } |
- } |
- } |
- } |
- |
- // Sort the list of sources so that they appear in a predictable order. |
- std::sort(sources.begin(), sources.end(), CompareSources); |
- |
- // Update list of windows before updating thumbnails. |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&DesktopMediaPickerModelImpl::OnSourcesList, model_, sources)); |
- |
- ImageHashesMap new_image_hashes; |
- |
- // Get a thumbnail for each source. |
- for (size_t i = 0; i < sources.size(); ++i) { |
- SourceDescription& source = sources[i]; |
- switch (source.id.type) { |
- case DesktopMediaID::TYPE_SCREEN: |
- screen_capturer_->Capture(webrtc::DesktopRegion()); |
- DCHECK(current_frame_); |
- break; |
- |
- case DesktopMediaID::TYPE_WINDOW: |
- if (!window_capturer_->SelectWindow(source.id.id)) |
- continue; |
- window_capturer_->Capture(webrtc::DesktopRegion()); |
- break; |
- |
- default: |
- NOTREACHED(); |
- } |
- |
- // Expect that DesktopCapturer to always captures frames synchronously. |
- // |current_frame_| may be NULL if capture failed (e.g. because window has |
- // been closed). |
- if (current_frame_) { |
- uint32 frame_hash = GetFrameHash(current_frame_.get()); |
- new_image_hashes[source.id] = frame_hash; |
- |
- // Scale the image only if it has changed. |
- ImageHashesMap::iterator it = image_hashes_.find(source.id); |
- if (it == image_hashes_.end() || it->second != frame_hash) { |
- gfx::ImageSkia thumbnail = |
- ScaleDesktopFrame(current_frame_.Pass(), thumbnail_size); |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&DesktopMediaPickerModelImpl::OnSourceThumbnail, model_, |
- i, thumbnail)); |
- } |
- } |
- } |
- |
- image_hashes_.swap(new_image_hashes); |
- |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&DesktopMediaPickerModelImpl::OnRefreshFinished, model_)); |
-} |
- |
-webrtc::SharedMemory* DesktopMediaPickerModelImpl::Worker::CreateSharedMemory( |
- size_t size) { |
- return NULL; |
-} |
- |
-void DesktopMediaPickerModelImpl::Worker::OnCaptureCompleted( |
- webrtc::DesktopFrame* frame) { |
- current_frame_.reset(frame); |
-} |
- |
-DesktopMediaPickerModelImpl::DesktopMediaPickerModelImpl( |
- scoped_ptr<webrtc::ScreenCapturer> screen_capturer, |
- scoped_ptr<webrtc::WindowCapturer> window_capturer) |
- : screen_capturer_(screen_capturer.Pass()), |
- window_capturer_(window_capturer.Pass()), |
- update_period_(base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)), |
- thumbnail_size_(100, 100), |
- view_dialog_id_(-1), |
- observer_(NULL), |
- weak_factory_(this) { |
- base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); |
- capture_task_runner_ = worker_pool->GetSequencedTaskRunner( |
- worker_pool->GetSequenceToken()); |
-} |
- |
-DesktopMediaPickerModelImpl::~DesktopMediaPickerModelImpl() { |
- capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release()); |
-} |
- |
-void DesktopMediaPickerModelImpl::SetUpdatePeriod(base::TimeDelta period) { |
- DCHECK(!observer_); |
- update_period_ = period; |
-} |
- |
-void DesktopMediaPickerModelImpl::SetThumbnailSize( |
- const gfx::Size& thumbnail_size) { |
- thumbnail_size_ = thumbnail_size; |
-} |
- |
-void DesktopMediaPickerModelImpl::SetViewDialogWindowId( |
- content::DesktopMediaID::Id dialog_id) { |
- view_dialog_id_ = dialog_id; |
-} |
- |
-void DesktopMediaPickerModelImpl::StartUpdating(Observer* observer) { |
- DCHECK(!observer_); |
- DCHECK(screen_capturer_ || window_capturer_); |
- |
- observer_ = observer; |
- |
- worker_.reset(new Worker(weak_factory_.GetWeakPtr(), |
- screen_capturer_.Pass(), window_capturer_.Pass())); |
- Refresh(); |
-} |
- |
-int DesktopMediaPickerModelImpl::source_count() const { |
- return sources_.size(); |
-} |
- |
-const DesktopMediaPickerModel::Source& DesktopMediaPickerModelImpl::source( |
- int index) const { |
- return sources_[index]; |
-} |
- |
-// static |
-bool DesktopMediaPickerModelImpl::CompareSources(const SourceDescription& a, |
- const SourceDescription& b) { |
- return a.id < b.id; |
-} |
- |
-void DesktopMediaPickerModelImpl::Refresh() { |
- capture_task_runner_->PostTask( |
- FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()), |
- thumbnail_size_, view_dialog_id_)); |
-} |
- |
-void DesktopMediaPickerModelImpl::OnSourcesList( |
- const std::vector<SourceDescription>& new_sources) { |
- // Step through |new_sources| adding and removing entries from |sources_|, and |
- // notifying the |observer_|, until two match. Requires that |sources| and |
- // |sources_| have the same ordering. |
- size_t pos = 0; |
- while (pos < sources_.size() || pos < new_sources.size()) { |
- // If |sources_[pos]| is not in |new_sources| then remove it. |
- if (pos < sources_.size() && |
- (pos == new_sources.size() || sources_[pos].id < new_sources[pos].id)) { |
- sources_.erase(sources_.begin() + pos); |
- observer_->OnSourceRemoved(pos); |
- continue; |
- } |
- |
- if (pos == sources_.size() || !(sources_[pos].id == new_sources[pos].id)) { |
- sources_.insert(sources_.begin() + pos, |
- Source(new_sources[pos].id, new_sources[pos].name)); |
- observer_->OnSourceAdded(pos); |
- } else if (sources_[pos].name != new_sources[pos].name) { |
- sources_[pos].name = new_sources[pos].name; |
- observer_->OnSourceNameChanged(pos); |
- } |
- |
- ++pos; |
- } |
- |
- DCHECK_EQ(new_sources.size(), sources_.size()); |
-} |
- |
-void DesktopMediaPickerModelImpl::OnSourceThumbnail(int index, |
- const gfx::ImageSkia& image) { |
- DCHECK_LT(index, static_cast<int>(sources_.size())); |
- sources_[index].thumbnail = image; |
- observer_->OnSourceThumbnailChanged(index); |
-} |
- |
-void DesktopMediaPickerModelImpl::OnRefreshFinished() { |
- BrowserThread::PostDelayedTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&DesktopMediaPickerModelImpl::Refresh, |
- weak_factory_.GetWeakPtr()), |
- update_period_); |
-} |