blob: d606dc09690eb4e068cbd9cfe521d9fca0557d47 [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/media/media_module.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/synchronization/waitable_event.h"
namespace cobalt {
namespace media {
namespace {
void RunClosureAndSignal(const base::Closure& closure,
base::WaitableEvent* event) {
closure.Run();
event->Signal();
}
void RunClosureOnMessageLoopAndWait(
const scoped_refptr<base::MessageLoopProxy>& message_loop,
const base::Closure& closure) {
base::WaitableEvent waitable_event(true, /* manual_reset */
false /* initially_signaled */);
message_loop->PostTask(
FROM_HERE, base::Bind(&RunClosureAndSignal, closure, &waitable_event));
waitable_event.Wait();
}
} // namespace
// static
math::Size MediaModule::CalculateOutputResolution(
system_window::SystemWindow* system_window,
const base::optional<math::Size>& output_size_override) {
if (output_size_override) {
return *output_size_override;
}
return system_window->GetVideoOutputResolution();
}
void MediaModule::Suspend() {
RunClosureOnMessageLoopAndWait(
message_loop_,
base::Bind(&MediaModule::SuspendTask, base::Unretained(this)));
OnSuspend();
}
void MediaModule::Resume(render_tree::ResourceProvider* resource_provider) {
OnResume(resource_provider);
RunClosureOnMessageLoopAndWait(
message_loop_,
base::Bind(&MediaModule::ResumeTask, base::Unretained(this)));
}
void MediaModule::RegisterPlayer(WebMediaPlayer* player) {
RunClosureOnMessageLoopAndWait(message_loop_,
base::Bind(&MediaModule::RegisterPlayerTask,
base::Unretained(this), player));
}
void MediaModule::UnregisterPlayer(WebMediaPlayer* player) {
RunClosureOnMessageLoopAndWait(message_loop_,
base::Bind(&MediaModule::UnregisterPlayerTask,
base::Unretained(this), player));
}
void MediaModule::RegisterDebugState(WebMediaPlayer* player) {
void* debug_state_address = NULL;
size_t debug_state_size = 0;
if (player->GetDebugReportDataAddress(&debug_state_address,
&debug_state_size)) {
base::UserLog::Register(base::UserLog::kWebMediaPlayerState,
"MediaPlyrState", debug_state_address,
debug_state_size);
}
}
void MediaModule::DeregisterDebugState() {
base::UserLog::Deregister(base::UserLog::kWebMediaPlayerState);
}
void MediaModule::SuspendTask() {
DCHECK(message_loop_->BelongsToCurrentThread());
suspended_ = true;
for (Players::iterator iter = players_.begin(); iter != players_.end();
++iter) {
DCHECK(!iter->second);
if (!iter->second) {
iter->first->Suspend();
}
}
}
void MediaModule::ResumeTask() {
DCHECK(message_loop_->BelongsToCurrentThread());
for (Players::iterator iter = players_.begin(); iter != players_.end();
++iter) {
DCHECK(!iter->second);
if (!iter->second) {
iter->first->Resume();
}
}
suspended_ = false;
}
void MediaModule::RegisterPlayerTask(WebMediaPlayer* player) {
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(players_.find(player) == players_.end());
players_.insert(std::make_pair(player, false));
// Track debug state for the most recently added WebMediaPlayer instance.
RegisterDebugState(player);
if (suspended_) {
player->Suspend();
}
}
void MediaModule::UnregisterPlayerTask(WebMediaPlayer* player) {
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(players_.find(player) != players_.end());
players_.erase(players_.find(player));
if (players_.empty()) {
DeregisterDebugState();
} else {
RegisterDebugState(players_.begin()->first);
}
}
} // namespace media
} // namespace cobalt