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::Create(
36 const AudioCodec audio_codec
,
39 const uint8
* extra_data
,
40 size_t extra_data_size
,
42 const base::Closure
& request_data_cb
) {
43 scoped_ptr
<AudioCodecBridge
> codec(AudioCodecBridge::Create(audio_codec
));
44 if (codec
&& codec
->Start(audio_codec
, sample_rate
, channel_count
, extra_data
,
45 extra_data_size
, true, media_crypto
)) {
46 scoped_ptr
<AudioTimestampHelper
> audio_timestamp_helper(
47 new AudioTimestampHelper(sample_rate
));
48 return new AudioDecoderJob(
49 audio_timestamp_helper
.Pass(), codec
.Pass(),
50 kBytesPerAudioOutputSample
* channel_count
, request_data_cb
);
52 LOG(ERROR
) << "Failed to create AudioDecoderJob.";
56 AudioDecoderJob::AudioDecoderJob(
57 scoped_ptr
<AudioTimestampHelper
> audio_timestamp_helper
,
58 scoped_ptr
<AudioCodecBridge
> audio_codec_bridge
,
60 const base::Closure
& request_data_cb
)
61 : MediaDecoderJob(g_audio_decoder_thread
.Pointer()->message_loop_proxy(),
62 audio_codec_bridge
.get(), request_data_cb
),
63 bytes_per_frame_(bytes_per_frame
),
64 audio_codec_bridge_(audio_codec_bridge
.Pass()),
65 audio_timestamp_helper_(audio_timestamp_helper
.Pass()) {
68 AudioDecoderJob::~AudioDecoderJob() {
71 void AudioDecoderJob::SetVolume(double volume
) {
72 audio_codec_bridge_
->SetVolume(volume
);
75 void AudioDecoderJob::SetBaseTimestamp(base::TimeDelta base_timestamp
) {
76 audio_timestamp_helper_
->SetBaseTimestamp(base_timestamp
);
79 void AudioDecoderJob::ReleaseOutputBuffer(
80 int output_buffer_index
,
83 base::TimeDelta current_presentation_timestamp
,
84 const ReleaseOutputCompletionCallback
& callback
) {
85 render_output
= render_output
&& (size
!= 0u);
87 int64 head_position
= audio_codec_bridge_
->PlayOutputBuffer(
88 output_buffer_index
, size
);
89 audio_timestamp_helper_
->AddFrames(size
/ (bytes_per_frame_
));
90 int64 frames_to_play
=
91 audio_timestamp_helper_
->frame_count() - head_position
;
92 DCHECK_GE(frames_to_play
, 0);
93 current_presentation_timestamp
=
94 audio_timestamp_helper_
->GetTimestamp() -
95 audio_timestamp_helper_
->GetFrameDuration(frames_to_play
);
97 current_presentation_timestamp
= kNoTimestamp();
99 audio_codec_bridge_
->ReleaseOutputBuffer(output_buffer_index
, false);
100 callback
.Run(current_presentation_timestamp
,
101 audio_timestamp_helper_
->GetTimestamp());
104 bool AudioDecoderJob::ComputeTimeToRender() const {