OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/filters/audio_file_reader.h" | 5 #include "media/filters/audio_file_reader.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <cmath> | 9 #include <cmath> |
10 #include <vector> | |
10 | 11 |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/numerics/safe_math.h" | 13 #include "base/numerics/safe_math.h" |
13 #include "base/time/time.h" | 14 #include "base/time/time.h" |
14 #include "media/base/audio_bus.h" | 15 #include "media/base/audio_bus.h" |
16 #include "media/base/audio_sample_types.h" | |
15 #include "media/ffmpeg/ffmpeg_common.h" | 17 #include "media/ffmpeg/ffmpeg_common.h" |
16 | 18 |
17 namespace media { | 19 namespace media { |
18 | 20 |
19 // AAC(M4A) decoding specific constants. | 21 // AAC(M4A) decoding specific constants. |
20 static const int kAACPrimingFrameCount = 2112; | 22 static const int kAACPrimingFrameCount = 2112; |
21 static const int kAACRemainderFrameCount = 519; | 23 static const int kAACRemainderFrameCount = 519; |
22 | 24 |
23 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol) | 25 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol) |
24 : stream_index_(0), | 26 : stream_index_(0), |
25 protocol_(protocol), | 27 protocol_(protocol), |
26 audio_codec_(kUnknownAudioCodec), | 28 audio_codec_(kUnknownAudioCodec), |
27 channels_(0), | 29 channels_(0), |
28 sample_rate_(0), | 30 sample_rate_(0), |
29 av_sample_format_(0) {} | 31 av_sample_format_(0) {} |
30 | 32 |
31 AudioFileReader::~AudioFileReader() { | 33 AudioFileReader::~AudioFileReader() { |
32 Close(); | 34 Close(); |
33 } | 35 } |
34 | 36 |
35 bool AudioFileReader::Open() { | 37 bool AudioFileReader::Open() { |
36 if (!OpenDemuxer()) | 38 return OpenDemuxer() && OpenDecoder(); |
37 return false; | |
38 if (!OpenDecoder()) | |
39 return false; | |
40 | |
41 // If the duration is unknown, fail out; this API can not work with streams of | |
42 // unknown duration currently. | |
43 return glue_->format_context()->duration != AV_NOPTS_VALUE; | |
44 } | 39 } |
45 | 40 |
46 bool AudioFileReader::OpenDemuxer() { | 41 bool AudioFileReader::OpenDemuxer() { |
47 glue_.reset(new FFmpegGlue(protocol_)); | 42 glue_.reset(new FFmpegGlue(protocol_)); |
48 AVFormatContext* format_context = glue_->format_context(); | 43 AVFormatContext* format_context = glue_->format_context(); |
49 | 44 |
50 // Open FFmpeg AVFormatContext. | 45 // Open FFmpeg AVFormatContext. |
51 if (!glue_->OpenContext()) { | 46 if (!glue_->OpenContext()) { |
52 DLOG(WARNING) << "AudioFileReader::Open() : error in avformat_open_input()"; | 47 DLOG(WARNING) << "AudioFileReader::Open() : error in avformat_open_input()"; |
53 return false; | 48 return false; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 } | 115 } |
121 | 116 |
122 // Store initial values to guard against midstream configuration changes. | 117 // Store initial values to guard against midstream configuration changes. |
123 channels_ = codec_context_->channels; | 118 channels_ = codec_context_->channels; |
124 audio_codec_ = CodecIDToAudioCodec(codec_context_->codec_id); | 119 audio_codec_ = CodecIDToAudioCodec(codec_context_->codec_id); |
125 sample_rate_ = codec_context_->sample_rate; | 120 sample_rate_ = codec_context_->sample_rate; |
126 av_sample_format_ = codec_context_->sample_fmt; | 121 av_sample_format_ = codec_context_->sample_fmt; |
127 return true; | 122 return true; |
128 } | 123 } |
129 | 124 |
125 bool AudioFileReader::HasKnownDuration() const { | |
126 return glue_->format_context()->duration != AV_NOPTS_VALUE; | |
127 } | |
128 | |
130 void AudioFileReader::Close() { | 129 void AudioFileReader::Close() { |
131 codec_context_.reset(); | 130 codec_context_.reset(); |
132 glue_.reset(); | 131 glue_.reset(); |
133 } | 132 } |
134 | 133 |
135 int AudioFileReader::Read(AudioBus* audio_bus) { | 134 int AudioFileReader::Read( |
136 DCHECK(glue_.get() && codec_context_) << | 135 std::vector<std::unique_ptr<AudioBus>>* decoded_audio_packets) { |
137 "AudioFileReader::Read() : reader is not opened!"; | 136 DCHECK(glue_.get() && codec_context_) |
138 | 137 << "AudioFileReader::Read() : reader is not opened!"; |
139 DCHECK_EQ(audio_bus->channels(), channels()); | |
140 if (audio_bus->channels() != channels()) | |
141 return 0; | |
142 | |
143 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt); | 138 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt); |
144 | 139 |
145 // Holds decoded audio. | 140 // Holds decoded audio. |
146 std::unique_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame(av_frame_alloc()); | 141 std::unique_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame(av_frame_alloc()); |
147 | 142 |
148 // Read until we hit EOF or we've read the requested number of frames. | |
149 AVPacket packet; | 143 AVPacket packet; |
150 int current_frame = 0; | 144 size_t total_frames = 0; |
DaleCurtis
2017/02/09 23:24:43
Int?
Raymond Toy
2017/02/10 16:36:02
Done.
| |
151 bool continue_decoding = true; | 145 bool continue_decoding = true; |
152 | 146 |
153 while (current_frame < audio_bus->frames() && continue_decoding && | 147 while (continue_decoding && ReadPacket(&packet)) { |
154 ReadPacket(&packet)) { | |
155 // Make a shallow copy of packet so we can slide packet.data as frames are | 148 // Make a shallow copy of packet so we can slide packet.data as frames are |
156 // decoded from the packet; otherwise av_packet_unref() will corrupt memory. | 149 // decoded from the packet; otherwise av_packet_unref() will corrupt memory. |
157 AVPacket packet_temp = packet; | 150 AVPacket packet_temp = packet; |
158 do { | 151 do { |
159 // Reset frame to default values. | 152 // Reset frame to default values. |
160 av_frame_unref(av_frame.get()); | 153 av_frame_unref(av_frame.get()); |
161 | 154 |
162 int frame_decoded = 0; | 155 int frame_decoded = 0; |
163 int result = avcodec_decode_audio4(codec_context_.get(), av_frame.get(), | 156 int result = avcodec_decode_audio4(codec_context_.get(), av_frame.get(), |
164 &frame_decoded, &packet_temp); | 157 &frame_decoded, &packet_temp); |
165 | 158 |
166 if (result < 0) { | 159 if (result < 0) { |
160 // Unable to decode this current packet. We'll skip it and | |
161 // continue decoding the next packet. | |
167 DLOG(WARNING) | 162 DLOG(WARNING) |
168 << "AudioFileReader::Read() : error in avcodec_decode_audio4() -" | 163 << "AudioFileReader::Read() : error in avcodec_decode_audio4() -" |
169 << result; | 164 << result; |
170 break; | 165 break; |
171 } | 166 } |
172 | 167 |
173 // Update packet size and data pointer in case we need to call the decoder | 168 // Update packet size and data pointer in case we need to call the decoder |
174 // with the remaining bytes from this packet. | 169 // with the remaining bytes from this packet. |
175 packet_temp.size -= result; | 170 packet_temp.size -= result; |
176 packet_temp.data += result; | 171 packet_temp.data += result; |
177 | 172 |
178 if (!frame_decoded) | 173 if (!frame_decoded) |
179 continue; | 174 continue; |
180 | 175 |
181 // Determine the number of sample-frames we just decoded. Check overflow. | 176 // Determine the number of sample-frames we just decoded. Check overflow. |
182 int frames_read = av_frame->nb_samples; | 177 int frames_read = av_frame->nb_samples; |
183 if (frames_read < 0) { | 178 if (frames_read < 0) { |
184 continue_decoding = false; | 179 continue_decoding = false; |
185 break; | 180 break; |
186 } | 181 } |
187 | 182 |
188 #ifdef CHROMIUM_NO_AVFRAME_CHANNELS | 183 #ifdef CHROMIUM_NO_AVFRAME_CHANNELS |
189 int channels = av_get_channel_layout_nb_channels( | 184 int channels = |
190 av_frame->channel_layout); | 185 av_get_channel_layout_nb_channels(av_frame->channel_layout); |
191 #else | 186 #else |
192 int channels = av_frame->channels; | 187 int channels = av_frame->channels; |
193 #endif | 188 #endif |
194 if (av_frame->sample_rate != sample_rate_ || | 189 if (av_frame->sample_rate != sample_rate_ || channels != channels_ || |
195 channels != channels_ || | |
196 av_frame->format != av_sample_format_) { | 190 av_frame->format != av_sample_format_) { |
197 DLOG(ERROR) << "Unsupported midstream configuration change!" | 191 DLOG(ERROR) << "Unsupported midstream configuration change!" |
198 << " Sample Rate: " << av_frame->sample_rate << " vs " | 192 << " Sample Rate: " << av_frame->sample_rate << " vs " |
199 << sample_rate_ | 193 << sample_rate_ << ", Channels: " << channels << " vs " |
200 << ", Channels: " << channels << " vs " | 194 << channels_ << ", Sample Format: " << av_frame->format |
201 << channels_ | 195 << " vs " << av_sample_format_; |
202 << ", Sample Format: " << av_frame->format << " vs " | |
203 << av_sample_format_; | |
204 | 196 |
205 // This is an unrecoverable error, so bail out. | 197 // This is an unrecoverable error, so bail out. We'll return |
198 // whatever we've decoded up to this point. | |
206 continue_decoding = false; | 199 continue_decoding = false; |
207 break; | 200 break; |
208 } | 201 } |
209 | 202 |
210 // Truncate, if necessary, if the destination isn't big enough. | |
211 if (current_frame + frames_read > audio_bus->frames()) { | |
212 DLOG(ERROR) << "Truncating decoded data due to output size."; | |
213 frames_read = audio_bus->frames() - current_frame; | |
214 } | |
215 | |
216 // Deinterleave each channel and convert to 32bit floating-point with | 203 // Deinterleave each channel and convert to 32bit floating-point with |
217 // nominal range -1.0 -> +1.0. If the output is already in float planar | 204 // nominal range -1.0 -> +1.0. If the output is already in float planar |
218 // format, just copy it into the AudioBus. | 205 // format, just copy it into the AudioBus. |
206 decoded_audio_packets->emplace_back( | |
207 AudioBus::Create(channels, frames_read)); | |
208 AudioBus* audio_bus = decoded_audio_packets->back().get(); | |
209 | |
219 if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLT) { | 210 if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLT) { |
DaleCurtis
2017/02/09 23:24:43
Note, if memory balloons too much here we can stor
| |
220 float* decoded_audio_data = reinterpret_cast<float*>(av_frame->data[0]); | 211 audio_bus->FromInterleaved<Float32SampleTypeTraits>( |
221 int channels = audio_bus->channels(); | 212 reinterpret_cast<float*>(av_frame->data[0]), frames_read); |
222 for (int ch = 0; ch < channels; ++ch) { | |
223 float* bus_data = audio_bus->channel(ch) + current_frame; | |
224 for (int i = 0, offset = ch; i < frames_read; | |
225 ++i, offset += channels) { | |
226 bus_data[i] = decoded_audio_data[offset]; | |
227 } | |
228 } | |
229 } else if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLTP) { | 213 } else if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLTP) { |
230 for (int ch = 0; ch < audio_bus->channels(); ++ch) { | 214 for (int ch = 0; ch < audio_bus->channels(); ++ch) { |
231 memcpy(audio_bus->channel(ch) + current_frame, | 215 memcpy(audio_bus->channel(ch), av_frame->extended_data[ch], |
232 av_frame->extended_data[ch], sizeof(float) * frames_read); | 216 sizeof(float) * frames_read); |
233 } | 217 } |
234 } else { | 218 } else { |
235 audio_bus->FromInterleavedPartial( | 219 audio_bus->FromInterleaved(av_frame->data[0], frames_read, |
236 av_frame->data[0], current_frame, frames_read, bytes_per_sample); | 220 bytes_per_sample); |
237 } | 221 } |
238 | 222 |
239 current_frame += frames_read; | 223 total_frames += frames_read; |
240 } while (packet_temp.size > 0); | 224 } while (packet_temp.size > 0); |
241 av_packet_unref(&packet); | 225 av_packet_unref(&packet); |
242 } | 226 } |
243 | 227 |
244 // Zero any remaining frames. | 228 return total_frames; |
245 audio_bus->ZeroFramesPartial( | |
246 current_frame, audio_bus->frames() - current_frame); | |
247 | |
248 // Returns the actual number of sample-frames decoded. | |
249 // Ideally this represents the "true" exact length of the file. | |
250 return current_frame; | |
251 } | 229 } |
252 | 230 |
253 base::TimeDelta AudioFileReader::GetDuration() const { | 231 base::TimeDelta AudioFileReader::GetDuration() const { |
254 const AVRational av_time_base = {1, AV_TIME_BASE}; | 232 const AVRational av_time_base = {1, AV_TIME_BASE}; |
255 | 233 |
256 DCHECK_NE(glue_->format_context()->duration, AV_NOPTS_VALUE); | 234 DCHECK_NE(glue_->format_context()->duration, AV_NOPTS_VALUE); |
257 base::CheckedNumeric<int64_t> estimated_duration_us = | 235 base::CheckedNumeric<int64_t> estimated_duration_us = |
258 glue_->format_context()->duration; | 236 glue_->format_context()->duration; |
259 | 237 |
260 if (audio_codec_ == kCodecAAC) { | 238 if (audio_codec_ == kCodecAAC) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
310 glue_->format_context(), stream_index_, | 288 glue_->format_context(), stream_index_, |
311 ConvertToTimeBase(GetAVStreamForTesting()->time_base, seek_time), | 289 ConvertToTimeBase(GetAVStreamForTesting()->time_base, seek_time), |
312 AVSEEK_FLAG_BACKWARD) >= 0; | 290 AVSEEK_FLAG_BACKWARD) >= 0; |
313 } | 291 } |
314 | 292 |
315 const AVStream* AudioFileReader::GetAVStreamForTesting() const { | 293 const AVStream* AudioFileReader::GetAVStreamForTesting() const { |
316 return glue_->format_context()->streams[stream_index_]; | 294 return glue_->format_context()->streams[stream_index_]; |
317 } | 295 } |
318 | 296 |
319 } // namespace media | 297 } // namespace media |
OLD | NEW |