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"
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;
22 class AudioDecoderThread
: public base::Thread
{
24 AudioDecoderThread() : base::Thread("MediaSource_AudioDecoderThread") {
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
;
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(),
40 on_demuxer_config_changed_cb
),
41 audio_codec_(kUnknownAudioCodec
),
48 AudioDecoderJob::~AudioDecoderJob() {}
50 bool AudioDecoderJob::HasStream() const {
51 return audio_codec_
!= kUnknownAudioCodec
;
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_
;
65 void AudioDecoderJob::SetVolume(double volume
) {
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_
);
77 void AudioDecoderJob::ReleaseOutputBuffer(
78 int output_buffer_index
,
81 base::TimeDelta current_presentation_timestamp
,
82 const ReleaseOutputCompletionCallback
& callback
) {
83 render_output
= render_output
&& (size
!= 0u);
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
);
96 current_presentation_timestamp
= kNoTimestamp();
98 media_codec_bridge_
->ReleaseOutputBuffer(output_buffer_index
, false);
100 callback
.Run(current_presentation_timestamp
,
101 audio_timestamp_helper_
->GetTimestamp());
104 bool AudioDecoderJob::ComputeTimeToRender() const {
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());
120 bool AudioDecoderJob::CreateMediaCodecBridgeInternal() {
121 media_codec_bridge_
.reset(AudioCodecBridge::Create(audio_codec_
));
122 if (!media_codec_bridge_
)
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();
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_
);
142 void AudioDecoderJob::SetVolumeInternal() {
143 if (media_codec_bridge_
) {
144 static_cast<AudioCodecBridge
*>(media_codec_bridge_
.get())->SetVolume(