Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: webkit/media/android/media_source_delegate.cc

Issue 14247018: Implement WebRTC in Chrome for TV (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed some comments Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/media/android/media_source_delegate.h" 5 #include "webkit/media/android/media_source_delegate.h"
6 6
7 #include "base/message_loop_proxy.h" 7 #include "base/message_loop_proxy.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "media/base/android/demuxer_stream_player_params.h" 9 #include "media/base/android/demuxer_stream_player_params.h"
10 #include "media/base/bind_to_loop.h" 10 #include "media/base/bind_to_loop.h"
11 #include "media/base/demuxer_stream.h" 11 #include "media/base/demuxer_stream.h"
12 #include "media/base/media_log.h" 12 #include "media/base/media_log.h"
13 #include "media/filters/chunk_demuxer.h" 13 #include "media/filters/chunk_demuxer.h"
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" 14 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h"
18 #include "webkit/media/android/webmediaplayer_proxy_android.h" 18 #include "webkit/media/android/webmediaplayer_proxy_android.h"
19 #include "webkit/media/crypto/key_systems.h" 19 #include "webkit/media/crypto/key_systems.h"
20 #include "webkit/media/crypto/proxy_decryptor.h" 20 #include "webkit/media/crypto/proxy_decryptor.h"
21 #include "webkit/media/webmediaplayer_util.h" 21 #include "webkit/media/webmediaplayer_util.h"
22 #include "webkit/media/webmediasourceclient_impl.h" 22 #include "webkit/media/webmediasourceclient_impl.h"
23 23
24 using media::DemuxerHost;
24 using media::DemuxerStream; 25 using media::DemuxerStream;
25 using media::MediaPlayerHostMsg_DemuxerReady_Params; 26 using media::MediaPlayerHostMsg_DemuxerReady_Params;
26 using media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params; 27 using media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params;
28 using media::PipelineStatusCB;
27 using WebKit::WebMediaPlayer; 29 using WebKit::WebMediaPlayer;
28 using WebKit::WebString; 30 using WebKit::WebString;
29 31
30 namespace { 32 namespace {
31 33
32 // The size of the access unit to transfer in an IPC. 34 // The size of the access unit to transfer in an IPC.
33 // 16: approximately 250ms of content in 60 fps movies. 35 // 16: approximately 250ms of content in 60 fps movies.
34 const size_t kAccessUnitSize = 16; 36 const size_t kAccessUnitSize = 16;
35 37
36 } // namespace 38 } // namespace
(...skipping 15 matching lines...) Expand all
52 #define BIND_TO_RENDER_LOOP_3(function, arg1, arg2, arg3) \ 54 #define BIND_TO_RENDER_LOOP_3(function, arg1, arg2, arg3) \
53 media::BindToLoop(base::MessageLoopProxy::current(), \ 55 media::BindToLoop(base::MessageLoopProxy::current(), \
54 base::Bind(function, \ 56 base::Bind(function, \
55 weak_this_.GetWeakPtr(), arg1, arg2, arg3)) 57 weak_this_.GetWeakPtr(), arg1, arg2, arg3))
56 58
57 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, 59 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log,
58 const std::string& error) { 60 const std::string& error) {
59 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); 61 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error));
60 } 62 }
61 63
62 MediaSourceDelegate::MediaSourceDelegate( 64 // KeyHandlingDemuxer ----------------------------------------------------------
65
66 class KeyHandlingDemuxer : public media::Demuxer {
67 public:
68 explicit KeyHandlingDemuxer(media::Demuxer* demuxer);
69 virtual ~KeyHandlingDemuxer();
70
71 virtual WebKit::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
72 const WebKit::WebString& key_system,
73 const unsigned char* init_data,
74 unsigned init_data_length) {
75 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
76 }
77 virtual WebKit::WebMediaPlayer::MediaKeyException AddKey(
78 const WebKit::WebString& key_system,
79 const unsigned char* key,
80 unsigned key_length,
81 const unsigned char* init_data,
82 unsigned init_data_length,
83 const WebKit::WebString& session_id) {
84 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
85 }
86 virtual WebKit::WebMediaPlayer::MediaKeyException CancelKeyRequest(
87 const WebKit::WebString& key_system,
88 const WebKit::WebString& session_id) {
89 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
90 }
91 virtual int GetDurationMs() { return -1; }
92
93 // media::Demuxer implementation
94 virtual void Initialize(DemuxerHost* host, const PipelineStatusCB& status_cb)
95 OVERRIDE;
96 virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
97 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& status_cb)
98 OVERRIDE;
99 virtual void Stop(const base::Closure& callback) OVERRIDE;
100 virtual void OnAudioRendererDisabled() OVERRIDE;
101 virtual DemuxerStream* GetStream(DemuxerStream::Type type) OVERRIDE;
102 virtual base::TimeDelta GetStartTime() const OVERRIDE;
103
104 protected:
105 scoped_ptr<media::Demuxer> demuxer_;
106 };
107
108 KeyHandlingDemuxer::KeyHandlingDemuxer(media::Demuxer* demuxer)
109 : demuxer_(demuxer) {}
110
111 KeyHandlingDemuxer::~KeyHandlingDemuxer() {}
112
113 void KeyHandlingDemuxer::Initialize(DemuxerHost* host,
114 const PipelineStatusCB& status_cb) {
115 demuxer_->Initialize(host, status_cb);
116 }
117
118 void KeyHandlingDemuxer::SetPlaybackRate(float playback_rate) {
119 demuxer_->SetPlaybackRate(playback_rate);
120 }
121
122 void KeyHandlingDemuxer::Seek(base::TimeDelta time,
123 const PipelineStatusCB& status_cb) {
124 demuxer_->Seek(time, status_cb);
125 }
126
127 void KeyHandlingDemuxer::Stop(const base::Closure& callback) {
128 demuxer_->Stop(callback);
129 }
130
131 void KeyHandlingDemuxer::OnAudioRendererDisabled() {
132 demuxer_->OnAudioRendererDisabled();
133 }
134
135 DemuxerStream* KeyHandlingDemuxer::GetStream(
136 DemuxerStream::Type type) {
137 return demuxer_->GetStream(type);
138 }
139
140 base::TimeDelta KeyHandlingDemuxer::GetStartTime() const {
141 return demuxer_->GetStartTime();
142 }
143
144 // KeyHandlingChunkDemuxer -----------------------------------------------------
145
146 namespace {
147
148 class KeyHandlingChunkDemuxer : public KeyHandlingDemuxer {
149 public:
150 typedef base::Callback<void(const std::string& key_system)> NotifyDemuxerCB;
151
152 KeyHandlingChunkDemuxer(WebKit::WebFrame* frame,
153 WebKit::WebMediaPlayerClient* client,
154 WebKit::WebMediaSource* media_source,
155 scoped_refptr<media::MediaLog> media_log,
156 NotifyDemuxerCB notify_demuxer_cb);
157 virtual ~KeyHandlingChunkDemuxer();
158
159 // KeyHandlingDemuxer
160 virtual WebKit::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
161 const WebKit::WebString& key_system,
162 const unsigned char* init_data,
163 unsigned init_data_length) OVERRIDE;
164 virtual WebKit::WebMediaPlayer::MediaKeyException AddKey(
165 const WebKit::WebString& key_system,
166 const unsigned char* key,
167 unsigned key_length,
168 const unsigned char* init_data,
169 unsigned init_data_length,
170 const WebKit::WebString& session_id) OVERRIDE;
171 virtual WebKit::WebMediaPlayer::MediaKeyException CancelKeyRequest(
172 const WebKit::WebString& key_system,
173 const WebKit::WebString& session_id) OVERRIDE;
174 virtual int GetDurationMs() OVERRIDE;
175
176 // media::Demuxer
177 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& status_cb)
178 OVERRIDE;
179
180 private:
181 // Callbacks for ChunkDemuxer & Decryptor.
182 void OnDemuxerOpened();
183 void OnKeyAdded(const std::string& key_system, const std::string& session_id);
184 void OnKeyError(const std::string& key_system,
185 const std::string& session_id,
186 media::Decryptor::KeyError error_code,
187 int system_code);
188 void OnKeyMessage(const std::string& key_system,
189 const std::string& session_id,
190 const std::string& message,
191 const std::string& default_url);
192 void OnNeedKey(const std::string& key_system,
193 const std::string& type,
194 const std::string& session_id,
195 scoped_ptr<uint8[]> init_data,
196 int init_data_size);
197 void OnDecryptorReady(media::Decryptor*);
198
199 base::WeakPtrFactory<KeyHandlingChunkDemuxer> weak_this_;
200 media::ChunkDemuxer* chunk_demuxer_;
201 WebKit::WebMediaPlayerClient* client_;
202 scoped_refptr<media::MediaLog> media_log_;
203
204 // The decryptor that manages decryption keys and decrypts encrypted frames.
205 scoped_ptr<ProxyDecryptor> decryptor_;
206
207 // The currently selected key system. Empty string means that no key system
208 // has been selected.
209 WebKit::WebString current_key_system_;
210
211 // Temporary for EME v0.1. In the future the init data type should be passed
212 // through GenerateKeyRequest() directly from WebKit.
213 std::string init_data_type_;
214
215 NotifyDemuxerCB notify_demuxer_cb_;
216
217 scoped_ptr<WebKit::WebMediaSource> media_source_;
218 };
219
220 KeyHandlingChunkDemuxer::KeyHandlingChunkDemuxer(
63 WebKit::WebFrame* frame, 221 WebKit::WebFrame* frame,
64 WebKit::WebMediaPlayerClient* client, 222 WebKit::WebMediaPlayerClient* client,
65 WebMediaPlayerProxyAndroid* proxy, 223 WebKit::WebMediaSource* media_source,
66 int player_id, 224 scoped_refptr<media::MediaLog> media_log,
67 media::MediaLog* media_log) 225 NotifyDemuxerCB notify_demuxer_cb)
68 : weak_this_(this), 226 : KeyHandlingDemuxer(NULL),
227 weak_this_(this),
69 client_(client), 228 client_(client),
70 proxy_(proxy),
71 player_id_(player_id),
72 media_log_(media_log), 229 media_log_(media_log),
73 audio_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params), 230 notify_demuxer_cb_(notify_demuxer_cb) {
74 video_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params), 231 chunk_demuxer_ = new media::ChunkDemuxer(
75 seeking_(false) { 232 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnDemuxerOpened),
233 BIND_TO_RENDER_LOOP_2(&KeyHandlingChunkDemuxer::OnNeedKey, "", ""),
234 base::Bind(&LogMediaSourceError, media_log));
235 demuxer_.reset(chunk_demuxer_);
236 media_source_.reset(media_source);
76 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { 237 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
77 decryptor_.reset(new ProxyDecryptor( 238 decryptor_.reset(new ProxyDecryptor(
78 client, 239 client,
79 frame, 240 frame,
80 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyAdded), 241 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnKeyAdded),
81 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyError), 242 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnKeyError),
82 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyMessage), 243 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnKeyMessage),
83 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnNeedKey))); 244 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnNeedKey)));
84 decryptor_->SetDecryptorReadyCB( 245 decryptor_->SetDecryptorReadyCB(
85 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDecryptorReady)); 246 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnDecryptorReady));
86 } 247 }
87 } 248 }
88 249
89 MediaSourceDelegate::~MediaSourceDelegate() {} 250 KeyHandlingChunkDemuxer::~KeyHandlingChunkDemuxer() {}
90 251
91 void MediaSourceDelegate::Initialize( 252 WebMediaPlayer::MediaKeyException KeyHandlingChunkDemuxer::GenerateKeyRequest(
92 scoped_ptr<WebKit::WebMediaSource> media_source,
93 const UpdateNetworkStateCB& update_network_state_cb) {
94 DCHECK(media_source);
95 media_source_ = media_source.Pass();
96 update_network_state_cb_ = update_network_state_cb;
97
98 chunk_demuxer_.reset(new media::ChunkDemuxer(
99 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened),
100 BIND_TO_RENDER_LOOP_2(&MediaSourceDelegate::OnNeedKey, "", ""),
101 base::Bind(&LogMediaSourceError, media_log_)));
102 chunk_demuxer_->Initialize(this,
103 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
104 }
105
106 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() {
107 buffered_web_time_ranges_ =
108 ConvertToWebTimeRanges(buffered_time_ranges_);
109 return buffered_web_time_ranges_;
110 }
111
112 size_t MediaSourceDelegate::DecodedFrameCount() const {
113 return statistics_.video_frames_decoded;
114 }
115
116 size_t MediaSourceDelegate::DroppedFrameCount() const {
117 return statistics_.video_frames_dropped;
118 }
119
120 size_t MediaSourceDelegate::AudioDecodedByteCount() const {
121 return statistics_.audio_bytes_decoded;
122 }
123
124 size_t MediaSourceDelegate::VideoDecodedByteCount() const {
125 return statistics_.video_bytes_decoded;
126 }
127
128 WebMediaPlayer::MediaKeyException MediaSourceDelegate::GenerateKeyRequest(
129 const WebString& key_system, 253 const WebString& key_system,
130 const unsigned char* init_data, 254 const unsigned char* init_data,
131 size_t init_data_length) { 255 size_t init_data_length) {
132 if (!IsSupportedKeySystem(key_system)) 256 if (!IsSupportedKeySystem(key_system))
133 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 257 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
134 258
135 // We do not support run-time switching between key systems for now. 259 // We do not support run-time switching between key systems for now.
136 if (current_key_system_.isEmpty()) 260 if (current_key_system_.isEmpty())
137 current_key_system_ = key_system; 261 current_key_system_ = key_system;
138 else if (key_system != current_key_system_) 262 else if (key_system != current_key_system_)
139 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; 263 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
140 264
141 DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": " 265 DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": "
142 << std::string(reinterpret_cast<const char*>(init_data), 266 << std::string(reinterpret_cast<const char*>(init_data),
143 init_data_length); 267 init_data_length);
144 268
145 // TODO(xhwang): We assume all streams are from the same container (thus have 269 // TODO(xhwang): We assume all streams are from the same container (thus have
146 // the same "type") for now. In the future, the "type" should be passed down 270 // the same "type") for now. In the future, the "type" should be passed down
147 // from the application. 271 // from the application.
148 if (!decryptor_->GenerateKeyRequest(key_system.utf8(), 272 if (!decryptor_->GenerateKeyRequest(key_system.utf8(),
149 init_data_type_, 273 init_data_type_,
150 init_data, init_data_length)) { 274 init_data, init_data_length)) {
151 current_key_system_.reset(); 275 current_key_system_.reset();
152 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 276 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
153 } 277 }
154 278
155 return WebMediaPlayer::MediaKeyExceptionNoError; 279 return WebMediaPlayer::MediaKeyExceptionNoError;
156 } 280 }
157 281
158 WebMediaPlayer::MediaKeyException MediaSourceDelegate::AddKey( 282 WebMediaPlayer::MediaKeyException KeyHandlingChunkDemuxer::AddKey(
159 const WebString& key_system, 283 const WebString& key_system,
160 const unsigned char* key, 284 const unsigned char* key,
161 size_t key_length, 285 size_t key_length,
162 const unsigned char* init_data, 286 const unsigned char* init_data,
163 size_t init_data_length, 287 size_t init_data_length,
164 const WebString& session_id) { 288 const WebString& session_id) {
165 DCHECK(key); 289 DCHECK(key);
166 DCHECK_EQ(key_length, 16u); 290 DCHECK_EQ(key_length, 16u);
167 291
168 if (!IsSupportedKeySystem(key_system)) 292 if (!IsSupportedKeySystem(key_system))
169 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 293 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
170 294
171 if (current_key_system_.isEmpty() || key_system != current_key_system_) 295 if (current_key_system_.isEmpty() || key_system != current_key_system_)
172 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; 296 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
173 297
174 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " 298 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": "
175 << base::HexEncode(key, key_length) << ", " 299 << base::HexEncode(key, key_length) << ", "
176 << base::HexEncode(init_data, std::max(init_data_length, 256u)) 300 << base::HexEncode(init_data, std::max(init_data_length, 256u))
177 << " [" << session_id.utf8().data() << "]"; 301 << " [" << session_id.utf8().data() << "]";
178 302
179 decryptor_->AddKey(key_system.utf8(), key, key_length, 303 decryptor_->AddKey(key_system.utf8(), key, key_length,
180 init_data, init_data_length, session_id.utf8()); 304 init_data, init_data_length, session_id.utf8());
181 return WebMediaPlayer::MediaKeyExceptionNoError; 305 return WebMediaPlayer::MediaKeyExceptionNoError;
182 } 306 }
183 307
184 WebMediaPlayer::MediaKeyException MediaSourceDelegate::CancelKeyRequest( 308 WebMediaPlayer::MediaKeyException KeyHandlingChunkDemuxer::CancelKeyRequest(
185 const WebString& key_system, 309 const WebString& key_system,
186 const WebString& session_id) { 310 const WebString& session_id) {
187 if (!IsSupportedKeySystem(key_system)) 311 if (!IsSupportedKeySystem(key_system))
188 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 312 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
189 313
190 if (current_key_system_.isEmpty() || key_system != current_key_system_) 314 if (current_key_system_.isEmpty() || key_system != current_key_system_)
191 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; 315 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
192 316
193 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); 317 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8());
194 return WebMediaPlayer::MediaKeyExceptionNoError; 318 return WebMediaPlayer::MediaKeyExceptionNoError;
195 } 319 }
196 320
321 int KeyHandlingChunkDemuxer::GetDurationMs() {
322 double duration_ms = chunk_demuxer_->GetDuration() * 1000;
323 if (duration_ms > std::numeric_limits<int>::max())
Ami GONE FROM CHROMIUM 2013/05/01 22:01:37 this is still pretty fishy...
wonsik 2013/05/02 15:22:00 Logged warning.
324 duration_ms = std::numeric_limits<int>::max();
325 return duration_ms;
326 }
327
328 void KeyHandlingChunkDemuxer::Seek(base::TimeDelta time,
329 const PipelineStatusCB& status_cb) {
330 chunk_demuxer_->StartWaitingForSeek();
331 chunk_demuxer_->Seek(time, status_cb);
332 }
333
334 void KeyHandlingChunkDemuxer::OnKeyError(const std::string& key_system,
335 const std::string& session_id,
336 media::Decryptor::KeyError error_code,
337 int system_code) {
338 client_->keyError(
339 WebString::fromUTF8(key_system),
340 WebString::fromUTF8(session_id),
341 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
342 system_code);
343 }
344
345 void KeyHandlingChunkDemuxer::OnKeyMessage(const std::string& key_system,
346 const std::string& session_id,
347 const std::string& message,
348 const std::string& default_url) {
349 const GURL default_url_gurl(default_url);
350 DLOG_IF(WARNING, !default_url.empty() && !default_url_gurl.is_valid())
351 << "Invalid URL in default_url: " << default_url;
352
353 client_->keyMessage(WebString::fromUTF8(key_system),
354 WebString::fromUTF8(session_id),
355 reinterpret_cast<const uint8*>(message.data()),
356 message.size(),
357 default_url_gurl);
358 }
359
360 void KeyHandlingChunkDemuxer::OnKeyAdded(const std::string& key_system,
361 const std::string& session_id) {
362 notify_demuxer_cb_.Run(key_system);
363 client_->keyAdded(WebString::fromUTF8(key_system),
364 WebString::fromUTF8(session_id));
365 }
366
367 void KeyHandlingChunkDemuxer::OnNeedKey(const std::string& key_system,
368 const std::string& session_id,
369 const std::string& type,
370 scoped_ptr<uint8[]> init_data,
371 int init_data_size) {
372 // Do not fire NeedKey event if encrypted media is not enabled.
373 if (!decryptor_)
374 return;
375
376 CHECK(init_data_size >= 0);
377 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
378 if (init_data_type_.empty())
379 init_data_type_ = type;
380
381 client_->keyNeeded(WebString::fromUTF8(key_system),
382 WebString::fromUTF8(session_id),
383 init_data.get(),
384 init_data_size);
385 }
386
387 void KeyHandlingChunkDemuxer::OnDecryptorReady(media::Decryptor* decryptor) {}
388
389 void KeyHandlingChunkDemuxer::OnDemuxerOpened() {
390 media_source_->open(new WebMediaSourceClientImpl(
391 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_)));
392 }
393
394 } // anonymous namespace
395
396 // MediaSourceDelegate ---------------------------------------------------------
397
398 MediaSourceDelegate::MediaSourceDelegate(
399 WebMediaPlayerProxyAndroid* proxy,
400 int player_id,
401 const UpdateNetworkStateCB& update_network_state_cb)
402 : weak_this_(this),
403 proxy_(proxy),
404 player_id_(player_id),
405 update_network_state_cb_(update_network_state_cb),
406 audio_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params),
407 video_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params),
408 seeking_(false),
409 low_latency_mode_(false) {
410 }
411
412 MediaSourceDelegate::~MediaSourceDelegate() {}
413
414 void MediaSourceDelegate::InitializeMediaSource(
415 WebKit::WebFrame * frame,
416 WebKit::WebMediaPlayerClient * client,
417 WebKit::WebMediaSource* media_source,
418 media::MediaLog * media_log) {
419 DCHECK(media_source);
420 demuxer_.reset(new KeyHandlingChunkDemuxer(
421 frame,
422 client,
423 media_source,
424 scoped_refptr<media::MediaLog>(media_log),
425 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::NotifyDemuxerReady)));
426 demuxer_->Initialize(this,
427 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
428 }
429
430 void MediaSourceDelegate::InitializeMediaStream(media::Demuxer* demuxer) {
431 DCHECK(demuxer);
432 low_latency_mode_ = true;
433 demuxer_.reset(new KeyHandlingDemuxer(demuxer));
434 demuxer_->Initialize(this,
435 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
436 }
437
438 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() {
439 buffered_web_time_ranges_ =
440 ConvertToWebTimeRanges(buffered_time_ranges_);
441 return buffered_web_time_ranges_;
442 }
443
444 unsigned MediaSourceDelegate::DecodedFrameCount() const {
445 return statistics_.video_frames_decoded;
446 }
447
448 unsigned MediaSourceDelegate::DroppedFrameCount() const {
449 return statistics_.video_frames_dropped;
450 }
451
452 unsigned MediaSourceDelegate::AudioDecodedByteCount() const {
453 return statistics_.audio_bytes_decoded;;
454 }
455
456 unsigned MediaSourceDelegate::VideoDecodedByteCount() const {
457 return statistics_.video_bytes_decoded;
458 }
459
460 WebMediaPlayer::MediaKeyException MediaSourceDelegate::GenerateKeyRequest(
461 const WebString& key_system,
462 const unsigned char* init_data,
463 unsigned init_data_length) {
464 return demuxer_->GenerateKeyRequest(key_system, init_data, init_data_length);
465 }
466
467 WebMediaPlayer::MediaKeyException MediaSourceDelegate::AddKey(
468 const WebString& key_system,
469 const unsigned char* key,
470 unsigned key_length,
471 const unsigned char* init_data,
472 unsigned init_data_length,
473 const WebString& session_id) {
474 return demuxer_->AddKey(
475 key_system, key, key_length, init_data, init_data_length, session_id);
476 }
477
478 WebMediaPlayer::MediaKeyException MediaSourceDelegate::CancelKeyRequest(
479 const WebString& key_system,
480 const WebString& session_id) {
481 return demuxer_->CancelKeyRequest(key_system, session_id);
482 }
483
197 void MediaSourceDelegate::Seek(base::TimeDelta time) { 484 void MediaSourceDelegate::Seek(base::TimeDelta time) {
198 seeking_ = true; 485 seeking_ = true;
199 DCHECK(chunk_demuxer_); 486 DCHECK(demuxer_);
200 if (!chunk_demuxer_) 487 if (!demuxer_)
201 return; 488 return;
202 chunk_demuxer_->StartWaitingForSeek(); 489 demuxer_->Seek(time,
203 chunk_demuxer_->Seek(time,
204 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError)); 490 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError));
205 } 491 }
206 492
207 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) { 493 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) {
208 NOTIMPLEMENTED(); 494 NOTIMPLEMENTED();
209 } 495 }
210 496
211 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) { 497 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) {
212 NOTIMPLEMENTED(); 498 NOTIMPLEMENTED();
213 } 499 }
214 500
215 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, 501 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start,
216 base::TimeDelta end) { 502 base::TimeDelta end) {
217 buffered_time_ranges_.Add(start, end); 503 buffered_time_ranges_.Add(start, end);
218 } 504 }
219 505
220 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { 506 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) {
221 // Do nothing 507 // Do nothing
222 } 508 }
223 509
224 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type, 510 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type,
225 bool seek_done) { 511 bool seek_done) {
226 if (seeking_ && !seek_done) 512 if (seeking_ && !seek_done)
227 return; // Drop the request during seeking. 513 return; // Drop the request during seeking.
228 seeking_ = false; 514 seeking_ = false;
229 515
230 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); 516 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
517
518 // When in low latency mode, don't wait to accumulate multiple packets per IPC
519 // communication.
520 size_t access_unit_size = low_latency_mode_ ? 1 : kAccessUnitSize;
521
231 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params = 522 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params =
232 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get(); 523 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get();
233 params->type = type; 524 params->type = type;
234 params->access_units.resize(kAccessUnitSize); 525 params->access_units.resize(access_unit_size);
235 DemuxerStream* stream = chunk_demuxer_->GetStream(type); 526 DemuxerStream* stream = demuxer_->GetStream(type);
236 DCHECK(stream != NULL); 527 DCHECK(stream != NULL);
237 ReadFromDemuxerStream(stream, params, 0); 528 ReadFromDemuxerStream(stream, params, 0);
238 } 529 }
239 530
240 void MediaSourceDelegate::ReadFromDemuxerStream( 531 void MediaSourceDelegate::ReadFromDemuxerStream(
241 DemuxerStream* stream, 532 DemuxerStream* stream,
242 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, 533 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params,
243 size_t index) { 534 size_t index) {
244 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady, 535 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady,
245 stream, params, index)); 536 stream, params, index));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 if (status != media::PIPELINE_OK) { 634 if (status != media::PIPELINE_OK) {
344 OnDemuxerError(status); 635 OnDemuxerError(status);
345 return; 636 return;
346 } 637 }
347 NotifyDemuxerReady(""); 638 NotifyDemuxerReady("");
348 } 639 }
349 640
350 void MediaSourceDelegate::NotifyDemuxerReady( 641 void MediaSourceDelegate::NotifyDemuxerReady(
351 const std::string& key_system) { 642 const std::string& key_system) {
352 MediaPlayerHostMsg_DemuxerReady_Params params; 643 MediaPlayerHostMsg_DemuxerReady_Params params;
353 DemuxerStream* audio_stream = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); 644 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
354 if (audio_stream) { 645 if (audio_stream) {
355 const media::AudioDecoderConfig& config = 646 const media::AudioDecoderConfig& config =
356 audio_stream->audio_decoder_config(); 647 audio_stream->audio_decoder_config();
357 params.audio_codec = config.codec(); 648 params.audio_codec = config.codec();
358 params.audio_channels = 649 params.audio_channels =
359 media::ChannelLayoutToChannelCount(config.channel_layout()); 650 media::ChannelLayoutToChannelCount(config.channel_layout());
360 params.audio_sampling_rate = config.samples_per_second(); 651 params.audio_sampling_rate = config.samples_per_second();
361 params.is_audio_encrypted = config.is_encrypted(); 652 params.is_audio_encrypted = config.is_encrypted();
362 } 653 }
363 DemuxerStream* video_stream = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); 654 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
364 if (video_stream) { 655 if (video_stream) {
365 const media::VideoDecoderConfig& config = 656 const media::VideoDecoderConfig& config =
366 video_stream->video_decoder_config(); 657 video_stream->video_decoder_config();
367 params.video_codec = config.codec(); 658 params.video_codec = config.codec();
368 params.video_size = config.natural_size(); 659 params.video_size = config.natural_size();
369 params.is_video_encrypted = config.is_encrypted(); 660 params.is_video_encrypted = config.is_encrypted();
370 } 661 }
371 double duration_ms = chunk_demuxer_->GetDuration() * 1000; 662 params.duration_ms = demuxer_->GetDurationMs();
372 DCHECK(duration_ms >= 0);
373 if (duration_ms > std::numeric_limits<int>::max())
374 duration_ms = std::numeric_limits<int>::max();
375 params.duration_ms = duration_ms;
376 params.key_system = key_system; 663 params.key_system = key_system;
377 664
378 bool ready_to_send = (!params.is_audio_encrypted && 665 bool ready_to_send = (!params.is_audio_encrypted &&
379 !params.is_video_encrypted) || !key_system.empty(); 666 !params.is_video_encrypted) || !key_system.empty();
380 if (proxy_ && ready_to_send) 667 if (proxy_ && ready_to_send)
381 proxy_->DemuxerReady(player_id_, params); 668 proxy_->DemuxerReady(player_id_, params);
382 } 669 }
383 670
384 void MediaSourceDelegate::OnDemuxerOpened() {
385 media_source_->open(new WebMediaSourceClientImpl(
386 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_)));
387 }
388
389 void MediaSourceDelegate::OnKeyError(const std::string& key_system,
390 const std::string& session_id,
391 media::Decryptor::KeyError error_code,
392 int system_code) {
393 client_->keyError(
394 WebString::fromUTF8(key_system),
395 WebString::fromUTF8(session_id),
396 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
397 system_code);
398 }
399
400 void MediaSourceDelegate::OnKeyMessage(const std::string& key_system,
401 const std::string& session_id,
402 const std::string& message,
403 const std::string& default_url) {
404 const GURL default_url_gurl(default_url);
405 DLOG_IF(WARNING, !default_url.empty() && !default_url_gurl.is_valid())
406 << "Invalid URL in default_url: " << default_url;
407
408 client_->keyMessage(WebString::fromUTF8(key_system),
409 WebString::fromUTF8(session_id),
410 reinterpret_cast<const uint8*>(message.data()),
411 message.size(),
412 default_url_gurl);
413 }
414
415 void MediaSourceDelegate::OnKeyAdded(const std::string& key_system,
416 const std::string& session_id) {
417 NotifyDemuxerReady(key_system);
418 client_->keyAdded(WebString::fromUTF8(key_system),
419 WebString::fromUTF8(session_id));
420 }
421
422 void MediaSourceDelegate::OnNeedKey(const std::string& key_system,
423 const std::string& session_id,
424 const std::string& type,
425 scoped_ptr<uint8[]> init_data,
426 int init_data_size) {
427 // Do not fire NeedKey event if encrypted media is not enabled.
428 if (!decryptor_)
429 return;
430
431 CHECK(init_data_size >= 0);
432 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
433 if (init_data_type_.empty())
434 init_data_type_ = type;
435
436 client_->keyNeeded(WebString::fromUTF8(key_system),
437 WebString::fromUTF8(session_id),
438 init_data.get(),
439 init_data_size);
440 }
441
442 void MediaSourceDelegate::OnDecryptorReady(media::Decryptor* decryptor) {}
443
444 } // namespace webkit_media 671 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698