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

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

Issue 14247018: Implement WebRTC in Chrome for TV (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Dongwon and Yuncheol's comments Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/media/android/media_source_delegate.h" 5 #include "webkit/media/android/media_source_delegate.h"
6 6
7 #include "base/message_loop_proxy.h" 7 #include "base/message_loop_proxy.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "media/base/android/demuxer_stream_player_params.h" 9 #include "media/base/android/demuxer_stream_player_params.h"
10 #include "media/base/bind_to_loop.h" 10 #include "media/base/bind_to_loop.h"
11 #include "media/base/demuxer_stream.h" 11 #include "media/base/demuxer_stream.h"
12 #include "media/base/media_log.h" 12 #include "media/base/media_log.h"
13 #include "media/filters/chunk_demuxer.h" 13 #include "media/filters/chunk_demuxer.h"
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" 14 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h"
18 #include "webkit/media/android/webmediaplayer_proxy_android.h" 18 #include "webkit/media/android/webmediaplayer_proxy_android.h"
19 #include "webkit/media/crypto/key_systems.h" 19 #include "webkit/media/crypto/key_systems.h"
20 #include "webkit/media/crypto/proxy_decryptor.h" 20 #include "webkit/media/crypto/proxy_decryptor.h"
21 #include "webkit/media/webmediaplayer_util.h" 21 #include "webkit/media/webmediaplayer_util.h"
22 #include "webkit/media/webmediasourceclient_impl.h" 22 #include "webkit/media/webmediasourceclient_impl.h"
23 23
24 using media::DemuxerHost;
24 using media::DemuxerStream; 25 using media::DemuxerStream;
25 using media::MediaPlayerHostMsg_DemuxerReady_Params; 26 using media::MediaPlayerHostMsg_DemuxerReady_Params;
26 using media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params; 27 using media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params;
28 using media::PipelineStatusCB;
27 using WebKit::WebMediaPlayer; 29 using WebKit::WebMediaPlayer;
28 using WebKit::WebString; 30 using WebKit::WebString;
29 31
30 namespace { 32 namespace {
31 33
32 // The size of the access unit to transfer in an IPC. 34 // The size of the access unit to transfer in an IPC in case of MediaSource.
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 kAccessUnitSizeForMediaSource = 16;
35 37
36 } // namespace 38 } // namespace
37 39
38 namespace webkit_media { 40 namespace webkit_media {
39 41
40 #define BIND_TO_RENDER_LOOP(function) \ 42 #define BIND_TO_RENDER_LOOP(function) \
41 media::BindToLoop(base::MessageLoopProxy::current(), \ 43 media::BindToLoop(base::MessageLoopProxy::current(), \
42 base::Bind(function, weak_this_.GetWeakPtr())) 44 base::Bind(function, weak_this_.GetWeakPtr()))
43 45
44 #define BIND_TO_RENDER_LOOP_1(function, arg1) \ 46 #define BIND_TO_RENDER_LOOP_1(function, arg1) \
45 media::BindToLoop(base::MessageLoopProxy::current(), \ 47 media::BindToLoop(base::MessageLoopProxy::current(), \
46 base::Bind(function, weak_this_.GetWeakPtr(), arg1)) 48 base::Bind(function, weak_this_.GetWeakPtr(), arg1))
47 49
48 #define BIND_TO_RENDER_LOOP_2(function, arg1, arg2) \ 50 #define BIND_TO_RENDER_LOOP_2(function, arg1, arg2) \
49 media::BindToLoop(base::MessageLoopProxy::current(), \ 51 media::BindToLoop(base::MessageLoopProxy::current(), \
50 base::Bind(function, weak_this_.GetWeakPtr(), arg1, arg2)) 52 base::Bind(function, weak_this_.GetWeakPtr(), arg1, arg2))
51 53
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;
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 const NotifyDemuxerCB& notify_demuxer_cb);
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;
acolwell GONE FROM CHROMIUM 2013/05/14 18:17:47 nit: I think the OVERRIDE is typically on the same
wonsik 2013/05/20 14:02:24 Done.
99 virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
100 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& status_cb)
101 OVERRIDE;
acolwell GONE FROM CHROMIUM 2013/05/14 18:17:47 ditto
wonsik 2013/05/20 14:02:24 Done.
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 const 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 access_unit_size_(0) {}
390
391 MediaSourceDelegate::~MediaSourceDelegate() {
392 if (!destroy_demuxer_cb_.is_null())
393 destroy_demuxer_cb_.Run(demuxer_->demuxer());
394 }
395
396 void MediaSourceDelegate::InitializeMediaSource(
397 WebKit::WebFrame* frame,
398 WebKit::WebMediaPlayerClient* client,
399 WebKit::WebMediaSource* media_source,
400 media::MediaLog* media_log) {
401 DCHECK(media_source);
402 demuxer_->InitializeChunkDemuxer(
403 frame,
404 client,
405 media_source,
406 scoped_refptr<media::MediaLog>(media_log),
407 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::NotifyDemuxerReady));
408 demuxer_->Initialize(
409 this, BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
410 access_unit_size_ = kAccessUnitSizeForMediaSource;
411 }
412
413 void MediaSourceDelegate::InitializeMediaStream(media::Demuxer* demuxer) {
414 DCHECK(demuxer);
415 demuxer_->InitializeDemuxer(demuxer);
416 demuxer_->Initialize(
417 this, BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
418 // When playing Media Stream, don't wait to accumulate multiple packets per
419 // IPC communication.
420 access_unit_size_ = 1;
421 }
422
423 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() {
424 buffered_web_time_ranges_ = ConvertToWebTimeRanges(buffered_time_ranges_);
425 return buffered_web_time_ranges_;
426 }
427
428 unsigned MediaSourceDelegate::DecodedFrameCount() const {
429 return statistics_.video_frames_decoded;
430 }
431
432 unsigned MediaSourceDelegate::DroppedFrameCount() const {
433 return statistics_.video_frames_dropped;
434 }
435
436 unsigned MediaSourceDelegate::AudioDecodedByteCount() const {
437 return statistics_.audio_bytes_decoded;
438 }
439
440 unsigned MediaSourceDelegate::VideoDecodedByteCount() const {
441 return statistics_.video_bytes_decoded;
442 }
443
444 WebMediaPlayer::MediaKeyException MediaSourceDelegate::GenerateKeyRequest(
445 const WebString& key_system,
446 const unsigned char* init_data,
447 unsigned init_data_length) {
448 return demuxer_->GenerateKeyRequest(key_system, init_data, init_data_length);
449 }
450
451 WebMediaPlayer::MediaKeyException MediaSourceDelegate::AddKey(
452 const WebString& key_system,
453 const unsigned char* key,
454 unsigned key_length,
455 const unsigned char* init_data,
456 unsigned init_data_length,
457 const WebString& session_id) {
458 return demuxer_->AddKey(
459 key_system, key, key_length, init_data, init_data_length, session_id);
460 }
461
462 WebMediaPlayer::MediaKeyException MediaSourceDelegate::CancelKeyRequest(
463 const WebString& key_system,
464 const WebString& session_id) {
465 return demuxer_->CancelKeyRequest(key_system, session_id);
466 }
467
197 void MediaSourceDelegate::Seek(base::TimeDelta time) { 468 void MediaSourceDelegate::Seek(base::TimeDelta time) {
198 seeking_ = true; 469 seeking_ = true;
199 DCHECK(chunk_demuxer_); 470 DCHECK(demuxer_);
200 if (!chunk_demuxer_) 471 if (!demuxer_)
201 return; 472 return;
202 chunk_demuxer_->StartWaitingForSeek(); 473 demuxer_->Seek(time,
203 chunk_demuxer_->Seek(time, 474 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError));
204 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError));
205 } 475 }
206 476
207 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) { 477 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) {
208 NOTIMPLEMENTED(); 478 NOTIMPLEMENTED();
209 } 479 }
210 480
211 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) { 481 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) {
212 NOTIMPLEMENTED(); 482 NOTIMPLEMENTED();
213 } 483 }
214 484
215 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, 485 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start,
216 base::TimeDelta end) { 486 base::TimeDelta end) {
217 buffered_time_ranges_.Add(start, end); 487 buffered_time_ranges_.Add(start, end);
218 } 488 }
219 489
220 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { 490 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) {
221 // Do nothing 491 // Do nothing
222 } 492 }
223 493
224 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type, 494 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type,
225 bool seek_done) { 495 bool seek_done) {
226 if (seeking_ && !seek_done) 496 if (seeking_ && !seek_done)
227 return; // Drop the request during seeking. 497 return; // Drop the request during seeking.
228 seeking_ = false; 498 seeking_ = false;
229 499
230 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); 500 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
501 // The access unit size should have been initialized properly at this stage.
502 DCHECK(access_unit_size_ > 0);
503
231 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params = 504 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params =
232 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get(); 505 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get();
233 params->type = type; 506 params->type = type;
234 params->access_units.resize(kAccessUnitSize); 507 params->access_units.resize(access_unit_size_);
235 DemuxerStream* stream = chunk_demuxer_->GetStream(type); 508 DemuxerStream* stream = demuxer_->GetStream(type);
236 DCHECK(stream != NULL); 509 DCHECK(stream != NULL);
237 ReadFromDemuxerStream(stream, params, 0); 510 ReadFromDemuxerStream(stream, params, 0);
238 } 511 }
239 512
240 void MediaSourceDelegate::ReadFromDemuxerStream( 513 void MediaSourceDelegate::ReadFromDemuxerStream(
241 DemuxerStream* stream, 514 DemuxerStream* stream,
242 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, 515 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params,
243 size_t index) { 516 size_t index) {
244 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady, 517 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady,
245 stream, params, index)); 518 stream, params, index));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 if (status != media::PIPELINE_OK) { 616 if (status != media::PIPELINE_OK) {
344 OnDemuxerError(status); 617 OnDemuxerError(status);
345 return; 618 return;
346 } 619 }
347 NotifyDemuxerReady(""); 620 NotifyDemuxerReady("");
348 } 621 }
349 622
350 void MediaSourceDelegate::NotifyDemuxerReady( 623 void MediaSourceDelegate::NotifyDemuxerReady(
351 const std::string& key_system) { 624 const std::string& key_system) {
352 MediaPlayerHostMsg_DemuxerReady_Params params; 625 MediaPlayerHostMsg_DemuxerReady_Params params;
353 DemuxerStream* audio_stream = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); 626 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
354 if (audio_stream) { 627 if (audio_stream) {
355 const media::AudioDecoderConfig& config = 628 const media::AudioDecoderConfig& config =
356 audio_stream->audio_decoder_config(); 629 audio_stream->audio_decoder_config();
357 params.audio_codec = config.codec(); 630 params.audio_codec = config.codec();
358 params.audio_channels = 631 params.audio_channels =
359 media::ChannelLayoutToChannelCount(config.channel_layout()); 632 media::ChannelLayoutToChannelCount(config.channel_layout());
360 params.audio_sampling_rate = config.samples_per_second(); 633 params.audio_sampling_rate = config.samples_per_second();
361 params.is_audio_encrypted = config.is_encrypted(); 634 params.is_audio_encrypted = config.is_encrypted();
362 params.audio_extra_data = std::vector<uint8>( 635 params.audio_extra_data = std::vector<uint8>(
363 config.extra_data(), config.extra_data() + config.extra_data_size()); 636 config.extra_data(), config.extra_data() + config.extra_data_size());
364 } 637 }
365 DemuxerStream* video_stream = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); 638 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
366 if (video_stream) { 639 if (video_stream) {
367 const media::VideoDecoderConfig& config = 640 const media::VideoDecoderConfig& config =
368 video_stream->video_decoder_config(); 641 video_stream->video_decoder_config();
369 params.video_codec = config.codec(); 642 params.video_codec = config.codec();
370 params.video_size = config.natural_size(); 643 params.video_size = config.natural_size();
371 params.is_video_encrypted = config.is_encrypted(); 644 params.is_video_encrypted = config.is_encrypted();
372 params.video_extra_data = std::vector<uint8>( 645 params.video_extra_data = std::vector<uint8>(
373 config.extra_data(), config.extra_data() + config.extra_data_size()); 646 config.extra_data(), config.extra_data() + config.extra_data_size());
374 } 647 }
375 double duration_ms = chunk_demuxer_->GetDuration() * 1000; 648 params.duration_ms = demuxer_->GetDurationMs();
376 DCHECK(duration_ms >= 0);
377 if (duration_ms > std::numeric_limits<int>::max())
378 duration_ms = std::numeric_limits<int>::max();
379 params.duration_ms = duration_ms;
380 params.key_system = key_system; 649 params.key_system = key_system;
381 650
382 bool ready_to_send = (!params.is_audio_encrypted && 651 bool ready_to_send = (!params.is_audio_encrypted &&
383 !params.is_video_encrypted) || !key_system.empty(); 652 !params.is_video_encrypted) || !key_system.empty();
384 if (proxy_ && ready_to_send) 653 if (proxy_ && ready_to_send)
385 proxy_->DemuxerReady(player_id_, params); 654 proxy_->DemuxerReady(player_id_, params);
386 } 655 }
387 656
388 void MediaSourceDelegate::OnDemuxerOpened() {
389 media_source_->open(new WebMediaSourceClientImpl(
390 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_)));
391 }
392
393 void MediaSourceDelegate::OnKeyError(const std::string& key_system,
394 const std::string& session_id,
395 media::Decryptor::KeyError error_code,
396 int system_code) {
397 client_->keyError(
398 WebString::fromUTF8(key_system),
399 WebString::fromUTF8(session_id),
400 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
401 system_code);
402 }
403
404 void MediaSourceDelegate::OnKeyMessage(const std::string& key_system,
405 const std::string& session_id,
406 const std::string& message,
407 const std::string& default_url) {
408 const GURL default_url_gurl(default_url);
409 DLOG_IF(WARNING, !default_url.empty() && !default_url_gurl.is_valid())
410 << "Invalid URL in default_url: " << default_url;
411
412 client_->keyMessage(WebString::fromUTF8(key_system),
413 WebString::fromUTF8(session_id),
414 reinterpret_cast<const uint8*>(message.data()),
415 message.size(),
416 default_url_gurl);
417 }
418
419 void MediaSourceDelegate::OnKeyAdded(const std::string& key_system,
420 const std::string& session_id) {
421 NotifyDemuxerReady(key_system);
422 client_->keyAdded(WebString::fromUTF8(key_system),
423 WebString::fromUTF8(session_id));
424 }
425
426 void MediaSourceDelegate::OnNeedKey(const std::string& key_system,
427 const std::string& session_id,
428 const std::string& type,
429 scoped_ptr<uint8[]> init_data,
430 int init_data_size) {
431 // Do not fire NeedKey event if encrypted media is not enabled.
432 if (!decryptor_)
433 return;
434
435 CHECK(init_data_size >= 0);
436 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
437 if (init_data_type_.empty())
438 init_data_type_ = type;
439
440 client_->keyNeeded(WebString::fromUTF8(key_system),
441 WebString::fromUTF8(session_id),
442 init_data.get(),
443 init_data_size);
444 }
445
446 void MediaSourceDelegate::OnDecryptorReady(media::Decryptor* decryptor) {}
447
448 } // namespace webkit_media 657 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698