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

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: Added tests and refined the code 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 media::Demuxer* demuxer() { return demuxer_; }
105
106 protected:
107 media::Demuxer* demuxer_;
108 };
109
110 KeyHandlingDemuxer::KeyHandlingDemuxer(media::Demuxer* demuxer)
111 : demuxer_(demuxer) {}
112
113 KeyHandlingDemuxer::~KeyHandlingDemuxer() {}
114
115 void KeyHandlingDemuxer::Initialize(DemuxerHost* host,
116 const PipelineStatusCB& status_cb) {
117 demuxer_->Initialize(host, status_cb);
118 }
119
120 void KeyHandlingDemuxer::SetPlaybackRate(float playback_rate) {
121 demuxer_->SetPlaybackRate(playback_rate);
122 }
123
124 void KeyHandlingDemuxer::Seek(base::TimeDelta time,
125 const PipelineStatusCB& status_cb) {
126 demuxer_->Seek(time, status_cb);
127 }
128
129 void KeyHandlingDemuxer::Stop(const base::Closure& callback) {
130 demuxer_->Stop(callback);
131 }
132
133 void KeyHandlingDemuxer::OnAudioRendererDisabled() {
134 demuxer_->OnAudioRendererDisabled();
135 }
136
137 DemuxerStream* KeyHandlingDemuxer::GetStream(
138 DemuxerStream::Type type) {
139 return demuxer_->GetStream(type);
140 }
141
142 base::TimeDelta KeyHandlingDemuxer::GetStartTime() const {
143 return demuxer_->GetStartTime();
144 }
145
146 // KeyHandlingChunkDemuxer -----------------------------------------------------
147
148 namespace {
149
150 class KeyHandlingChunkDemuxer : public KeyHandlingDemuxer {
151 public:
152 typedef base::Callback<void(const std::string& key_system)> NotifyDemuxerCB;
153
154 KeyHandlingChunkDemuxer(WebKit::WebFrame* frame,
155 WebKit::WebMediaPlayerClient* client,
156 WebKit::WebMediaSource* media_source,
157 scoped_refptr<media::MediaLog> media_log,
158 NotifyDemuxerCB notify_demuxer_cb);
159 virtual ~KeyHandlingChunkDemuxer();
160
161 // KeyHandlingDemuxer
162 virtual WebKit::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
163 const WebKit::WebString& key_system,
164 const unsigned char* init_data,
165 unsigned init_data_length) OVERRIDE;
166 virtual WebKit::WebMediaPlayer::MediaKeyException AddKey(
167 const WebKit::WebString& key_system,
168 const unsigned char* key,
169 unsigned key_length,
170 const unsigned char* init_data,
171 unsigned init_data_length,
172 const WebKit::WebString& session_id) OVERRIDE;
173 virtual WebKit::WebMediaPlayer::MediaKeyException CancelKeyRequest(
174 const WebKit::WebString& key_system,
175 const WebKit::WebString& session_id) OVERRIDE;
176 virtual int GetDurationMs() OVERRIDE;
177
178 // media::Demuxer
179 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& status_cb)
180 OVERRIDE;
181
182 private:
183 // Callbacks for ChunkDemuxer & Decryptor.
184 void OnDemuxerOpened();
185 void OnKeyAdded(const std::string& key_system, const std::string& session_id);
186 void OnKeyError(const std::string& key_system,
187 const std::string& session_id,
188 media::Decryptor::KeyError error_code,
189 int system_code);
190 void OnKeyMessage(const std::string& key_system,
191 const std::string& session_id,
192 const std::string& message,
193 const std::string& default_url);
194 void OnNeedKey(const std::string& key_system,
195 const std::string& type,
196 const std::string& session_id,
197 scoped_ptr<uint8[]> init_data,
198 int init_data_size);
199 void OnDecryptorReady(media::Decryptor*);
200
201 base::WeakPtrFactory<KeyHandlingChunkDemuxer> weak_this_;
202 scoped_ptr<media::ChunkDemuxer> chunk_demuxer_;
203 WebKit::WebMediaPlayerClient* client_;
204 scoped_refptr<media::MediaLog> media_log_;
205
206 // The decryptor that manages decryption keys and decrypts encrypted frames.
207 scoped_ptr<ProxyDecryptor> decryptor_;
208
209 // The currently selected key system. Empty string means that no key system
210 // has been selected.
211 WebKit::WebString current_key_system_;
212
213 // Temporary for EME v0.1. In the future the init data type should be passed
214 // through GenerateKeyRequest() directly from WebKit.
215 std::string init_data_type_;
216
217 NotifyDemuxerCB notify_demuxer_cb_;
218
219 scoped_ptr<WebKit::WebMediaSource> media_source_;
220 };
221
222 KeyHandlingChunkDemuxer::KeyHandlingChunkDemuxer(
63 WebKit::WebFrame* frame, 223 WebKit::WebFrame* frame,
64 WebKit::WebMediaPlayerClient* client, 224 WebKit::WebMediaPlayerClient* client,
65 WebMediaPlayerProxyAndroid* proxy, 225 WebKit::WebMediaSource* media_source,
66 int player_id, 226 scoped_refptr<media::MediaLog> media_log,
67 media::MediaLog* media_log) 227 NotifyDemuxerCB notify_demuxer_cb)
68 : weak_this_(this), 228 : KeyHandlingDemuxer(NULL),
229 weak_this_(this),
69 client_(client), 230 client_(client),
70 proxy_(proxy),
71 player_id_(player_id),
72 media_log_(media_log), 231 media_log_(media_log),
73 audio_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params), 232 notify_demuxer_cb_(notify_demuxer_cb) {
74 video_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params), 233 chunk_demuxer_.reset(new media::ChunkDemuxer(
75 seeking_(false) { 234 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnDemuxerOpened),
235 BIND_TO_RENDER_LOOP_2(&KeyHandlingChunkDemuxer::OnNeedKey, "", ""),
236 base::Bind(&LogMediaSourceError, media_log)));
237 demuxer_ = chunk_demuxer_.get();
238 media_source_.reset(media_source);
76 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { 239 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
77 decryptor_.reset(new ProxyDecryptor( 240 decryptor_.reset(new ProxyDecryptor(
78 client, 241 client,
79 frame, 242 frame,
80 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyAdded), 243 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnKeyAdded),
81 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyError), 244 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnKeyError),
82 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyMessage), 245 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnKeyMessage),
83 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnNeedKey))); 246 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnNeedKey)));
84 decryptor_->SetDecryptorReadyCB( 247 decryptor_->SetDecryptorReadyCB(
85 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDecryptorReady)); 248 BIND_TO_RENDER_LOOP(&KeyHandlingChunkDemuxer::OnDecryptorReady));
86 } 249 }
87 } 250 }
88 251
89 MediaSourceDelegate::~MediaSourceDelegate() {} 252 KeyHandlingChunkDemuxer::~KeyHandlingChunkDemuxer() {}
90 253
91 void MediaSourceDelegate::Initialize( 254 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, 255 const WebString& key_system,
130 const unsigned char* init_data, 256 const unsigned char* init_data,
131 size_t init_data_length) { 257 size_t init_data_length) {
132 if (!IsSupportedKeySystem(key_system)) 258 if (!IsSupportedKeySystem(key_system))
133 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 259 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
134 260
135 // We do not support run-time switching between key systems for now. 261 // We do not support run-time switching between key systems for now.
136 if (current_key_system_.isEmpty()) 262 if (current_key_system_.isEmpty())
137 current_key_system_ = key_system; 263 current_key_system_ = key_system;
138 else if (key_system != current_key_system_) 264 else if (key_system != current_key_system_)
139 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; 265 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
140 266
141 DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": " 267 DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": "
142 << std::string(reinterpret_cast<const char*>(init_data), 268 << std::string(reinterpret_cast<const char*>(init_data),
143 init_data_length); 269 init_data_length);
144 270
145 // TODO(xhwang): We assume all streams are from the same container (thus have 271 // 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 272 // the same "type") for now. In the future, the "type" should be passed down
147 // from the application. 273 // from the application.
148 if (!decryptor_->GenerateKeyRequest(key_system.utf8(), 274 if (!decryptor_->GenerateKeyRequest(key_system.utf8(),
149 init_data_type_, 275 init_data_type_,
150 init_data, init_data_length)) { 276 init_data, init_data_length)) {
151 current_key_system_.reset(); 277 current_key_system_.reset();
152 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 278 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
153 } 279 }
154 280
155 return WebMediaPlayer::MediaKeyExceptionNoError; 281 return WebMediaPlayer::MediaKeyExceptionNoError;
156 } 282 }
157 283
158 WebMediaPlayer::MediaKeyException MediaSourceDelegate::AddKey( 284 WebMediaPlayer::MediaKeyException KeyHandlingChunkDemuxer::AddKey(
159 const WebString& key_system, 285 const WebString& key_system,
160 const unsigned char* key, 286 const unsigned char* key,
161 size_t key_length, 287 size_t key_length,
162 const unsigned char* init_data, 288 const unsigned char* init_data,
163 size_t init_data_length, 289 size_t init_data_length,
164 const WebString& session_id) { 290 const WebString& session_id) {
165 DCHECK(key); 291 DCHECK(key);
166 DCHECK_EQ(key_length, 16u); 292 DCHECK_EQ(key_length, 16u);
167 293
168 if (!IsSupportedKeySystem(key_system)) 294 if (!IsSupportedKeySystem(key_system))
169 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 295 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
170 296
171 if (current_key_system_.isEmpty() || key_system != current_key_system_) 297 if (current_key_system_.isEmpty() || key_system != current_key_system_)
172 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; 298 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
173 299
174 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " 300 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": "
175 << base::HexEncode(key, key_length) << ", " 301 << base::HexEncode(key, key_length) << ", "
176 << base::HexEncode(init_data, std::max(init_data_length, 256u)) 302 << base::HexEncode(init_data, std::max(init_data_length, 256u))
177 << " [" << session_id.utf8().data() << "]"; 303 << " [" << session_id.utf8().data() << "]";
178 304
179 decryptor_->AddKey(key_system.utf8(), key, key_length, 305 decryptor_->AddKey(key_system.utf8(), key, key_length,
180 init_data, init_data_length, session_id.utf8()); 306 init_data, init_data_length, session_id.utf8());
181 return WebMediaPlayer::MediaKeyExceptionNoError; 307 return WebMediaPlayer::MediaKeyExceptionNoError;
182 } 308 }
183 309
184 WebMediaPlayer::MediaKeyException MediaSourceDelegate::CancelKeyRequest( 310 WebMediaPlayer::MediaKeyException KeyHandlingChunkDemuxer::CancelKeyRequest(
185 const WebString& key_system, 311 const WebString& key_system,
186 const WebString& session_id) { 312 const WebString& session_id) {
187 if (!IsSupportedKeySystem(key_system)) 313 if (!IsSupportedKeySystem(key_system))
188 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 314 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
189 315
190 if (current_key_system_.isEmpty() || key_system != current_key_system_) 316 if (current_key_system_.isEmpty() || key_system != current_key_system_)
191 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; 317 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
192 318
193 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); 319 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8());
194 return WebMediaPlayer::MediaKeyExceptionNoError; 320 return WebMediaPlayer::MediaKeyExceptionNoError;
195 } 321 }
196 322
323 int KeyHandlingChunkDemuxer::GetDurationMs() {
324 double duration_ms = chunk_demuxer_->GetDuration() * 1000;
325 if (duration_ms > std::numeric_limits<int>::max()) {
326 LOG(WARNING) << "Duration from ChunkDemuxer is too large; probably "
327 "something have gone wrong.";
328 return std::numeric_limits<int>::max();
329 }
330 return duration_ms;
331 }
332
333 void KeyHandlingChunkDemuxer::Seek(base::TimeDelta time,
334 const PipelineStatusCB& status_cb) {
335 chunk_demuxer_->StartWaitingForSeek();
336 chunk_demuxer_->Seek(time, status_cb);
337 }
338
339 void KeyHandlingChunkDemuxer::OnKeyError(const std::string& key_system,
340 const std::string& session_id,
341 media::Decryptor::KeyError error_code,
342 int system_code) {
343 client_->keyError(
344 WebString::fromUTF8(key_system),
345 WebString::fromUTF8(session_id),
346 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
347 system_code);
348 }
349
350 void KeyHandlingChunkDemuxer::OnKeyMessage(const std::string& key_system,
351 const std::string& session_id,
352 const std::string& message,
353 const std::string& default_url) {
354 const GURL default_url_gurl(default_url);
355 DLOG_IF(WARNING, !default_url.empty() && !default_url_gurl.is_valid())
356 << "Invalid URL in default_url: " << default_url;
357
358 client_->keyMessage(WebString::fromUTF8(key_system),
359 WebString::fromUTF8(session_id),
360 reinterpret_cast<const uint8*>(message.data()),
361 message.size(),
362 default_url_gurl);
363 }
364
365 void KeyHandlingChunkDemuxer::OnKeyAdded(const std::string& key_system,
366 const std::string& session_id) {
367 notify_demuxer_cb_.Run(key_system);
368 client_->keyAdded(WebString::fromUTF8(key_system),
369 WebString::fromUTF8(session_id));
370 }
371
372 void KeyHandlingChunkDemuxer::OnNeedKey(const std::string& key_system,
373 const std::string& session_id,
374 const std::string& type,
375 scoped_ptr<uint8[]> init_data,
376 int init_data_size) {
377 // Do not fire NeedKey event if encrypted media is not enabled.
378 if (!decryptor_)
379 return;
380
381 CHECK(init_data_size >= 0);
382 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
383 if (init_data_type_.empty())
384 init_data_type_ = type;
385
386 client_->keyNeeded(WebString::fromUTF8(key_system),
387 WebString::fromUTF8(session_id),
388 init_data.get(),
389 init_data_size);
390 }
391
392 void KeyHandlingChunkDemuxer::OnDecryptorReady(media::Decryptor* decryptor) {}
393
394 void KeyHandlingChunkDemuxer::OnDemuxerOpened() {
395 media_source_->open(new WebMediaSourceClientImpl(
396 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_)));
397 }
398
399 } // anonymous namespace
400
401 // MediaSourceDelegate ---------------------------------------------------------
402
403 MediaSourceDelegate::MediaSourceDelegate(
404 WebMediaPlayerProxyAndroid* proxy,
405 int player_id,
406 const UpdateNetworkStateCB& update_network_state_cb)
407 : weak_this_(this),
408 proxy_(proxy),
409 player_id_(player_id),
410 update_network_state_cb_(update_network_state_cb),
411 audio_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params),
412 video_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params),
413 seeking_(false),
414 is_media_stream_(false) {
415 }
416
417 MediaSourceDelegate::~MediaSourceDelegate() {
418 if (!destroy_demuxer_cb_.is_null())
419 destroy_demuxer_cb_.Run(demuxer_->demuxer());
420 }
421
422 void MediaSourceDelegate::InitializeMediaSource(
423 WebKit::WebFrame * frame,
ycheo (away) 2013/05/06 05:45:34 Attach '*' on the type.
wonsik 2013/05/06 12:28:43 Done.
424 WebKit::WebMediaPlayerClient * client,
425 WebKit::WebMediaSource* media_source,
426 media::MediaLog * media_log) {
427 DCHECK(media_source);
428 demuxer_.reset(new KeyHandlingChunkDemuxer(
429 frame,
430 client,
431 media_source,
432 scoped_refptr<media::MediaLog>(media_log),
433 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::NotifyDemuxerReady)));
434 demuxer_->Initialize(this,
435 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
436 }
437
438 void MediaSourceDelegate::InitializeMediaStream(
439 media::Demuxer* demuxer,
440 const DestroyDemuxerCB& destroy_demuxer_cb) {
441 DCHECK(demuxer);
442 is_media_stream_ = true;
443 destroy_demuxer_cb_ = destroy_demuxer_cb;
444 demuxer_.reset(new KeyHandlingDemuxer(demuxer));
445 demuxer_->Initialize(this,
446 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
447 }
448
449 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() {
450 buffered_web_time_ranges_ =
451 ConvertToWebTimeRanges(buffered_time_ranges_);
452 return buffered_web_time_ranges_;
453 }
454
455 unsigned MediaSourceDelegate::DecodedFrameCount() const {
456 return statistics_.video_frames_decoded;
457 }
458
459 unsigned MediaSourceDelegate::DroppedFrameCount() const {
460 return statistics_.video_frames_dropped;
461 }
462
463 unsigned MediaSourceDelegate::AudioDecodedByteCount() const {
464 return statistics_.audio_bytes_decoded;;
465 }
466
467 unsigned MediaSourceDelegate::VideoDecodedByteCount() const {
468 return statistics_.video_bytes_decoded;
469 }
470
471 WebMediaPlayer::MediaKeyException MediaSourceDelegate::GenerateKeyRequest(
472 const WebString& key_system,
473 const unsigned char* init_data,
474 unsigned init_data_length) {
475 return demuxer_->GenerateKeyRequest(key_system, init_data, init_data_length);
476 }
477
478 WebMediaPlayer::MediaKeyException MediaSourceDelegate::AddKey(
479 const WebString& key_system,
480 const unsigned char* key,
481 unsigned key_length,
482 const unsigned char* init_data,
483 unsigned init_data_length,
484 const WebString& session_id) {
485 return demuxer_->AddKey(
486 key_system, key, key_length, init_data, init_data_length, session_id);
487 }
488
489 WebMediaPlayer::MediaKeyException MediaSourceDelegate::CancelKeyRequest(
490 const WebString& key_system,
491 const WebString& session_id) {
492 return demuxer_->CancelKeyRequest(key_system, session_id);
493 }
494
197 void MediaSourceDelegate::Seek(base::TimeDelta time) { 495 void MediaSourceDelegate::Seek(base::TimeDelta time) {
198 seeking_ = true; 496 seeking_ = true;
199 DCHECK(chunk_demuxer_); 497 DCHECK(demuxer_);
200 if (!chunk_demuxer_) 498 if (!demuxer_)
201 return; 499 return;
202 chunk_demuxer_->StartWaitingForSeek(); 500 demuxer_->Seek(time,
203 chunk_demuxer_->Seek(time,
204 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError)); 501 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError));
205 } 502 }
206 503
207 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) { 504 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) {
208 NOTIMPLEMENTED(); 505 NOTIMPLEMENTED();
209 } 506 }
210 507
211 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) { 508 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) {
212 NOTIMPLEMENTED(); 509 NOTIMPLEMENTED();
213 } 510 }
214 511
215 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, 512 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start,
216 base::TimeDelta end) { 513 base::TimeDelta end) {
217 buffered_time_ranges_.Add(start, end); 514 buffered_time_ranges_.Add(start, end);
218 } 515 }
219 516
220 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { 517 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) {
221 // Do nothing 518 // Do nothing
222 } 519 }
223 520
224 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type, 521 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type,
225 bool seek_done) { 522 bool seek_done) {
226 if (seeking_ && !seek_done) 523 if (seeking_ && !seek_done)
227 return; // Drop the request during seeking. 524 return; // Drop the request during seeking.
228 seeking_ = false; 525 seeking_ = false;
229 526
230 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); 527 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
528
529 // When playing Media Stream, don't wait to accumulate multiple packets per
530 // IPC communication.
531 size_t access_unit_size = is_media_stream_ ? 1 : kAccessUnitSize;
532
231 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params = 533 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params =
232 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get(); 534 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get();
233 params->type = type; 535 params->type = type;
234 params->access_units.resize(kAccessUnitSize); 536 params->access_units.resize(access_unit_size);
235 DemuxerStream* stream = chunk_demuxer_->GetStream(type); 537 DemuxerStream* stream = demuxer_->GetStream(type);
236 DCHECK(stream != NULL); 538 DCHECK(stream != NULL);
237 ReadFromDemuxerStream(stream, params, 0); 539 ReadFromDemuxerStream(stream, params, 0);
238 } 540 }
239 541
240 void MediaSourceDelegate::ReadFromDemuxerStream( 542 void MediaSourceDelegate::ReadFromDemuxerStream(
241 DemuxerStream* stream, 543 DemuxerStream* stream,
242 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, 544 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params,
243 size_t index) { 545 size_t index) {
244 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady, 546 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady,
245 stream, params, index)); 547 stream, params, index));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 if (status != media::PIPELINE_OK) { 645 if (status != media::PIPELINE_OK) {
344 OnDemuxerError(status); 646 OnDemuxerError(status);
345 return; 647 return;
346 } 648 }
347 NotifyDemuxerReady(""); 649 NotifyDemuxerReady("");
348 } 650 }
349 651
350 void MediaSourceDelegate::NotifyDemuxerReady( 652 void MediaSourceDelegate::NotifyDemuxerReady(
351 const std::string& key_system) { 653 const std::string& key_system) {
352 MediaPlayerHostMsg_DemuxerReady_Params params; 654 MediaPlayerHostMsg_DemuxerReady_Params params;
353 DemuxerStream* audio_stream = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); 655 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
354 if (audio_stream) { 656 if (audio_stream) {
355 const media::AudioDecoderConfig& config = 657 const media::AudioDecoderConfig& config =
356 audio_stream->audio_decoder_config(); 658 audio_stream->audio_decoder_config();
357 params.audio_codec = config.codec(); 659 params.audio_codec = config.codec();
358 params.audio_channels = 660 params.audio_channels =
359 media::ChannelLayoutToChannelCount(config.channel_layout()); 661 media::ChannelLayoutToChannelCount(config.channel_layout());
360 params.audio_sampling_rate = config.samples_per_second(); 662 params.audio_sampling_rate = config.samples_per_second();
361 params.is_audio_encrypted = config.is_encrypted(); 663 params.is_audio_encrypted = config.is_encrypted();
362 } 664 }
363 DemuxerStream* video_stream = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); 665 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
364 if (video_stream) { 666 if (video_stream) {
365 const media::VideoDecoderConfig& config = 667 const media::VideoDecoderConfig& config =
366 video_stream->video_decoder_config(); 668 video_stream->video_decoder_config();
367 params.video_codec = config.codec(); 669 params.video_codec = config.codec();
368 params.video_size = config.natural_size(); 670 params.video_size = config.natural_size();
369 params.is_video_encrypted = config.is_encrypted(); 671 params.is_video_encrypted = config.is_encrypted();
370 } 672 }
371 double duration_ms = chunk_demuxer_->GetDuration() * 1000; 673 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; 674 params.key_system = key_system;
377 675
378 bool ready_to_send = (!params.is_audio_encrypted && 676 bool ready_to_send = (!params.is_audio_encrypted &&
379 !params.is_video_encrypted) || !key_system.empty(); 677 !params.is_video_encrypted) || !key_system.empty();
380 if (proxy_ && ready_to_send) 678 if (proxy_ && ready_to_send)
381 proxy_->DemuxerReady(player_id_, params); 679 proxy_->DemuxerReady(player_id_, params);
382 } 680 }
383 681
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 682 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698