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