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"
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"
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;
23 class AudioDecoderThread
: public base::Thread
{
25 AudioDecoderThread() : base::Thread("MediaSource_AudioDecoderThread") {
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(),
41 on_demuxer_config_changed_cb
),
42 audio_codec_(kUnknownAudioCodec
),
44 config_sampling_rate_(0),
47 output_sampling_rate_(0),
51 AudioDecoderJob::~AudioDecoderJob() {}
53 bool AudioDecoderJob::HasStream() const {
54 return audio_codec_
!= kUnknownAudioCodec
;
57 void AudioDecoderJob::Flush() {
58 MediaDecoderJob::Flush();
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
) {
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
,
102 base::TimeDelta current_presentation_timestamp
,
103 const ReleaseOutputCompletionCallback
& callback
) {
104 render_output
= render_output
&& (size
!= 0u);
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
);
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 {
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
;
158 // Reset values used to track codec bridge output
160 ResetTimestampHelper();
162 return STATUS_SUCCESS
;
165 void AudioDecoderJob::SetVolumeInternal() {
166 if (media_codec_bridge_
) {
167 static_cast<AudioCodecBridge
*>(media_codec_bridge_
.get())->SetVolume(
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();