OLD | NEW |
---|---|
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 Loading... | |
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 { | |
qinmin
2013/05/07 02:41:24
this file defines both a base class and an inherit
wonsik
2013/05/07 07:12:27
Done.
| |
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, | |
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 Loading... | |
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 |
OLD | NEW |