blob: 9ebec48f2a8387f4a50e085aecfa9e1e53dd93ca [file] [log] [blame]
// 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/player/web_media_player_proxy.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#if defined(_DEBUG)
#include "base/string_number_conversions.h"
#endif
#include "media/base/pipeline_status.h"
#include "media/filters/video_renderer_base.h"
#include "media/player/web_media_player_impl.h"
namespace media {
// Limits the maximum outstanding repaints posted on render thread.
// This number of 50 is a guess, it does not take too much memory on the task
// queue but gives up a pretty good latency on repaint.
static const int kMaxOutstandingRepaints = 50;
WebMediaPlayerProxy::WebMediaPlayerProxy(
const scoped_refptr<base::MessageLoopProxy>& render_loop,
WebMediaPlayerImpl* webmediaplayer)
: render_loop_(render_loop),
webmediaplayer_(webmediaplayer) {
DCHECK(render_loop_);
DCHECK(webmediaplayer_);
}
WebMediaPlayerProxy::~WebMediaPlayerProxy() {
Detach();
}
void WebMediaPlayerProxy::Paint(SkCanvas* canvas,
const gfx::Rect& dest_rect,
uint8_t alpha) {
DCHECK(render_loop_->BelongsToCurrentThread());
if (frame_provider_) {
scoped_refptr<VideoFrame> video_frame;
frame_provider_->GetCurrentFrame(&video_frame);
video_renderer_.Paint(video_frame, canvas, dest_rect, alpha);
frame_provider_->PutCurrentFrame(video_frame);
}
}
bool WebMediaPlayerProxy::HasSingleOrigin() {
DCHECK(render_loop_->BelongsToCurrentThread());
if (data_source_)
return data_source_->HasSingleOrigin();
return true;
}
bool WebMediaPlayerProxy::DidPassCORSAccessCheck() const {
DCHECK(render_loop_->BelongsToCurrentThread());
if (data_source_)
return data_source_->DidPassCORSAccessCheck();
return false;
}
void WebMediaPlayerProxy::AbortDataSource() {
DCHECK(render_loop_->BelongsToCurrentThread());
if (data_source_)
data_source_->Abort();
}
void WebMediaPlayerProxy::Detach() {
DCHECK(render_loop_->BelongsToCurrentThread());
webmediaplayer_ = NULL;
data_source_.reset();
frame_provider_ = NULL;
}
void WebMediaPlayerProxy::GetCurrentFrame(
scoped_refptr<VideoFrame>* frame_out) {
if (frame_provider_)
frame_provider_->GetCurrentFrame(frame_out);
}
void WebMediaPlayerProxy::PutCurrentFrame(scoped_refptr<VideoFrame> frame) {
if (frame_provider_)
frame_provider_->PutCurrentFrame(frame);
}
void WebMediaPlayerProxy::KeyAdded(const std::string& key_system,
const std::string& session_id) {
render_loop_->PostTask(FROM_HERE,
base::Bind(&WebMediaPlayerProxy::KeyAddedTask, this,
key_system, session_id));
}
void WebMediaPlayerProxy::KeyError(const std::string& key_system,
const std::string& session_id,
Decryptor::KeyError error_code,
int system_code) {
render_loop_->PostTask(
FROM_HERE, base::Bind(&WebMediaPlayerProxy::KeyErrorTask, this,
key_system, session_id, error_code, system_code));
}
void WebMediaPlayerProxy::KeyMessage(const std::string& key_system,
const std::string& session_id,
const std::string& message,
const std::string& default_url) {
#if defined(_DEBUG)
std::string hex = base::HexEncode(message.data(), message.size());
DLOG(INFO) << "DRM Key Request: " << hex;
#endif
render_loop_->PostTask(
FROM_HERE, base::Bind(&WebMediaPlayerProxy::KeyMessageTask, this,
key_system, session_id, message, default_url));
}
void WebMediaPlayerProxy::NeedKey(const std::string& key_system,
const std::string& session_id,
const std::string& type,
scoped_array<uint8> init_data,
int init_data_size) {
render_loop_->PostTask(
FROM_HERE,
base::Bind(&WebMediaPlayerProxy::NeedKeyTask, this, key_system,
session_id, type, base::Passed(&init_data), init_data_size));
}
void WebMediaPlayerProxy::KeyAddedTask(const std::string& key_system,
const std::string& session_id) {
DCHECK(render_loop_->BelongsToCurrentThread());
if (webmediaplayer_)
webmediaplayer_->OnKeyAdded(key_system, session_id);
}
void WebMediaPlayerProxy::KeyErrorTask(const std::string& key_system,
const std::string& session_id,
Decryptor::KeyError error_code,
int system_code) {
DCHECK(render_loop_->BelongsToCurrentThread());
if (webmediaplayer_)
webmediaplayer_->OnKeyError(key_system, session_id, error_code,
system_code);
}
void WebMediaPlayerProxy::KeyMessageTask(const std::string& key_system,
const std::string& session_id,
const std::string& message,
const std::string& default_url) {
DCHECK(render_loop_->BelongsToCurrentThread());
if (webmediaplayer_) {
const GURL default_url_gurl(default_url);
DLOG_IF(WARNING, !default_url.empty() && !default_url_gurl.is_valid())
<< "Invalid URL in default_url: " << default_url;
webmediaplayer_->OnKeyMessage(key_system, session_id, message,
default_url_gurl);
}
}
void WebMediaPlayerProxy::NeedKeyTask(const std::string& key_system,
const std::string& session_id,
const std::string& type,
scoped_array<uint8> init_data,
int init_data_size) {
DCHECK(render_loop_->BelongsToCurrentThread());
if (webmediaplayer_)
webmediaplayer_->OnNeedKey(key_system, session_id, type, init_data.Pass(),
init_data_size);
}
} // namespace media