Update broken references to image assets
[chromium-blink-merge.git] / media / mojo / services / mojo_renderer_service.cc
blob054f9bc763adc42461bcc8e7b40b610e0206ede2
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 "media/mojo/services/mojo_renderer_service.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/message_loop/message_loop.h"
11 #include "media/base/audio_decoder.h"
12 #include "media/base/audio_renderer.h"
13 #include "media/base/audio_renderer_sink.h"
14 #include "media/base/cdm_context.h"
15 #include "media/base/decryptor.h"
16 #include "media/base/media_log.h"
17 #include "media/base/renderer_factory.h"
18 #include "media/base/video_renderer.h"
19 #include "media/base/video_renderer_sink.h"
20 #include "media/mojo/services/demuxer_stream_provider_shim.h"
21 #include "media/mojo/services/mojo_media_client.h"
22 #include "media/renderers/audio_renderer_impl.h"
23 #include "media/renderers/renderer_impl.h"
24 #include "media/renderers/video_renderer_impl.h"
26 namespace media {
28 // Time interval to update media time.
29 const int kTimeUpdateIntervalMs = 50;
31 MojoRendererService::MojoRendererService(
32 base::WeakPtr<CdmContextProvider> cdm_context_provider,
33 RendererFactory* renderer_factory,
34 const scoped_refptr<MediaLog>& media_log,
35 mojo::InterfaceRequest<interfaces::Renderer> request)
36 : binding_(this, request.Pass()),
37 cdm_context_provider_(cdm_context_provider),
38 state_(STATE_UNINITIALIZED),
39 last_media_time_usec_(0),
40 weak_factory_(this) {
41 weak_this_ = weak_factory_.GetWeakPtr();
42 DVLOG(1) << __FUNCTION__;
44 scoped_refptr<base::SingleThreadTaskRunner> task_runner(
45 base::MessageLoop::current()->task_runner());
46 MojoMediaClient* mojo_media_client = MojoMediaClient::Get();
47 audio_renderer_sink_ = mojo_media_client->CreateAudioRendererSink();
48 video_renderer_sink_ =
49 mojo_media_client->CreateVideoRendererSink(task_runner);
51 // Create renderer.
52 if (renderer_factory) {
53 renderer_ = renderer_factory->CreateRenderer(task_runner, task_runner,
54 audio_renderer_sink_.get(),
55 video_renderer_sink_.get());
56 } else {
57 scoped_ptr<AudioRenderer> audio_renderer(new AudioRendererImpl(
58 task_runner, audio_renderer_sink_.get(),
59 mojo_media_client->CreateAudioDecoders(task_runner, media_log).Pass(),
60 mojo_media_client->GetAudioHardwareConfig(), media_log));
61 scoped_ptr<VideoRenderer> video_renderer(new VideoRendererImpl(
62 task_runner, task_runner, video_renderer_sink_.get(),
63 mojo_media_client->CreateVideoDecoders(task_runner, media_log).Pass(),
64 true, nullptr, media_log));
65 renderer_.reset(new RendererImpl(task_runner, audio_renderer.Pass(),
66 video_renderer.Pass()));
70 MojoRendererService::~MojoRendererService() {
73 void MojoRendererService::Initialize(
74 interfaces::RendererClientPtr client,
75 interfaces::DemuxerStreamPtr audio,
76 interfaces::DemuxerStreamPtr video,
77 const mojo::Callback<void(bool)>& callback) {
78 DVLOG(1) << __FUNCTION__;
79 DCHECK_EQ(state_, STATE_UNINITIALIZED);
80 client_ = client.Pass();
81 state_ = STATE_INITIALIZING;
82 stream_provider_.reset(new DemuxerStreamProviderShim(
83 audio.Pass(),
84 video.Pass(),
85 base::Bind(&MojoRendererService::OnStreamReady, weak_this_, callback)));
88 void MojoRendererService::Flush(const mojo::Closure& callback) {
89 DVLOG(2) << __FUNCTION__;
90 DCHECK_EQ(state_, STATE_PLAYING);
92 state_ = STATE_FLUSHING;
93 CancelPeriodicMediaTimeUpdates();
94 renderer_->Flush(
95 base::Bind(&MojoRendererService::OnFlushCompleted, weak_this_, callback));
98 void MojoRendererService::StartPlayingFrom(int64_t time_delta_usec) {
99 DVLOG(2) << __FUNCTION__ << ": " << time_delta_usec;
100 renderer_->StartPlayingFrom(
101 base::TimeDelta::FromMicroseconds(time_delta_usec));
102 SchedulePeriodicMediaTimeUpdates();
105 void MojoRendererService::SetPlaybackRate(double playback_rate) {
106 DVLOG(2) << __FUNCTION__ << ": " << playback_rate;
107 DCHECK_EQ(state_, STATE_PLAYING);
108 renderer_->SetPlaybackRate(playback_rate);
111 void MojoRendererService::SetVolume(float volume) {
112 renderer_->SetVolume(volume);
115 void MojoRendererService::SetCdm(int32_t cdm_id,
116 const mojo::Callback<void(bool)>& callback) {
117 if (!cdm_context_provider_) {
118 LOG(ERROR) << "CDM context provider not available.";
119 callback.Run(false);
120 return;
123 CdmContext* cdm_context = cdm_context_provider_->GetCdmContext(cdm_id);
124 if (!cdm_context) {
125 LOG(ERROR) << "CDM context not found: " << cdm_id;
126 callback.Run(false);
127 return;
130 renderer_->SetCdm(cdm_context, base::Bind(&MojoRendererService::OnCdmAttached,
131 weak_this_, callback));
134 void MojoRendererService::OnStreamReady(
135 const mojo::Callback<void(bool)>& callback) {
136 DCHECK_EQ(state_, STATE_INITIALIZING);
138 renderer_->Initialize(
139 stream_provider_.get(),
140 base::Bind(
141 &MojoRendererService::OnRendererInitializeDone, weak_this_, callback),
142 base::Bind(&MojoRendererService::OnUpdateStatistics, weak_this_),
143 base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_),
144 base::Bind(&MojoRendererService::OnRendererEnded, weak_this_),
145 base::Bind(&MojoRendererService::OnError, weak_this_),
146 base::Bind(base::DoNothing));
149 void MojoRendererService::OnRendererInitializeDone(
150 const mojo::Callback<void(bool)>& callback,
151 PipelineStatus status) {
152 DVLOG(1) << __FUNCTION__;
153 DCHECK_EQ(state_, STATE_INITIALIZING);
155 if (status != PIPELINE_OK) {
156 state_ = STATE_ERROR;
157 callback.Run(false);
158 return;
161 state_ = STATE_PLAYING;
162 callback.Run(true);
165 void MojoRendererService::OnUpdateStatistics(const PipelineStatistics& stats) {
168 void MojoRendererService::UpdateMediaTime(bool force) {
169 const uint64_t media_time = renderer_->GetMediaTime().InMicroseconds();
170 if (!force && media_time == last_media_time_usec_)
171 return;
173 client_->OnTimeUpdate(media_time, media_time);
174 last_media_time_usec_ = media_time;
177 void MojoRendererService::CancelPeriodicMediaTimeUpdates() {
178 DVLOG(2) << __FUNCTION__;
179 UpdateMediaTime(false);
180 time_update_timer_.Stop();
183 void MojoRendererService::SchedulePeriodicMediaTimeUpdates() {
184 DVLOG(2) << __FUNCTION__;
185 UpdateMediaTime(true);
186 time_update_timer_.Start(
187 FROM_HERE,
188 base::TimeDelta::FromMilliseconds(kTimeUpdateIntervalMs),
189 base::Bind(&MojoRendererService::UpdateMediaTime, weak_this_, false));
192 void MojoRendererService::OnBufferingStateChanged(
193 BufferingState new_buffering_state) {
194 DVLOG(2) << __FUNCTION__ << "(" << new_buffering_state << ")";
195 client_->OnBufferingStateChange(
196 static_cast<interfaces::BufferingState>(new_buffering_state));
199 void MojoRendererService::OnRendererEnded() {
200 DVLOG(1) << __FUNCTION__;
201 CancelPeriodicMediaTimeUpdates();
202 client_->OnEnded();
205 void MojoRendererService::OnError(PipelineStatus error) {
206 DVLOG(1) << __FUNCTION__ << "(" << error << ")";
207 state_ = STATE_ERROR;
208 client_->OnError();
211 void MojoRendererService::OnFlushCompleted(const mojo::Closure& callback) {
212 DVLOG(1) << __FUNCTION__;
213 DCHECK_EQ(state_, STATE_FLUSHING);
214 state_ = STATE_PLAYING;
215 callback.Run();
218 void MojoRendererService::OnCdmAttached(
219 const mojo::Callback<void(bool)>& callback,
220 bool success) {
221 DVLOG(1) << __FUNCTION__ << "(" << success << ")";
222 callback.Run(success);
225 } // namespace media