1 // Copyright 2015 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/media_codec_audio_decoder.h"
8 #include "base/logging.h"
9 #include "media/base/android/media_codec_bridge.h"
10 #include "media/base/audio_timestamp_helper.h"
11 #include "media/base/demuxer_stream.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 MediaCodecAudioDecoder::MediaCodecAudioDecoder(
23 const scoped_refptr
<base::SingleThreadTaskRunner
>& media_task_runner
,
24 const base::Closure
& request_data_cb
,
25 const base::Closure
& starvation_cb
,
26 const base::Closure
& decoder_drained_cb
,
27 const base::Closure
& stop_done_cb
,
28 const base::Closure
& error_cb
,
29 const SetTimeCallback
& update_current_time_cb
)
30 : MediaCodecDecoder(media_task_runner
,
39 output_sampling_rate_(0),
41 update_current_time_cb_(update_current_time_cb
) {
44 MediaCodecAudioDecoder::~MediaCodecAudioDecoder() {
45 DCHECK(media_task_runner_
->BelongsToCurrentThread());
46 DVLOG(1) << "AudioDecoder::~AudioDecoder()";
47 ReleaseDecoderResources();
50 const char* MediaCodecAudioDecoder::class_name() const {
51 return "AudioDecoder";
54 bool MediaCodecAudioDecoder::HasStream() const {
55 DCHECK(media_task_runner_
->BelongsToCurrentThread());
57 return configs_
.audio_codec
!= kUnknownAudioCodec
;
60 void MediaCodecAudioDecoder::SetDemuxerConfigs(const DemuxerConfigs
& configs
) {
61 DVLOG(1) << class_name() << "::" << __FUNCTION__
<< " " << configs
;
64 if (!media_codec_bridge_
)
65 output_sampling_rate_
= configs
.audio_sampling_rate
;
68 void MediaCodecAudioDecoder::ReleaseDecoderResources() {
69 DCHECK(media_task_runner_
->BelongsToCurrentThread());
70 DVLOG(1) << class_name() << "::" << __FUNCTION__
;
77 void MediaCodecAudioDecoder::Flush() {
78 DCHECK(media_task_runner_
->BelongsToCurrentThread());
80 MediaCodecDecoder::Flush();
84 void MediaCodecAudioDecoder::SetVolume(double volume
) {
85 DCHECK(media_task_runner_
->BelongsToCurrentThread());
87 DVLOG(1) << class_name() << "::" << __FUNCTION__
<< " " << volume
;
93 void MediaCodecAudioDecoder::SetBaseTimestamp(base::TimeDelta base_timestamp
) {
94 // Called from Media thread and Decoder thread. When called from Media thread
95 // Decoder thread should not be running.
97 DVLOG(1) << __FUNCTION__
<< " " << base_timestamp
;
99 base_timestamp_
= base_timestamp
;
100 if (audio_timestamp_helper_
)
101 audio_timestamp_helper_
->SetBaseTimestamp(base_timestamp_
);
104 bool MediaCodecAudioDecoder::IsCodecReconfigureNeeded(
105 const DemuxerConfigs
& next
) const {
106 if (always_reconfigure_for_tests_
)
109 return configs_
.audio_codec
!= next
.audio_codec
||
110 configs_
.audio_channels
!= next
.audio_channels
||
111 configs_
.audio_sampling_rate
!= next
.audio_sampling_rate
||
112 next
.is_audio_encrypted
!= next
.is_audio_encrypted
||
113 configs_
.audio_extra_data
.size() != next
.audio_extra_data
.size() ||
114 !std::equal(configs_
.audio_extra_data
.begin(),
115 configs_
.audio_extra_data
.end(),
116 next
.audio_extra_data
.begin());
119 MediaCodecDecoder::ConfigStatus
MediaCodecAudioDecoder::ConfigureInternal() {
120 DCHECK(media_task_runner_
->BelongsToCurrentThread());
122 DVLOG(1) << class_name() << "::" << __FUNCTION__
;
124 if (configs_
.audio_codec
== kUnknownAudioCodec
) {
125 DVLOG(0) << class_name() << "::" << __FUNCTION__
126 << " configuration parameters are required";
127 return kConfigFailure
;
130 media_codec_bridge_
.reset(AudioCodecBridge::Create(configs_
.audio_codec
));
131 if (!media_codec_bridge_
)
132 return kConfigFailure
;
134 if (!(static_cast<AudioCodecBridge
*>(media_codec_bridge_
.get()))
136 configs_
.audio_codec
,
137 configs_
.audio_sampling_rate
,
138 configs_
.audio_channels
,
139 &configs_
.audio_extra_data
[0],
140 configs_
.audio_extra_data
.size(),
141 configs_
.audio_codec_delay_ns
,
142 configs_
.audio_seek_preroll_ns
,
144 GetMediaCrypto().obj())) {
145 DVLOG(0) << class_name() << "::" << __FUNCTION__
146 << " failed: cannot start audio codec";
148 media_codec_bridge_
.reset();
149 return kConfigFailure
;
152 DVLOG(0) << class_name() << "::" << __FUNCTION__
<< " succeeded";
156 bytes_per_frame_
= kBytesPerAudioOutputSample
* configs_
.audio_channels
;
158 ResetTimestampHelper();
160 if (!codec_created_for_tests_cb_
.is_null())
161 media_task_runner_
->PostTask(FROM_HERE
, codec_created_for_tests_cb_
);
166 void MediaCodecAudioDecoder::OnOutputFormatChanged() {
167 DCHECK(decoder_thread_
.task_runner()->BelongsToCurrentThread());
169 DCHECK(media_codec_bridge_
);
171 int old_sampling_rate
= output_sampling_rate_
;
172 output_sampling_rate_
= media_codec_bridge_
->GetOutputSamplingRate();
173 if (output_sampling_rate_
!= old_sampling_rate
)
174 ResetTimestampHelper();
177 void MediaCodecAudioDecoder::Render(int buffer_index
,
180 RenderMode render_mode
,
182 bool eos_encountered
) {
183 DCHECK(decoder_thread_
.task_runner()->BelongsToCurrentThread());
185 DVLOG(2) << class_name() << "::" << __FUNCTION__
<< " pts:" << pts
<< " "
186 << AsString(render_mode
);
188 const bool do_play
= (render_mode
!= kRenderSkip
);
191 AudioCodecBridge
* audio_codec
=
192 static_cast<AudioCodecBridge
*>(media_codec_bridge_
.get());
196 const bool postpone
= (render_mode
== kRenderAfterPreroll
);
198 int64 head_position
=
199 audio_codec
->PlayOutputBuffer(buffer_index
, size
, offset
, postpone
);
201 // Reset the base timestamp if we have not started playing.
202 // SetBaseTimestamp() must be called before AddFrames() since it resets the
203 // internal frame count.
204 if (postpone
&& !frame_count_
)
205 SetBaseTimestamp(pts
);
207 size_t new_frames_count
= size
/ bytes_per_frame_
;
208 frame_count_
+= new_frames_count
;
209 audio_timestamp_helper_
->AddFrames(new_frames_count
);
212 DVLOG(2) << class_name() << "::" << __FUNCTION__
<< " pts:" << pts
215 // Let the player adjust the start time.
216 media_task_runner_
->PostTask(
217 FROM_HERE
, base::Bind(update_current_time_cb_
, pts
, pts
, true));
219 int64 frames_to_play
= frame_count_
- head_position
;
221 DCHECK_GE(frames_to_play
, 0) << class_name() << "::" << __FUNCTION__
223 << " frame_count_:" << frame_count_
224 << " head_position:" << head_position
;
226 base::TimeDelta last_buffered
= audio_timestamp_helper_
->GetTimestamp();
227 base::TimeDelta now_playing
=
229 audio_timestamp_helper_
->GetFrameDuration(frames_to_play
);
231 DVLOG(2) << class_name() << "::" << __FUNCTION__
<< " pts:" << pts
232 << " will play: [" << now_playing
<< "," << last_buffered
<< "]";
234 media_task_runner_
->PostTask(
235 FROM_HERE
, base::Bind(update_current_time_cb_
, now_playing
,
236 last_buffered
, false));
240 media_codec_bridge_
->ReleaseOutputBuffer(buffer_index
, false);
242 CheckLastFrame(eos_encountered
, false); // no delayed tasks
245 void MediaCodecAudioDecoder::SetVolumeInternal() {
246 DCHECK(media_task_runner_
->BelongsToCurrentThread());
248 if (media_codec_bridge_
) {
249 static_cast<AudioCodecBridge
*>(media_codec_bridge_
.get())
250 ->SetVolume(volume_
);
254 void MediaCodecAudioDecoder::ResetTimestampHelper() {
255 // Media thread or Decoder thread
256 // When this method is called on Media thread, decoder thread
257 // should not be running.
259 if (audio_timestamp_helper_
)
260 base_timestamp_
= audio_timestamp_helper_
->GetTimestamp();
262 audio_timestamp_helper_
.reset(
263 new AudioTimestampHelper(configs_
.audio_sampling_rate
));
265 audio_timestamp_helper_
->SetBaseTimestamp(base_timestamp_
);