diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-08-05 13:57:33 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-08-05 13:57:33 +0100 |
commit | a36e5920737c6adbddd3e43b760e5de8431db6e0 (patch) | |
tree | 347d048bb8c8828d50113bf94ace40bf0613f2cd /media/base/android/media_source_player.cc | |
parent | 34378da0e9429d394aafdaa771301aff58447cb1 (diff) | |
download | chromium_org-a36e5920737c6adbddd3e43b760e5de8431db6e0.tar.gz |
Merge from Chromium at DEPS revision r215573
This commit was generated by merge_to_master.py.
Change-Id: Ib95814f98e5765b459dd32425f9bf9138edf2bca
Diffstat (limited to 'media/base/android/media_source_player.cc')
-rw-r--r-- | media/base/android/media_source_player.cc | 120 |
1 files changed, 80 insertions, 40 deletions
diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc index 5673b926a0..5d4aa98b66 100644 --- a/media/base/android/media_source_player.cc +++ b/media/base/android/media_source_player.cc @@ -22,7 +22,7 @@ namespace { // Timeout value for media codec operations. Because the first // DequeInputBuffer() can take about 150 milliseconds, use 250 milliseconds // here. See b/9357571. -const int kMediaCodecTimeoutInMicroseconds = 250000; +const int kMediaCodecTimeoutInMilliseconds = 250; // Use 16bit PCM for audio output. Keep this value in sync with the output // format we passed to AudioTrack in MediaCodecBridge. @@ -82,6 +82,8 @@ class AudioDecoderJob : public MediaDecoderJob { const AudioCodec audio_codec, int sample_rate, int channel_count, const uint8* extra_data, size_t extra_data_size, jobject media_crypto); + void SetVolume(double volume); + private: AudioDecoderJob(MediaCodecBridge* media_codec_bridge); }; @@ -100,7 +102,7 @@ class VideoDecoderJob : public MediaDecoderJob { }; void MediaDecoderJob::Decode( - const MediaPlayerHostMsg_ReadFromDemuxerAck_Params::AccessUnit& unit, + const AccessUnit& unit, const base::TimeTicks& start_time_ticks, const base::TimeDelta& start_presentation_timestamp, const MediaDecoderJob::DecoderCallback& callback) { @@ -114,43 +116,55 @@ void MediaDecoderJob::Decode( needs_flush_ = false; } +MediaDecoderJob::DecodeStatus MediaDecoderJob::QueueInputBuffer( + const AccessUnit& unit) { + base::TimeDelta timeout = base::TimeDelta::FromMilliseconds( + kMediaCodecTimeoutInMilliseconds); + int input_buf_index = media_codec_bridge_->DequeueInputBuffer(timeout); + if (input_buf_index == MediaCodecBridge::INFO_MEDIA_CODEC_ERROR) + return DECODE_FAILED; + if (input_buf_index == MediaCodecBridge::INFO_TRY_AGAIN_LATER) + return DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER; + + // TODO(qinmin): skip frames if video is falling far behind. + DCHECK(input_buf_index >= 0); + if (unit.end_of_stream || unit.data.empty()) { + media_codec_bridge_->QueueEOS(input_buf_index); + } else if (unit.key_id.empty()) { + media_codec_bridge_->QueueInputBuffer( + input_buf_index, &unit.data[0], unit.data.size(), unit.timestamp); + } else { + if (unit.iv.empty() || unit.subsamples.empty()) { + LOG(ERROR) << "The access unit doesn't have iv or subsamples while it " + << "has key IDs!"; + return DECODE_FAILED; + } + media_codec_bridge_->QueueSecureInputBuffer( + input_buf_index, &unit.data[0], unit.data.size(), + reinterpret_cast<const uint8*>(&unit.key_id[0]), unit.key_id.size(), + reinterpret_cast<const uint8*>(&unit.iv[0]), unit.iv.size(), + &unit.subsamples[0], unit.subsamples.size(), unit.timestamp); + } + + return DECODE_SUCCEEDED; +} + void MediaDecoderJob::DecodeInternal( - const MediaPlayerHostMsg_ReadFromDemuxerAck_Params::AccessUnit& unit, + const AccessUnit& unit, const base::TimeTicks& start_time_ticks, const base::TimeDelta& start_presentation_timestamp, bool needs_flush, const MediaDecoderJob::DecoderCallback& callback) { - if (needs_flush) + if (needs_flush) { + DVLOG(1) << "DecodeInternal needs flush."; media_codec_bridge_->Reset(); - base::TimeDelta timeout = base::TimeDelta::FromMicroseconds( - kMediaCodecTimeoutInMicroseconds); - int input_buf_index = media_codec_bridge_->DequeueInputBuffer(timeout); - if (input_buf_index == MediaCodecBridge::INFO_MEDIA_CODEC_ERROR) { - ui_loop_->PostTask(FROM_HERE, base::Bind( - callback, DECODE_FAILED, start_presentation_timestamp, 0)); - return; } - // TODO(qinmin): skip frames if video is falling far behind. - if (input_buf_index >= 0) { - if (unit.end_of_stream || unit.data.empty()) { - media_codec_bridge_->QueueEOS(input_buf_index); - } else if (unit.key_id.empty()){ - media_codec_bridge_->QueueInputBuffer( - input_buf_index, &unit.data[0], unit.data.size(), unit.timestamp); - } else { - if (unit.iv.empty() || unit.subsamples.empty()) { - LOG(ERROR) << "The access unit doesn't have iv or subsamples while it " - << "has key IDs!"; - ui_loop_->PostTask(FROM_HERE, base::Bind( - callback, DECODE_FAILED, start_presentation_timestamp, 0)); - return; - } - media_codec_bridge_->QueueSecureInputBuffer( - input_buf_index, &unit.data[0], unit.data.size(), - reinterpret_cast<const uint8*>(&unit.key_id[0]), unit.key_id.size(), - reinterpret_cast<const uint8*>(&unit.iv[0]), unit.iv.size(), - &unit.subsamples[0], unit.subsamples.size(), unit.timestamp); - } + + DecodeStatus decode_status = QueueInputBuffer(unit); + if (decode_status != DECODE_SUCCEEDED) { + ui_loop_->PostTask(FROM_HERE, + base::Bind(callback, decode_status, start_presentation_timestamp, 0)); + return; } size_t offset = 0; @@ -158,9 +172,11 @@ void MediaDecoderJob::DecodeInternal( base::TimeDelta presentation_timestamp; bool end_of_stream = false; + base::TimeDelta timeout = base::TimeDelta::FromMilliseconds( + kMediaCodecTimeoutInMilliseconds); int outputBufferIndex = media_codec_bridge_->DequeueOutputBuffer( timeout, &offset, &size, &presentation_timestamp, &end_of_stream); - DecodeStatus decode_status = DECODE_SUCCEEDED; + if (end_of_stream) decode_status = DECODE_END_OF_STREAM; switch (outputBufferIndex) { @@ -172,7 +188,7 @@ void MediaDecoderJob::DecodeInternal( decode_status = DECODE_FORMAT_CHANGED; break; case MediaCodecBridge::INFO_TRY_AGAIN_LATER: - decode_status = DECODE_TRY_AGAIN_LATER; + decode_status = DECODE_TRY_DEQUEUE_OUTPUT_AGAIN_LATER; break; case MediaCodecBridge::INFO_MEDIA_CODEC_ERROR: decode_status = DECODE_FAILED; @@ -257,7 +273,7 @@ VideoDecoderJob* VideoDecoderJob::Create( const VideoCodec video_codec, const gfx::Size& size, jobject surface, jobject media_crypto) { scoped_ptr<VideoCodecBridge> codec(VideoCodecBridge::Create(video_codec)); - if (codec->Start(video_codec, size, surface, media_crypto)) + if (codec && codec->Start(video_codec, size, surface, media_crypto)) return new VideoDecoderJob(codec.release()); return NULL; } @@ -275,8 +291,8 @@ AudioDecoderJob* AudioDecoderJob::Create( size_t extra_data_size, jobject media_crypto) { scoped_ptr<AudioCodecBridge> codec(AudioCodecBridge::Create(audio_codec)); - if (codec->Start(audio_codec, sample_rate, channel_count, extra_data, - extra_data_size, true, media_crypto)) { + if (codec && codec->Start(audio_codec, sample_rate, channel_count, extra_data, + extra_data_size, true, media_crypto)) { return new AudioDecoderJob(codec.release()); } return NULL; @@ -287,6 +303,10 @@ AudioDecoderJob::AudioDecoderJob(MediaCodecBridge* media_codec_bridge) media_codec_bridge, true) {} +void AudioDecoderJob::SetVolume(double volume) { + static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->SetVolume(volume); +} + MediaSourcePlayer::MediaSourcePlayer( int player_id, MediaPlayerManager* manager) @@ -304,6 +324,7 @@ MediaSourcePlayer::MediaSourcePlayer( playing_(false), is_audio_encrypted_(false), is_video_encrypted_(false), + volume_(-1.0), clock_(&default_tick_clock_), reconfig_audio_decoder_(false), reconfig_video_decoder_(false), @@ -407,7 +428,9 @@ void MediaSourcePlayer::Release() { ReleaseMediaResourcesFromManager(); } -void MediaSourcePlayer::SetVolume(float leftVolume, float rightVolume) { +void MediaSourcePlayer::SetVolume(double volume) { + volume_ = volume; + SetVolumeInternal(); } bool MediaSourcePlayer::CanPause() { @@ -546,6 +569,7 @@ void MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) { } void MediaSourcePlayer::OnSeekRequestAck(unsigned seek_request_id) { + DVLOG(1) << "OnSeekRequestAck(" << seek_request_id << ")"; // Do nothing until the most recent seek request is processed. if (seek_request_id_ != seek_request_id) return; @@ -613,7 +637,9 @@ void MediaSourcePlayer::MediaDecoderCallback( Release(); OnMediaError(MEDIA_ERROR_DECODE); return; - } else if (decode_status == MediaDecoderJob::DECODE_SUCCEEDED) { + } + + if (decode_status != MediaDecoderJob::DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER) { if (is_audio) audio_access_unit_index_++; else @@ -698,6 +724,7 @@ void MediaSourcePlayer::DecodeMoreAudio() { } void MediaSourcePlayer::DecodeMoreVideo() { + DVLOG(1) << "DecodeMoreVideo()"; DCHECK(!video_decoder_job_->is_decoding()); DCHECK(HasVideoData()); @@ -712,6 +739,9 @@ void MediaSourcePlayer::DecodeMoreVideo() { return; } + DVLOG(3) << "VideoDecoderJob::Decode(" << video_access_unit_index_ << ", " + << start_time_ticks_.ToInternalValue() << ", " + << start_presentation_timestamp_.InMilliseconds() << ")"; video_decoder_job_->Decode( received_video_.access_units[video_access_unit_index_], start_time_ticks_, start_presentation_timestamp_, @@ -734,6 +764,7 @@ void MediaSourcePlayer::PlaybackCompleted(bool is_audio) { } void MediaSourcePlayer::ClearDecodingData() { + DVLOG(1) << "ClearDecodingData()"; if (audio_decoder_job_) audio_decoder_job_->Flush(); if (video_decoder_job_) @@ -786,8 +817,10 @@ void MediaSourcePlayer::ConfigureAudioDecoderJob() { audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0], audio_extra_data_.size(), media_codec.obj())); - if (audio_decoder_job_) + if (audio_decoder_job_) { + SetVolumeInternal(); reconfig_audio_decoder_ = false; + } } void MediaSourcePlayer::ConfigureVideoDecoderJob() { @@ -866,6 +899,7 @@ void MediaSourcePlayer::SyncAndStartDecoderJobs() { } void MediaSourcePlayer::RequestAudioData() { + DVLOG(2) << "RequestAudioData()"; DCHECK(HasAudio()); if (waiting_for_audio_data_) @@ -878,6 +912,7 @@ void MediaSourcePlayer::RequestAudioData() { } void MediaSourcePlayer::RequestVideoData() { + DVLOG(2) << "RequestVideoData()"; DCHECK(HasVideo()); if (waiting_for_video_data_) return; @@ -896,4 +931,9 @@ bool MediaSourcePlayer::HasVideoData() const { return video_access_unit_index_ < received_video_.access_units.size(); } +void MediaSourcePlayer::SetVolumeInternal() { + if (audio_decoder_job_ && volume_ >= 0) + audio_decoder_job_.get()->SetVolume(volume_); +} + } // namespace media |