diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-13 08:04:01 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-13 08:04:01 +0000 |
commit | 12ef690fc90c72489505cf1aafecefe1bd6489f6 (patch) | |
tree | b4a27f787948fe2eac24c981fbe64e786f8b41e4 /content | |
parent | 4e58f3d0f0b05b3dbdf8e4bddab916d4060c5aec (diff) | |
download | chromium_src-12ef690fc90c72489505cf1aafecefe1bd6489f6.zip chromium_src-12ef690fc90c72489505cf1aafecefe1bd6489f6.tar.gz chromium_src-12ef690fc90c72489505cf1aafecefe1bd6489f6.tar.bz2 |
Move demuxer-related operations from WebMediaPlayerProxyAndroid to RendererDemuxerAndroid.
BUG=263652
Review URL: https://chromiumcodereview.appspot.com/23450029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223001 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
10 files changed, 272 insertions, 155 deletions
diff --git a/content/browser/android/browser_demuxer_android.h b/content/browser/android/browser_demuxer_android.h index 816d8b7..6f02a40 100644 --- a/content/browser/android/browser_demuxer_android.h +++ b/content/browser/android/browser_demuxer_android.h @@ -13,6 +13,8 @@ namespace content { // Represents the browser process half of an IPC-based implementation of // media::DemuxerAndroid. +// +// Refer to RendererDemuxerAndroid for the renderer process half. class CONTENT_EXPORT BrowserDemuxerAndroid : public RenderViewHostObserver, public media::DemuxerAndroid { diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 2cb173d..9442fdc 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -164,6 +164,8 @@ 'renderer/media/android/media_source_delegate.h', 'renderer/media/android/proxy_media_keys.cc', 'renderer/media/android/proxy_media_keys.h', + 'renderer/media/android/renderer_demuxer_android.cc', + 'renderer/media/android/renderer_demuxer_android.h', 'renderer/media/android/renderer_media_player_manager.cc', 'renderer/media/android/renderer_media_player_manager.h', 'renderer/media/android/stream_texture_factory_android.h', diff --git a/content/renderer/media/android/media_source_delegate.cc b/content/renderer/media/android/media_source_delegate.cc index 4824213..b83a1a0 100644 --- a/content/renderer/media/android/media_source_delegate.cc +++ b/content/renderer/media/android/media_source_delegate.cc @@ -10,7 +10,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "base/strings/string_number_conversions.h" -#include "content/renderer/media/android/webmediaplayer_proxy_android.h" +#include "content/renderer/media/android/renderer_demuxer_android.h" #include "content/renderer/media/webmediaplayer_util.h" #include "content/renderer/media/webmediasource_impl.h" #include "media/base/android/demuxer_stream_player_params.h" @@ -53,8 +53,8 @@ static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, } MediaSourceDelegate::MediaSourceDelegate( - WebMediaPlayerProxyAndroid* proxy, - int player_id, + RendererDemuxerAndroid* demuxer_client, + int demuxer_client_id, const scoped_refptr<base::MessageLoopProxy>& media_loop, media::MediaLog* media_log) : main_loop_(base::MessageLoopProxy::current()), @@ -62,8 +62,8 @@ MediaSourceDelegate::MediaSourceDelegate( main_weak_this_(main_weak_factory_.GetWeakPtr()), media_loop_(media_loop), media_weak_factory_(this), - proxy_(proxy), - player_id_(player_id), + demuxer_client_(demuxer_client), + demuxer_client_id_(demuxer_client_id), media_log_(media_log), demuxer_(NULL), is_demuxer_ready_(false), @@ -76,31 +76,34 @@ MediaSourceDelegate::MediaSourceDelegate( #endif access_unit_size_(0) { DCHECK(main_loop_->BelongsToCurrentThread()); + demuxer_client_->AddDelegate(demuxer_client_id_, this); } MediaSourceDelegate::~MediaSourceDelegate() { DCHECK(main_loop_->BelongsToCurrentThread()); - DVLOG(1) << "~MediaSourceDelegate() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; DCHECK(!chunk_demuxer_); DCHECK(!demuxer_); DCHECK(!audio_decrypting_demuxer_stream_); DCHECK(!video_decrypting_demuxer_stream_); DCHECK(!audio_stream_); DCHECK(!video_stream_); + demuxer_client_->RemoveDelegate(demuxer_client_id_); } void MediaSourceDelegate::Destroy() { DCHECK(main_loop_->BelongsToCurrentThread()); - DVLOG(1) << "Destroy() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; if (!demuxer_) { delete this; return; } duration_change_cb_.Reset(); + time_update_seek_hack_cb_.Reset(); update_network_state_cb_.Reset(); media_source_opened_cb_.Reset(); - proxy_ = NULL; + demuxer_client_ = NULL; main_weak_factory_.InvalidateWeakPtrs(); DCHECK(!main_weak_factory_.HasWeakPtrs()); @@ -142,14 +145,16 @@ void MediaSourceDelegate::InitializeMediaSource( const media::NeedKeyCB& need_key_cb, const media::SetDecryptorReadyCB& set_decryptor_ready_cb, const UpdateNetworkStateCB& update_network_state_cb, - const DurationChangeCB& duration_change_cb) { + const DurationChangeCB& duration_change_cb, + const TimeUpdateSeekHackCB& time_update_seek_hack_cb) { DCHECK(main_loop_->BelongsToCurrentThread()); DCHECK(!media_source_opened_cb.is_null()); media_source_opened_cb_ = media_source_opened_cb; need_key_cb_ = need_key_cb; set_decryptor_ready_cb_ = set_decryptor_ready_cb; update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb); - duration_change_cb_ = media::BindToCurrentLoop(duration_change_cb); + duration_change_cb_ = duration_change_cb; + time_update_seek_hack_cb_ = time_update_seek_hack_cb; access_unit_size_ = kAccessUnitSizeForMediaSource; chunk_demuxer_.reset(new media::ChunkDemuxer( @@ -216,9 +221,11 @@ size_t MediaSourceDelegate::VideoDecodedByteCount() const { return statistics_.video_bytes_decoded; } -void MediaSourceDelegate::Seek(base::TimeDelta time, unsigned seek_request_id) { +void MediaSourceDelegate::Seek(const base::TimeDelta& time, + unsigned seek_request_id) { DCHECK(main_loop_->BelongsToCurrentThread()); - DVLOG(1) << "Seek(" << time.InSecondsF() << ") : " << player_id_; + DVLOG(1) << __FUNCTION__ << "(" << time.InSecondsF() << ") : " + << demuxer_client_id_; last_seek_time_ = time; last_seek_request_id_ = seek_request_id; @@ -238,9 +245,18 @@ void MediaSourceDelegate::Seek(base::TimeDelta time, unsigned seek_request_id) { base::Bind(&MediaSourceDelegate::SeekInternal, base::Unretained(this), time, seek_request_id)); + + // During fullscreen media source playback Seek() can be called without + // WebMediaPlayerAndroid's knowledge. We need to inform it that a seek is + // in progress so the correct time can be returned to web applications while + // seeking. + // + // TODO(wolenetz): Remove after landing a uniform seeking codepath. + if (!time_update_seek_hack_cb_.is_null()) + time_update_seek_hack_cb_.Run(time); } -void MediaSourceDelegate::SeekInternal(base::TimeDelta time, +void MediaSourceDelegate::SeekInternal(const base::TimeDelta& time, unsigned request_id) { DCHECK(media_loop_->BelongsToCurrentThread()); demuxer_->Seek(time, base::Bind( @@ -262,9 +278,17 @@ void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, } void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { - DVLOG(1) << "SetDuration(" << duration.InSecondsF() << ") : " << player_id_; - // Notify our owner (e.g. WebMediaPlayerAndroid) that duration has changed. - // |duration_change_cb_| is bound to the main thread. + DCHECK(media_loop_->BelongsToCurrentThread()); + DVLOG(1) << __FUNCTION__ << "(" << duration.InSecondsF() << ") : " + << demuxer_client_id_; + main_loop_->PostTask(FROM_HERE, base::Bind( + &MediaSourceDelegate::OnDurationChanged, main_weak_this_, duration)); +} + +void MediaSourceDelegate::OnDurationChanged(const base::TimeDelta& duration) { + DCHECK(main_loop_->BelongsToCurrentThread()); + if (demuxer_client_) + demuxer_client_->DurationChanged(demuxer_client_id_, duration); if (!duration_change_cb_.is_null()) duration_change_cb_.Run(duration); } @@ -280,7 +304,7 @@ void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) { void MediaSourceDelegate::OnReadFromDemuxerInternal( media::DemuxerStream::Type type) { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "OnReadFromDemuxer(" << type << ") : " << player_id_; + DVLOG(1) << __FUNCTION__ << "(" << type << ") : " << demuxer_client_id_; if (IsSeeking()) return; // Drop the request during seeking. @@ -312,16 +336,16 @@ void MediaSourceDelegate::OnBufferReady( DemuxerStream::Status status, const scoped_refptr<media::DecoderBuffer>& buffer) { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "OnBufferReady(" << index << ", " << status << ", " + DVLOG(1) << __FUNCTION__ << "(" << index << ", " << status << ", " << ((!buffer || buffer->end_of_stream()) ? -1 : buffer->timestamp().InMilliseconds()) - << ") : " << player_id_; + << ") : " << demuxer_client_id_; DCHECK(demuxer_); // No new OnReadFromDemuxer() will be called during seeking. So this callback // must be from previous OnReadFromDemuxer() call and should be ignored. if (IsSeeking()) { - DVLOG(1) << "OnBufferReady(): Ignore previous read during seeking."; + DVLOG(1) << __FUNCTION__ << ": Ignore previous read during seeking."; return; } @@ -338,7 +362,7 @@ void MediaSourceDelegate::OnBufferReady( switch (status) { case DemuxerStream::kAborted: - DVLOG(1) << "OnBufferReady() : Aborted"; + DVLOG(1) << __FUNCTION__ << " : Aborted"; data->access_units[index].status = status; data->access_units.resize(index + 1); break; @@ -416,12 +440,12 @@ void MediaSourceDelegate::OnBufferReady( void MediaSourceDelegate::SendReadFromDemuxerAck(scoped_ptr<DemuxerData> data) { DCHECK(main_loop_->BelongsToCurrentThread()); - if (!IsSeeking() && proxy_) - proxy_->ReadFromDemuxerAck(player_id_, *data); + if (!IsSeeking() && demuxer_client_) + demuxer_client_->ReadFromDemuxerAck(demuxer_client_id_, *data); } void MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) { - DVLOG(1) << "OnDemuxerError(" << status << ") : " << player_id_; + DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; // |update_network_state_cb_| is bound to the main thread. if (status != media::PIPELINE_OK && !update_network_state_cb_.is_null()) update_network_state_cb_.Run(PipelineErrorToNetworkState(status)); @@ -429,7 +453,7 @@ void MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) { void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "OnDemuxerInitDone(" << status << ") : " << player_id_; + DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; DCHECK(demuxer_); if (status != media::PIPELINE_OK) { @@ -462,7 +486,7 @@ void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "InitAudioDecryptingDemuxerStream() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; DCHECK(!set_decryptor_ready_cb_.is_null()); audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( @@ -475,7 +499,7 @@ void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "InitVideoDecryptingDemuxerStream() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; DCHECK(!set_decryptor_ready_cb_.is_null()); video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( @@ -489,8 +513,7 @@ void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( media::PipelineStatus status) { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "OnAudioDecryptingDemuxerStreamInitDone(" << status - << ") : " << player_id_; + DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; DCHECK(demuxer_); if (status != media::PIPELINE_OK) @@ -513,8 +536,7 @@ void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( media::PipelineStatus status) { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "OnVideoDecryptingDemuxerStreamInitDone(" << status - << ") : " << player_id_; + DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; DCHECK(demuxer_); if (status != media::PIPELINE_OK) @@ -531,7 +553,7 @@ void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id, media::PipelineStatus status) { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "OnDemuxerSeekDone(" << status << ") : " << player_id_; + DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; DCHECK(IsSeeking()); if (status != media::PIPELINE_OK) { @@ -552,7 +574,7 @@ void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id, void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "ResetAudioDecryptingDemuxerStream() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; if (audio_decrypting_demuxer_stream_) { audio_decrypting_demuxer_stream_->Reset( base::Bind(&MediaSourceDelegate::ResetVideoDecryptingDemuxerStream, @@ -565,7 +587,7 @@ void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "ResetVideoDecryptingDemuxerStream()"; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; if (video_decrypting_demuxer_stream_) { video_decrypting_demuxer_stream_->Reset(base::Bind( &MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams, @@ -578,22 +600,22 @@ void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { void MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams() { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "FinishResettingDecryptingDemuxerStreams()"; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; main_loop_->PostTask(FROM_HERE, base::Bind( &MediaSourceDelegate::SendSeekRequestAck, main_weak_this_)); } void MediaSourceDelegate::SendSeekRequestAck() { DCHECK(main_loop_->BelongsToCurrentThread()); - DVLOG(1) << "SendSeekRequestAck() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; SetSeeking(false); - proxy_->SeekRequestAck(player_id_, last_seek_request_id_); + demuxer_client_->SeekRequestAck(demuxer_client_id_, last_seek_request_id_); last_seek_request_id_ = 0; } void MediaSourceDelegate::OnDemuxerStopDone() { DCHECK(main_loop_->BelongsToCurrentThread()); - DVLOG(1) << "OnDemuxerStopDone() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; chunk_demuxer_.reset(); demuxer_ = NULL; delete this; @@ -621,7 +643,7 @@ void MediaSourceDelegate::NotifyKeyAdded(const std::string& key_system) { base::Unretained(this), key_system)); return; } - DVLOG(1) << "NotifyKeyAdded() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; if (key_added_) return; key_added_ = true; @@ -651,7 +673,7 @@ bool MediaSourceDelegate::CanNotifyDemuxerReady() { void MediaSourceDelegate::NotifyDemuxerReady() { DCHECK(media_loop_->BelongsToCurrentThread()); - DVLOG(1) << "NotifyDemuxerReady() : " << player_id_; + DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; DCHECK(CanNotifyDemuxerReady()); scoped_ptr<DemuxerConfigs> configs(new DemuxerConfigs()); @@ -686,8 +708,8 @@ void MediaSourceDelegate::NotifyDemuxerReady() { void MediaSourceDelegate::SendDemuxerReady(scoped_ptr<DemuxerConfigs> configs) { DCHECK(main_loop_->BelongsToCurrentThread()); - if (proxy_) - proxy_->DemuxerReady(player_id_, *configs); + if (demuxer_client_) + demuxer_client_->DemuxerReady(demuxer_client_id_, *configs); } int MediaSourceDelegate::GetDurationMs() { diff --git a/content/renderer/media/android/media_source_delegate.h b/content/renderer/media/android/media_source_delegate.h index c641548..9213c28 100644 --- a/content/renderer/media/android/media_source_delegate.h +++ b/content/renderer/media/android/media_source_delegate.h @@ -34,7 +34,7 @@ struct DemuxerData; namespace content { -class WebMediaPlayerProxyAndroid; +class RendererDemuxerAndroid; class MediaSourceDelegate : public media::DemuxerHost { public: @@ -43,6 +43,7 @@ class MediaSourceDelegate : public media::DemuxerHost { typedef base::Callback<void(WebKit::WebMediaPlayer::NetworkState)> UpdateNetworkStateCB; typedef base::Callback<void(const base::TimeDelta&)> DurationChangeCB; + typedef base::Callback<void(const base::TimeDelta&)> TimeUpdateSeekHackCB; // Helper class used by scoped_ptr to destroy an instance of // MediaSourceDelegate. @@ -53,8 +54,8 @@ class MediaSourceDelegate : public media::DemuxerHost { } }; - MediaSourceDelegate(WebMediaPlayerProxyAndroid* proxy, - int player_id, + MediaSourceDelegate(RendererDemuxerAndroid* demuxer_client, + int demuxer_client_id, const scoped_refptr<base::MessageLoopProxy>& media_loop, media::MediaLog* media_log); @@ -65,7 +66,8 @@ class MediaSourceDelegate : public media::DemuxerHost { const media::NeedKeyCB& need_key_cb, const media::SetDecryptorReadyCB& set_decryptor_ready_cb, const UpdateNetworkStateCB& update_network_state_cb, - const DurationChangeCB& duration_change_cb); + const DurationChangeCB& duration_change_cb, + const TimeUpdateSeekHackCB& time_update_seek_hack_cb); #if defined(GOOGLE_TV) void InitializeMediaStream( @@ -82,7 +84,7 @@ class MediaSourceDelegate : public media::DemuxerHost { // Seeks the demuxer and acknowledges the seek request with |seek_request_id| // after the seek has been completed. This method can be called during pending // seeks, in which case only the last seek request will be acknowledged. - void Seek(base::TimeDelta time, unsigned seek_request_id); + void Seek(const base::TimeDelta& time, unsigned seek_request_id); void NotifyKeyAdded(const std::string& key_system); @@ -112,6 +114,9 @@ class MediaSourceDelegate : public media::DemuxerHost { virtual void SetDuration(base::TimeDelta duration) OVERRIDE; virtual void OnDemuxerError(media::PipelineStatus status) OVERRIDE; + // Notifies |demuxer_client_| and fires |duration_changed_cb_|. + void OnDurationChanged(const base::TimeDelta& duration); + // Callback for ChunkDemuxer initialization. void OnDemuxerInitDone(media::PipelineStatus status); @@ -148,7 +153,7 @@ class MediaSourceDelegate : public media::DemuxerHost { void StopDemuxer(); void InitializeDemuxer(); - void SeekInternal(base::TimeDelta time, unsigned seek_request_id); + void SeekInternal(const base::TimeDelta& time, unsigned seek_request_id); void OnReadFromDemuxerInternal(media::DemuxerStream::Type type); // Reads an access unit from the demuxer stream |stream| and stores it in // the |index|th access unit in |params|. @@ -180,12 +185,13 @@ class MediaSourceDelegate : public media::DemuxerHost { const scoped_refptr<base::MessageLoopProxy> media_loop_; base::WeakPtrFactory<MediaSourceDelegate> media_weak_factory_; - WebMediaPlayerProxyAndroid* proxy_; - int player_id_; + RendererDemuxerAndroid* demuxer_client_; + int demuxer_client_id_; scoped_refptr<media::MediaLog> media_log_; UpdateNetworkStateCB update_network_state_cb_; DurationChangeCB duration_change_cb_; + TimeUpdateSeekHackCB time_update_seek_hack_cb_; scoped_ptr<media::ChunkDemuxer> chunk_demuxer_; media::Demuxer* demuxer_; diff --git a/content/renderer/media/android/renderer_demuxer_android.cc b/content/renderer/media/android/renderer_demuxer_android.cc new file mode 100644 index 0000000..10d3b03 --- /dev/null +++ b/content/renderer/media/android/renderer_demuxer_android.cc @@ -0,0 +1,90 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/android/renderer_demuxer_android.h" + +#include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "content/common/media/media_player_messages_android.h" +#include "content/renderer/media/android/media_source_delegate.h" +#include "content/renderer/media/android/renderer_media_player_manager.h" +#include "content/renderer/media/android/webmediaplayer_android.h" + +namespace content { + +RendererDemuxerAndroid::RendererDemuxerAndroid(RenderView* render_view) + : RenderViewObserver(render_view) {} + +RendererDemuxerAndroid::~RendererDemuxerAndroid() {} + +void RendererDemuxerAndroid::AddDelegate(int demuxer_client_id, + MediaSourceDelegate* delegate) { + delegates_.AddWithID(delegate, demuxer_client_id); +} + +void RendererDemuxerAndroid::RemoveDelegate(int demuxer_client_id) { + delegates_.Remove(demuxer_client_id); +} + +bool RendererDemuxerAndroid::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(RendererDemuxerAndroid, msg) + IPC_MESSAGE_HANDLER(MediaPlayerMsg_ReadFromDemuxer, OnReadFromDemuxer) + IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaSeekRequest, OnMediaSeekRequest) + IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaConfigRequest, OnMediaConfigRequest) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void RendererDemuxerAndroid::DemuxerReady( + int demuxer_client_id, + const media::DemuxerConfigs& configs) { + Send(new MediaPlayerHostMsg_DemuxerReady( + routing_id(), demuxer_client_id, configs)); +} + +void RendererDemuxerAndroid::ReadFromDemuxerAck( + int demuxer_client_id, + const media::DemuxerData& data) { + Send(new MediaPlayerHostMsg_ReadFromDemuxerAck( + routing_id(), demuxer_client_id, data)); +} + +void RendererDemuxerAndroid::SeekRequestAck(int demuxer_client_id, + unsigned seek_request_id) { + Send(new MediaPlayerHostMsg_MediaSeekRequestAck( + routing_id(), demuxer_client_id, seek_request_id)); +} + +void RendererDemuxerAndroid::DurationChanged(int demuxer_client_id, + const base::TimeDelta& duration) { + Send(new MediaPlayerHostMsg_DurationChanged( + routing_id(), demuxer_client_id, duration)); +} + +void RendererDemuxerAndroid::OnReadFromDemuxer( + int demuxer_client_id, + media::DemuxerStream::Type type) { + MediaSourceDelegate* delegate = delegates_.Lookup(demuxer_client_id); + if (delegate) + delegate->OnReadFromDemuxer(type); +} + +void RendererDemuxerAndroid::OnMediaSeekRequest( + int demuxer_client_id, + const base::TimeDelta& time_to_seek, + unsigned seek_request_id) { + MediaSourceDelegate* delegate = delegates_.Lookup(demuxer_client_id); + if (delegate) + delegate->Seek(time_to_seek, seek_request_id); +} + +void RendererDemuxerAndroid::OnMediaConfigRequest(int demuxer_client_id) { + MediaSourceDelegate* delegate = delegates_.Lookup(demuxer_client_id); + if (delegate) + delegate->OnMediaConfigRequest(); +} + +} // namespace content diff --git a/content/renderer/media/android/renderer_demuxer_android.h b/content/renderer/media/android/renderer_demuxer_android.h new file mode 100644 index 0000000..fa6c771 --- /dev/null +++ b/content/renderer/media/android/renderer_demuxer_android.h @@ -0,0 +1,62 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_ANDROID_RENDERER_DEMUXER_ANDROID_H_ +#define CONTENT_RENDERER_MEDIA_ANDROID_RENDERER_DEMUXER_ANDROID_H_ + +#include "base/id_map.h" +#include "content/public/renderer/render_view_observer.h" +#include "media/base/android/demuxer_stream_player_params.h" + +namespace content { + +class MediaSourceDelegate; + +// Represents the renderer process half of an IPC-based implementation of +// media::DemuxerAndroid. +// +// Refer to BrowserDemuxerAndroid for the browser process half. +class RendererDemuxerAndroid : public RenderViewObserver { + public: + explicit RendererDemuxerAndroid(RenderView* render_view); + virtual ~RendererDemuxerAndroid(); + + // Associates |delegate| with |demuxer_client_id| for handling incoming IPC + // messages. + void AddDelegate(int demuxer_client_id, MediaSourceDelegate* delegate); + + // Removes the association created by AddDelegate(). + void RemoveDelegate(int demuxer_client_id); + + // RenderViewObserver overrides. + virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; + + // media::DemuxerAndroidClient "implementation". + // + // TODO(scherkus): Consider having RendererDemuxerAndroid actually implement + // media::DemuxerAndroidClient and MediaSourceDelegate actually implement + // media::DemuxerAndroid. + void DemuxerReady(int demuxer_client_id, + const media::DemuxerConfigs& configs); + void ReadFromDemuxerAck(int demuxer_client_id, + const media::DemuxerData& data); + void SeekRequestAck(int demuxer_client_id, unsigned seek_request_id); + void DurationChanged(int demuxer_client_id, const base::TimeDelta& duration); + + private: + void OnReadFromDemuxer(int demuxer_client_id, + media::DemuxerStream::Type type); + void OnMediaSeekRequest(int demuxer_client_id, + const base::TimeDelta& time_to_seek, + unsigned seek_request_id); + void OnMediaConfigRequest(int demuxer_client_id); + + IDMap<MediaSourceDelegate> delegates_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(RendererDemuxerAndroid); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_ANDROID_RENDERER_DEMUXER_ANDROID_H_ diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index 22abbad..f8b6132 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc @@ -55,9 +55,6 @@ const char* kMediaEme = "Media.EME."; namespace content { -#define BIND_TO_RENDER_LOOP(function) \ - media::BindToLoop(main_loop_, base::Bind(function, AsWeakPtr())) - WebMediaPlayerAndroid::WebMediaPlayerAndroid( WebKit::WebFrame* frame, WebKit::WebMediaPlayerClient* client, @@ -232,7 +229,11 @@ void WebMediaPlayerAndroid::load(LoadType load_type, if (player_type_ != MEDIA_PLAYER_TYPE_URL) { has_media_info_ = true; media_source_delegate_.reset( - new MediaSourceDelegate(proxy_, player_id_, media_loop_, media_log_)); + new MediaSourceDelegate(proxy_->renderer_demuxer_android(), + player_id_, + media_loop_, + media_log_)); + // |media_source_delegate_| is owned, so Unretained() is safe here. if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE) { media_source_delegate_->InitializeMediaSource( @@ -242,7 +243,10 @@ void WebMediaPlayerAndroid::load(LoadType load_type, set_decryptor_ready_cb, base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState, base::Unretained(this)), - BIND_TO_RENDER_LOOP(&WebMediaPlayerAndroid::OnDurationChange)); + base::Bind(&WebMediaPlayerAndroid::OnDurationChanged, + base::Unretained(this)), + base::Bind(&WebMediaPlayerAndroid::OnTimeUpdate, + base::Unretained(this))); } #if defined(GOOGLE_TV) // TODO(xhwang): Pass set_decryptor_ready_cb in InitializeMediaStream() to @@ -534,7 +538,7 @@ unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { } void WebMediaPlayerAndroid::OnMediaMetadataChanged( - base::TimeDelta duration, int width, int height, bool success) { + const base::TimeDelta& duration, int width, int height, bool success) { bool need_to_signal_duration_changed = false; if (url_.SchemeIs("file")) @@ -552,7 +556,7 @@ void WebMediaPlayerAndroid::OnMediaMetadataChanged( // already triggers a durationchanged event. If this is a different // transition, remember to signal durationchanged. // Do not ever signal durationchanged on metadata change in MSE case - // because OnDurationChange() handles this. + // because OnDurationChanged() handles this. if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing && player_type_ != MEDIA_PLAYER_TYPE_MEDIA_SOURCE) { need_to_signal_duration_changed = true; @@ -604,7 +608,8 @@ void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) { did_loading_progress_ = true; } -void WebMediaPlayerAndroid::OnSeekComplete(base::TimeDelta current_time) { +void WebMediaPlayerAndroid::OnSeekComplete( + const base::TimeDelta& current_time) { seeking_ = false; OnTimeUpdate(current_time); @@ -669,7 +674,8 @@ void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { ReallocateVideoFrame(); } -void WebMediaPlayerAndroid::OnTimeUpdate(base::TimeDelta current_time) { +void WebMediaPlayerAndroid::OnTimeUpdate(const base::TimeDelta& current_time) { + DCHECK(main_loop_->BelongsToCurrentThread()); current_time_ = current_time.InSecondsF(); } @@ -711,23 +717,8 @@ void WebMediaPlayerAndroid::OnMediaPlayerPause() { client_->playbackStateChanged(); } -void WebMediaPlayerAndroid::OnMediaSeekRequest(base::TimeDelta time_to_seek, - unsigned seek_request_id) { - if (!media_source_delegate_) - return; - - media_source_delegate_->Seek(time_to_seek, seek_request_id); - OnTimeUpdate(time_to_seek); -} - -void WebMediaPlayerAndroid::OnMediaConfigRequest() { - if (!media_source_delegate_) - return; - - media_source_delegate_->OnMediaConfigRequest(); -} - -void WebMediaPlayerAndroid::OnDurationChange(const base::TimeDelta& duration) { +void WebMediaPlayerAndroid::OnDurationChanged(const base::TimeDelta& duration) { + DCHECK(main_loop_->BelongsToCurrentThread()); // Only MSE |player_type_| registers this callback. DCHECK_EQ(player_type_, MEDIA_PLAYER_TYPE_MEDIA_SOURCE); @@ -739,10 +730,6 @@ void WebMediaPlayerAndroid::OnDurationChange(const base::TimeDelta& duration) { duration_ = duration; ignore_metadata_duration_change_ = true; - // Send message to Android MediaSourcePlayer to update duration. - if (proxy_) - proxy_->DurationChanged(player_id_, duration_); - // Notify MediaPlayerClient that duration has changed, if > HAVE_NOTHING. if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing) client_->durationChanged(); @@ -750,6 +737,7 @@ void WebMediaPlayerAndroid::OnDurationChange(const base::TimeDelta& duration) { void WebMediaPlayerAndroid::UpdateNetworkState( WebMediaPlayer::NetworkState state) { + DCHECK(main_loop_->BelongsToCurrentThread()); if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing && (state == WebMediaPlayer::NetworkStateNetworkError || state == WebMediaPlayer::NetworkStateDecodeError)) { @@ -1151,6 +1139,7 @@ void WebMediaPlayerAndroid::OnMediaSourceOpened( void WebMediaPlayerAndroid::OnNeedKey(const std::string& session_id, const std::string& type, const std::vector<uint8>& init_data) { + DCHECK(main_loop_->BelongsToCurrentThread()); // Do not fire NeedKey event if encrypted media is not enabled. if (!WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled() && !WebKit::WebRuntimeFeatures::isLegacyEncryptedMediaEnabled()) { diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h index d7a0378..475e2ca 100644 --- a/content/renderer/media/android/webmediaplayer_android.h +++ b/content/renderer/media/android/webmediaplayer_android.h @@ -156,20 +156,17 @@ class WebMediaPlayerAndroid OVERRIDE; // Media player callback handlers. - void OnMediaMetadataChanged(base::TimeDelta duration, int width, + void OnMediaMetadataChanged(const base::TimeDelta& duration, int width, int height, bool success); void OnPlaybackComplete(); void OnBufferingUpdate(int percentage); - void OnSeekComplete(base::TimeDelta current_time); + void OnSeekComplete(const base::TimeDelta& current_time); void OnMediaError(int error_type); void OnVideoSizeChanged(int width, int height); - void OnMediaSeekRequest(base::TimeDelta time_to_seek, - unsigned seek_request_id); - void OnMediaConfigRequest(); - void OnDurationChange(const base::TimeDelta& duration); + void OnDurationChanged(const base::TimeDelta& duration); // Called to update the current time. - void OnTimeUpdate(base::TimeDelta current_time); + void OnTimeUpdate(const base::TimeDelta& current_time); // Functions called when media player status changes. void OnMediaPlayerPlay(); @@ -314,7 +311,7 @@ class WebMediaPlayerAndroid base::TimeDelta duration_; // Flag to remember if we have a trusted duration_ value provided by - // MediaSourceDelegate notifying OnDurationChange(). In this case, ignore + // MediaSourceDelegate notifying OnDurationChanged(). In this case, ignore // any subsequent duration value passed to OnMediaMetadataChange(). bool ignore_metadata_duration_change_; diff --git a/content/renderer/media/android/webmediaplayer_proxy_android.cc b/content/renderer/media/android/webmediaplayer_proxy_android.cc index 3b44680..d371c99 100644 --- a/content/renderer/media/android/webmediaplayer_proxy_android.cc +++ b/content/renderer/media/android/webmediaplayer_proxy_android.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "content/common/media/media_player_messages_android.h" +#include "content/renderer/media/android/renderer_demuxer_android.h" #include "content/renderer/media/android/renderer_media_player_manager.h" #include "content/renderer/media/android/webmediaplayer_android.h" @@ -15,7 +16,9 @@ namespace content { WebMediaPlayerProxyAndroid::WebMediaPlayerProxyAndroid( RenderView* render_view, RendererMediaPlayerManager* manager) - : RenderViewObserver(render_view), manager_(manager) {} + : RenderViewObserver(render_view), + renderer_demuxer_android_(new RendererDemuxerAndroid(render_view)), + manager_(manager) {} WebMediaPlayerProxyAndroid::~WebMediaPlayerProxyAndroid() { Send(new MediaPlayerHostMsg_DestroyAllMediaPlayers(routing_id())); @@ -41,9 +44,6 @@ bool WebMediaPlayerProxyAndroid::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidExitFullscreen, OnDidExitFullscreen) IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPlay, OnPlayerPlay) IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPause, OnPlayerPause) - IPC_MESSAGE_HANDLER(MediaPlayerMsg_ReadFromDemuxer, OnReadFromDemuxer) - IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaSeekRequest, OnMediaSeekRequest) - IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaConfigRequest, OnMediaConfigRequest) IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyAdded, OnKeyAdded) IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyError, OnKeyError) IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyMessage, OnKeyMessage) @@ -176,19 +176,6 @@ void WebMediaPlayerProxyAndroid::ExitFullscreen(int player_id) { Send(new MediaPlayerHostMsg_ExitFullscreen(routing_id(), player_id)); } -void WebMediaPlayerProxyAndroid::ReadFromDemuxerAck( - int player_id, - const media::DemuxerData& data) { - Send(new MediaPlayerHostMsg_ReadFromDemuxerAck( - routing_id(), player_id, data)); -} - -void WebMediaPlayerProxyAndroid::SeekRequestAck(int player_id, - unsigned seek_request_id) { - Send(new MediaPlayerHostMsg_MediaSeekRequestAck( - routing_id(), player_id, seek_request_id)); -} - #if defined(GOOGLE_TV) void WebMediaPlayerProxyAndroid::RequestExternalSurface( int player_id, @@ -209,27 +196,6 @@ void WebMediaPlayerProxyAndroid::DidCommitCompositorFrame() { } #endif -void WebMediaPlayerProxyAndroid::OnReadFromDemuxer( - int player_id, - media::DemuxerStream::Type type) { - WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id); - if (player) - player->OnReadFromDemuxer(type); -} - -void WebMediaPlayerProxyAndroid::DemuxerReady( - int player_id, - const media::DemuxerConfigs& configs) { - Send(new MediaPlayerHostMsg_DemuxerReady(routing_id(), player_id, configs)); -} - -void WebMediaPlayerProxyAndroid::DurationChanged( - int player_id, - const base::TimeDelta& duration) { - Send(new MediaPlayerHostMsg_DurationChanged( - routing_id(), player_id, duration)); -} - void WebMediaPlayerProxyAndroid::InitializeCDM(int media_keys_id, const std::vector<uint8>& uuid) { Send(new MediaKeysHostMsg_InitializeCDM(routing_id(), media_keys_id, uuid)); @@ -264,21 +230,6 @@ WebMediaPlayerAndroid* WebMediaPlayerProxyAndroid::GetWebMediaPlayer( manager_->GetMediaPlayer(player_id)); } -void WebMediaPlayerProxyAndroid::OnMediaSeekRequest( - int player_id, - base::TimeDelta time_to_seek, - unsigned seek_request_id) { - WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id); - if (player) - player->OnMediaSeekRequest(time_to_seek, seek_request_id); -} - -void WebMediaPlayerProxyAndroid::OnMediaConfigRequest(int player_id) { - WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id); - if (player) - player->OnMediaConfigRequest(); -} - void WebMediaPlayerProxyAndroid::OnKeyAdded(int media_keys_id, const std::string& session_id) { WebMediaPlayerAndroid* player = GetWebMediaPlayer(media_keys_id); diff --git a/content/renderer/media/android/webmediaplayer_proxy_android.h b/content/renderer/media/android/webmediaplayer_proxy_android.h index 4942828..d74ec6e 100644 --- a/content/renderer/media/android/webmediaplayer_proxy_android.h +++ b/content/renderer/media/android/webmediaplayer_proxy_android.h @@ -12,14 +12,15 @@ #include "base/time/time.h" #include "content/common/media/media_player_messages_enums_android.h" #include "content/public/renderer/render_view_observer.h" -#include "media/base/android/demuxer_stream_player_params.h" #include "media/base/android/media_player_android.h" #include "media/base/media_keys.h" #include "url/gurl.h" namespace content { -class WebMediaPlayerAndroid; + +class RendererDemuxerAndroid; class RendererMediaPlayerManager; +class WebMediaPlayerAndroid; // This class manages IPC communication between WebMediaPlayerAndroid and the // MediaPlayerManagerAndroid in the browser process. @@ -74,12 +75,6 @@ class WebMediaPlayerProxyAndroid : public RenderViewObserver { virtual void DidCommitCompositorFrame() OVERRIDE; #endif - // Media source related methods. - void DemuxerReady(int player_id, const media::DemuxerConfigs& configs); - void ReadFromDemuxerAck(int player_id, const media::DemuxerData& data); - void SeekRequestAck(int player_id, unsigned seek_request_id); - void DurationChanged(int player_id, const base::TimeDelta& duration); - // Encrypted media related methods. void InitializeCDM(int media_keys_id, const std::vector<uint8>& uuid); void GenerateKeyRequest(int media_keys_id, @@ -91,6 +86,10 @@ class WebMediaPlayerProxyAndroid : public RenderViewObserver { const std::string& session_id); void CancelKeyRequest(int media_keys_id, const std::string& session_id); + RendererDemuxerAndroid* renderer_demuxer_android() { + return renderer_demuxer_android_; + } + private: WebMediaPlayerAndroid* GetWebMediaPlayer(int player_id); @@ -111,12 +110,6 @@ class WebMediaPlayerProxyAndroid : public RenderViewObserver { void OnDidEnterFullscreen(int player_id); void OnPlayerPlay(int player_id); void OnPlayerPause(int player_id); - void OnReadFromDemuxer(int player_id, - media::DemuxerStream::Type type); - void OnMediaSeekRequest(int player_id, - base::TimeDelta time_to_seek, - unsigned seek_request_id); - void OnMediaConfigRequest(int player_id); void OnKeyAdded(int media_keys_id, const std::string& session_id); void OnKeyError(int media_keys_id, const std::string& session_id, @@ -127,6 +120,9 @@ class WebMediaPlayerProxyAndroid : public RenderViewObserver { const std::vector<uint8>& message, const std::string& destination_url); + // Owned by RenderView. + RendererDemuxerAndroid* renderer_demuxer_android_; + RendererMediaPlayerManager* manager_; DISALLOW_IMPLICIT_CONSTRUCTORS(WebMediaPlayerProxyAndroid); |