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

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

Issue 15754004: Fix various MediaSource related crashes on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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(
qinmin 2013/05/22 18:51:24 Could there be any chance that message loop is gon
acolwell GONE FROM CHROMIUM 2013/05/22 19:12:09 Done. I added a media_source_delegate_.reset() to
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698