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

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);
366
367
wolenetz 2014/03/18 21:14:47 nit: remove extra lines (both of these)
qinmin 2014/03/19 02:45:22 Done.
350 } else if (data.type == DemuxerStream::VIDEO) { 368 } else if (data.type == DemuxerStream::VIDEO) {
351 next_video_data_is_iframe_ = false; 369 next_video_data_is_iframe_ = false;
352 if (video_decoder_job_) 370 if (video_decoder_job_)
353 video_decoder_job_->OnDataReceived(data); 371 video_decoder_job_->OnDataReceived(data);
354 } 372 }
355 } 373 }
356 374
357 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) { 375 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
358 duration_ = duration; 376 duration_ = duration;
359 clock_.SetDuration(duration_); 377 clock_.SetDuration(duration_);
(...skipping 30 matching lines...) Expand all
390 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( 408 drm_bridge_->SetMediaCryptoReadyCB(base::Bind(
391 &MediaSourcePlayer::OnMediaCryptoReady, weak_this_.GetWeakPtr())); 409 &MediaSourcePlayer::OnMediaCryptoReady, weak_this_.GetWeakPtr()));
392 return; 410 return;
393 } 411 }
394 412
395 if (playing_) 413 if (playing_)
396 StartInternal(); 414 StartInternal();
397 } 415 }
398 416
399 void MediaSourcePlayer::OnDemuxerSeekDone( 417 void MediaSourcePlayer::OnDemuxerSeekDone(
400 const base::TimeDelta& actual_browser_seek_time) { 418 base::TimeDelta actual_browser_seek_time) {
401 DVLOG(1) << __FUNCTION__; 419 DVLOG(1) << __FUNCTION__;
402 420
403 ClearPendingEvent(SEEK_EVENT_PENDING); 421 ClearPendingEvent(SEEK_EVENT_PENDING);
404 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) 422 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING))
405 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 423 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
406 424
407 next_video_data_is_iframe_ = true; 425 next_video_data_is_iframe_ = true;
408 426
409 if (pending_seek_) { 427 if (pending_seek_) {
410 DVLOG(1) << __FUNCTION__ << "processing pending seek"; 428 DVLOG(1) << __FUNCTION__ << "processing pending seek";
411 DCHECK(doing_browser_seek_); 429 DCHECK(doing_browser_seek_);
412 pending_seek_ = false; 430 pending_seek_ = false;
413 SeekTo(pending_seek_time_); 431 SeekTo(pending_seek_time_);
414 return; 432 return;
415 } 433 }
416 434
417 // 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
418 // 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
419 // player clock to the actual seek target. 437 // player clock to the actual seek target.
420 if (doing_browser_seek_) { 438 if (doing_browser_seek_) {
421 DCHECK(actual_browser_seek_time != kNoTimestamp()); 439 base::TimeDelta seek_time = (actual_browser_seek_time == kNoTimestamp()) ?
wolenetz 2014/03/18 21:14:47 See also comment in unit tests. Why are we now all
qinmin 2014/03/19 02:45:22 I saw the kNoTimestamp() in unit tests and it make
440 base::TimeDelta() : actual_browser_seek_time;
422 // 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
423 // requested time, but it might jump into the future. 442 // requested time, but it might jump into the future.
424 DCHECK(actual_browser_seek_time >= GetCurrentTime()); 443 DCHECK(seek_time >= GetCurrentTime());
425 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " 444 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
426 << actual_browser_seek_time.InSecondsF(); 445 << seek_time.InSecondsF();
427 clock_.SetTime(actual_browser_seek_time, actual_browser_seek_time); 446 clock_.SetTime(seek_time, seek_time);
428 if (audio_timestamp_helper_) 447 if (audio_timestamp_helper_)
429 audio_timestamp_helper_->SetBaseTimestamp(actual_browser_seek_time); 448 audio_timestamp_helper_->SetBaseTimestamp(seek_time);
430 } 449 }
431 450
432 reached_audio_eos_ = false; 451 reached_audio_eos_ = false;
433 reached_video_eos_ = false; 452 reached_video_eos_ = false;
434 453
435 base::TimeDelta current_time = GetCurrentTime(); 454 base::TimeDelta current_time = GetCurrentTime();
436 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| 455 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
437 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| 456 // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
438 // is calculated from decoder output, while preroll relies on the access 457 // is calculated from decoder output, while preroll relies on the access
439 // unit's timestamp. There are some differences between the two. 458 // unit's timestamp. There are some differences between the two.
440 preroll_timestamp_ = current_time; 459 preroll_timestamp_ = current_time;
441 if (audio_decoder_job_) 460 if (audio_decoder_job_)
442 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 461 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
443 if (video_decoder_job_) 462 if (video_decoder_job_)
444 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 463 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
445 464
446 if (!doing_browser_seek_) 465 if (!doing_browser_seek_)
447 manager()->OnSeekComplete(player_id(), current_time); 466 manager()->OnSeekComplete(player_id(), current_time);
448 467
449 ProcessPendingEvents(); 468 ProcessPendingEvents();
450 } 469 }
451 470
452 void MediaSourcePlayer::UpdateTimestamps( 471 void MediaSourcePlayer::UpdateTimestamps(
453 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { 472 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) {
454 base::TimeDelta new_max_time = presentation_timestamp; 473 base::TimeDelta new_max_time = presentation_timestamp;
455 474
456 if (audio_output_bytes > 0) { 475 if (audio_output_bytes > 0) {
457 audio_timestamp_helper_->AddFrames( 476 audio_timestamp_helper_->AddFrames(
458 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); 477 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_));
459 new_max_time = audio_timestamp_helper_->GetTimestamp(); 478 new_max_time = audio_timestamp_helper_->GetTimestamp();
460 } 479 }
461 480
462 clock_.SetMaxTime(new_max_time); 481 clock_.SetMaxTime(new_max_time);
463 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); 482 manager()->OnTimeUpdate(player_id(), GetCurrentTime());
464 } 483 }
465 484
466 void MediaSourcePlayer::ProcessPendingEvents() { 485 void MediaSourcePlayer::ProcessPendingEvents() {
467 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; 486 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
468 // Wait for all the decoding jobs to finish before processing pending tasks. 487 // Wait for all the decoding jobs to finish before processing pending tasks.
469 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { 488 if (video_decoder_job_ && video_decoder_job_->is_decoding()) {
470 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; 489 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
471 return; 490 return;
472 } 491 }
473 492
474 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) { 493 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) {
475 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding."; 494 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
476 return; 495 return;
477 } 496 }
478 497
498 if (has_pending_audio_data_request_ || has_pending_video_data_request_) {
499 DVLOG(1) << __FUNCTION__ << " : has pending data request.";
500 return;
501 }
502
479 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { 503 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
480 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; 504 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
481 return; 505 return;
482 } 506 }
483 507
484 if (IsEventPending(SEEK_EVENT_PENDING)) { 508 if (IsEventPending(SEEK_EVENT_PENDING)) {
485 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT"; 509 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
486 ClearDecodingData(); 510 ClearDecodingData();
487 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_); 511 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
488 return; 512 return;
(...skipping 14 matching lines...) Expand all
503 ConfigureVideoDecoderJob(); 527 ConfigureVideoDecoderJob();
504 528
505 // Return early if we can't successfully configure a new video decoder job 529 // Return early if we can't successfully configure a new video decoder job
506 // yet. 530 // yet.
507 if (HasVideo() && !video_decoder_job_) 531 if (HasVideo() && !video_decoder_job_)
508 return; 532 return;
509 } 533 }
510 534
511 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { 535 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
512 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT."; 536 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
537 // If one of the decoder is not initialized, cancel this event as it will be
538 // called later when Start() is called again.
539 if ((HasVideo() && !video_decoder_job_) ||
540 (HasAudio() && !audio_decoder_job_)) {
541 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
542 return;
543 }
544
513 DCHECK(audio_decoder_job_ || AudioFinished()); 545 DCHECK(audio_decoder_job_ || AudioFinished());
514 DCHECK(video_decoder_job_ || VideoFinished()); 546 DCHECK(video_decoder_job_ || VideoFinished());
515 547
516 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); 548 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
517 549
518 // It is possible that all streams have finished decode, yet starvation 550 // 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 551 // occurred during the last stream's EOS decode. In this case, prefetch is a
520 // no-op. 552 // no-op.
521 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 553 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
522 if (count == 0) 554 if (count == 0)
(...skipping 15 matching lines...) Expand all
538 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); 570 DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
539 571
540 // Now that all pending events have been handled, resume decoding if we are 572 // Now that all pending events have been handled, resume decoding if we are
541 // still playing. 573 // still playing.
542 if (playing_) 574 if (playing_)
543 StartInternal(); 575 StartInternal();
544 } 576 }
545 577
546 void MediaSourcePlayer::MediaDecoderCallback( 578 void MediaSourcePlayer::MediaDecoderCallback(
547 bool is_audio, MediaCodecStatus status, 579 bool is_audio, MediaCodecStatus status,
548 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { 580 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) {
549 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; 581 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status;
550 582
551 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed. 583 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed.
552 if (is_audio) { 584 if (is_audio) {
553 TRACE_EVENT_ASYNC_END1("media", 585 TRACE_EVENT_ASYNC_END1("media",
554 "MediaSourcePlayer::DecodeMoreAudio", 586 "MediaSourcePlayer::DecodeMoreAudio",
555 audio_decoder_job_.get(), 587 audio_decoder_job_.get(),
556 "MediaCodecStatus", 588 "MediaCodecStatus",
557 base::IntToString(status)); 589 base::IntToString(status));
558 } else { 590 } else {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 bool MediaSourcePlayer::AudioFinished() { 772 bool MediaSourcePlayer::AudioFinished() {
741 return reached_audio_eos_ || !HasAudio(); 773 return reached_audio_eos_ || !HasAudio();
742 } 774 }
743 775
744 bool MediaSourcePlayer::VideoFinished() { 776 bool MediaSourcePlayer::VideoFinished() {
745 return reached_video_eos_ || !HasVideo(); 777 return reached_video_eos_ || !HasVideo();
746 } 778 }
747 779
748 void MediaSourcePlayer::ConfigureAudioDecoderJob() { 780 void MediaSourcePlayer::ConfigureAudioDecoderJob() {
749 if (!HasAudio()) { 781 if (!HasAudio()) {
750 audio_decoder_job_.reset(); 782 ResetAudioDecoderJob();
751 return; 783 return;
752 } 784 }
753 785
754 // Create audio decoder job only if config changes. 786 // Create audio decoder job only if config changes.
755 if (audio_decoder_job_ && !reconfig_audio_decoder_) 787 if (audio_decoder_job_ && !reconfig_audio_decoder_)
756 return; 788 return;
757 789
758 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto(); 790 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
759 if (is_audio_encrypted_ && media_crypto.is_null()) 791 if (is_audio_encrypted_ && media_crypto.is_null())
760 return; 792 return;
761 793
762 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); 794 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
763 795
796 ResetAudioDecoderJob();
764 DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job"; 797 DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job";
765
766 audio_decoder_job_.reset(AudioDecoderJob::Create( 798 audio_decoder_job_.reset(AudioDecoderJob::Create(
767 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0], 799 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
768 audio_extra_data_.size(), media_crypto.obj(), 800 audio_extra_data_.size(), media_crypto.obj(),
769 base::Bind(&DemuxerAndroid::RequestDemuxerData, 801 base::Bind(&DemuxerAndroid::RequestDemuxerData,
770 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO))); 802 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
771 803
772 if (audio_decoder_job_) { 804 if (audio_decoder_job_) {
773 SetVolumeInternal(); 805 SetVolumeInternal();
774 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 806 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
775 reconfig_audio_decoder_ = false; 807 reconfig_audio_decoder_ = false;
776 } 808 }
777 } 809 }
778 810
779 void MediaSourcePlayer::ResetVideoDecoderJob() { 811 void MediaSourcePlayer::ResetVideoDecoderJob() {
812 if (video_decoder_job_) {
813 has_pending_video_data_request_ =
814 video_decoder_job_->is_requesting_demuxer_data();
815 }
780 video_decoder_job_.reset(); 816 video_decoder_job_.reset();
781 817
782 // Any eventual video decoder job re-creation will use the current |surface_|. 818 // Any eventual video decoder job re-creation will use the current |surface_|.
783 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) 819 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
784 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING); 820 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
785 } 821 }
786 822
823 void MediaSourcePlayer::ResetAudioDecoderJob() {
824 if (audio_decoder_job_) {
825 has_pending_audio_data_request_ =
826 audio_decoder_job_->is_requesting_demuxer_data();
827 }
828 audio_decoder_job_.reset();
829 }
830
787 void MediaSourcePlayer::ConfigureVideoDecoderJob() { 831 void MediaSourcePlayer::ConfigureVideoDecoderJob() {
788 if (!HasVideo() || surface_.IsEmpty()) { 832 if (!HasVideo() || surface_.IsEmpty()) {
789 ResetVideoDecoderJob(); 833 ResetVideoDecoderJob();
790 return; 834 return;
791 } 835 }
792 836
793 // Create video decoder job only if config changes or we don't have a job. 837 // Create video decoder job only if config changes or we don't have a job.
794 if (video_decoder_job_ && !reconfig_video_decoder_) { 838 if (video_decoder_job_ && !reconfig_video_decoder_) {
795 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING)); 839 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING));
796 return; 840 return;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 player_id(), duration_, width_, height_, true); 897 player_id(), duration_, width_, height_, true);
854 } 898 }
855 899
856 void MediaSourcePlayer::OnDecoderStarved() { 900 void MediaSourcePlayer::OnDecoderStarved() {
857 DVLOG(1) << __FUNCTION__; 901 DVLOG(1) << __FUNCTION__;
858 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 902 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
859 ProcessPendingEvents(); 903 ProcessPendingEvents();
860 } 904 }
861 905
862 void MediaSourcePlayer::StartStarvationCallback( 906 void MediaSourcePlayer::StartStarvationCallback(
863 const base::TimeDelta& presentation_timestamp) { 907 base::TimeDelta presentation_timestamp) {
864 // 20ms was chosen because it is the typical size of a compressed audio frame. 908 // 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 909 // Anything smaller than this would likely cause unnecessary cycling in and
866 // out of the prefetch state. 910 // out of the prefetch state.
867 const base::TimeDelta kMinStarvationTimeout = 911 const base::TimeDelta kMinStarvationTimeout =
868 base::TimeDelta::FromMilliseconds(20); 912 base::TimeDelta::FromMilliseconds(20);
869 913
870 base::TimeDelta current_timestamp = GetCurrentTime(); 914 base::TimeDelta current_timestamp = GetCurrentTime();
871 base::TimeDelta timeout; 915 base::TimeDelta timeout;
872 if (HasAudio()) { 916 if (HasAudio()) {
873 timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp; 917 timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 1012
969 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 1013 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
970 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 1014 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
971 DCHECK_NE(event, NO_EVENT_PENDING); 1015 DCHECK_NE(event, NO_EVENT_PENDING);
972 DCHECK(IsEventPending(event)) << GetEventName(event); 1016 DCHECK(IsEventPending(event)) << GetEventName(event);
973 1017
974 pending_event_ &= ~event; 1018 pending_event_ &= ~event;
975 } 1019 }
976 1020
977 } // namespace media 1021 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698