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

Side by Side Diff: media/base/android/media_source_player.cc

Issue 196133020: Reducing the IPC latency for MSE video decoding (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix clang warning Created 6 years, 9 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 | Annotate | Revision Log
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 "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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.h ('k') | media/base/android/media_source_player_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698