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

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

Powered by Google App Engine
This is Rietveld 408576698