BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / media / base / android / audio_decoder_job.cc
blob07b828882a29e5d32137c2db08ad08a509308950
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.
5 #include "media/base/android/audio_decoder_job.h"
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 #include "media/base/timestamp_constants.h"
14 namespace {
16 // Use 16bit PCM for audio output. Keep this value in sync with the output
17 // format we passed to AudioTrack in MediaCodecBridge.
18 const int kBytesPerAudioOutputSample = 2;
21 namespace media {
23 class AudioDecoderThread : public base::Thread {
24 public:
25 AudioDecoderThread() : base::Thread("MediaSource_AudioDecoderThread") {
26 Start();
30 // TODO(qinmin): Check if it is tolerable to use worker pool to handle all the
31 // decoding tasks so that we don't need a global thread here.
32 // http://crbug.com/245750
33 base::LazyInstance<AudioDecoderThread>::Leaky
34 g_audio_decoder_thread = LAZY_INSTANCE_INITIALIZER;
36 AudioDecoderJob::AudioDecoderJob(
37 const base::Closure& request_data_cb,
38 const base::Closure& on_demuxer_config_changed_cb)
39 : MediaDecoderJob(g_audio_decoder_thread.Pointer()->task_runner(),
40 request_data_cb,
41 on_demuxer_config_changed_cb),
42 audio_codec_(kUnknownAudioCodec),
43 num_channels_(0),
44 config_sampling_rate_(0),
45 volume_(-1.0),
46 bytes_per_frame_(0),
47 output_sampling_rate_(0),
48 frame_count_(0) {
51 AudioDecoderJob::~AudioDecoderJob() {}
53 bool AudioDecoderJob::HasStream() const {
54 return audio_codec_ != kUnknownAudioCodec;
57 void AudioDecoderJob::Flush() {
58 MediaDecoderJob::Flush();
59 frame_count_ = 0;
62 void AudioDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) {
63 // TODO(qinmin): split DemuxerConfig for audio and video separately so we
64 // can simply store the stucture here.
65 audio_codec_ = configs.audio_codec;
66 num_channels_ = configs.audio_channels;
67 config_sampling_rate_ = configs.audio_sampling_rate;
68 set_is_content_encrypted(configs.is_audio_encrypted);
69 audio_extra_data_ = configs.audio_extra_data;
70 audio_codec_delay_ns_ = configs.audio_codec_delay_ns;
71 audio_seek_preroll_ns_ = configs.audio_seek_preroll_ns;
72 bytes_per_frame_ = kBytesPerAudioOutputSample * num_channels_;
73 if (!media_codec_bridge_)
74 output_sampling_rate_ = config_sampling_rate_;
77 void AudioDecoderJob::SetVolume(double volume) {
78 volume_ = volume;
79 SetVolumeInternal();
82 void AudioDecoderJob::SetBaseTimestamp(base::TimeDelta base_timestamp) {
83 DCHECK(!is_decoding());
84 base_timestamp_ = base_timestamp;
85 if (audio_timestamp_helper_)
86 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_);
89 void AudioDecoderJob::ResetTimestampHelper() {
90 if (audio_timestamp_helper_)
91 base_timestamp_ = audio_timestamp_helper_->GetTimestamp();
92 audio_timestamp_helper_.reset(
93 new AudioTimestampHelper(output_sampling_rate_));
94 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_);
97 void AudioDecoderJob::ReleaseOutputBuffer(
98 int output_buffer_index,
99 size_t offset,
100 size_t size,
101 bool render_output,
102 base::TimeDelta current_presentation_timestamp,
103 const ReleaseOutputCompletionCallback& callback) {
104 render_output = render_output && (size != 0u);
105 if (render_output) {
106 int64 head_position = (static_cast<AudioCodecBridge*>(
107 media_codec_bridge_.get()))->PlayOutputBuffer(
108 output_buffer_index, size, offset);
109 size_t new_frames_count = size / bytes_per_frame_;
110 frame_count_ += new_frames_count;
111 audio_timestamp_helper_->AddFrames(new_frames_count);
112 int64 frames_to_play = frame_count_ - head_position;
113 DCHECK_GE(frames_to_play, 0);
114 current_presentation_timestamp =
115 audio_timestamp_helper_->GetTimestamp() -
116 audio_timestamp_helper_->GetFrameDuration(frames_to_play);
117 } else {
118 current_presentation_timestamp = kNoTimestamp();
120 media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, false);
122 callback.Run(current_presentation_timestamp,
123 audio_timestamp_helper_->GetTimestamp());
126 bool AudioDecoderJob::ComputeTimeToRender() const {
127 return false;
130 bool AudioDecoderJob::AreDemuxerConfigsChanged(
131 const DemuxerConfigs& configs) const {
132 return audio_codec_ != configs.audio_codec ||
133 num_channels_ != configs.audio_channels ||
134 config_sampling_rate_ != configs.audio_sampling_rate ||
135 is_content_encrypted() != configs.is_audio_encrypted ||
136 audio_extra_data_.size() != configs.audio_extra_data.size() ||
137 !std::equal(audio_extra_data_.begin(),
138 audio_extra_data_.end(),
139 configs.audio_extra_data.begin());
142 MediaDecoderJob::MediaDecoderJobStatus
143 AudioDecoderJob::CreateMediaCodecBridgeInternal() {
144 media_codec_bridge_.reset(AudioCodecBridge::Create(audio_codec_));
145 if (!media_codec_bridge_)
146 return STATUS_FAILURE;
148 if (!(static_cast<AudioCodecBridge*>(media_codec_bridge_.get()))->Start(
149 audio_codec_, config_sampling_rate_, num_channels_, &audio_extra_data_[0],
150 audio_extra_data_.size(), audio_codec_delay_ns_, audio_seek_preroll_ns_,
151 true, GetMediaCrypto().obj())) {
152 media_codec_bridge_.reset();
153 return STATUS_FAILURE;
156 SetVolumeInternal();
158 // Reset values used to track codec bridge output
159 frame_count_ = 0;
160 ResetTimestampHelper();
162 return STATUS_SUCCESS;
165 void AudioDecoderJob::SetVolumeInternal() {
166 if (media_codec_bridge_) {
167 static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->SetVolume(
168 volume_);
172 void AudioDecoderJob::OnOutputFormatChanged() {
173 DCHECK(media_codec_bridge_);
175 int old_sampling_rate = output_sampling_rate_;
176 output_sampling_rate_ = media_codec_bridge_->GetOutputSamplingRate();
177 if (output_sampling_rate_ != old_sampling_rate)
178 ResetTimestampHelper();
181 } // namespace media