Index: media/base/android/audio_decoder_job.cc |
diff --git a/media/base/android/audio_decoder_job.cc b/media/base/android/audio_decoder_job.cc |
deleted file mode 100644 |
index 287b0f1500eb8664079120302fc120a675468a6d..0000000000000000000000000000000000000000 |
--- a/media/base/android/audio_decoder_job.cc |
+++ /dev/null |
@@ -1,249 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "media/base/android/audio_decoder_job.h" |
- |
-#include "base/bind.h" |
-#include "base/lazy_instance.h" |
-#include "base/threading/thread.h" |
-#include "media/base/android/sdk_media_codec_bridge.h" |
-#include "media/base/audio_timestamp_helper.h" |
-#include "media/base/timestamp_constants.h" |
- |
-namespace { |
- |
-// Use 16bit PCM for audio output. Keep this value in sync with the output |
-// format we passed to AudioTrack in MediaCodecBridge. |
-const int kBytesPerAudioOutputSample = 2; |
-} |
- |
-namespace media { |
- |
-class AudioDecoderThread : public base::Thread { |
- public: |
- AudioDecoderThread() : base::Thread("MediaSource_AudioDecoderThread") { |
- Start(); |
- } |
-}; |
- |
-// TODO(qinmin): Check if it is tolerable to use worker pool to handle all the |
-// decoding tasks so that we don't need a global thread here. |
-// http://crbug.com/245750 |
-base::LazyInstance<AudioDecoderThread>::Leaky |
- g_audio_decoder_thread = LAZY_INSTANCE_INITIALIZER; |
- |
-AudioDecoderJob::AudioDecoderJob( |
- const base::Closure& request_data_cb, |
- const base::Closure& on_demuxer_config_changed_cb) |
- : MediaDecoderJob(g_audio_decoder_thread.Pointer()->task_runner(), |
- request_data_cb, |
- on_demuxer_config_changed_cb), |
- audio_codec_(kUnknownAudioCodec), |
- config_num_channels_(0), |
- config_sampling_rate_(0), |
- volume_(-1.0), |
- output_sampling_rate_(0), |
- output_num_channels_(0), |
- frame_count_(0) {} |
- |
-AudioDecoderJob::~AudioDecoderJob() {} |
- |
-bool AudioDecoderJob::HasStream() const { |
- return audio_codec_ != kUnknownAudioCodec; |
-} |
- |
-void AudioDecoderJob::Flush() { |
- MediaDecoderJob::Flush(); |
- frame_count_ = 0; |
-} |
- |
-void AudioDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) { |
- // TODO(qinmin): split DemuxerConfig for audio and video separately so we |
- // can simply store the stucture here. |
- audio_codec_ = configs.audio_codec; |
- config_num_channels_ = configs.audio_channels; |
- config_sampling_rate_ = configs.audio_sampling_rate; |
- set_is_content_encrypted(configs.is_audio_encrypted); |
- audio_extra_data_ = configs.audio_extra_data; |
- audio_codec_delay_ns_ = configs.audio_codec_delay_ns; |
- audio_seek_preroll_ns_ = configs.audio_seek_preroll_ns; |
- |
- if (!media_codec_bridge_) { |
- output_sampling_rate_ = config_sampling_rate_; |
- output_num_channels_ = config_num_channels_; |
- } |
-} |
- |
-void AudioDecoderJob::SetVolume(double volume) { |
- volume_ = volume; |
- SetVolumeInternal(); |
-} |
- |
-void AudioDecoderJob::SetBaseTimestamp(base::TimeDelta base_timestamp) { |
- DCHECK(!is_decoding()); |
- base_timestamp_ = base_timestamp; |
- if (audio_timestamp_helper_) |
- audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); |
-} |
- |
-void AudioDecoderJob::ResetTimestampHelper() { |
- if (audio_timestamp_helper_) |
- base_timestamp_ = audio_timestamp_helper_->GetTimestamp(); |
- audio_timestamp_helper_.reset( |
- new AudioTimestampHelper(output_sampling_rate_)); |
- audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); |
-} |
- |
-void AudioDecoderJob::ReleaseOutputBuffer( |
- int output_buffer_index, |
- size_t offset, |
- size_t size, |
- bool render_output, |
- bool /* is_late_frame */, |
- base::TimeDelta current_presentation_timestamp, |
- MediaCodecStatus status, |
- const DecoderCallback& callback) { |
- render_output = render_output && (size != 0u); |
- bool is_audio_underrun = false; |
- |
- // Ignore input value. |
- current_presentation_timestamp = kNoTimestamp; |
- |
- if (render_output) { |
- int64_t head_position; |
- MediaCodecStatus play_status = |
- (static_cast<AudioCodecBridge*>(media_codec_bridge_.get())) |
- ->PlayOutputBuffer(output_buffer_index, size, offset, false, |
- &head_position); |
- if (play_status == MEDIA_CODEC_OK) { |
- base::TimeTicks current_time = base::TimeTicks::Now(); |
- |
- size_t bytes_per_frame = |
- kBytesPerAudioOutputSample * output_num_channels_; |
- size_t new_frames_count = size / bytes_per_frame; |
- frame_count_ += new_frames_count; |
- audio_timestamp_helper_->AddFrames(new_frames_count); |
- int64_t frames_to_play = frame_count_ - head_position; |
- DCHECK_GE(frames_to_play, 0); |
- |
- const base::TimeDelta last_buffered = |
- audio_timestamp_helper_->GetTimestamp(); |
- |
- current_presentation_timestamp = |
- last_buffered - |
- audio_timestamp_helper_->GetFrameDuration(frames_to_play); |
- |
- // Potential audio underrun is considered a late frame for UMA. |
- is_audio_underrun = !next_frame_time_limit_.is_null() && |
- next_frame_time_limit_ < current_time; |
- |
- next_frame_time_limit_ = |
- current_time + (last_buffered - current_presentation_timestamp); |
- } else { |
- DLOG(ERROR) << __FUNCTION__ << ": PlayOutputBuffer failed for index:" |
- << output_buffer_index; |
- |
- // Override output status. |
- status = MEDIA_CODEC_ERROR; |
- } |
- } |
- |
- media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, false); |
- |
- callback.Run(status, is_audio_underrun, current_presentation_timestamp, |
- audio_timestamp_helper_->GetTimestamp()); |
-} |
- |
-bool AudioDecoderJob::ComputeTimeToRender() const { |
- return false; |
-} |
- |
-bool AudioDecoderJob::AreDemuxerConfigsChanged( |
- const DemuxerConfigs& configs) const { |
- return audio_codec_ != configs.audio_codec || |
- config_num_channels_ != configs.audio_channels || |
- config_sampling_rate_ != configs.audio_sampling_rate || |
- is_content_encrypted() != configs.is_audio_encrypted || |
- audio_extra_data_.size() != configs.audio_extra_data.size() || |
- !std::equal(audio_extra_data_.begin(), audio_extra_data_.end(), |
- configs.audio_extra_data.begin()); |
-} |
- |
-MediaDecoderJob::MediaDecoderJobStatus |
- AudioDecoderJob::CreateMediaCodecBridgeInternal() { |
- media_codec_bridge_.reset(AudioCodecBridge::Create(audio_codec_)); |
- if (!media_codec_bridge_) |
- return STATUS_FAILURE; |
- |
- if (!(static_cast<AudioCodecBridge*>(media_codec_bridge_.get())) |
- ->ConfigureAndStart(audio_codec_, config_sampling_rate_, |
- config_num_channels_, &audio_extra_data_[0], |
- audio_extra_data_.size(), audio_codec_delay_ns_, |
- audio_seek_preroll_ns_, true, |
- GetMediaCrypto())) { |
- media_codec_bridge_.reset(); |
- return STATUS_FAILURE; |
- } |
- |
- // ConfigureAndStart() creates AudioTrack with |config_sampling_rate_| |
- // and |config_num_channels_|. Keep |output_...| in sync to detect the changes |
- // that might come with OnOutputFormatChanged(). |
- output_sampling_rate_ = config_sampling_rate_; |
- output_num_channels_ = config_num_channels_; |
- |
- SetVolumeInternal(); |
- |
- // Reset values used to track codec bridge output |
- frame_count_ = 0; |
- ResetTimestampHelper(); |
- |
- return STATUS_SUCCESS; |
-} |
- |
-void AudioDecoderJob::SetVolumeInternal() { |
- if (media_codec_bridge_) { |
- static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->SetVolume( |
- volume_); |
- } |
-} |
- |
-bool AudioDecoderJob::OnOutputFormatChanged() { |
- DCHECK(media_codec_bridge_); |
- |
- // Recreate AudioTrack if either sample rate or output channel count changed. |
- // If we cannot obtain these values we assume they did not change. |
- bool needs_recreate_audio_track = false; |
- |
- const int old_sampling_rate = output_sampling_rate_; |
- MediaCodecStatus status = |
- media_codec_bridge_->GetOutputSamplingRate(&output_sampling_rate_); |
- |
- if (status == MEDIA_CODEC_OK && old_sampling_rate != output_sampling_rate_) { |
- DCHECK_GT(output_sampling_rate_, 0); |
- DVLOG(2) << __FUNCTION__ << ": new sampling rate " << output_sampling_rate_; |
- needs_recreate_audio_track = true; |
- |
- ResetTimestampHelper(); |
- } |
- |
- const int old_num_channels = output_num_channels_; |
- status = media_codec_bridge_->GetOutputChannelCount(&output_num_channels_); |
- |
- if (status == MEDIA_CODEC_OK && old_num_channels != output_num_channels_) { |
- DCHECK_GT(output_num_channels_, 0); |
- DVLOG(2) << __FUNCTION__ << ": new channel count " << output_num_channels_; |
- needs_recreate_audio_track = true; |
- } |
- |
- if (needs_recreate_audio_track && |
- !static_cast<AudioCodecBridge*>(media_codec_bridge_.get()) |
- ->CreateAudioTrack(output_sampling_rate_, output_num_channels_)) { |
- DLOG(ERROR) << __FUNCTION__ << ": cannot create AudioTrack"; |
- return false; |
- } |
- |
- return true; |
-} |
- |
-} // namespace media |