| 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 |