Commit bf072197 authored by erickung's avatar erickung Committed by Commit bot

[Chromecast] Add IPC code on brower process side

BUG=408189

Review URL: https://codereview.chromium.org/823923002

Cr-Commit-Position: refs/heads/master@{#309607}
parent 4eb828fa
This diff is collapsed.
// 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.
#ifndef CHROMECAST_BROWSER_MEDIA_CMA_MESSAGE_FILTER_HOST_H_
#define CHROMECAST_BROWSER_MEDIA_CMA_MESSAGE_FILTER_HOST_H_
#include <map>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "base/memory/weak_ptr.h"
#include "chromecast/common/media/cma_ipc_common.h"
#include "chromecast/media/cma/pipeline/load_type.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
#include "media/base/buffering_state.h"
#include "media/base/pipeline_status.h"
namespace base {
class CancelableSyncSocket;
class SingleThreadTaskRunner;
}
namespace gfx {
class PointF;
class Size;
}
namespace media {
class AudioDecoderConfig;
class BrowserCdm;
class VideoDecoderConfig;
}
namespace chromecast {
namespace media {
class MediaPipelineHost;
class CmaMessageFilterHost
: public content::BrowserMessageFilter {
public:
explicit CmaMessageFilterHost(int render_process_id);
// content::BrowserMessageFilter implementation.
void OnChannelClosing() override;
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
private:
typedef std::map<int, MediaPipelineHost*> MediaPipelineMap;
friend class content::BrowserThread;
friend class base::DeleteHelper<CmaMessageFilterHost>;
~CmaMessageFilterHost() override;
void DeleteEntries();
MediaPipelineHost* LookupById(int media_id);
// Handling of incoming IPC messages.
void CreateMedia(int media_id, LoadType load_type);
void DestroyMedia(int media_id);
void SetCdm(int media_id, int render_frame_id, int cdm_id);
void CreateAvPipe(int media_id, TrackId track_id, size_t shared_mem_size);
void OnAvPipeSet(int media_id,
TrackId track_id,
base::SharedMemoryHandle foreign_memory_handle,
scoped_ptr<base::CancelableSyncSocket> foreign_socket);
void AudioInitialize(int media_id,
TrackId track_id,
const ::media::AudioDecoderConfig& config);
void VideoInitialize(int media_id,
TrackId track_id,
const ::media::VideoDecoderConfig& config);
void StartPlayingFrom(int media_id, base::TimeDelta time);
void Flush(int media_id);
void Stop(int media_id);
void SetPlaybackRate(int media_id, float playback_rate);
void SetVolume(int media_id, TrackId track_id, float volume);
void NotifyPipeWrite(int media_id, TrackId track_id);
void NotifyExternalSurface(int surface_id,
const gfx::PointF& p0, const gfx::PointF& p1,
const gfx::PointF& p2, const gfx::PointF& p3);
// Audio/Video callbacks.
void OnMediaStateChanged(int media_id,
::media::PipelineStatus status);
void OnTrackStateChanged(int media_id,
TrackId track_id,
::media::PipelineStatus status);
void OnPipeReadActivity(int media_id, TrackId track_id);
void OnTimeUpdate(int media_id,
base::TimeDelta media_time,
base::TimeDelta max_media_time,
base::TimeTicks stc);
void OnBufferingNotification(int media_id, ::media::BufferingState state);
void OnEos(int media_id, TrackId track_id);
void OnPlaybackError(int media_id, TrackId track_id,
::media::PipelineStatus status);
void OnStatisticsUpdated(int media_id,
TrackId track_id,
const ::media::PipelineStatistics& stats);
void OnNaturalSizeChanged(int media_id,
TrackId track_id,
const gfx::Size& size);
// Render process ID correponding to this message filter.
const int process_id_;
// List of media pipeline and message loop media pipelines are running on.
MediaPipelineMap media_pipelines_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtr<CmaMessageFilterHost> weak_this_;
base::WeakPtrFactory<CmaMessageFilterHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CmaMessageFilterHost);
};
} // namespace media
} // namespace chromecast
#endif // CHROMECAST_BROWSER_MEDIA_CMA_MESSAGE_FILTER_HOST_H_
// 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/browser/media/cma_message_loop.h"
#include "base/threading/thread.h"
namespace chromecast {
namespace media {
// static
scoped_refptr<base::MessageLoopProxy> CmaMessageLoop::GetMessageLoopProxy() {
return GetInstance()->thread_->message_loop_proxy();
}
// static
CmaMessageLoop* CmaMessageLoop::GetInstance() {
return Singleton<CmaMessageLoop>::get();
}
CmaMessageLoop::CmaMessageLoop()
: thread_(new base::Thread("CmaThread")) {
thread_->Start();
}
CmaMessageLoop::~CmaMessageLoop() {
// This will automatically shutdown the thread.
}
} // namespace media
} // namespace chromecast
// 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.
#ifndef CHROMECAST_BROWSER_MEDIA_CMA_MESSAGE_LOOP_H_
#define CHROMECAST_BROWSER_MEDIA_CMA_MESSAGE_LOOP_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
namespace base {
class MessageLoopProxy;
class Thread;
}
namespace chromecast {
namespace media {
class CmaMessageLoop {
public:
static scoped_refptr<base::MessageLoopProxy> GetMessageLoopProxy();
private:
friend struct DefaultSingletonTraits<CmaMessageLoop>;
friend class Singleton<CmaMessageLoop>;
static CmaMessageLoop* GetInstance();
CmaMessageLoop();
~CmaMessageLoop();
scoped_ptr<base::Thread> thread_;
DISALLOW_COPY_AND_ASSIGN(CmaMessageLoop);
};
} // namespace media
} // namespace chromecast
#endif // CHROMECAST_BROWSER_MEDIA_CMA_MESSAGE_LOOP_H_
// 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/browser/media/media_pipeline_host.h"
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/memory/shared_memory.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/common/media/shared_memory_chunk.h"
#include "chromecast/media/cma/backend/media_pipeline_device.h"
#include "chromecast/media/cma/backend/media_pipeline_device_params.h"
#include "chromecast/media/cma/ipc/media_message_fifo.h"
#include "chromecast/media/cma/ipc_streamer/coded_frame_provider_host.h"
#include "chromecast/media/cma/pipeline/audio_pipeline_impl.h"
#include "chromecast/media/cma/pipeline/media_pipeline_impl.h"
#include "chromecast/media/cma/pipeline/video_pipeline_impl.h"
namespace chromecast {
namespace media {
struct MediaPipelineHost::MediaTrackHost {
MediaTrackHost();
~MediaTrackHost();
base::Closure pipe_write_cb;
};
MediaPipelineHost::MediaTrackHost::MediaTrackHost() {
}
MediaPipelineHost::MediaTrackHost::~MediaTrackHost() {
}
MediaPipelineHost::MediaPipelineHost() {
thread_checker_.DetachFromThread();
}
MediaPipelineHost::~MediaPipelineHost() {
DCHECK(thread_checker_.CalledOnValidThread());
for (MediaTrackMap::iterator it = media_track_map_.begin();
it != media_track_map_.end(); ++it) {
scoped_ptr<MediaTrackHost> media_track(it->second);
}
media_track_map_.clear();
}
void MediaPipelineHost::Initialize(
LoadType load_type,
const MediaPipelineClient& client) {
DCHECK(thread_checker_.CalledOnValidThread());
media_pipeline_.reset(new MediaPipelineImpl());
MediaPipelineDeviceParams default_parameters;
if (load_type == kLoadTypeMediaStream)
default_parameters.disable_synchronization = true;
media_pipeline_->Initialize(
load_type,
CreateMediaPipelineDevice(default_parameters).Pass());
media_pipeline_->SetClient(client);
}
void MediaPipelineHost::SetAvPipe(
TrackId track_id,
scoped_ptr<base::SharedMemory> shared_mem,
const base::Closure& pipe_read_activity_cb,
const base::Closure& av_pipe_set_cb) {
DCHECK(thread_checker_.CalledOnValidThread());
CHECK(track_id == kAudioTrackId || track_id == kVideoTrackId);
size_t shared_mem_size = shared_mem->requested_size();
scoped_ptr<MediaMemoryChunk> shared_memory_chunk(
new SharedMemoryChunk(shared_mem.Pass(), shared_mem_size));
scoped_ptr<MediaMessageFifo> media_message_fifo(
new MediaMessageFifo(shared_memory_chunk.Pass(), shared_mem_size));
media_message_fifo->ObserveReadActivity(pipe_read_activity_cb);
scoped_ptr<CodedFrameProviderHost> frame_provider_host(
new CodedFrameProviderHost(media_message_fifo.Pass()));
MediaTrackMap::iterator it = media_track_map_.find(track_id);
MediaTrackHost* media_track_host;
if (it == media_track_map_.end()) {
media_track_host = new MediaTrackHost();
media_track_map_.insert(
std::pair<TrackId, MediaTrackHost*>(track_id, media_track_host));
} else {
media_track_host = it->second;
}
media_track_host->pipe_write_cb = frame_provider_host->GetFifoWriteEventCb();
scoped_ptr<CodedFrameProvider> frame_provider(frame_provider_host.release());
if (track_id == kAudioTrackId) {
media_pipeline_->GetAudioPipelineImpl()->SetCodedFrameProvider(
frame_provider.Pass());
} else {
media_pipeline_->GetVideoPipelineImpl()->SetCodedFrameProvider(
frame_provider.Pass());
}
av_pipe_set_cb.Run();
}
void MediaPipelineHost::AudioInitialize(
TrackId track_id,
const AvPipelineClient& client,
const ::media::AudioDecoderConfig& config,
const ::media::PipelineStatusCB& status_cb) {
DCHECK(thread_checker_.CalledOnValidThread());
CHECK(track_id == kAudioTrackId);
media_pipeline_->GetAudioPipeline()->SetClient(client);
media_pipeline_->InitializeAudio(
config, scoped_ptr<CodedFrameProvider>(), status_cb);
}
void MediaPipelineHost::VideoInitialize(
TrackId track_id,
const VideoPipelineClient& client,
const ::media::VideoDecoderConfig& config,
const ::media::PipelineStatusCB& status_cb) {
DCHECK(thread_checker_.CalledOnValidThread());
CHECK(track_id == kVideoTrackId);
media_pipeline_->GetVideoPipeline()->SetClient(client);
media_pipeline_->InitializeVideo(
config, scoped_ptr<CodedFrameProvider>(), status_cb);
}
void MediaPipelineHost::StartPlayingFrom(base::TimeDelta time) {
DCHECK(thread_checker_.CalledOnValidThread());
media_pipeline_->StartPlayingFrom(time);
}
void MediaPipelineHost::Flush(const ::media::PipelineStatusCB& status_cb) {
DCHECK(thread_checker_.CalledOnValidThread());
media_pipeline_->Flush(status_cb);
}
void MediaPipelineHost::Stop() {
DCHECK(thread_checker_.CalledOnValidThread());
media_pipeline_->Stop();
}
void MediaPipelineHost::SetPlaybackRate(float playback_rate) {
DCHECK(thread_checker_.CalledOnValidThread());
media_pipeline_->SetPlaybackRate(playback_rate);
}
void MediaPipelineHost::SetVolume(TrackId track_id, float volume) {
DCHECK(thread_checker_.CalledOnValidThread());
CHECK(track_id == kAudioTrackId);
media_pipeline_->GetAudioPipeline()->SetVolume(volume);
}
void MediaPipelineHost::SetCdm(
int render_process_id, int render_frame_id, int cdm_id) {
DCHECK(thread_checker_.CalledOnValidThread());
// TODO(gunsch): crbug.com/444930. Find a way to get
// content::BrowserCdmManager since it is not under content/public/.
NOTIMPLEMENTED();
}
void MediaPipelineHost::NotifyPipeWrite(TrackId track_id) {
DCHECK(thread_checker_.CalledOnValidThread());
MediaTrackMap::iterator it = media_track_map_.find(track_id);
if (it == media_track_map_.end())
return;
MediaTrackHost* media_track_host = it->second;
if (!media_track_host->pipe_write_cb.is_null())
media_track_host->pipe_write_cb.Run();
}
} // namespace media
} // namespace chromecast
// 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.
#ifndef CHROMECAST_BROWSER_MEDIA_MEDIA_PIPELINE_HOST_H_
#define CHROMECAST_BROWSER_MEDIA_MEDIA_PIPELINE_HOST_H_
#include <map>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "chromecast/common/media/cma_ipc_common.h"
#include "chromecast/media/cma/pipeline/load_type.h"
#include "media/base/pipeline_status.h"
namespace base {
class SharedMemory;
class SingleThreadTaskRunner;
}
namespace media {
class AudioDecoderConfig;
class VideoDecoderConfig;
}
namespace chromecast {
namespace media {
struct AvPipelineClient;
struct MediaPipelineClient;
class MediaPipelineImpl;
struct VideoPipelineClient;
class MediaPipelineHost {
public:
MediaPipelineHost();
~MediaPipelineHost();
void Initialize(LoadType load_type,
const MediaPipelineClient& client);
void SetAvPipe(TrackId track_id,
scoped_ptr<base::SharedMemory> shared_mem,
const base::Closure& pipe_read_activity_cb,
const base::Closure& av_pipe_set_cb);
void AudioInitialize(TrackId track_id,
const AvPipelineClient& client,
const ::media::AudioDecoderConfig& config,
const ::media::PipelineStatusCB& status_cb);
void VideoInitialize(TrackId track_id,
const VideoPipelineClient& client,
const ::media::VideoDecoderConfig& config,
const ::media::PipelineStatusCB& status_cb);
void StartPlayingFrom(base::TimeDelta time);
void Flush(const ::media::PipelineStatusCB& status_cb);
void Stop();
void SetPlaybackRate(float playback_rate);
void SetVolume(TrackId track_id, float playback_rate);
void SetCdm(int render_process_id, int render_frame_id, int cdm_id);
void NotifyPipeWrite(TrackId track_id);
private:
base::ThreadChecker thread_checker_;
scoped_ptr<MediaPipelineImpl> media_pipeline_;
// The shared memory for a track id must be valid until Stop is invoked on
// that track id.
struct MediaTrackHost;
typedef std::map<TrackId, MediaTrackHost*> MediaTrackMap;
MediaTrackMap media_track_map_;
DISALLOW_COPY_AND_ASSIGN(MediaPipelineHost);
};
} // namespace media
} // namespace chromecast
#endif // CHROMECAST_BROWSER_MEDIA_MEDIA_PIPELINE_HOST_H_
...@@ -428,6 +428,12 @@ ...@@ -428,6 +428,12 @@
'../ipc/ipc.gyp:ipc', '../ipc/ipc.gyp:ipc',
], ],
'sources': [ 'sources': [
'browser/media/cma_message_filter_host.cc',
'browser/media/cma_message_filter_host.h',
'browser/media/cma_message_loop.cc',
'browser/media/cma_message_loop.h',
'browser/media/media_pipeline_host.cc',
'browser/media/media_pipeline_host.h',
'common/media/cma_ipc_common.h', 'common/media/cma_ipc_common.h',
'common/media/cma_messages.h', 'common/media/cma_messages.h',
'common/media/cma_message_generator.cc', 'common/media/cma_message_generator.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment