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

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

Issue 15898002: Fix various MediaSource related crashes on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make Destroy() public and remove friend decl to make compiler happy 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"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « webkit/media/android/media_source_delegate.h ('k') | webkit/media/android/webmediaplayer_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698