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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 DVLOG(1) << __FUNCTION__; | 309 DVLOG(1) << __FUNCTION__; |
310 duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms); | 310 duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms); |
311 clock_.SetDuration(duration_); | 311 clock_.SetDuration(duration_); |
312 | 312 |
313 audio_codec_ = configs.audio_codec; | 313 audio_codec_ = configs.audio_codec; |
314 num_channels_ = configs.audio_channels; | 314 num_channels_ = configs.audio_channels; |
315 sampling_rate_ = configs.audio_sampling_rate; | 315 sampling_rate_ = configs.audio_sampling_rate; |
316 is_audio_encrypted_ = configs.is_audio_encrypted; | 316 is_audio_encrypted_ = configs.is_audio_encrypted; |
317 audio_extra_data_ = configs.audio_extra_data; | 317 audio_extra_data_ = configs.audio_extra_data; |
318 if (HasAudio()) { | 318 if (HasAudio()) { |
319 DCHECK_GT(num_channels_, 0); | 319 if (reconfig_audio_decoder_ || !audio_decoder_job_) { |
320 audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_)); | 320 DCHECK_GT(num_channels_, 0); |
321 audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime()); | 321 audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_)); |
322 audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime()); | |
323 } | |
322 } else { | 324 } else { |
323 audio_timestamp_helper_.reset(); | 325 audio_timestamp_helper_.reset(); |
324 } | 326 } |
325 | 327 |
326 video_codec_ = configs.video_codec; | 328 video_codec_ = configs.video_codec; |
327 width_ = configs.video_size.width(); | 329 width_ = configs.video_size.width(); |
328 height_ = configs.video_size.height(); | 330 height_ = configs.video_size.height(); |
329 is_video_encrypted_ = configs.is_video_encrypted; | 331 is_video_encrypted_ = configs.is_video_encrypted; |
330 | 332 |
331 manager()->OnMediaMetadataChanged( | 333 manager()->OnMediaMetadataChanged( |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 if (video_decoder_job_) | 466 if (video_decoder_job_) |
465 video_decoder_job_->BeginPrerolling(preroll_timestamp_); | 467 video_decoder_job_->BeginPrerolling(preroll_timestamp_); |
466 | 468 |
467 if (!doing_browser_seek_) | 469 if (!doing_browser_seek_) |
468 manager()->OnSeekComplete(player_id(), current_time); | 470 manager()->OnSeekComplete(player_id(), current_time); |
469 | 471 |
470 ProcessPendingEvents(); | 472 ProcessPendingEvents(); |
471 } | 473 } |
472 | 474 |
473 void MediaSourcePlayer::UpdateTimestamps( | 475 void MediaSourcePlayer::UpdateTimestamps( |
474 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) { | 476 base::TimeDelta presentation_timestamp, size_t audio_output_bytes, |
475 base::TimeDelta new_max_time = presentation_timestamp; | 477 int64 audio_head_position, base::TimeTicks audio_render_time) { |
476 | |
477 if (audio_output_bytes > 0) { | 478 if (audio_output_bytes > 0) { |
478 audio_timestamp_helper_->AddFrames( | 479 audio_timestamp_helper_->AddFrames( |
479 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); | 480 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); |
480 new_max_time = audio_timestamp_helper_->GetTimestamp(); | 481 int64 frames_to_play = |
482 audio_timestamp_helper_->frame_count() - audio_head_position; | |
483 DCHECK(frames_to_play >= 0); | |
wolenetz
2014/04/01 18:15:47
nit: lint: "Consider using DCHECK_GE instead of DC
qinmin
2014/04/01 20:42:34
Done.
| |
484 base::TimeDelta new_max_time = audio_timestamp_helper_->GetTimestamp(); | |
485 base::TimeDelta current_presentation_timestamp = | |
486 base::TimeTicks::Now() - audio_render_time + new_max_time - | |
487 audio_timestamp_helper_->GetFrameDuration(frames_to_play); | |
488 if (current_presentation_timestamp >= new_max_time) | |
489 current_presentation_timestamp = new_max_time; | |
490 clock_.SetTime(current_presentation_timestamp, new_max_time); | |
491 } else { | |
492 clock_.SetMaxTime(presentation_timestamp); | |
481 } | 493 } |
482 | 494 |
483 clock_.SetMaxTime(new_max_time); | |
484 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); | 495 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); |
485 } | 496 } |
486 | 497 |
487 void MediaSourcePlayer::ProcessPendingEvents() { | 498 void MediaSourcePlayer::ProcessPendingEvents() { |
488 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; | 499 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; |
489 // Wait for all the decoding jobs to finish before processing pending tasks. | 500 // Wait for all the decoding jobs to finish before processing pending tasks. |
490 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { | 501 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { |
491 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; | 502 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; |
492 return; | 503 return; |
493 } | 504 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
574 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); | 585 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); |
575 | 586 |
576 // Now that all pending events have been handled, resume decoding if we are | 587 // Now that all pending events have been handled, resume decoding if we are |
577 // still playing. | 588 // still playing. |
578 if (playing_) | 589 if (playing_) |
579 StartInternal(); | 590 StartInternal(); |
580 } | 591 } |
581 | 592 |
582 void MediaSourcePlayer::MediaDecoderCallback( | 593 void MediaSourcePlayer::MediaDecoderCallback( |
583 bool is_audio, MediaCodecStatus status, | 594 bool is_audio, MediaCodecStatus status, |
584 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) { | 595 base::TimeDelta presentation_timestamp, size_t audio_output_bytes, |
596 int64 audio_head_position, base::TimeTicks audio_render_time) { | |
585 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; | 597 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; |
586 | 598 |
587 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed. | 599 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed. |
588 if (is_audio) { | 600 if (is_audio) { |
589 TRACE_EVENT_ASYNC_END1("media", | 601 TRACE_EVENT_ASYNC_END1("media", |
590 "MediaSourcePlayer::DecodeMoreAudio", | 602 "MediaSourcePlayer::DecodeMoreAudio", |
591 audio_decoder_job_.get(), | 603 audio_decoder_job_.get(), |
592 "MediaCodecStatus", | 604 "MediaCodecStatus", |
593 base::IntToString(status)); | 605 base::IntToString(status)); |
594 } else { | 606 } else { |
(...skipping 23 matching lines...) Expand all Loading... | |
618 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING)); | 630 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING)); |
619 | 631 |
620 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of | 632 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of |
621 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process | 633 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process |
622 // any other pending events only after handling EOS detection. | 634 // any other pending events only after handling EOS detection. |
623 if (IsEventPending(SEEK_EVENT_PENDING)) { | 635 if (IsEventPending(SEEK_EVENT_PENDING)) { |
624 ProcessPendingEvents(); | 636 ProcessPendingEvents(); |
625 return; | 637 return; |
626 } | 638 } |
627 | 639 |
640 if (status == MEDIA_CODEC_OK && is_clock_manager && | |
641 presentation_timestamp != kNoTimestamp()) { | |
642 UpdateTimestamps( | |
643 presentation_timestamp, audio_output_bytes, audio_head_position, | |
644 audio_render_time); | |
645 } | |
646 | |
628 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) | 647 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) |
629 PlaybackCompleted(is_audio); | 648 PlaybackCompleted(is_audio); |
630 | 649 |
631 if (pending_event_ != NO_EVENT_PENDING) { | 650 if (pending_event_ != NO_EVENT_PENDING) { |
632 ProcessPendingEvents(); | 651 ProcessPendingEvents(); |
633 return; | 652 return; |
634 } | 653 } |
635 | 654 |
636 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) | 655 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) |
637 return; | 656 return; |
638 | 657 |
639 if (status == MEDIA_CODEC_OK && is_clock_manager && | |
640 presentation_timestamp != kNoTimestamp()) { | |
641 UpdateTimestamps(presentation_timestamp, audio_output_bytes); | |
642 } | |
643 | |
644 if (!playing_) { | 658 if (!playing_) { |
645 if (is_clock_manager) | 659 if (is_clock_manager) |
646 clock_.Pause(); | 660 clock_.Pause(); |
647 return; | 661 return; |
648 } | 662 } |
649 | 663 |
650 if (status == MEDIA_CODEC_NO_KEY) { | 664 if (status == MEDIA_CODEC_NO_KEY) { |
651 is_waiting_for_key_ = true; | 665 is_waiting_for_key_ = true; |
652 return; | 666 return; |
653 } | 667 } |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1019 | 1033 |
1020 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { | 1034 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { |
1021 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; | 1035 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; |
1022 DCHECK_NE(event, NO_EVENT_PENDING); | 1036 DCHECK_NE(event, NO_EVENT_PENDING); |
1023 DCHECK(IsEventPending(event)) << GetEventName(event); | 1037 DCHECK(IsEventPending(event)) << GetEventName(event); |
1024 | 1038 |
1025 pending_event_ &= ~event; | 1039 pending_event_ &= ~event; |
1026 } | 1040 } |
1027 | 1041 |
1028 } // namespace media | 1042 } // namespace media |
OLD | NEW |