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

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

Powered by Google App Engine
This is Rietveld 408576698