OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chromecast/browser/media/media_pipeline_host.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <utility> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/callback.h" | |
13 #include "base/location.h" | |
14 #include "base/memory/shared_memory.h" | |
15 #include "base/single_thread_task_runner.h" | |
16 #include "base/threading/thread_task_runner_handle.h" | |
17 #include "chromecast/base/task_runner_impl.h" | |
18 #include "chromecast/common/media/shared_memory_chunk.h" | |
19 #include "chromecast/media/base/media_caps.h" | |
20 #include "chromecast/media/cdm/cast_cdm_context.h" | |
21 #include "chromecast/media/cma/ipc/media_message_fifo.h" | |
22 #include "chromecast/media/cma/ipc_streamer/coded_frame_provider_host.h" | |
23 #include "chromecast/media/cma/pipeline/audio_pipeline_impl.h" | |
24 #include "chromecast/media/cma/pipeline/media_pipeline_impl.h" | |
25 #include "chromecast/media/cma/pipeline/video_pipeline_impl.h" | |
26 #include "chromecast/public/media/media_pipeline_backend.h" | |
27 #include "chromecast/public/media/media_pipeline_device_params.h" | |
28 #include "media/audio/audio_device_description.h" | |
29 | |
30 namespace chromecast { | |
31 namespace media { | |
32 | |
33 struct MediaPipelineHost::MediaTrackHost { | |
34 MediaTrackHost(); | |
35 ~MediaTrackHost(); | |
36 | |
37 base::Closure pipe_write_cb; | |
38 }; | |
39 | |
40 MediaPipelineHost::MediaTrackHost::MediaTrackHost() { | |
41 } | |
42 | |
43 MediaPipelineHost::MediaTrackHost::~MediaTrackHost() { | |
44 } | |
45 | |
46 MediaPipelineHost::MediaPipelineHost() { | |
47 thread_checker_.DetachFromThread(); | |
48 } | |
49 | |
50 MediaPipelineHost::~MediaPipelineHost() { | |
51 DCHECK(thread_checker_.CalledOnValidThread()); | |
52 | |
53 for (MediaTrackMap::iterator it = media_track_map_.begin(); | |
54 it != media_track_map_.end(); ++it) { | |
55 std::unique_ptr<MediaTrackHost> media_track(it->second); | |
56 } | |
57 media_track_map_.clear(); | |
58 } | |
59 | |
60 void MediaPipelineHost::Initialize( | |
61 LoadType load_type, | |
62 const MediaPipelineClient& client, | |
63 const CreateMediaPipelineBackendCB& create_backend_cb) { | |
64 DCHECK(thread_checker_.CalledOnValidThread()); | |
65 media_pipeline_.reset(new MediaPipelineImpl()); | |
66 task_runner_.reset(new TaskRunnerImpl()); | |
67 MediaPipelineDeviceParams::MediaSyncType sync_type = | |
68 (load_type == kLoadTypeMediaStream) | |
69 ? MediaPipelineDeviceParams::kModeIgnorePts | |
70 : MediaPipelineDeviceParams::kModeSyncPts; | |
71 MediaPipelineDeviceParams default_parameters(sync_type, task_runner_.get()); | |
72 | |
73 media_pipeline_->SetClient(client); | |
74 media_pipeline_->Initialize( | |
75 load_type, | |
76 create_backend_cb.Run(default_parameters, | |
77 ::media::AudioDeviceDescription::kDefaultDeviceId)); | |
78 } | |
79 | |
80 void MediaPipelineHost::SetAvPipe( | |
81 TrackId track_id, | |
82 std::unique_ptr<base::SharedMemory> shared_mem, | |
83 const base::Closure& pipe_read_activity_cb, | |
84 const base::Closure& av_pipe_set_cb) { | |
85 DCHECK(thread_checker_.CalledOnValidThread()); | |
86 CHECK(track_id == kAudioTrackId || track_id == kVideoTrackId); | |
87 | |
88 size_t shared_mem_size = shared_mem->requested_size(); | |
89 std::unique_ptr<MediaMemoryChunk> shared_memory_chunk( | |
90 new SharedMemoryChunk(std::move(shared_mem), shared_mem_size)); | |
91 std::unique_ptr<MediaMessageFifo> media_message_fifo( | |
92 new MediaMessageFifo(std::move(shared_memory_chunk), shared_mem_size)); | |
93 media_message_fifo->ObserveReadActivity(pipe_read_activity_cb); | |
94 std::unique_ptr<CodedFrameProviderHost> frame_provider_host( | |
95 new CodedFrameProviderHost(std::move(media_message_fifo))); | |
96 | |
97 MediaTrackMap::iterator it = media_track_map_.find(track_id); | |
98 MediaTrackHost* media_track_host; | |
99 if (it == media_track_map_.end()) { | |
100 media_track_host = new MediaTrackHost(); | |
101 media_track_map_.insert( | |
102 std::pair<TrackId, MediaTrackHost*>(track_id, media_track_host)); | |
103 } else { | |
104 media_track_host = it->second; | |
105 } | |
106 media_track_host->pipe_write_cb = frame_provider_host->GetFifoWriteEventCb(); | |
107 | |
108 if (track_id == kAudioTrackId) { | |
109 audio_frame_provider_ = std::move(frame_provider_host); | |
110 } else { | |
111 video_frame_provider_ = std::move(frame_provider_host); | |
112 } | |
113 av_pipe_set_cb.Run(); | |
114 } | |
115 | |
116 void MediaPipelineHost::AudioInitialize( | |
117 TrackId track_id, | |
118 const AvPipelineClient& client, | |
119 const ::media::AudioDecoderConfig& config, | |
120 const ::media::PipelineStatusCB& status_cb) { | |
121 DCHECK(thread_checker_.CalledOnValidThread()); | |
122 CHECK(track_id == kAudioTrackId); | |
123 ::media::PipelineStatus status = media_pipeline_->InitializeAudio( | |
124 config, client, std::move(audio_frame_provider_)); | |
125 status_cb.Run(status); | |
126 } | |
127 | |
128 void MediaPipelineHost::VideoInitialize( | |
129 TrackId track_id, | |
130 const VideoPipelineClient& client, | |
131 const std::vector< ::media::VideoDecoderConfig>& configs, | |
132 const ::media::PipelineStatusCB& status_cb) { | |
133 DCHECK(thread_checker_.CalledOnValidThread()); | |
134 CHECK(track_id == kVideoTrackId); | |
135 ::media::PipelineStatus status = media_pipeline_->InitializeVideo( | |
136 configs, client, std::move(video_frame_provider_)); | |
137 status_cb.Run(status); | |
138 } | |
139 | |
140 void MediaPipelineHost::StartPlayingFrom(base::TimeDelta time) { | |
141 DCHECK(thread_checker_.CalledOnValidThread()); | |
142 media_pipeline_->StartPlayingFrom(time); | |
143 } | |
144 | |
145 void MediaPipelineHost::Flush(const base::Closure& flush_cb) { | |
146 DCHECK(thread_checker_.CalledOnValidThread()); | |
147 media_pipeline_->Flush(flush_cb); | |
148 } | |
149 | |
150 void MediaPipelineHost::Stop() { | |
151 DCHECK(thread_checker_.CalledOnValidThread()); | |
152 media_pipeline_->Stop(); | |
153 } | |
154 | |
155 void MediaPipelineHost::SetPlaybackRate(double playback_rate) { | |
156 DCHECK(thread_checker_.CalledOnValidThread()); | |
157 media_pipeline_->SetPlaybackRate(playback_rate); | |
158 } | |
159 | |
160 void MediaPipelineHost::SetVolume(TrackId track_id, float volume) { | |
161 DCHECK(thread_checker_.CalledOnValidThread()); | |
162 CHECK(track_id == kAudioTrackId); | |
163 media_pipeline_->SetVolume(volume); | |
164 } | |
165 | |
166 void MediaPipelineHost::SetCdm(CastCdmContext* cdm) { | |
167 DCHECK(thread_checker_.CalledOnValidThread()); | |
168 media_pipeline_->SetCdm(cdm); | |
169 } | |
170 | |
171 void MediaPipelineHost::NotifyPipeWrite(TrackId track_id) { | |
172 DCHECK(thread_checker_.CalledOnValidThread()); | |
173 MediaTrackMap::iterator it = media_track_map_.find(track_id); | |
174 if (it == media_track_map_.end()) | |
175 return; | |
176 | |
177 MediaTrackHost* media_track_host = it->second; | |
178 if (!media_track_host->pipe_write_cb.is_null()) | |
179 media_track_host->pipe_write_cb.Run(); | |
180 } | |
181 | |
182 } // namespace media | |
183 } // namespace chromecast | |
OLD | NEW |