Chromium Code Reviews| Index: media/base/android/media_source_player.cc |
| diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc |
| index b29d182d84938638a33561467efe1f6dae3f4c9a..9d47292c539b2a9e6400baab71ed32ba5a96d4c7 100644 |
| --- a/media/base/android/media_source_player.cc |
| +++ b/media/base/android/media_source_player.cc |
| @@ -193,6 +193,8 @@ MediaSourcePlayer::MediaSourcePlayer( |
| MediaPlayerManager* manager) |
| : MediaPlayerAndroid(player_id, manager), |
| pending_play_(false), |
| + pending_media_seek_request_(false), |
| + active_decoding_tasks_(0), |
| width_(0), |
| height_(0), |
| audio_codec_(kUnknownAudioCodec), |
| @@ -271,7 +273,6 @@ int MediaSourcePlayer::GetVideoHeight() { |
| void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) { |
| last_presentation_timestamp_ = timestamp; |
| start_wallclock_time_ = base::Time(); |
| - last_seek_time_ = base::Time::Now(); |
| if (audio_decoder_job_) |
| audio_decoder_job_->Flush(); |
| if (video_decoder_job_) |
| @@ -280,7 +281,9 @@ void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) { |
| received_video_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params(); |
| audio_access_unit_index_ = 0; |
| video_access_unit_index_ = 0; |
| - OnSeekComplete(); |
| + pending_media_seek_request_ = true; |
| + if (!active_decoding_tasks_) |
|
ycheo (away)
2013/05/22 06:59:13
This SeekTo() can be called from ContentVideoView:
qinmin
2013/05/22 07:20:38
SeekTo() is always called on the browser thread si
|
| + manager()->OnMediaSeekRequest(player_id(), last_presentation_timestamp_); |
| } |
| base::TimeDelta MediaSourcePlayer::GetCurrentTime() { |
| @@ -294,6 +297,7 @@ base::TimeDelta MediaSourcePlayer::GetDuration() { |
| void MediaSourcePlayer::Release() { |
| audio_decoder_job_.reset(); |
| video_decoder_job_.reset(); |
| + active_decoding_tasks_ = 0; |
| ReleaseMediaResourcesFromManager(); |
| } |
| @@ -348,41 +352,67 @@ void MediaSourcePlayer::DemuxerReady( |
| void MediaSourcePlayer::ReadFromDemuxerAck( |
| const MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) { |
| + if (params.type == DemuxerStream::AUDIO) |
| + waiting_for_audio_data_ = false; |
| + else |
| + waiting_for_video_data_ = false; |
| + |
| + // If there is a pending seek request, ignore the data from the chunk demuxer. |
| + // The data will be requested later when OnSeekRequestAck() is called. |
| + if (pending_media_seek_request_) |
| + return; |
| + |
| if (params.type == DemuxerStream::AUDIO) { |
| DCHECK_EQ(0u, audio_access_unit_index_); |
| received_audio_ = params; |
| - waiting_for_audio_data_ = false; |
| DecodeMoreAudio(); |
| } else { |
| DCHECK_EQ(0u, video_access_unit_index_); |
| received_video_ = params; |
| - waiting_for_video_data_ = false; |
| DecodeMoreVideo(); |
| } |
| } |
| +void MediaSourcePlayer::OnSeekRequestAck() { |
| + pending_media_seek_request_ = false; |
| + OnSeekComplete(); |
| + if (!playing_) |
| + return; |
| + |
| + if (HasAudio()) |
| + DecodeMoreAudio(); |
| + if (HasVideo()) |
| + DecodeMoreVideo(); |
| +} |
| + |
| void MediaSourcePlayer::UpdateTimestamps( |
| - const base::Time& kickoff_time, |
| const base::TimeDelta& presentation_timestamp, |
| const base::Time& wallclock_time) { |
| - // If the job was posted after last seek, update the presentation time. |
| - // Otherwise, ignore it. |
| - if (kickoff_time > last_seek_time_) { |
| - last_presentation_timestamp_ = presentation_timestamp; |
| - OnTimeUpdated(); |
| - if (start_wallclock_time_.is_null() && playing_) { |
| - start_wallclock_time_ = wallclock_time; |
| - start_presentation_timestamp_ = last_presentation_timestamp_; |
| - } |
| + last_presentation_timestamp_ = presentation_timestamp; |
| + OnTimeUpdated(); |
| + if (start_wallclock_time_.is_null() && playing_) { |
| + start_wallclock_time_ = wallclock_time; |
| + start_presentation_timestamp_ = last_presentation_timestamp_; |
| } |
| } |
| void MediaSourcePlayer::MediaDecoderCallback( |
| - bool is_audio, const base::Time& kickoff_time, |
| - const base::TimeDelta& presentation_timestamp, |
| + bool is_audio, const base::TimeDelta& presentation_timestamp, |
| const base::Time& wallclock_time, bool end_of_stream) { |
| + if (active_decoding_tasks_ > 0) |
| + active_decoding_tasks_--; |
| + |
| + if (pending_media_seek_request_) { |
| + // Wait for all the decoding jobs to finish before sending a seek request. |
| + if (!active_decoding_tasks_) { |
| + manager()->OnMediaSeekRequest(player_id(), |
| + last_presentation_timestamp_); |
| + } |
| + return; |
| + } |
| + |
| if (is_audio || !HasAudio()) |
| - UpdateTimestamps(kickoff_time, presentation_timestamp, wallclock_time); |
| + UpdateTimestamps(presentation_timestamp, wallclock_time); |
| if (end_of_stream) { |
| PlaybackCompleted(is_audio); |
| @@ -413,8 +443,9 @@ void MediaSourcePlayer::DecodeMoreAudio() { |
| received_audio_.access_units[audio_access_unit_index_], |
| start_wallclock_time_, start_presentation_timestamp_, |
| base::Bind(&MediaSourcePlayer::MediaDecoderCallback, |
| - weak_this_.GetWeakPtr(), true, base::Time::Now())); |
| - ++audio_access_unit_index_; |
| + weak_this_.GetWeakPtr(), true)); |
| + active_decoding_tasks_++; |
| + audio_access_unit_index_++; |
| } |
| void MediaSourcePlayer::DecodeMoreVideo() { |
| @@ -432,8 +463,9 @@ void MediaSourcePlayer::DecodeMoreVideo() { |
| received_video_.access_units[video_access_unit_index_], |
| start_wallclock_time_, start_presentation_timestamp_, |
| base::Bind(&MediaSourcePlayer::MediaDecoderCallback, |
| - weak_this_.GetWeakPtr(), false, base::Time::Now())); |
| - ++video_access_unit_index_; |
| + weak_this_.GetWeakPtr(), false)); |
| + active_decoding_tasks_++; |
| + video_access_unit_index_++; |
| } |