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" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 frame, | 81 frame, |
82 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyAdded), | 82 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyAdded), |
83 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyError), | 83 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyError), |
84 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyMessage), | 84 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnKeyMessage), |
85 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnNeedKey))); | 85 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnNeedKey))); |
86 decryptor_->SetDecryptorReadyCB( | 86 decryptor_->SetDecryptorReadyCB( |
87 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDecryptorReady)); | 87 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDecryptorReady)); |
88 } | 88 } |
89 } | 89 } |
90 | 90 |
91 MediaSourceDelegate::~MediaSourceDelegate() {} | 91 MediaSourceDelegate::~MediaSourceDelegate() { |
| 92 DVLOG(1) << "MediaSourceDelegate::~MediaSourceDelegate() : " << player_id_; |
| 93 DCHECK(!chunk_demuxer_); |
| 94 } |
| 95 |
| 96 void MediaSourceDelegate::Destroy() { |
| 97 DVLOG(1) << "MediaSourceDelegate::Destroy() : " << player_id_; |
| 98 if (!chunk_demuxer_) { |
| 99 delete this; |
| 100 return; |
| 101 } |
| 102 |
| 103 update_network_state_cb_.Reset(); |
| 104 media_source_.reset(); |
| 105 client_ = NULL; |
| 106 proxy_ = NULL; |
| 107 |
| 108 chunk_demuxer_->Stop( |
| 109 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerStopDone)); |
| 110 } |
92 | 111 |
93 void MediaSourceDelegate::Initialize( | 112 void MediaSourceDelegate::Initialize( |
94 WebKit::WebMediaSource* media_source, | 113 WebKit::WebMediaSource* media_source, |
95 const UpdateNetworkStateCB& update_network_state_cb) { | 114 const UpdateNetworkStateCB& update_network_state_cb) { |
96 DCHECK(media_source); | 115 DCHECK(media_source); |
97 media_source_.reset(media_source); | 116 media_source_.reset(media_source); |
98 update_network_state_cb_ = update_network_state_cb; | 117 update_network_state_cb_ = update_network_state_cb; |
99 | 118 |
100 chunk_demuxer_.reset(new media::ChunkDemuxer( | 119 chunk_demuxer_.reset(new media::ChunkDemuxer( |
101 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened), | 120 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened), |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 209 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
191 | 210 |
192 if (current_key_system_.isEmpty() || key_system != current_key_system_) | 211 if (current_key_system_.isEmpty() || key_system != current_key_system_) |
193 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; | 212 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; |
194 | 213 |
195 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); | 214 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); |
196 return WebMediaPlayer::MediaKeyExceptionNoError; | 215 return WebMediaPlayer::MediaKeyExceptionNoError; |
197 } | 216 } |
198 | 217 |
199 void MediaSourceDelegate::Seek(base::TimeDelta time) { | 218 void MediaSourceDelegate::Seek(base::TimeDelta time) { |
| 219 DVLOG(1) << "MediaSourceDelegate::Seek(" << time.InSecondsF() << ") : " |
| 220 << player_id_; |
200 seeking_ = true; | 221 seeking_ = true; |
201 DCHECK(chunk_demuxer_); | 222 DCHECK(chunk_demuxer_); |
202 if (!chunk_demuxer_) | 223 if (!chunk_demuxer_) |
203 return; | 224 return; |
204 chunk_demuxer_->StartWaitingForSeek(); | 225 chunk_demuxer_->StartWaitingForSeek(); |
205 chunk_demuxer_->Seek(time, | 226 chunk_demuxer_->Seek(time, |
206 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError)); | 227 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError)); |
207 } | 228 } |
208 | 229 |
209 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) { | 230 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) { |
210 NOTIMPLEMENTED(); | 231 NOTIMPLEMENTED(); |
211 } | 232 } |
212 | 233 |
213 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) { | 234 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) { |
214 NOTIMPLEMENTED(); | 235 NOTIMPLEMENTED(); |
215 } | 236 } |
216 | 237 |
217 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, | 238 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, |
218 base::TimeDelta end) { | 239 base::TimeDelta end) { |
219 buffered_time_ranges_.Add(start, end); | 240 buffered_time_ranges_.Add(start, end); |
220 } | 241 } |
221 | 242 |
222 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { | 243 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { |
223 // Do nothing | 244 // Do nothing |
224 } | 245 } |
225 | 246 |
226 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type, | 247 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type, |
227 bool seek_done) { | 248 bool seek_done) { |
| 249 DVLOG(1) << "MediaSourceDelegate::OnReadFromDemuxer(" << type |
| 250 << ", " << seek_done << ") : " << player_id_; |
228 if (seeking_ && !seek_done) | 251 if (seeking_ && !seek_done) |
229 return; // Drop the request during seeking. | 252 return; // Drop the request during seeking. |
230 seeking_ = false; | 253 seeking_ = false; |
231 | 254 |
232 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); | 255 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); |
233 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params = | 256 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params = |
234 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get(); | 257 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get(); |
235 params->type = type; | 258 params->type = type; |
236 params->access_units.resize(kAccessUnitSize); | 259 params->access_units.resize(kAccessUnitSize); |
237 DemuxerStream* stream = chunk_demuxer_->GetStream(type); | 260 DemuxerStream* stream = chunk_demuxer_->GetStream(type); |
238 DCHECK(stream != NULL); | 261 DCHECK(stream != NULL); |
239 ReadFromDemuxerStream(stream, params, 0); | 262 ReadFromDemuxerStream(stream, params, 0); |
240 } | 263 } |
241 | 264 |
242 void MediaSourceDelegate::ReadFromDemuxerStream( | 265 void MediaSourceDelegate::ReadFromDemuxerStream( |
243 DemuxerStream* stream, | 266 DemuxerStream* stream, |
244 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, | 267 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, |
245 size_t index) { | 268 size_t index) { |
246 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady, | 269 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady, |
247 stream, params, index)); | 270 stream, params, index)); |
248 } | 271 } |
249 | 272 |
250 void MediaSourceDelegate::OnBufferReady( | 273 void MediaSourceDelegate::OnBufferReady( |
251 DemuxerStream* stream, | 274 DemuxerStream* stream, |
252 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, | 275 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, |
253 size_t index, | 276 size_t index, |
254 DemuxerStream::Status status, | 277 DemuxerStream::Status status, |
255 const scoped_refptr<media::DecoderBuffer>& buffer) { | 278 const scoped_refptr<media::DecoderBuffer>& buffer) { |
| 279 DVLOG(1) << "MediaSourceDelegate::OnBufferReady() : " << player_id_; |
256 DCHECK(status == DemuxerStream::kAborted || | 280 DCHECK(status == DemuxerStream::kAborted || |
257 index < params->access_units.size()); | 281 index < params->access_units.size()); |
258 bool is_audio = stream->type() == DemuxerStream::AUDIO; | 282 bool is_audio = stream->type() == DemuxerStream::AUDIO; |
259 if (status != DemuxerStream::kAborted && | 283 if (status != DemuxerStream::kAborted && |
260 index >= params->access_units.size()) { | 284 index >= params->access_units.size()) { |
261 LOG(ERROR) << "The internal state inconsistency onBufferReady: " | 285 LOG(ERROR) << "The internal state inconsistency onBufferReady: " |
262 << (is_audio ? "Audio" : "Video") << ", index " << index | 286 << (is_audio ? "Audio" : "Video") << ", index " << index |
263 <<", size " << params->access_units.size() | 287 <<", size " << params->access_units.size() |
264 << ", status " << static_cast<int>(status); | 288 << ", status " << static_cast<int>(status); |
265 return; | 289 return; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 NOTREACHED(); | 357 NOTREACHED(); |
334 } | 358 } |
335 | 359 |
336 if (proxy_) | 360 if (proxy_) |
337 proxy_->ReadFromDemuxerAck(player_id_, *params); | 361 proxy_->ReadFromDemuxerAck(player_id_, *params); |
338 params->access_units.resize(0); | 362 params->access_units.resize(0); |
339 } | 363 } |
340 | 364 |
341 void MediaSourceDelegate::OnDemuxerError( | 365 void MediaSourceDelegate::OnDemuxerError( |
342 media::PipelineStatus status) { | 366 media::PipelineStatus status) { |
| 367 DVLOG(1) << "MediaSourceDelegate::OnDemuxerError(" << status << ") : " |
| 368 << player_id_; |
343 if (status != media::PIPELINE_OK) { | 369 if (status != media::PIPELINE_OK) { |
344 DCHECK(status == media::DEMUXER_ERROR_COULD_NOT_OPEN || | 370 DCHECK(status == media::DEMUXER_ERROR_COULD_NOT_OPEN || |
345 status == media::DEMUXER_ERROR_COULD_NOT_PARSE || | 371 status == media::DEMUXER_ERROR_COULD_NOT_PARSE || |
346 status == media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS) | 372 status == media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS) |
347 << "Unexpected error from demuxer: " << static_cast<int>(status); | 373 << "Unexpected error from demuxer: " << static_cast<int>(status); |
348 if (!update_network_state_cb_.is_null()) | 374 if (!update_network_state_cb_.is_null()) |
349 update_network_state_cb_.Run(WebMediaPlayer::NetworkStateFormatError); | 375 update_network_state_cb_.Run(WebMediaPlayer::NetworkStateFormatError); |
350 } | 376 } |
351 } | 377 } |
352 | 378 |
353 void MediaSourceDelegate::OnDemuxerInitDone( | 379 void MediaSourceDelegate::OnDemuxerInitDone( |
354 media::PipelineStatus status) { | 380 media::PipelineStatus status) { |
| 381 DVLOG(1) << "MediaSourceDelegate::OnDemuxerInitDone(" << status << ") : " |
| 382 << player_id_; |
355 if (status != media::PIPELINE_OK) { | 383 if (status != media::PIPELINE_OK) { |
356 OnDemuxerError(status); | 384 OnDemuxerError(status); |
357 return; | 385 return; |
358 } | 386 } |
359 NotifyDemuxerReady(""); | 387 NotifyDemuxerReady(""); |
360 } | 388 } |
361 | 389 |
| 390 void MediaSourceDelegate::OnDemuxerStopDone() { |
| 391 DVLOG(1) << "MediaSourceDelegate::OnDemuxerStopDone() : " << player_id_; |
| 392 chunk_demuxer_.reset(); |
| 393 delete this; |
| 394 } |
| 395 |
362 void MediaSourceDelegate::NotifyDemuxerReady(const std::string& key_system) { | 396 void MediaSourceDelegate::NotifyDemuxerReady(const std::string& key_system) { |
363 MediaPlayerHostMsg_DemuxerReady_Params params; | 397 MediaPlayerHostMsg_DemuxerReady_Params params; |
364 DemuxerStream* audio_stream = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); | 398 DemuxerStream* audio_stream = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); |
365 if (audio_stream) { | 399 if (audio_stream) { |
366 const media::AudioDecoderConfig& config = | 400 const media::AudioDecoderConfig& config = |
367 audio_stream->audio_decoder_config(); | 401 audio_stream->audio_decoder_config(); |
368 params.audio_codec = config.codec(); | 402 params.audio_codec = config.codec(); |
369 params.audio_channels = | 403 params.audio_channels = |
370 media::ChannelLayoutToChannelCount(config.channel_layout()); | 404 media::ChannelLayoutToChannelCount(config.channel_layout()); |
371 params.audio_sampling_rate = config.samples_per_second(); | 405 params.audio_sampling_rate = config.samples_per_second(); |
(...skipping 18 matching lines...) Expand all Loading... |
390 params.duration_ms = duration_ms; | 424 params.duration_ms = duration_ms; |
391 params.key_system = key_system; | 425 params.key_system = key_system; |
392 | 426 |
393 bool ready_to_send = (!params.is_audio_encrypted && | 427 bool ready_to_send = (!params.is_audio_encrypted && |
394 !params.is_video_encrypted) || !key_system.empty(); | 428 !params.is_video_encrypted) || !key_system.empty(); |
395 if (proxy_ && ready_to_send) | 429 if (proxy_ && ready_to_send) |
396 proxy_->DemuxerReady(player_id_, params); | 430 proxy_->DemuxerReady(player_id_, params); |
397 } | 431 } |
398 | 432 |
399 void MediaSourceDelegate::OnDemuxerOpened() { | 433 void MediaSourceDelegate::OnDemuxerOpened() { |
| 434 if (!media_source_) |
| 435 return; |
| 436 |
400 media_source_->open(new WebMediaSourceClientImpl( | 437 media_source_->open(new WebMediaSourceClientImpl( |
401 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); | 438 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); |
402 } | 439 } |
403 | 440 |
404 void MediaSourceDelegate::OnKeyError(const std::string& key_system, | 441 void MediaSourceDelegate::OnKeyError(const std::string& key_system, |
405 const std::string& session_id, | 442 const std::string& session_id, |
406 media::Decryptor::KeyError error_code, | 443 media::Decryptor::KeyError error_code, |
407 int system_code) { | 444 int system_code) { |
| 445 if (!client_) |
| 446 return; |
| 447 |
408 client_->keyError( | 448 client_->keyError( |
409 WebString::fromUTF8(key_system), | 449 WebString::fromUTF8(key_system), |
410 WebString::fromUTF8(session_id), | 450 WebString::fromUTF8(session_id), |
411 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code), | 451 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code), |
412 system_code); | 452 system_code); |
413 } | 453 } |
414 | 454 |
415 void MediaSourceDelegate::OnKeyMessage(const std::string& key_system, | 455 void MediaSourceDelegate::OnKeyMessage(const std::string& key_system, |
416 const std::string& session_id, | 456 const std::string& session_id, |
417 const std::string& message, | 457 const std::string& message, |
418 const std::string& default_url) { | 458 const std::string& default_url) { |
419 const GURL default_url_gurl(default_url); | 459 const GURL default_url_gurl(default_url); |
420 DLOG_IF(WARNING, !default_url.empty() && !default_url_gurl.is_valid()) | 460 DLOG_IF(WARNING, !default_url.empty() && !default_url_gurl.is_valid()) |
421 << "Invalid URL in default_url: " << default_url; | 461 << "Invalid URL in default_url: " << default_url; |
422 | 462 |
| 463 if (!client_) |
| 464 return; |
| 465 |
423 client_->keyMessage(WebString::fromUTF8(key_system), | 466 client_->keyMessage(WebString::fromUTF8(key_system), |
424 WebString::fromUTF8(session_id), | 467 WebString::fromUTF8(session_id), |
425 reinterpret_cast<const uint8*>(message.data()), | 468 reinterpret_cast<const uint8*>(message.data()), |
426 message.size(), | 469 message.size(), |
427 default_url_gurl); | 470 default_url_gurl); |
428 } | 471 } |
429 | 472 |
430 void MediaSourceDelegate::OnKeyAdded(const std::string& key_system, | 473 void MediaSourceDelegate::OnKeyAdded(const std::string& key_system, |
431 const std::string& session_id) { | 474 const std::string& session_id) { |
| 475 if (!client_) |
| 476 return; |
| 477 |
432 NotifyDemuxerReady(key_system); | 478 NotifyDemuxerReady(key_system); |
| 479 |
433 client_->keyAdded(WebString::fromUTF8(key_system), | 480 client_->keyAdded(WebString::fromUTF8(key_system), |
434 WebString::fromUTF8(session_id)); | 481 WebString::fromUTF8(session_id)); |
435 } | 482 } |
436 | 483 |
437 void MediaSourceDelegate::OnNeedKey(const std::string& key_system, | 484 void MediaSourceDelegate::OnNeedKey(const std::string& key_system, |
438 const std::string& session_id, | 485 const std::string& session_id, |
439 const std::string& type, | 486 const std::string& type, |
440 scoped_ptr<uint8[]> init_data, | 487 scoped_ptr<uint8[]> init_data, |
441 int init_data_size) { | 488 int init_data_size) { |
442 // Do not fire NeedKey event if encrypted media is not enabled. | 489 // Do not fire NeedKey event if encrypted media is not enabled. |
443 if (!decryptor_) | 490 if (!client_ || !decryptor_) |
444 return; | 491 return; |
445 | 492 |
446 CHECK(init_data_size >= 0); | 493 CHECK(init_data_size >= 0); |
447 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_); | 494 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_); |
448 if (init_data_type_.empty()) | 495 if (init_data_type_.empty()) |
449 init_data_type_ = type; | 496 init_data_type_ = type; |
450 | 497 |
451 client_->keyNeeded(WebString::fromUTF8(key_system), | 498 client_->keyNeeded(WebString::fromUTF8(key_system), |
452 WebString::fromUTF8(session_id), | 499 WebString::fromUTF8(session_id), |
453 init_data.get(), | 500 init_data.get(), |
454 init_data_size); | 501 init_data_size); |
455 } | 502 } |
456 | 503 |
457 void MediaSourceDelegate::OnDecryptorReady(media::Decryptor* decryptor) {} | 504 void MediaSourceDelegate::OnDecryptorReady(media::Decryptor* decryptor) {} |
458 | 505 |
459 } // namespace webkit_media | 506 } // namespace webkit_media |
OLD | NEW |