OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/android/media_codec_audio_decoder.h" | 5 #include "media/base/android/audio_media_codec_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "media/base/android/media_statistics.h" | 9 #include "media/base/android/media_statistics.h" |
10 #include "media/base/android/sdk_media_codec_bridge.h" | 10 #include "media/base/android/sdk_media_codec_bridge.h" |
11 #include "media/base/audio_timestamp_helper.h" | 11 #include "media/base/audio_timestamp_helper.h" |
12 #include "media/base/demuxer_stream.h" | 12 #include "media/base/demuxer_stream.h" |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 // Use 16bit PCM for audio output. Keep this value in sync with the output | 16 // Use 16bit PCM for audio output. Keep this value in sync with the output |
17 // format we passed to AudioTrack in MediaCodecBridge. | 17 // format we passed to AudioTrack in MediaCodecBridge. |
18 const int kBytesPerAudioOutputSample = 2; | 18 const int kBytesPerAudioOutputSample = 2; |
19 } | 19 } |
20 | 20 |
21 namespace media { | 21 namespace media { |
22 | 22 |
23 MediaCodecAudioDecoder::MediaCodecAudioDecoder( | 23 AudioMediaCodecDecoder::AudioMediaCodecDecoder( |
24 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 24 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
25 FrameStatistics* frame_statistics, | 25 FrameStatistics* frame_statistics, |
26 const base::Closure& request_data_cb, | 26 const base::Closure& request_data_cb, |
27 const base::Closure& starvation_cb, | 27 const base::Closure& starvation_cb, |
28 const base::Closure& decoder_drained_cb, | 28 const base::Closure& decoder_drained_cb, |
29 const base::Closure& stop_done_cb, | 29 const base::Closure& stop_done_cb, |
30 const base::Closure& waiting_for_decryption_key_cb, | 30 const base::Closure& waiting_for_decryption_key_cb, |
31 const base::Closure& error_cb, | 31 const base::Closure& error_cb, |
32 const SetTimeCallback& update_current_time_cb) | 32 const SetTimeCallback& update_current_time_cb) |
33 : MediaCodecDecoder("AudioDecoder", | 33 : MediaCodecDecoder("AudioDecoder", |
34 media_task_runner, | 34 media_task_runner, |
35 frame_statistics, | 35 frame_statistics, |
36 request_data_cb, | 36 request_data_cb, |
37 starvation_cb, | 37 starvation_cb, |
38 decoder_drained_cb, | 38 decoder_drained_cb, |
39 stop_done_cb, | 39 stop_done_cb, |
40 waiting_for_decryption_key_cb, | 40 waiting_for_decryption_key_cb, |
41 error_cb), | 41 error_cb), |
42 volume_(-1.0), | 42 volume_(-1.0), |
43 bytes_per_frame_(0), | 43 bytes_per_frame_(0), |
44 output_sampling_rate_(0), | 44 output_sampling_rate_(0), |
45 frame_count_(0), | 45 frame_count_(0), |
46 update_current_time_cb_(update_current_time_cb) { | 46 update_current_time_cb_(update_current_time_cb) {} |
47 } | |
48 | 47 |
49 MediaCodecAudioDecoder::~MediaCodecAudioDecoder() { | 48 AudioMediaCodecDecoder::~AudioMediaCodecDecoder() { |
50 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 49 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
51 DVLOG(1) << "AudioDecoder::~AudioDecoder()"; | 50 DVLOG(1) << "AudioDecoder::~AudioDecoder()"; |
52 ReleaseDecoderResources(); | 51 ReleaseDecoderResources(); |
53 } | 52 } |
54 | 53 |
55 const char* MediaCodecAudioDecoder::class_name() const { | 54 const char* AudioMediaCodecDecoder::class_name() const { |
56 return "AudioDecoder"; | 55 return "AudioDecoder"; |
57 } | 56 } |
58 | 57 |
59 bool MediaCodecAudioDecoder::HasStream() const { | 58 bool AudioMediaCodecDecoder::HasStream() const { |
60 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 59 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
61 | 60 |
62 return configs_.audio_codec != kUnknownAudioCodec; | 61 return configs_.audio_codec != kUnknownAudioCodec; |
63 } | 62 } |
64 | 63 |
65 void MediaCodecAudioDecoder::SetDemuxerConfigs(const DemuxerConfigs& configs) { | 64 void AudioMediaCodecDecoder::SetDemuxerConfigs(const DemuxerConfigs& configs) { |
66 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << configs; | 65 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << configs; |
67 | 66 |
68 configs_ = configs; | 67 configs_ = configs; |
69 if (!media_codec_bridge_) | 68 if (!media_codec_bridge_) |
70 output_sampling_rate_ = configs.audio_sampling_rate; | 69 output_sampling_rate_ = configs.audio_sampling_rate; |
71 } | 70 } |
72 | 71 |
73 bool MediaCodecAudioDecoder::IsContentEncrypted() const { | 72 bool AudioMediaCodecDecoder::IsContentEncrypted() const { |
74 // Make sure SetDemuxerConfigs() as been called. | 73 // Make sure SetDemuxerConfigs() as been called. |
75 DCHECK(configs_.audio_codec != kUnknownAudioCodec); | 74 DCHECK(configs_.audio_codec != kUnknownAudioCodec); |
76 return configs_.is_audio_encrypted; | 75 return configs_.is_audio_encrypted; |
77 } | 76 } |
78 | 77 |
79 void MediaCodecAudioDecoder::ReleaseDecoderResources() { | 78 void AudioMediaCodecDecoder::ReleaseDecoderResources() { |
80 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 79 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
81 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 80 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
82 | 81 |
83 DoEmergencyStop(); | 82 DoEmergencyStop(); |
84 | 83 |
85 ReleaseMediaCodec(); | 84 ReleaseMediaCodec(); |
86 } | 85 } |
87 | 86 |
88 void MediaCodecAudioDecoder::Flush() { | 87 void AudioMediaCodecDecoder::Flush() { |
89 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 88 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
90 | 89 |
91 MediaCodecDecoder::Flush(); | 90 MediaCodecDecoder::Flush(); |
92 frame_count_ = 0; | 91 frame_count_ = 0; |
93 } | 92 } |
94 | 93 |
95 void MediaCodecAudioDecoder::SetVolume(double volume) { | 94 void AudioMediaCodecDecoder::SetVolume(double volume) { |
96 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 95 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
97 | 96 |
98 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << volume; | 97 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << volume; |
99 | 98 |
100 volume_ = volume; | 99 volume_ = volume; |
101 SetVolumeInternal(); | 100 SetVolumeInternal(); |
102 } | 101 } |
103 | 102 |
104 void MediaCodecAudioDecoder::SetBaseTimestamp(base::TimeDelta base_timestamp) { | 103 void AudioMediaCodecDecoder::SetBaseTimestamp(base::TimeDelta base_timestamp) { |
105 // Called from Media thread and Decoder thread. When called from Media thread | 104 // Called from Media thread and Decoder thread. When called from Media thread |
106 // Decoder thread should not be running. | 105 // Decoder thread should not be running. |
107 | 106 |
108 DVLOG(1) << __FUNCTION__ << " " << base_timestamp; | 107 DVLOG(1) << __FUNCTION__ << " " << base_timestamp; |
109 | 108 |
110 base_timestamp_ = base_timestamp; | 109 base_timestamp_ = base_timestamp; |
111 if (audio_timestamp_helper_) | 110 if (audio_timestamp_helper_) |
112 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); | 111 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); |
113 } | 112 } |
114 | 113 |
115 bool MediaCodecAudioDecoder::IsCodecReconfigureNeeded( | 114 bool AudioMediaCodecDecoder::IsCodecReconfigureNeeded( |
116 const DemuxerConfigs& next) const { | 115 const DemuxerConfigs& next) const { |
117 if (always_reconfigure_for_tests_) | 116 if (always_reconfigure_for_tests_) |
118 return true; | 117 return true; |
119 | 118 |
120 return configs_.audio_codec != next.audio_codec || | 119 return configs_.audio_codec != next.audio_codec || |
121 configs_.audio_channels != next.audio_channels || | 120 configs_.audio_channels != next.audio_channels || |
122 configs_.audio_sampling_rate != next.audio_sampling_rate || | 121 configs_.audio_sampling_rate != next.audio_sampling_rate || |
123 configs_.is_audio_encrypted != next.is_audio_encrypted || | 122 configs_.is_audio_encrypted != next.is_audio_encrypted || |
124 configs_.audio_extra_data.size() != next.audio_extra_data.size() || | 123 configs_.audio_extra_data.size() != next.audio_extra_data.size() || |
125 !std::equal(configs_.audio_extra_data.begin(), | 124 !std::equal(configs_.audio_extra_data.begin(), |
126 configs_.audio_extra_data.end(), | 125 configs_.audio_extra_data.end(), |
127 next.audio_extra_data.begin()); | 126 next.audio_extra_data.begin()); |
128 } | 127 } |
129 | 128 |
130 MediaCodecDecoder::ConfigStatus MediaCodecAudioDecoder::ConfigureInternal( | 129 MediaCodecDecoder::ConfigStatus AudioMediaCodecDecoder::ConfigureInternal( |
131 jobject media_crypto) { | 130 jobject media_crypto) { |
132 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 131 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
133 | 132 |
134 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 133 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
135 | 134 |
136 if (configs_.audio_codec == kUnknownAudioCodec) { | 135 if (configs_.audio_codec == kUnknownAudioCodec) { |
137 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 136 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
138 << " configuration parameters are required"; | 137 << " configuration parameters are required"; |
139 return kConfigFailure; | 138 return kConfigFailure; |
140 } | 139 } |
(...skipping 22 matching lines...) Expand all Loading... |
163 bytes_per_frame_ = kBytesPerAudioOutputSample * configs_.audio_channels; | 162 bytes_per_frame_ = kBytesPerAudioOutputSample * configs_.audio_channels; |
164 frame_count_ = 0; | 163 frame_count_ = 0; |
165 ResetTimestampHelper(); | 164 ResetTimestampHelper(); |
166 | 165 |
167 if (!codec_created_for_tests_cb_.is_null()) | 166 if (!codec_created_for_tests_cb_.is_null()) |
168 media_task_runner_->PostTask(FROM_HERE, codec_created_for_tests_cb_); | 167 media_task_runner_->PostTask(FROM_HERE, codec_created_for_tests_cb_); |
169 | 168 |
170 return kConfigOk; | 169 return kConfigOk; |
171 } | 170 } |
172 | 171 |
173 void MediaCodecAudioDecoder::OnOutputFormatChanged() { | 172 void AudioMediaCodecDecoder::OnOutputFormatChanged() { |
174 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 173 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
175 | 174 |
176 DCHECK(media_codec_bridge_); | 175 DCHECK(media_codec_bridge_); |
177 | 176 |
178 int old_sampling_rate = output_sampling_rate_; | 177 int old_sampling_rate = output_sampling_rate_; |
179 output_sampling_rate_ = media_codec_bridge_->GetOutputSamplingRate(); | 178 output_sampling_rate_ = media_codec_bridge_->GetOutputSamplingRate(); |
180 if (output_sampling_rate_ != old_sampling_rate) | 179 if (output_sampling_rate_ != old_sampling_rate) |
181 ResetTimestampHelper(); | 180 ResetTimestampHelper(); |
182 } | 181 } |
183 | 182 |
184 void MediaCodecAudioDecoder::Render(int buffer_index, | 183 void AudioMediaCodecDecoder::Render(int buffer_index, |
185 size_t offset, | 184 size_t offset, |
186 size_t size, | 185 size_t size, |
187 RenderMode render_mode, | 186 RenderMode render_mode, |
188 base::TimeDelta pts, | 187 base::TimeDelta pts, |
189 bool eos_encountered) { | 188 bool eos_encountered) { |
190 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 189 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
191 | 190 |
192 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts << " " | 191 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts << " " |
193 << AsString(render_mode); | 192 << AsString(render_mode); |
194 | 193 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 FROM_HERE, base::Bind(update_current_time_cb_, now_playing, | 255 FROM_HERE, base::Bind(update_current_time_cb_, now_playing, |
257 last_buffered, false)); | 256 last_buffered, false)); |
258 } | 257 } |
259 } | 258 } |
260 | 259 |
261 media_codec_bridge_->ReleaseOutputBuffer(buffer_index, false); | 260 media_codec_bridge_->ReleaseOutputBuffer(buffer_index, false); |
262 | 261 |
263 CheckLastFrame(eos_encountered, false); // no delayed tasks | 262 CheckLastFrame(eos_encountered, false); // no delayed tasks |
264 } | 263 } |
265 | 264 |
266 void MediaCodecAudioDecoder::SetVolumeInternal() { | 265 void AudioMediaCodecDecoder::SetVolumeInternal() { |
267 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 266 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
268 | 267 |
269 if (media_codec_bridge_) { | 268 if (media_codec_bridge_) { |
270 static_cast<AudioCodecBridge*>(media_codec_bridge_.get()) | 269 static_cast<AudioCodecBridge*>(media_codec_bridge_.get()) |
271 ->SetVolume(volume_); | 270 ->SetVolume(volume_); |
272 } | 271 } |
273 } | 272 } |
274 | 273 |
275 void MediaCodecAudioDecoder::ResetTimestampHelper() { | 274 void AudioMediaCodecDecoder::ResetTimestampHelper() { |
276 // Media thread or Decoder thread | 275 // Media thread or Decoder thread |
277 // When this method is called on Media thread, decoder thread | 276 // When this method is called on Media thread, decoder thread |
278 // should not be running. | 277 // should not be running. |
279 | 278 |
280 if (audio_timestamp_helper_) | 279 if (audio_timestamp_helper_) |
281 base_timestamp_ = audio_timestamp_helper_->GetTimestamp(); | 280 base_timestamp_ = audio_timestamp_helper_->GetTimestamp(); |
282 | 281 |
283 audio_timestamp_helper_.reset( | 282 audio_timestamp_helper_.reset( |
284 new AudioTimestampHelper(configs_.audio_sampling_rate)); | 283 new AudioTimestampHelper(configs_.audio_sampling_rate)); |
285 | 284 |
286 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); | 285 audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_); |
287 } | 286 } |
288 | 287 |
289 } // namespace media | 288 } // namespace media |
OLD | NEW |