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 "media/base/android/media_source_player.h" | 5 #include "media/base/android/media_source_player.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 is_video_encrypted_(false), | 56 is_video_encrypted_(false), |
57 volume_(-1.0), | 57 volume_(-1.0), |
58 clock_(&default_tick_clock_), | 58 clock_(&default_tick_clock_), |
59 next_video_data_is_iframe_(true), | 59 next_video_data_is_iframe_(true), |
60 doing_browser_seek_(false), | 60 doing_browser_seek_(false), |
61 pending_seek_(false), | 61 pending_seek_(false), |
62 reconfig_audio_decoder_(false), | 62 reconfig_audio_decoder_(false), |
63 reconfig_video_decoder_(false), | 63 reconfig_video_decoder_(false), |
64 drm_bridge_(NULL), | 64 drm_bridge_(NULL), |
65 is_waiting_for_key_(false), | 65 is_waiting_for_key_(false), |
| 66 has_pending_audio_data_request_(false), |
| 67 has_pending_video_data_request_(false), |
66 weak_factory_(this) { | 68 weak_factory_(this) { |
67 demuxer_->Initialize(this); | 69 demuxer_->Initialize(this); |
68 clock_.SetMaxTime(base::TimeDelta()); | 70 clock_.SetMaxTime(base::TimeDelta()); |
69 } | 71 } |
70 | 72 |
71 MediaSourcePlayer::~MediaSourcePlayer() { | 73 MediaSourcePlayer::~MediaSourcePlayer() { |
72 Release(); | 74 Release(); |
73 } | 75 } |
74 | 76 |
75 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { | 77 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { |
(...skipping 25 matching lines...) Expand all Loading... |
101 // If video config change is already pending, processing of the pending | 103 // If video config change is already pending, processing of the pending |
102 // surface change event will occur in OnDemuxerConfigsAvailable(). | 104 // surface change event will occur in OnDemuxerConfigsAvailable(). |
103 if (reconfig_video_decoder_ && IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) | 105 if (reconfig_video_decoder_ && IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) |
104 return; | 106 return; |
105 | 107 |
106 // Otherwise we need to trigger pending event processing now. | 108 // Otherwise we need to trigger pending event processing now. |
107 ProcessPendingEvents(); | 109 ProcessPendingEvents(); |
108 } | 110 } |
109 | 111 |
110 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding( | 112 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding( |
111 const base::TimeDelta& seek_time) { | 113 base::TimeDelta seek_time) { |
112 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")"; | 114 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")"; |
113 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); | 115 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); |
114 | 116 |
115 pending_seek_ = false; | 117 pending_seek_ = false; |
116 | 118 |
117 clock_.SetTime(seek_time, seek_time); | 119 clock_.SetTime(seek_time, seek_time); |
118 if (audio_timestamp_helper_) | 120 if (audio_timestamp_helper_) |
119 audio_timestamp_helper_->SetBaseTimestamp(seek_time); | 121 audio_timestamp_helper_->SetBaseTimestamp(seek_time); |
120 | 122 |
121 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) | 123 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 } | 174 } |
173 | 175 |
174 int MediaSourcePlayer::GetVideoWidth() { | 176 int MediaSourcePlayer::GetVideoWidth() { |
175 return width_; | 177 return width_; |
176 } | 178 } |
177 | 179 |
178 int MediaSourcePlayer::GetVideoHeight() { | 180 int MediaSourcePlayer::GetVideoHeight() { |
179 return height_; | 181 return height_; |
180 } | 182 } |
181 | 183 |
182 void MediaSourcePlayer::SeekTo(const base::TimeDelta& timestamp) { | 184 void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) { |
183 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; | 185 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; |
184 | 186 |
185 if (IsEventPending(SEEK_EVENT_PENDING)) { | 187 if (IsEventPending(SEEK_EVENT_PENDING)) { |
186 DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress"; | 188 DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress"; |
187 DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek"; | 189 DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek"; |
188 | 190 |
189 // There is a browser seek currently in progress to obtain I-frame to feed | 191 // There is a browser seek currently in progress to obtain I-frame to feed |
190 // a newly constructed video decoder. Remember this real seek request so | 192 // a newly constructed video decoder. Remember this real seek request so |
191 // it can be initiated once OnDemuxerSeekDone() occurs for the browser seek. | 193 // it can be initiated once OnDemuxerSeekDone() occurs for the browser seek. |
192 pending_seek_ = true; | 194 pending_seek_ = true; |
(...skipping 24 matching lines...) Expand all Loading... |
217 // or drop data received across Release()+Start(). See http://crbug.com/306314 | 219 // or drop data received across Release()+Start(). See http://crbug.com/306314 |
218 // and http://crbug.com/304234. | 220 // and http://crbug.com/304234. |
219 bool process_pending_events = false; | 221 bool process_pending_events = false; |
220 process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) || | 222 process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) || |
221 (audio_decoder_job_ && audio_decoder_job_->is_decoding()) || | 223 (audio_decoder_job_ && audio_decoder_job_->is_decoding()) || |
222 (video_decoder_job_ && video_decoder_job_->is_decoding()); | 224 (video_decoder_job_ && video_decoder_job_->is_decoding()); |
223 | 225 |
224 // Clear all the pending events except seeks and config changes. | 226 // Clear all the pending events except seeks and config changes. |
225 pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING); | 227 pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING); |
226 is_surface_in_use_ = false; | 228 is_surface_in_use_ = false; |
227 audio_decoder_job_.reset(); | 229 ResetAudioDecoderJob(); |
228 ResetVideoDecoderJob(); | 230 ResetVideoDecoderJob(); |
229 | 231 |
230 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable() | 232 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable() |
231 reconfig_audio_decoder_ = false; | 233 reconfig_audio_decoder_ = false; |
232 reconfig_video_decoder_ = false; | 234 reconfig_video_decoder_ = false; |
233 | 235 |
234 // Prevent player restart, including job re-creation attempts. | 236 // Prevent player restart, including job re-creation attempts. |
235 playing_ = false; | 237 playing_ = false; |
236 | 238 |
237 decoder_starvation_callback_.Cancel(); | 239 decoder_starvation_callback_.Cancel(); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 342 |
341 // Resume decoding after the config change if we are still playing. | 343 // Resume decoding after the config change if we are still playing. |
342 if (playing_) | 344 if (playing_) |
343 StartInternal(); | 345 StartInternal(); |
344 } | 346 } |
345 } | 347 } |
346 | 348 |
347 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) { | 349 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) { |
348 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")"; | 350 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")"; |
349 DCHECK_LT(0u, data.access_units.size()); | 351 DCHECK_LT(0u, data.access_units.size()); |
| 352 |
| 353 if (has_pending_audio_data_request_ && data.type == DemuxerStream::AUDIO) { |
| 354 has_pending_audio_data_request_ = false; |
| 355 ProcessPendingEvents(); |
| 356 return; |
| 357 } |
| 358 |
| 359 if (has_pending_video_data_request_ && data.type == DemuxerStream::VIDEO) { |
| 360 next_video_data_is_iframe_ = false; |
| 361 has_pending_video_data_request_ = false; |
| 362 ProcessPendingEvents(); |
| 363 return; |
| 364 } |
| 365 |
350 if (data.type == DemuxerStream::AUDIO && audio_decoder_job_) { | 366 if (data.type == DemuxerStream::AUDIO && audio_decoder_job_) { |
351 audio_decoder_job_->OnDataReceived(data); | 367 audio_decoder_job_->OnDataReceived(data); |
352 } else if (data.type == DemuxerStream::VIDEO) { | 368 } else if (data.type == DemuxerStream::VIDEO) { |
353 next_video_data_is_iframe_ = false; | 369 next_video_data_is_iframe_ = false; |
354 if (video_decoder_job_) | 370 if (video_decoder_job_) |
355 video_decoder_job_->OnDataReceived(data); | 371 video_decoder_job_->OnDataReceived(data); |
356 } | 372 } |
357 } | 373 } |
358 | 374 |
359 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) { | 375 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( | 408 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( |
393 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr())); | 409 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr())); |
394 return; | 410 return; |
395 } | 411 } |
396 | 412 |
397 if (playing_) | 413 if (playing_) |
398 StartInternal(); | 414 StartInternal(); |
399 } | 415 } |
400 | 416 |
401 void MediaSourcePlayer::OnDemuxerSeekDone( | 417 void MediaSourcePlayer::OnDemuxerSeekDone( |
402 const base::TimeDelta& actual_browser_seek_time) { | 418 base::TimeDelta actual_browser_seek_time) { |
403 DVLOG(1) << __FUNCTION__; | 419 DVLOG(1) << __FUNCTION__; |
404 | 420 |
405 ClearPendingEvent(SEEK_EVENT_PENDING); | 421 ClearPendingEvent(SEEK_EVENT_PENDING); |
406 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) | 422 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) |
407 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); | 423 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); |
408 | 424 |
409 next_video_data_is_iframe_ = true; | 425 next_video_data_is_iframe_ = true; |
410 | 426 |
411 if (pending_seek_) { | 427 if (pending_seek_) { |
412 DVLOG(1) << __FUNCTION__ << "processing pending seek"; | 428 DVLOG(1) << __FUNCTION__ << "processing pending seek"; |
413 DCHECK(doing_browser_seek_); | 429 DCHECK(doing_browser_seek_); |
414 pending_seek_ = false; | 430 pending_seek_ = false; |
415 SeekTo(pending_seek_time_); | 431 SeekTo(pending_seek_time_); |
416 return; | 432 return; |
417 } | 433 } |
418 | 434 |
419 // It is possible that a browser seek to I-frame had to seek to a buffered | 435 // It is possible that a browser seek to I-frame had to seek to a buffered |
420 // I-frame later than the requested one due to data removal or GC. Update | 436 // I-frame later than the requested one due to data removal or GC. Update |
421 // player clock to the actual seek target. | 437 // player clock to the actual seek target. |
422 if (doing_browser_seek_) { | 438 if (doing_browser_seek_) { |
423 DCHECK(actual_browser_seek_time != kNoTimestamp()); | 439 DCHECK(actual_browser_seek_time != kNoTimestamp()); |
| 440 base::TimeDelta seek_time = actual_browser_seek_time; |
424 // A browser seek must not jump into the past. Ideally, it seeks to the | 441 // A browser seek must not jump into the past. Ideally, it seeks to the |
425 // requested time, but it might jump into the future. | 442 // requested time, but it might jump into the future. |
426 DCHECK(actual_browser_seek_time >= GetCurrentTime()); | 443 DCHECK(seek_time >= GetCurrentTime()); |
427 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " | 444 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " |
428 << actual_browser_seek_time.InSecondsF(); | 445 << seek_time.InSecondsF(); |
429 clock_.SetTime(actual_browser_seek_time, actual_browser_seek_time); | 446 clock_.SetTime(seek_time, seek_time); |
430 if (audio_timestamp_helper_) | 447 if (audio_timestamp_helper_) |
431 audio_timestamp_helper_->SetBaseTimestamp(actual_browser_seek_time); | 448 audio_timestamp_helper_->SetBaseTimestamp(seek_time); |
| 449 } else { |
| 450 DCHECK(actual_browser_seek_time == kNoTimestamp()); |
432 } | 451 } |
433 | 452 |
434 reached_audio_eos_ = false; | 453 reached_audio_eos_ = false; |
435 reached_video_eos_ = false; | 454 reached_video_eos_ = false; |
436 | 455 |
437 base::TimeDelta current_time = GetCurrentTime(); | 456 base::TimeDelta current_time = GetCurrentTime(); |
438 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| | 457 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| |
439 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| | 458 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| |
440 // is calculated from decoder output, while preroll relies on the access | 459 // is calculated from decoder output, while preroll relies on the access |
441 // unit's timestamp. There are some differences between the two. | 460 // unit's timestamp. There are some differences between the two. |
442 preroll_timestamp_ = current_time; | 461 preroll_timestamp_ = current_time; |
443 if (audio_decoder_job_) | 462 if (audio_decoder_job_) |
444 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); | 463 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); |
445 if (video_decoder_job_) | 464 if (video_decoder_job_) |
446 video_decoder_job_->BeginPrerolling(preroll_timestamp_); | 465 video_decoder_job_->BeginPrerolling(preroll_timestamp_); |
447 | 466 |
448 if (!doing_browser_seek_) | 467 if (!doing_browser_seek_) |
449 manager()->OnSeekComplete(player_id(), current_time); | 468 manager()->OnSeekComplete(player_id(), current_time); |
450 | 469 |
451 ProcessPendingEvents(); | 470 ProcessPendingEvents(); |
452 } | 471 } |
453 | 472 |
454 void MediaSourcePlayer::UpdateTimestamps( | 473 void MediaSourcePlayer::UpdateTimestamps( |
455 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { | 474 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) { |
456 base::TimeDelta new_max_time = presentation_timestamp; | 475 base::TimeDelta new_max_time = presentation_timestamp; |
457 | 476 |
458 if (audio_output_bytes > 0) { | 477 if (audio_output_bytes > 0) { |
459 audio_timestamp_helper_->AddFrames( | 478 audio_timestamp_helper_->AddFrames( |
460 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); | 479 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); |
461 new_max_time = audio_timestamp_helper_->GetTimestamp(); | 480 new_max_time = audio_timestamp_helper_->GetTimestamp(); |
462 } | 481 } |
463 | 482 |
464 clock_.SetMaxTime(new_max_time); | 483 clock_.SetMaxTime(new_max_time); |
465 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); | 484 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); |
466 } | 485 } |
467 | 486 |
468 void MediaSourcePlayer::ProcessPendingEvents() { | 487 void MediaSourcePlayer::ProcessPendingEvents() { |
469 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; | 488 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; |
470 // Wait for all the decoding jobs to finish before processing pending tasks. | 489 // Wait for all the decoding jobs to finish before processing pending tasks. |
471 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { | 490 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { |
472 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; | 491 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; |
473 return; | 492 return; |
474 } | 493 } |
475 | 494 |
476 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) { | 495 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) { |
477 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding."; | 496 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding."; |
478 return; | 497 return; |
479 } | 498 } |
480 | 499 |
| 500 if (has_pending_audio_data_request_ || has_pending_video_data_request_) { |
| 501 DVLOG(1) << __FUNCTION__ << " : has pending data request."; |
| 502 return; |
| 503 } |
| 504 |
481 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { | 505 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { |
482 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; | 506 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; |
483 return; | 507 return; |
484 } | 508 } |
485 | 509 |
486 if (IsEventPending(SEEK_EVENT_PENDING)) { | 510 if (IsEventPending(SEEK_EVENT_PENDING)) { |
487 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT"; | 511 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT"; |
488 ClearDecodingData(); | 512 ClearDecodingData(); |
489 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_); | 513 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_); |
490 return; | 514 return; |
(...skipping 14 matching lines...) Expand all Loading... |
505 ConfigureVideoDecoderJob(); | 529 ConfigureVideoDecoderJob(); |
506 | 530 |
507 // Return early if we can't successfully configure a new video decoder job | 531 // Return early if we can't successfully configure a new video decoder job |
508 // yet. | 532 // yet. |
509 if (HasVideo() && !video_decoder_job_) | 533 if (HasVideo() && !video_decoder_job_) |
510 return; | 534 return; |
511 } | 535 } |
512 | 536 |
513 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { | 537 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { |
514 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT."; | 538 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT."; |
| 539 // If one of the decoder is not initialized, cancel this event as it will be |
| 540 // called later when Start() is called again. |
| 541 if ((HasVideo() && !video_decoder_job_) || |
| 542 (HasAudio() && !audio_decoder_job_)) { |
| 543 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); |
| 544 return; |
| 545 } |
| 546 |
515 DCHECK(audio_decoder_job_ || AudioFinished()); | 547 DCHECK(audio_decoder_job_ || AudioFinished()); |
516 DCHECK(video_decoder_job_ || VideoFinished()); | 548 DCHECK(video_decoder_job_ || VideoFinished()); |
517 | 549 |
518 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); | 550 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); |
519 | 551 |
520 // It is possible that all streams have finished decode, yet starvation | 552 // It is possible that all streams have finished decode, yet starvation |
521 // occurred during the last stream's EOS decode. In this case, prefetch is a | 553 // occurred during the last stream's EOS decode. In this case, prefetch is a |
522 // no-op. | 554 // no-op. |
523 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); | 555 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); |
524 if (count == 0) | 556 if (count == 0) |
(...skipping 17 matching lines...) Expand all Loading... |
542 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); | 574 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); |
543 | 575 |
544 // Now that all pending events have been handled, resume decoding if we are | 576 // Now that all pending events have been handled, resume decoding if we are |
545 // still playing. | 577 // still playing. |
546 if (playing_) | 578 if (playing_) |
547 StartInternal(); | 579 StartInternal(); |
548 } | 580 } |
549 | 581 |
550 void MediaSourcePlayer::MediaDecoderCallback( | 582 void MediaSourcePlayer::MediaDecoderCallback( |
551 bool is_audio, MediaCodecStatus status, | 583 bool is_audio, MediaCodecStatus status, |
552 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { | 584 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) { |
553 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; | 585 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; |
554 | 586 |
555 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed. | 587 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed. |
556 if (is_audio) { | 588 if (is_audio) { |
557 TRACE_EVENT_ASYNC_END1("media", | 589 TRACE_EVENT_ASYNC_END1("media", |
558 "MediaSourcePlayer::DecodeMoreAudio", | 590 "MediaSourcePlayer::DecodeMoreAudio", |
559 audio_decoder_job_.get(), | 591 audio_decoder_job_.get(), |
560 "MediaCodecStatus", | 592 "MediaCodecStatus", |
561 base::IntToString(status)); | 593 base::IntToString(status)); |
562 } else { | 594 } else { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 bool MediaSourcePlayer::AudioFinished() { | 780 bool MediaSourcePlayer::AudioFinished() { |
749 return reached_audio_eos_ || !HasAudio(); | 781 return reached_audio_eos_ || !HasAudio(); |
750 } | 782 } |
751 | 783 |
752 bool MediaSourcePlayer::VideoFinished() { | 784 bool MediaSourcePlayer::VideoFinished() { |
753 return reached_video_eos_ || !HasVideo(); | 785 return reached_video_eos_ || !HasVideo(); |
754 } | 786 } |
755 | 787 |
756 void MediaSourcePlayer::ConfigureAudioDecoderJob() { | 788 void MediaSourcePlayer::ConfigureAudioDecoderJob() { |
757 if (!HasAudio()) { | 789 if (!HasAudio()) { |
758 audio_decoder_job_.reset(); | 790 ResetAudioDecoderJob(); |
759 return; | 791 return; |
760 } | 792 } |
761 | 793 |
762 // Create audio decoder job only if config changes. | 794 // Create audio decoder job only if config changes. |
763 if (audio_decoder_job_ && !reconfig_audio_decoder_) | 795 if (audio_decoder_job_ && !reconfig_audio_decoder_) |
764 return; | 796 return; |
765 | 797 |
766 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto(); | 798 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto(); |
767 if (is_audio_encrypted_ && media_crypto.is_null()) | 799 if (is_audio_encrypted_ && media_crypto.is_null()) |
768 return; | 800 return; |
769 | 801 |
770 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); | 802 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); |
771 | 803 |
| 804 ResetAudioDecoderJob(); |
772 DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job"; | 805 DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job"; |
773 | |
774 audio_decoder_job_.reset(AudioDecoderJob::Create( | 806 audio_decoder_job_.reset(AudioDecoderJob::Create( |
775 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0], | 807 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0], |
776 audio_extra_data_.size(), media_crypto.obj(), | 808 audio_extra_data_.size(), media_crypto.obj(), |
777 base::Bind(&DemuxerAndroid::RequestDemuxerData, | 809 base::Bind(&DemuxerAndroid::RequestDemuxerData, |
778 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO))); | 810 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO))); |
779 | 811 |
780 if (audio_decoder_job_) { | 812 if (audio_decoder_job_) { |
781 SetVolumeInternal(); | 813 SetVolumeInternal(); |
782 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); | 814 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); |
783 reconfig_audio_decoder_ = false; | 815 reconfig_audio_decoder_ = false; |
784 } | 816 } |
785 } | 817 } |
786 | 818 |
787 void MediaSourcePlayer::ResetVideoDecoderJob() { | 819 void MediaSourcePlayer::ResetVideoDecoderJob() { |
| 820 if (video_decoder_job_) { |
| 821 has_pending_video_data_request_ = |
| 822 video_decoder_job_->is_requesting_demuxer_data(); |
| 823 } |
788 video_decoder_job_.reset(); | 824 video_decoder_job_.reset(); |
789 | 825 |
790 // Any eventual video decoder job re-creation will use the current |surface_|. | 826 // Any eventual video decoder job re-creation will use the current |surface_|. |
791 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) | 827 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) |
792 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); | 828 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); |
793 } | 829 } |
794 | 830 |
| 831 void MediaSourcePlayer::ResetAudioDecoderJob() { |
| 832 if (audio_decoder_job_) { |
| 833 has_pending_audio_data_request_ = |
| 834 audio_decoder_job_->is_requesting_demuxer_data(); |
| 835 } |
| 836 audio_decoder_job_.reset(); |
| 837 } |
| 838 |
795 void MediaSourcePlayer::ConfigureVideoDecoderJob() { | 839 void MediaSourcePlayer::ConfigureVideoDecoderJob() { |
796 if (!HasVideo() || surface_.IsEmpty()) { | 840 if (!HasVideo() || surface_.IsEmpty()) { |
797 ResetVideoDecoderJob(); | 841 ResetVideoDecoderJob(); |
798 return; | 842 return; |
799 } | 843 } |
800 | 844 |
801 // Create video decoder job only if config changes or we don't have a job. | 845 // Create video decoder job only if config changes or we don't have a job. |
802 if (video_decoder_job_ && !reconfig_video_decoder_) { | 846 if (video_decoder_job_ && !reconfig_video_decoder_) { |
803 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING)); | 847 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING)); |
804 return; | 848 return; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 player_id(), duration_, width_, height_, true); | 905 player_id(), duration_, width_, height_, true); |
862 } | 906 } |
863 | 907 |
864 void MediaSourcePlayer::OnDecoderStarved() { | 908 void MediaSourcePlayer::OnDecoderStarved() { |
865 DVLOG(1) << __FUNCTION__; | 909 DVLOG(1) << __FUNCTION__; |
866 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); | 910 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); |
867 ProcessPendingEvents(); | 911 ProcessPendingEvents(); |
868 } | 912 } |
869 | 913 |
870 void MediaSourcePlayer::StartStarvationCallback( | 914 void MediaSourcePlayer::StartStarvationCallback( |
871 const base::TimeDelta& presentation_timestamp) { | 915 base::TimeDelta presentation_timestamp) { |
872 // 20ms was chosen because it is the typical size of a compressed audio frame. | 916 // 20ms was chosen because it is the typical size of a compressed audio frame. |
873 // Anything smaller than this would likely cause unnecessary cycling in and | 917 // Anything smaller than this would likely cause unnecessary cycling in and |
874 // out of the prefetch state. | 918 // out of the prefetch state. |
875 const base::TimeDelta kMinStarvationTimeout = | 919 const base::TimeDelta kMinStarvationTimeout = |
876 base::TimeDelta::FromMilliseconds(20); | 920 base::TimeDelta::FromMilliseconds(20); |
877 | 921 |
878 base::TimeDelta current_timestamp = GetCurrentTime(); | 922 base::TimeDelta current_timestamp = GetCurrentTime(); |
879 base::TimeDelta timeout; | 923 base::TimeDelta timeout; |
880 if (HasAudio()) { | 924 if (HasAudio()) { |
881 timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp; | 925 timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 | 1019 |
976 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { | 1020 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { |
977 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; | 1021 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; |
978 DCHECK_NE(event, NO_EVENT_PENDING); | 1022 DCHECK_NE(event, NO_EVENT_PENDING); |
979 DCHECK(IsEventPending(event)) << GetEventName(event); | 1023 DCHECK(IsEventPending(event)) << GetEventName(event); |
980 | 1024 |
981 pending_event_ &= ~event; | 1025 pending_event_ &= ~event; |
982 } | 1026 } |
983 | 1027 |
984 } // namespace media | 1028 } // namespace media |
OLD | NEW |