summaryrefslogtreecommitdiffstats
path: root/webkit/media/webmediaplayer_ms.cc
diff options
context:
space:
mode:
authorwjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-25 01:28:39 +0000
committerwjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-25 01:28:39 +0000
commit5f04c353a604c8e3f654019c9c267529455a8fbf (patch)
treee56168cdbb4df164d4d0dd9677b94835be9bb403 /webkit/media/webmediaplayer_ms.cc
parenta380186d005aaa91bf62dbefca4f6fd17329afba (diff)
downloadchromium_src-5f04c353a604c8e3f654019c9c267529455a8fbf.zip
chromium_src-5f04c353a604c8e3f654019c9c267529455a8fbf.tar.gz
chromium_src-5f04c353a604c8e3f654019c9c267529455a8fbf.tar.bz2
create a separate WebMediaPlayer for URL derived from media stream
When the "src" of <video> is derived from media stream, WebMediaPlayerMS is created. Its real time charateristics allows it to simplify some controls in WebMediaPlayer, e.g., no buffering, no preload, etc. WebMediaPlayerMS has 2 different VideoFrameProviders: LocalVideoCapture(for local preview) and RTCVideoRender(for remote view). Audio will be added in the following patches. BUG=142988,110938 TEST=turn on WebMediaPlayer_MS, run apprtc.appspot.com/?debug=loopback Review URL: https://chromiumcodereview.appspot.com/10918052 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158490 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/media/webmediaplayer_ms.cc')
-rw-r--r--webkit/media/webmediaplayer_ms.cc398
1 files changed, 398 insertions, 0 deletions
diff --git a/webkit/media/webmediaplayer_ms.cc b/webkit/media/webmediaplayer_ms.cc
new file mode 100644
index 0000000..6e09d9d
--- /dev/null
+++ b/webkit/media/webmediaplayer_ms.cc
@@ -0,0 +1,398 @@
+// 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 "webkit/media/webmediaplayer_ms.h"
+
+#include <limits>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "media/base/media_log.h"
+#include "media/base/video_frame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
+#include "webkit/media/media_stream_client.h"
+#include "webkit/media/video_frame_provider.h"
+#include "webkit/media/webmediaplayer_delegate.h"
+#include "webkit/media/webmediaplayer_util.h"
+#include "webkit/media/webvideoframe_impl.h"
+
+using WebKit::WebCanvas;
+using WebKit::WebMediaPlayer;
+using WebKit::WebRect;
+using WebKit::WebSize;
+
+namespace webkit_media {
+
+WebMediaPlayerMS::WebMediaPlayerMS(
+ WebKit::WebFrame* frame,
+ WebKit::WebMediaPlayerClient* client,
+ base::WeakPtr<WebMediaPlayerDelegate> delegate,
+ MediaStreamClient* media_stream_client,
+ media::MediaLog* media_log)
+ : frame_(frame),
+ network_state_(WebMediaPlayer::NetworkStateEmpty),
+ ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
+ buffered_(static_cast<size_t>(1)),
+ client_(client),
+ delegate_(delegate),
+ media_stream_client_(media_stream_client),
+ video_frame_provider_started_(false),
+ paused_(true),
+ pending_repaint_(false),
+ got_first_frame_(false),
+ total_frame_count_(0),
+ dropped_frame_count_(0),
+ media_log_(media_log) {
+ DVLOG(1) << "WebMediaPlayerMS::ctor";
+ DCHECK(media_stream_client);
+ media_log_->AddEvent(
+ media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
+}
+
+WebMediaPlayerMS::~WebMediaPlayerMS() {
+ DVLOG(1) << "WebMediaPlayerMS::dtor";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (video_frame_provider_) {
+ video_frame_provider_->Stop();
+ }
+
+ media_log_->AddEvent(
+ media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
+
+ if (delegate_)
+ delegate_->PlayerGone(this);
+}
+
+void WebMediaPlayerMS::load(const WebKit::WebURL& url, CORSMode cors_mode) {
+ DVLOG(1) << "WebMediaPlayerMS::load";
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ GURL gurl(url);
+
+ setVolume(GetClient()->volume());
+ SetNetworkState(WebMediaPlayer::NetworkStateLoading);
+ SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
+ media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
+
+ // Check if this url is media stream.
+ video_frame_provider_ = media_stream_client_->GetVideoFrameProvider(
+ url,
+ base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
+ base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()));
+ if (video_frame_provider_) {
+ SetNetworkState(WebMediaPlayer::NetworkStateLoaded);
+ GetClient()->sourceOpened();
+ GetClient()->setOpaque(true);
+ SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
+ SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
+ RepaintInternal();
+ } else {
+ SetNetworkState(WebMediaPlayer::NetworkStateNetworkError);
+ }
+}
+
+void WebMediaPlayerMS::cancelLoad() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void WebMediaPlayerMS::play() {
+ DVLOG(1) << "WebMediaPlayerMS::play";
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ paused_ = false;
+ if (video_frame_provider_) {
+ if (video_frame_provider_started_) {
+ video_frame_provider_->Play();
+ } else {
+ video_frame_provider_started_ = true;
+ video_frame_provider_->Start();
+ }
+ }
+ // TODO(wjia): add audio. See crbug.com/142988.
+
+ media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
+
+ if (delegate_)
+ delegate_->DidPlay(this);
+}
+
+void WebMediaPlayerMS::pause() {
+ DVLOG(1) << "WebMediaPlayerMS::pause";
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (video_frame_provider_)
+ video_frame_provider_->Pause();
+ // TODO(wjia): add audio. See crbug.com/142988.
+ paused_ = true;
+
+ media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
+
+ if (delegate_)
+ delegate_->DidPause(this);
+}
+
+bool WebMediaPlayerMS::supportsFullscreen() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return true;
+}
+
+bool WebMediaPlayerMS::supportsSave() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return false;
+}
+
+void WebMediaPlayerMS::seek(float seconds) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void WebMediaPlayerMS::setEndTime(float seconds) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void WebMediaPlayerMS::setRate(float rate) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void WebMediaPlayerMS::setVolume(float volume) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // TODO(wjia): set audio volume. See crbug.com/142988.
+ NOTIMPLEMENTED();
+}
+
+void WebMediaPlayerMS::setVisible(bool visible) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void WebMediaPlayerMS::setPreload(WebMediaPlayer::Preload preload) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+bool WebMediaPlayerMS::totalBytesKnown() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return false;
+}
+
+bool WebMediaPlayerMS::hasVideo() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return (video_frame_provider_ != NULL);
+}
+
+bool WebMediaPlayerMS::hasAudio() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // TODO(wjia): add audio support. See crbug.com/142988.
+ return false;
+}
+
+WebKit::WebSize WebMediaPlayerMS::naturalSize() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ gfx::Size size;
+ if (current_frame_)
+ size = current_frame_->natural_size();
+ DVLOG(1) << "WebMediaPlayerMS::naturalSize, " << size.ToString();
+ return WebKit::WebSize(size);
+}
+
+bool WebMediaPlayerMS::paused() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return paused_;
+}
+
+bool WebMediaPlayerMS::seeking() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return false;
+}
+
+float WebMediaPlayerMS::duration() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return std::numeric_limits<float>::infinity();
+}
+
+float WebMediaPlayerMS::currentTime() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (current_frame_.get()) {
+ return current_frame_->GetTimestamp().InSecondsF();
+ }
+ return 0.0f;
+}
+
+int WebMediaPlayerMS::dataRate() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return 0;
+}
+
+WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
+ return network_state_;
+}
+
+WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(1) << "WebMediaPlayerMS::readyState, state:" << ready_state_;
+ return ready_state_;
+}
+
+const WebKit::WebTimeRanges& WebMediaPlayerMS::buffered() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return buffered_;
+}
+
+float WebMediaPlayerMS::maxTimeSeekable() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return 0.0f;
+}
+
+bool WebMediaPlayerMS::didLoadingProgress() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return false;
+}
+
+unsigned long long WebMediaPlayerMS::totalBytes() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return 0;
+}
+
+void WebMediaPlayerMS::setSize(const WebSize& size) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // Don't need to do anything as we use the dimensions passed in via paint().
+}
+
+void WebMediaPlayerMS::paint(WebCanvas* canvas,
+ const WebRect& rect,
+ uint8_t alpha) {
+ DVLOG(1) << "WebMediaPlayerMS::paint";
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ video_renderer_.Paint(current_frame_, canvas, rect, alpha);
+}
+
+bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return true;
+}
+
+bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return true;
+}
+
+WebMediaPlayer::MovieLoadType WebMediaPlayerMS::movieLoadType() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return WebMediaPlayer::MovieLoadTypeUnknown;
+}
+
+float WebMediaPlayerMS::mediaTimeForTimeValue(float timeValue) const {
+ return ConvertSecondsToTimestamp(timeValue).InSecondsF();
+}
+
+unsigned WebMediaPlayerMS::decodedFrameCount() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_;
+ return total_frame_count_;
+}
+
+unsigned WebMediaPlayerMS::droppedFrameCount() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_;
+ return dropped_frame_count_;
+}
+
+unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+WebKit::WebVideoFrame* WebMediaPlayerMS::getCurrentFrame() {
+ DVLOG(1) << "WebMediaPlayerMS::getCurrentFrame";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!pending_repaint_);
+ pending_repaint_ = true;
+ if (current_frame_.get())
+ return new webkit_media::WebVideoFrameImpl(current_frame_);
+ return NULL;
+}
+
+void WebMediaPlayerMS::putCurrentFrame(
+ WebKit::WebVideoFrame* web_video_frame) {
+ DVLOG(1) << "WebMediaPlayerMS::putCurrentFrame";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(pending_repaint_);
+ pending_repaint_ = false;
+ if (web_video_frame) {
+ delete web_video_frame;
+ }
+}
+
+void WebMediaPlayerMS::OnFrameAvailable(
+ const scoped_refptr<media::VideoFrame>& frame) {
+ DVLOG(1) << "WebMediaPlayerMS::OnFrameAvailable";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ ++total_frame_count_;
+ if (!got_first_frame_) {
+ got_first_frame_ = true;
+ start_time_ = frame->GetTimestamp();
+ }
+ current_frame_ = frame;
+ current_frame_->SetTimestamp(frame->GetTimestamp() - start_time_);
+ if (pending_repaint_) {
+ // TODO(wjia): Figure out how to calculate dropped frame count for
+ // both S/W and H/W compositing.
+ // ++dropped_frame_count_;
+ } else {
+ GetClient()->repaint();
+ }
+}
+
+void WebMediaPlayerMS::RepaintInternal() {
+ DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!pending_repaint_) {
+ GetClient()->repaint();
+ }
+}
+
+void WebMediaPlayerMS::OnSourceError() {
+ DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
+ RepaintInternal();
+}
+
+void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ network_state_ = state;
+ // Always notify to ensure client has the latest value.
+ GetClient()->networkStateChanged();
+}
+
+void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ ready_state_ = state;
+ // Always notify to ensure client has the latest value.
+ GetClient()->readyStateChanged();
+}
+
+WebKit::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(client_);
+ return client_;
+}
+
+} // namespace webkit_media