1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/browser/media/media_pipeline_host.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/memory/shared_memory.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "chromecast/base/task_runner_impl.h"
16 #include "chromecast/common/media/shared_memory_chunk.h"
17 #include "chromecast/media/base/media_caps.h"
18 #include "chromecast/media/cma/ipc/media_message_fifo.h"
19 #include "chromecast/media/cma/ipc_streamer/coded_frame_provider_host.h"
20 #include "chromecast/media/cma/pipeline/audio_pipeline_impl.h"
21 #include "chromecast/media/cma/pipeline/media_pipeline_impl.h"
22 #include "chromecast/media/cma/pipeline/video_pipeline_impl.h"
23 #include "chromecast/public/media/media_pipeline_backend.h"
24 #include "chromecast/public/media/media_pipeline_device_params.h"
26 namespace chromecast
{
29 struct MediaPipelineHost::MediaTrackHost
{
33 base::Closure pipe_write_cb
;
36 MediaPipelineHost::MediaTrackHost::MediaTrackHost() {
39 MediaPipelineHost::MediaTrackHost::~MediaTrackHost() {
42 MediaPipelineHost::MediaPipelineHost() {
43 thread_checker_
.DetachFromThread();
46 MediaPipelineHost::~MediaPipelineHost() {
47 DCHECK(thread_checker_
.CalledOnValidThread());
49 for (MediaTrackMap::iterator it
= media_track_map_
.begin();
50 it
!= media_track_map_
.end(); ++it
) {
51 scoped_ptr
<MediaTrackHost
> media_track(it
->second
);
53 media_track_map_
.clear();
56 void MediaPipelineHost::Initialize(
58 const MediaPipelineClient
& client
,
59 const CreateDeviceComponentsCB
& create_device_components_cb
) {
60 DCHECK(thread_checker_
.CalledOnValidThread());
61 media_pipeline_
.reset(new MediaPipelineImpl());
62 task_runner_
.reset(new TaskRunnerImpl());
63 MediaPipelineDeviceParams::MediaSyncType sync_type
=
64 (load_type
== kLoadTypeMediaStream
)
65 ? MediaPipelineDeviceParams::kModeIgnorePts
66 : MediaPipelineDeviceParams::kModeSyncPts
;
67 MediaPipelineDeviceParams
default_parameters(sync_type
, task_runner_
.get());
69 media_pipeline_
->Initialize(
70 load_type
, create_device_components_cb
.Run(default_parameters
).Pass());
71 media_pipeline_
->SetClient(client
);
74 void MediaPipelineHost::SetAvPipe(
76 scoped_ptr
<base::SharedMemory
> shared_mem
,
77 const base::Closure
& pipe_read_activity_cb
,
78 const base::Closure
& av_pipe_set_cb
) {
79 DCHECK(thread_checker_
.CalledOnValidThread());
80 CHECK(track_id
== kAudioTrackId
|| track_id
== kVideoTrackId
);
82 size_t shared_mem_size
= shared_mem
->requested_size();
83 scoped_ptr
<MediaMemoryChunk
> shared_memory_chunk(
84 new SharedMemoryChunk(shared_mem
.Pass(), shared_mem_size
));
85 scoped_ptr
<MediaMessageFifo
> media_message_fifo(
86 new MediaMessageFifo(shared_memory_chunk
.Pass(), shared_mem_size
));
87 media_message_fifo
->ObserveReadActivity(pipe_read_activity_cb
);
88 scoped_ptr
<CodedFrameProviderHost
> frame_provider_host(
89 new CodedFrameProviderHost(media_message_fifo
.Pass()));
91 MediaTrackMap::iterator it
= media_track_map_
.find(track_id
);
92 MediaTrackHost
* media_track_host
;
93 if (it
== media_track_map_
.end()) {
94 media_track_host
= new MediaTrackHost();
95 media_track_map_
.insert(
96 std::pair
<TrackId
, MediaTrackHost
*>(track_id
, media_track_host
));
98 media_track_host
= it
->second
;
100 media_track_host
->pipe_write_cb
= frame_provider_host
->GetFifoWriteEventCb();
102 scoped_ptr
<CodedFrameProvider
> frame_provider(frame_provider_host
.release());
103 if (track_id
== kAudioTrackId
) {
104 media_pipeline_
->GetAudioPipelineImpl()->SetCodedFrameProvider(
105 frame_provider
.Pass());
107 media_pipeline_
->GetVideoPipelineImpl()->SetCodedFrameProvider(
108 frame_provider
.Pass());
110 av_pipe_set_cb
.Run();
113 void MediaPipelineHost::AudioInitialize(
115 const AvPipelineClient
& client
,
116 const ::media::AudioDecoderConfig
& config
,
117 const ::media::PipelineStatusCB
& status_cb
) {
118 DCHECK(thread_checker_
.CalledOnValidThread());
119 CHECK(track_id
== kAudioTrackId
);
120 media_pipeline_
->GetAudioPipeline()->SetClient(client
);
121 media_pipeline_
->InitializeAudio(
122 config
, scoped_ptr
<CodedFrameProvider
>(), status_cb
);
125 void MediaPipelineHost::VideoInitialize(
127 const VideoPipelineClient
& client
,
128 const std::vector
<::media::VideoDecoderConfig
>& configs
,
129 const ::media::PipelineStatusCB
& status_cb
) {
130 DCHECK(thread_checker_
.CalledOnValidThread());
131 CHECK(track_id
== kVideoTrackId
);
132 media_pipeline_
->GetVideoPipeline()->SetClient(client
);
133 media_pipeline_
->InitializeVideo(
134 configs
, scoped_ptr
<CodedFrameProvider
>(), status_cb
);
137 void MediaPipelineHost::StartPlayingFrom(base::TimeDelta time
) {
138 DCHECK(thread_checker_
.CalledOnValidThread());
139 media_pipeline_
->StartPlayingFrom(time
);
142 void MediaPipelineHost::Flush(const ::media::PipelineStatusCB
& status_cb
) {
143 DCHECK(thread_checker_
.CalledOnValidThread());
144 media_pipeline_
->Flush(status_cb
);
147 void MediaPipelineHost::Stop() {
148 DCHECK(thread_checker_
.CalledOnValidThread());
149 media_pipeline_
->Stop();
152 void MediaPipelineHost::SetPlaybackRate(double playback_rate
) {
153 DCHECK(thread_checker_
.CalledOnValidThread());
154 media_pipeline_
->SetPlaybackRate(playback_rate
);
157 void MediaPipelineHost::SetVolume(TrackId track_id
, float volume
) {
158 DCHECK(thread_checker_
.CalledOnValidThread());
159 CHECK(track_id
== kAudioTrackId
);
160 media_pipeline_
->GetAudioPipeline()->SetVolume(volume
);
163 void MediaPipelineHost::SetCdm(BrowserCdmCast
* cdm
) {
164 DCHECK(thread_checker_
.CalledOnValidThread());
165 media_pipeline_
->SetCdm(cdm
);
168 void MediaPipelineHost::NotifyPipeWrite(TrackId track_id
) {
169 DCHECK(thread_checker_
.CalledOnValidThread());
170 MediaTrackMap::iterator it
= media_track_map_
.find(track_id
);
171 if (it
== media_track_map_
.end())
174 MediaTrackHost
* media_track_host
= it
->second
;
175 if (!media_track_host
->pipe_write_cb
.is_null())
176 media_track_host
->pipe_write_cb
.Run();
180 } // namespace chromecast