1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/base/android/audio_decoder_job.h" 6 7 #include "base/bind.h" 8 #include "base/lazy_instance.h" 9 #include "base/threading/thread.h" 10 #include "media/base/android/media_codec_bridge.h" 11 #include "media/base/audio_timestamp_helper.h" 12 13 namespace { 14 15 // Use 16bit PCM for audio output. Keep this value in sync with the output 16 // format we passed to AudioTrack in MediaCodecBridge. 17 const int kBytesPerAudioOutputSample = 2; 18 } 19 20 namespace media { 21 22 class AudioDecoderThread : public base::Thread { 23 public: 24 AudioDecoderThread() : base::Thread("MediaSource_AudioDecoderThread") { 25 Start(); 26 } 27 }; 28 29 // TODO(qinmin): Check if it is tolerable to use worker pool to handle all the 30 // decoding tasks so that we don't need a global thread here. 31 // http://crbug.com/245750 32 base::LazyInstance<AudioDecoderThread>::Leaky 33 g_audio_decoder_thread = LAZY_INSTANCE_INITIALIZER; 34 35 AudioDecoderJob::AudioDecoderJob( 36 const base::Closure& request_data_cb, 37 const base::Closure& on_demuxer_config_changed_cb) 38 : MediaDecoderJob(g_audio_decoder_thread.Pointer()->message_loop_proxy(), 39 request_data_cb, 40 on_demuxer_config_changed_cb), 41 audio_codec_(kUnknownAudioCodec), 42 num_channels_(0), 43 sampling_rate_(0), 44 volume_(-1.0), 45 bytes_per_frame_(0) { 46 } 47 48 AudioDecoderJob::~AudioDecoderJob() {} 49 50 bool AudioDecoderJob::HasStream() const { 51 return audio_codec_ != kUnknownAudioCodec; 52 } 53 54 void AudioDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) { 55 // TODO(qinmin): split DemuxerConfig for audio and video separately so we 56 // can simply store the stucture here. 57 audio_codec_ = configs.audio_codec; 58 num_channels_ = configs.audio_channels; 59 sampling_rate_ = configs.audio_sampling_rate; 60 set_is_content_encrypted(configs.is_audio_encrypted); 61 audio_extra_data_ = configs.audio_extra_data; 62 bytes_per_frame_ = kBytesPerAudioOutputSample * num_channels_; 63 } 64 65 void AudioDecoderJob::SetVolume(double volume) { 66 volume_ = volume; 67 SetVolumeInternal(); 68 } 69 70 void AudioDecoderJob::SetBaseTimestamp(base::TimeDelta base_timestamp) { 71 DCHECK(!is_decoding()); 72 base_timestamp_ = base_timestamp; 73 if (audio_timestamp_helper_) 74 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); 75 } 76 77 void AudioDecoderJob::ReleaseOutputBuffer( 78 int output_buffer_index, 79 size_t size, 80 bool render_output, 81 base::TimeDelta current_presentation_timestamp, 82 const ReleaseOutputCompletionCallback& callback) { 83 render_output = render_output && (size != 0u); 84 if (render_output) { 85 int64 head_position = (static_cast<AudioCodecBridge*>( 86 media_codec_bridge_.get()))->PlayOutputBuffer( 87 output_buffer_index, size); 88 audio_timestamp_helper_->AddFrames(size / bytes_per_frame_); 89 int64 frames_to_play = 90 audio_timestamp_helper_->frame_count() - head_position; 91 DCHECK_GE(frames_to_play, 0); 92 current_presentation_timestamp = 93 audio_timestamp_helper_->GetTimestamp() - 94 audio_timestamp_helper_->GetFrameDuration(frames_to_play); 95 } else { 96 current_presentation_timestamp = kNoTimestamp(); 97 } 98 media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, false); 99 100 callback.Run(current_presentation_timestamp, 101 audio_timestamp_helper_->GetTimestamp()); 102 } 103 104 bool AudioDecoderJob::ComputeTimeToRender() const { 105 return false; 106 } 107 108 bool AudioDecoderJob::AreDemuxerConfigsChanged( 109 const DemuxerConfigs& configs) const { 110 return audio_codec_ != configs.audio_codec || 111 num_channels_ != configs.audio_channels || 112 sampling_rate_ != configs.audio_sampling_rate || 113 is_content_encrypted() != configs.is_audio_encrypted || 114 audio_extra_data_.size() != configs.audio_extra_data.size() || 115 !std::equal(audio_extra_data_.begin(), 116 audio_extra_data_.end(), 117 configs.audio_extra_data.begin()); 118 } 119 120 bool AudioDecoderJob::CreateMediaCodecBridgeInternal() { 121 media_codec_bridge_.reset(AudioCodecBridge::Create(audio_codec_)); 122 if (!media_codec_bridge_) 123 return false; 124 125 if (!(static_cast<AudioCodecBridge*>(media_codec_bridge_.get()))->Start( 126 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0], 127 audio_extra_data_.size(), true, GetMediaCrypto().obj())) { 128 media_codec_bridge_.reset(); 129 return false; 130 } 131 132 SetVolumeInternal(); 133 134 // Need to pass the base timestamp to the new decoder. 135 if (audio_timestamp_helper_) 136 base_timestamp_ = audio_timestamp_helper_->GetTimestamp(); 137 audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_)); 138 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); 139 return true; 140 } 141 142 void AudioDecoderJob::SetVolumeInternal() { 143 if (media_codec_bridge_) { 144 static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->SetVolume( 145 volume_); 146 } 147 } 148 149 } // namespace media 150