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

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

Powered by Google App Engine
This is Rietveld 408576698