X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmedia%2Fmojo%2Fservices%2Fmojo_renderer_impl.cc;h=9ed903f0a31e40ea4fffc01cad5a26605888ed05;hb=1afa4dd80ef85af7c90efaea6959db1d92330844;hp=d905b2c0eb7c1c3b4adeb7aa0d899b194a6d3b4a;hpb=90762837333c13ccf56f2ad88e4481fc71e8d281;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/media/mojo/services/mojo_renderer_impl.cc b/src/media/mojo/services/mojo_renderer_impl.cc index d905b2c..9ed903f 100644 --- a/src/media/mojo/services/mojo_renderer_impl.cc +++ b/src/media/mojo/services/mojo_renderer_impl.cc @@ -6,7 +6,9 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/location.h" #include "base/single_thread_task_runner.h" +#include "media/base/bind_to_current_loop.h" #include "media/base/demuxer_stream_provider.h" #include "media/mojo/services/mojo_demuxer_stream_impl.h" #include "mojo/public/cpp/application/connect.h" @@ -17,11 +19,10 @@ namespace media { MojoRendererImpl::MojoRendererImpl( const scoped_refptr& task_runner, - DemuxerStreamProvider* demuxer_stream_provider, mojo::ServiceProvider* audio_renderer_provider) : task_runner_(task_runner), - demuxer_stream_provider_(demuxer_stream_provider), weak_factory_(this) { + DVLOG(1) << __FUNCTION__; // For now we only support audio and there must be a provider. DCHECK(audio_renderer_provider); mojo::ConnectToService(audio_renderer_provider, &remote_audio_renderer_); @@ -29,88 +30,160 @@ MojoRendererImpl::MojoRendererImpl( } MojoRendererImpl::~MojoRendererImpl() { + DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); // Connection to |remote_audio_renderer_| will error-out here. } -void MojoRendererImpl::Initialize(const base::Closure& init_cb, - const StatisticsCB& statistics_cb, - const base::Closure& ended_cb, - const PipelineStatusCB& error_cb, - const BufferingStateCB& buffering_state_cb) { +void MojoRendererImpl::Initialize( + DemuxerStreamProvider* demuxer_stream_provider, + const base::Closure& init_cb, + const StatisticsCB& statistics_cb, + const base::Closure& ended_cb, + const PipelineStatusCB& error_cb, + const BufferingStateCB& buffering_state_cb) { + DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(demuxer_stream_provider); + + demuxer_stream_provider_ = demuxer_stream_provider; + // |init_cb| can be called on other thread. init_cb_ = init_cb; ended_cb_ = ended_cb; error_cb_ = error_cb; buffering_state_cb_ = buffering_state_cb; - // Create a mojo::DemuxerStream and bind its lifetime to the pipe. - mojo::DemuxerStreamPtr demuxer_stream; - mojo::BindToProxy( - new MojoDemuxerStreamImpl( - demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)), - &demuxer_stream); - remote_audio_renderer_->Initialize(demuxer_stream.Pass(), init_cb); + // Create audio and video mojo::DemuxerStream and bind its lifetime to the + // pipe. + DemuxerStream* const audio = + demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); + DemuxerStream* const video = + demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); + + mojo::DemuxerStreamPtr audio_stream; + if (audio) + mojo::BindToProxy(new MojoDemuxerStreamImpl(audio), &audio_stream); + + mojo::DemuxerStreamPtr video_stream; + if (video) + mojo::BindToProxy(new MojoDemuxerStreamImpl(video), &video_stream); + + remote_audio_renderer_->Initialize( + audio_stream.Pass(), + video_stream.Pass(), + BindToCurrentLoop(base::Bind(&MojoRendererImpl::OnInitialized, + weak_factory_.GetWeakPtr()))); } void MojoRendererImpl::Flush(const base::Closure& flush_cb) { + DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); remote_audio_renderer_->Flush(flush_cb); } void MojoRendererImpl::StartPlayingFrom(base::TimeDelta time) { + DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); + + { + base::AutoLock auto_lock(lock_); + time_ = time; + } + remote_audio_renderer_->StartPlayingFrom(time.InMicroseconds()); } void MojoRendererImpl::SetPlaybackRate(float playback_rate) { + DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); remote_audio_renderer_->SetPlaybackRate(playback_rate); } void MojoRendererImpl::SetVolume(float volume) { + DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); remote_audio_renderer_->SetVolume(volume); } base::TimeDelta MojoRendererImpl::GetMediaTime() { - NOTIMPLEMENTED(); - return base::TimeDelta(); + base::AutoLock auto_lock(lock_); + DVLOG(3) << __FUNCTION__ << ": " << time_.InMilliseconds() << " ms"; + return time_; } bool MojoRendererImpl::HasAudio() { + DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(remote_audio_renderer_.get()); // We always bind the renderer. - return true; + return !!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); } bool MojoRendererImpl::HasVideo() { + DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); - return false; + return !!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); } void MojoRendererImpl::SetCdm(MediaKeys* cdm) { + DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); NOTIMPLEMENTED(); } void MojoRendererImpl::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) { - DCHECK(task_runner_->BelongsToCurrentThread()); - NOTIMPLEMENTED(); + DVLOG(3) << __FUNCTION__ << ": " << time_usec << ", " << max_time_usec; + + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->PostTask(FROM_HERE, + base::Bind(&MojoRendererImpl::OnTimeUpdate, + weak_factory_.GetWeakPtr(), + time_usec, + max_time_usec)); + return; + } + + base::AutoLock auto_lock(lock_); + time_ = base::TimeDelta::FromMicroseconds(time_usec); + max_time_ = base::TimeDelta::FromMicroseconds(max_time_usec); } void MojoRendererImpl::OnBufferingStateChange(mojo::BufferingState state) { - DCHECK(task_runner_->BelongsToCurrentThread()); + DVLOG(2) << __FUNCTION__; + + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->PostTask(FROM_HERE, + base::Bind(&MojoRendererImpl::OnBufferingStateChange, + weak_factory_.GetWeakPtr(), + state)); + return; + } + buffering_state_cb_.Run(static_cast(state)); } void MojoRendererImpl::OnEnded() { - DCHECK(task_runner_->BelongsToCurrentThread()); - ended_cb_.Run(); + DVLOG(1) << __FUNCTION__; + + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->PostTask( + FROM_HERE, + base::Bind(&MojoRendererImpl::OnEnded, weak_factory_.GetWeakPtr())); + return; + } + + base::ResetAndReturn(&ended_cb_).Run(); } void MojoRendererImpl::OnError() { - DCHECK(task_runner_->BelongsToCurrentThread()); + DVLOG(1) << __FUNCTION__; + + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->PostTask( + FROM_HERE, + base::Bind(&MojoRendererImpl::OnError, weak_factory_.GetWeakPtr())); + return; + } + // TODO(tim): Should we plumb error code from remote renderer? // http://crbug.com/410451. if (init_cb_.is_null()) // We have initialized already. @@ -120,7 +193,10 @@ void MojoRendererImpl::OnError() { } void MojoRendererImpl::OnInitialized() { + DVLOG(1) << __FUNCTION__; + DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(!init_cb_.is_null()); + base::ResetAndReturn(&init_cb_).Run(); }