Unregister from GCM when the only GCM app is removed
[chromium-blink-merge.git] / media / mojo / services / mojo_renderer_service.cc
blob02f4573f7555ddfdd9dc0014311719aa1019679b
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/decryptor.h"
15 #include "media/base/media_log.h"
16 #include "media/base/video_renderer.h"
17 #include "media/filters/audio_renderer_impl.h"
18 #include "media/filters/renderer_impl.h"
19 #include "media/filters/video_renderer_impl.h"
20 #include "media/mojo/services/demuxer_stream_provider_shim.h"
21 #include "media/mojo/services/renderer_config.h"
23 namespace media {
25 // Time interval to update media time.
26 const int kTimeUpdateIntervalMs = 50;
28 static void LogMediaSourceError(const scoped_refptr<MediaLog>& media_log,
29 const std::string& error) {
30 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error));
33 static void PaintNothing(const scoped_refptr<VideoFrame>& frame) {
36 MojoRendererService::MojoRendererService()
37 : state_(STATE_UNINITIALIZED),
38 last_media_time_usec_(0),
39 weak_factory_(this) {
40 weak_this_ = weak_factory_.GetWeakPtr();
41 DVLOG(1) << __FUNCTION__;
43 scoped_refptr<base::SingleThreadTaskRunner> task_runner(
44 base::MessageLoop::current()->task_runner());
45 scoped_refptr<MediaLog> media_log(new MediaLog());
46 RendererConfig* renderer_config = RendererConfig::Get();
47 audio_renderer_sink_ = renderer_config->GetAudioRendererSink();
49 scoped_ptr<AudioRenderer> audio_renderer(new AudioRendererImpl(
50 task_runner, audio_renderer_sink_.get(),
51 renderer_config->GetAudioDecoders(
52 task_runner,
53 base::Bind(&LogMediaSourceError, media_log)).Pass(),
54 renderer_config->GetAudioHardwareConfig(), media_log));
56 scoped_ptr<VideoRenderer> video_renderer(new VideoRendererImpl(
57 task_runner,
58 renderer_config->GetVideoDecoders(
59 task_runner,
60 base::Bind(&LogMediaSourceError, media_log)).Pass(),
61 true, media_log));
63 // Create renderer.
64 renderer_.reset(new RendererImpl(
65 task_runner, audio_renderer.Pass(), video_renderer.Pass()));
68 MojoRendererService::~MojoRendererService() {
71 void MojoRendererService::Initialize(mojo::MediaRendererClientPtr client,
72 mojo::DemuxerStreamPtr audio,
73 mojo::DemuxerStreamPtr video,
74 const mojo::Closure& callback) {
75 DVLOG(1) << __FUNCTION__;
76 DCHECK_EQ(state_, STATE_UNINITIALIZED);
77 client_ = client.Pass();
78 state_ = STATE_INITIALIZING;
79 stream_provider_.reset(new DemuxerStreamProviderShim(
80 audio.Pass(),
81 video.Pass(),
82 base::Bind(&MojoRendererService::OnStreamReady, weak_this_, callback)));
85 void MojoRendererService::Flush(const mojo::Closure& callback) {
86 DVLOG(2) << __FUNCTION__;
87 DCHECK_EQ(state_, STATE_PLAYING);
89 state_ = STATE_FLUSHING;
90 CancelPeriodicMediaTimeUpdates();
91 renderer_->Flush(
92 base::Bind(&MojoRendererService::OnFlushCompleted, weak_this_, callback));
95 void MojoRendererService::StartPlayingFrom(int64_t time_delta_usec) {
96 DVLOG(2) << __FUNCTION__ << ": " << time_delta_usec;
97 renderer_->StartPlayingFrom(
98 base::TimeDelta::FromMicroseconds(time_delta_usec));
99 SchedulePeriodicMediaTimeUpdates();
102 void MojoRendererService::SetPlaybackRate(float playback_rate) {
103 DVLOG(2) << __FUNCTION__ << ": " << playback_rate;
104 DCHECK_EQ(state_, STATE_PLAYING);
105 renderer_->SetPlaybackRate(playback_rate);
108 void MojoRendererService::SetVolume(float volume) {
109 renderer_->SetVolume(volume);
112 void MojoRendererService::OnStreamReady(const mojo::Closure& callback) {
113 DCHECK_EQ(state_, STATE_INITIALIZING);
115 renderer_->Initialize(
116 stream_provider_.get(),
117 base::Bind(
118 &MojoRendererService::OnRendererInitializeDone, weak_this_, callback),
119 base::Bind(&MojoRendererService::OnUpdateStatistics, weak_this_),
120 base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_),
121 base::Bind(&PaintNothing),
122 base::Bind(&MojoRendererService::OnRendererEnded, weak_this_),
123 base::Bind(&MojoRendererService::OnError, weak_this_));
126 void MojoRendererService::OnRendererInitializeDone(
127 const mojo::Closure& callback, PipelineStatus status) {
128 DVLOG(1) << __FUNCTION__;
130 if (status != PIPELINE_OK && state_ != STATE_ERROR)
131 OnError(status);
133 if (state_ == STATE_ERROR) {
134 renderer_.reset();
135 } else {
136 DCHECK_EQ(state_, STATE_INITIALIZING);
137 state_ = STATE_PLAYING;
140 callback.Run();
143 void MojoRendererService::OnUpdateStatistics(const PipelineStatistics& stats) {
146 void MojoRendererService::UpdateMediaTime(bool force) {
147 const uint64_t media_time = renderer_->GetMediaTime().InMicroseconds();
148 if (!force && media_time == last_media_time_usec_)
149 return;
151 client_->OnTimeUpdate(media_time, media_time);
152 last_media_time_usec_ = media_time;
155 void MojoRendererService::CancelPeriodicMediaTimeUpdates() {
156 UpdateMediaTime(false);
157 time_update_timer_.Reset();
160 void MojoRendererService::SchedulePeriodicMediaTimeUpdates() {
161 UpdateMediaTime(true);
162 time_update_timer_.Start(
163 FROM_HERE,
164 base::TimeDelta::FromMilliseconds(kTimeUpdateIntervalMs),
165 base::Bind(&MojoRendererService::UpdateMediaTime, weak_this_, false));
168 void MojoRendererService::OnBufferingStateChanged(
169 BufferingState new_buffering_state) {
170 DVLOG(2) << __FUNCTION__ << "(" << new_buffering_state << ") ";
171 client_->OnBufferingStateChange(
172 static_cast<mojo::BufferingState>(new_buffering_state));
175 void MojoRendererService::OnRendererEnded() {
176 DVLOG(1) << __FUNCTION__;
177 CancelPeriodicMediaTimeUpdates();
178 client_->OnEnded();
181 void MojoRendererService::OnError(PipelineStatus error) {
182 DVLOG(1) << __FUNCTION__;
183 state_ = STATE_ERROR;
184 client_->OnError();
187 void MojoRendererService::OnFlushCompleted(const mojo::Closure& callback) {
188 DVLOG(1) << __FUNCTION__;
189 DCHECK_EQ(state_, STATE_FLUSHING);
190 state_ = STATE_PLAYING;
191 callback.Run();
194 } // namespace media