Revert of Roll src/third_party/WebKit e0eac24:489c548 (svn 193311:193320) (patchset...
[chromium-blink-merge.git] / media / mojo / services / mojo_renderer_impl.cc
blobe4a133261579296415cda12d4a304d653473c79c
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_impl.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "media/base/bind_to_current_loop.h"
12 #include "media/base/demuxer_stream_provider.h"
13 #include "media/mojo/services/mojo_demuxer_stream_impl.h"
14 #include "third_party/mojo/src/mojo/public/cpp/application/connect.h"
15 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_impl.h"
16 #include "third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom.h"
18 namespace media {
20 MojoRendererImpl::MojoRendererImpl(
21 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
22 mojo::MediaRendererPtr remote_media_renderer)
23 : task_runner_(task_runner),
24 remote_media_renderer_(remote_media_renderer.Pass()),
25 binding_(this),
26 weak_factory_(this) {
27 DVLOG(1) << __FUNCTION__;
30 MojoRendererImpl::~MojoRendererImpl() {
31 DVLOG(1) << __FUNCTION__;
32 DCHECK(task_runner_->BelongsToCurrentThread());
33 // Connection to |remote_media_renderer_| will error-out here.
36 // TODO(xhwang): Support |paint_cb| and |waiting_for_decryption_key_cb|,
37 // if needed.
38 void MojoRendererImpl::Initialize(
39 DemuxerStreamProvider* demuxer_stream_provider,
40 const PipelineStatusCB& init_cb,
41 const StatisticsCB& statistics_cb,
42 const BufferingStateCB& buffering_state_cb,
43 const PaintCB& /* paint_cb */,
44 const base::Closure& ended_cb,
45 const PipelineStatusCB& error_cb,
46 const base::Closure& /* waiting_for_decryption_key_cb */) {
47 DVLOG(1) << __FUNCTION__;
48 DCHECK(task_runner_->BelongsToCurrentThread());
49 DCHECK(demuxer_stream_provider);
51 demuxer_stream_provider_ = demuxer_stream_provider;
52 init_cb_ = init_cb;
53 ended_cb_ = ended_cb;
54 error_cb_ = error_cb;
55 buffering_state_cb_ = buffering_state_cb;
57 // Create audio and video mojo::DemuxerStream and bind its lifetime to the
58 // pipe.
59 DemuxerStream* const audio =
60 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO);
61 DemuxerStream* const video =
62 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
64 mojo::DemuxerStreamPtr audio_stream;
65 if (audio)
66 mojo::BindToProxy(new MojoDemuxerStreamImpl(audio), &audio_stream);
68 mojo::DemuxerStreamPtr video_stream;
69 if (video)
70 mojo::BindToProxy(new MojoDemuxerStreamImpl(video), &video_stream);
72 mojo::MediaRendererClientPtr client_ptr;
73 binding_.Bind(GetProxy(&client_ptr));
74 remote_media_renderer_->Initialize(
75 client_ptr.Pass(),
76 audio_stream.Pass(),
77 video_stream.Pass(),
78 BindToCurrentLoop(base::Bind(&MojoRendererImpl::OnInitialized,
79 weak_factory_.GetWeakPtr())));
82 void MojoRendererImpl::SetCdm(CdmContext* cdm_context,
83 const CdmAttachedCB& cdm_attached_cb) {
84 DVLOG(1) << __FUNCTION__;
85 DCHECK(task_runner_->BelongsToCurrentThread());
86 NOTIMPLEMENTED();
87 cdm_attached_cb.Run(false);
90 void MojoRendererImpl::Flush(const base::Closure& flush_cb) {
91 DVLOG(2) << __FUNCTION__;
92 DCHECK(task_runner_->BelongsToCurrentThread());
93 remote_media_renderer_->Flush(flush_cb);
96 void MojoRendererImpl::StartPlayingFrom(base::TimeDelta time) {
97 DVLOG(2) << __FUNCTION__;
98 DCHECK(task_runner_->BelongsToCurrentThread());
101 base::AutoLock auto_lock(lock_);
102 time_ = time;
105 remote_media_renderer_->StartPlayingFrom(time.InMicroseconds());
108 void MojoRendererImpl::SetPlaybackRate(float playback_rate) {
109 DVLOG(2) << __FUNCTION__;
110 DCHECK(task_runner_->BelongsToCurrentThread());
111 remote_media_renderer_->SetPlaybackRate(playback_rate);
114 void MojoRendererImpl::SetVolume(float volume) {
115 DVLOG(2) << __FUNCTION__;
116 DCHECK(task_runner_->BelongsToCurrentThread());
117 remote_media_renderer_->SetVolume(volume);
120 base::TimeDelta MojoRendererImpl::GetMediaTime() {
121 base::AutoLock auto_lock(lock_);
122 DVLOG(3) << __FUNCTION__ << ": " << time_.InMilliseconds() << " ms";
123 return time_;
126 bool MojoRendererImpl::HasAudio() {
127 DVLOG(1) << __FUNCTION__;
128 DCHECK(task_runner_->BelongsToCurrentThread());
129 DCHECK(remote_media_renderer_.get()); // We always bind the renderer.
130 return !!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO);
133 bool MojoRendererImpl::HasVideo() {
134 DVLOG(1) << __FUNCTION__;
135 DCHECK(task_runner_->BelongsToCurrentThread());
136 return !!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
139 void MojoRendererImpl::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) {
140 DVLOG(3) << __FUNCTION__ << ": " << time_usec << ", " << max_time_usec;
142 if (!task_runner_->BelongsToCurrentThread()) {
143 task_runner_->PostTask(FROM_HERE,
144 base::Bind(&MojoRendererImpl::OnTimeUpdate,
145 weak_factory_.GetWeakPtr(),
146 time_usec,
147 max_time_usec));
148 return;
151 base::AutoLock auto_lock(lock_);
152 time_ = base::TimeDelta::FromMicroseconds(time_usec);
153 max_time_ = base::TimeDelta::FromMicroseconds(max_time_usec);
156 void MojoRendererImpl::OnBufferingStateChange(mojo::BufferingState state) {
157 DVLOG(2) << __FUNCTION__;
159 if (!task_runner_->BelongsToCurrentThread()) {
160 task_runner_->PostTask(FROM_HERE,
161 base::Bind(&MojoRendererImpl::OnBufferingStateChange,
162 weak_factory_.GetWeakPtr(),
163 state));
164 return;
167 buffering_state_cb_.Run(static_cast<media::BufferingState>(state));
170 void MojoRendererImpl::OnEnded() {
171 DVLOG(1) << __FUNCTION__;
173 if (!task_runner_->BelongsToCurrentThread()) {
174 task_runner_->PostTask(
175 FROM_HERE,
176 base::Bind(&MojoRendererImpl::OnEnded, weak_factory_.GetWeakPtr()));
177 return;
180 ended_cb_.Run();
183 void MojoRendererImpl::OnError() {
184 DVLOG(1) << __FUNCTION__;
186 if (!task_runner_->BelongsToCurrentThread()) {
187 task_runner_->PostTask(
188 FROM_HERE,
189 base::Bind(&MojoRendererImpl::OnError, weak_factory_.GetWeakPtr()));
190 return;
193 // TODO(tim): Should we plumb error code from remote renderer?
194 // http://crbug.com/410451.
195 if (init_cb_.is_null()) // We have initialized already.
196 error_cb_.Run(PIPELINE_ERROR_DECODE);
197 else
198 init_cb_.Run(PIPELINE_ERROR_COULD_NOT_RENDER);
201 void MojoRendererImpl::OnInitialized() {
202 DVLOG(1) << __FUNCTION__;
203 DCHECK(task_runner_->BelongsToCurrentThread());
204 if (!init_cb_.is_null())
205 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
208 } // namespace media