summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-13 08:04:01 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-13 08:04:01 +0000
commit12ef690fc90c72489505cf1aafecefe1bd6489f6 (patch)
treeb4a27f787948fe2eac24c981fbe64e786f8b41e4 /content
parent4e58f3d0f0b05b3dbdf8e4bddab916d4060c5aec (diff)
downloadchromium_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')
-rw-r--r--content/browser/android/browser_demuxer_android.h2
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/renderer/media/android/media_source_delegate.cc106
-rw-r--r--content/renderer/media/android/media_source_delegate.h22
-rw-r--r--content/renderer/media/android/renderer_demuxer_android.cc90
-rw-r--r--content/renderer/media/android/renderer_demuxer_android.h62
-rw-r--r--content/renderer/media/android/webmediaplayer_android.cc49
-rw-r--r--content/renderer/media/android/webmediaplayer_android.h13
-rw-r--r--content/renderer/media/android/webmediaplayer_proxy_android.cc57
-rw-r--r--content/renderer/media/android/webmediaplayer_proxy_android.h24
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);