blob: d03213b5ca77f3b8c4dc43636a7cac5368158373 [file] [log] [blame]
// Copyright 2014 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 "chromecast/renderer/media/cma_message_filter_proxy.h"
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
#include "chromecast/common/media/cma_messages.h"
#include "ipc/ipc_logging.h"
#include "ipc/ipc_sender.h"
namespace chromecast {
namespace media {
CmaMessageFilterProxy::MediaDelegate::MediaDelegate() {
}
CmaMessageFilterProxy::MediaDelegate::~MediaDelegate() {
}
CmaMessageFilterProxy::AudioDelegate::AudioDelegate() {
}
CmaMessageFilterProxy::AudioDelegate::~AudioDelegate() {
}
CmaMessageFilterProxy::VideoDelegate::VideoDelegate() {
}
CmaMessageFilterProxy::VideoDelegate::~VideoDelegate() {
}
CmaMessageFilterProxy::DelegateEntry::DelegateEntry() {
}
CmaMessageFilterProxy::DelegateEntry::~DelegateEntry() {
}
CmaMessageFilterProxy* CmaMessageFilterProxy::filter_ = NULL;
// static
CmaMessageFilterProxy* CmaMessageFilterProxy::Get() {
return filter_;
}
CmaMessageFilterProxy::CmaMessageFilterProxy(
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
: sender_(NULL), io_task_runner_(io_task_runner) {
DCHECK(!filter_);
filter_ = this;
}
int CmaMessageFilterProxy::CreateChannel() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
DelegateEntry* entry = new DelegateEntry();
int id = delegates_.Add(entry);
return id;
}
void CmaMessageFilterProxy::DestroyChannel(int id) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
delegates_.Remove(id);
delete entry;
}
bool CmaMessageFilterProxy::SetMediaDelegate(
int id, const MediaDelegate& media_delegate) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return false;
entry->media_delegate = media_delegate;
return true;
}
bool CmaMessageFilterProxy::SetAudioDelegate(
int id, const AudioDelegate& audio_delegate) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return false;
entry->audio_delegate = audio_delegate;
return true;
}
bool CmaMessageFilterProxy::SetVideoDelegate(
int id, const VideoDelegate& video_delegate) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return false;
entry->video_delegate = video_delegate;
return true;
}
bool CmaMessageFilterProxy::Send(std::unique_ptr<IPC::Message> message) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (!sender_)
return false;
bool status = sender_->Send(message.release());
return status;
}
bool CmaMessageFilterProxy::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(CmaMessageFilterProxy, message)
IPC_MESSAGE_HANDLER(CmaMsg_AvPipeCreated, OnAvPipeCreated)
IPC_MESSAGE_HANDLER(CmaMsg_NotifyPipeRead, OnPipeRead)
IPC_MESSAGE_HANDLER(CmaMsg_FlushDone, OnFlushDone)
IPC_MESSAGE_HANDLER(CmaMsg_TrackStateChanged, OnTrackStateChanged)
IPC_MESSAGE_HANDLER(CmaMsg_WaitForKey, OnWaitForKey)
IPC_MESSAGE_HANDLER(CmaMsg_Eos, OnEos)
IPC_MESSAGE_HANDLER(CmaMsg_TimeUpdate, OnTimeUpdate)
IPC_MESSAGE_HANDLER(CmaMsg_BufferingNotification, OnBufferingNotification)
IPC_MESSAGE_HANDLER(CmaMsg_PlaybackError, OnPlaybackError)
IPC_MESSAGE_HANDLER(CmaMsg_PlaybackStatistics, OnStatisticsUpdated)
IPC_MESSAGE_HANDLER(CmaMsg_NaturalSizeChanged, OnNaturalSizeChanged)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void CmaMessageFilterProxy::OnFilterAdded(IPC::Sender* sender) {
sender_ = sender;
}
void CmaMessageFilterProxy::OnFilterRemoved() {
sender_ = NULL;
}
void CmaMessageFilterProxy::OnChannelClosing() {
sender_ = NULL;
}
CmaMessageFilterProxy::~CmaMessageFilterProxy() {
DCHECK(filter_);
filter_ = NULL;
}
void CmaMessageFilterProxy::OnAvPipeCreated(
int id,
TrackId track_id,
bool status,
base::SharedMemoryHandle shared_memory_handle,
base::FileDescriptor socket_handle) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const AvPipeCB& cb = (track_id == kAudioTrackId) ?
entry->audio_delegate.av_pipe_cb :
entry->video_delegate.av_pipe_cb;
if (!cb.is_null())
cb.Run(status, shared_memory_handle, socket_handle);
}
void CmaMessageFilterProxy::OnPipeRead(
int id, TrackId track_id) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const base::Closure& cb = (track_id == kAudioTrackId) ?
entry->audio_delegate.pipe_read_cb :
entry->video_delegate.pipe_read_cb;
if (!cb.is_null())
cb.Run();
}
void CmaMessageFilterProxy::OnFlushDone(int id) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const base::Closure& cb = entry->media_delegate.flush_cb;
if (!cb.is_null())
cb.Run();
}
void CmaMessageFilterProxy::OnTrackStateChanged(
int id, TrackId track_id, ::media::PipelineStatus status) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const ::media::PipelineStatusCB& cb = (track_id == kAudioTrackId) ?
entry->audio_delegate.state_changed_cb :
entry->video_delegate.state_changed_cb;
if (!cb.is_null())
cb.Run(status);
}
void CmaMessageFilterProxy::OnWaitForKey(int id, TrackId track_id) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const base::Closure& cb = (track_id == kAudioTrackId) ?
entry->audio_delegate.client.wait_for_key_cb :
entry->video_delegate.client.av_pipeline_client.wait_for_key_cb;
if (!cb.is_null())
cb.Run();
}
void CmaMessageFilterProxy::OnEos(int id, TrackId track_id) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const base::Closure& cb = (track_id == kAudioTrackId) ?
entry->audio_delegate.client.eos_cb :
entry->video_delegate.client.av_pipeline_client.eos_cb;
if (!cb.is_null())
cb.Run();
}
void CmaMessageFilterProxy::OnTimeUpdate(
int id,
base::TimeDelta time,
base::TimeDelta max_time,
base::TimeTicks stc) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const MediaPipelineClient::TimeUpdateCB& cb =
entry->media_delegate.client.time_update_cb;
if (!cb.is_null())
cb.Run(time, max_time, stc);
}
void CmaMessageFilterProxy::OnBufferingNotification(
int id, ::media::BufferingState buffering_state) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const ::media::BufferingStateCB& cb =
entry->media_delegate.client.buffering_state_cb;
if (!cb.is_null())
cb.Run(buffering_state);
}
void CmaMessageFilterProxy::OnPlaybackError(
int id, TrackId track_id, ::media::PipelineStatus status) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const ::media::PipelineStatusCB& cb =
(track_id == kNoTrackId) ? entry->media_delegate.client.error_cb :
(track_id == kAudioTrackId) ?
entry->audio_delegate.client.playback_error_cb :
entry->video_delegate.client.av_pipeline_client.playback_error_cb;
if (!cb.is_null())
cb.Run(status);
}
void CmaMessageFilterProxy::OnStatisticsUpdated(
int id, TrackId track_id, const ::media::PipelineStatistics& stats) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
const ::media::StatisticsCB& cb = (track_id == kAudioTrackId) ?
entry->audio_delegate.client.statistics_cb :
entry->video_delegate.client.av_pipeline_client.statistics_cb;
if (!cb.is_null())
cb.Run(stats);
}
void CmaMessageFilterProxy::OnNaturalSizeChanged(
int id, TrackId track_id, const gfx::Size& size) {
DelegateEntry* entry = delegates_.Lookup(id);
if (!entry)
return;
if (track_id == kAudioTrackId)
return;
const VideoPipelineClient::NaturalSizeChangedCB& cb =
entry->video_delegate.client.natural_size_changed_cb;
if (!cb.is_null())
cb.Run(size);
}
} // namespace media
} // namespace chromecast