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 3 // found in the LICENSE file. 4 5 #include "media/filters/audio_file_reader.h" 6 7 #include "base/logging.h" 8 #include "base/time/time.h" 9 #include "media/base/audio_bus.h" 10 #include "media/ffmpeg/ffmpeg_common.h" 11 #include "media/filters/ffmpeg_glue.h" 12 13 namespace media { 14 15 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol) 16 : codec_context_(NULL), 17 stream_index_(0), 18 protocol_(protocol), 19 channels_(0), 20 sample_rate_(0), 21 av_sample_format_(0) { 22 } 23 24 AudioFileReader::~AudioFileReader() { 25 Close(); 26 } 27 28 base::TimeDelta AudioFileReader::duration() const { 29 const AVRational av_time_base = {1, AV_TIME_BASE}; 30 31 // Add one microsecond to avoid rounding-down errors which can occur when 32 // |duration| has been calculated from an exact number of sample-frames. 33 // One microsecond is much less than the time of a single sample-frame 34 // at any real-world sample-rate. 35 return ConvertFromTimeBase( 36 av_time_base, glue_->format_context()->duration + 1); 37 } 38 39 int64 AudioFileReader::number_of_frames() const { 40 return static_cast<int64>(duration().InSecondsF() * sample_rate()); 41 } 42 43 bool AudioFileReader::Open() { 44 glue_.reset(new FFmpegGlue(protocol_)); 45 AVFormatContext* format_context = glue_->format_context(); 46 47 // Open FFmpeg AVFormatContext. 48 if (!glue_->OpenContext()) { 49 DLOG(WARNING) << "AudioFileReader::Open() : error in avformat_open_input()"; 50 return false; 51 } 52 53 // Get the codec context. 54 codec_context_ = NULL; 55 for (size_t i = 0; i < format_context->nb_streams; ++i) { 56 AVCodecContext* c = format_context->streams[i]->codec; 57 if (c->codec_type == AVMEDIA_TYPE_AUDIO) { 58 codec_context_ = c; 59 stream_index_ = i; 60 break; 61 } 62 } 63 64 // Get the codec. 65 if (!codec_context_) 66 return false; 67 68 int result = avformat_find_stream_info(format_context, NULL); 69 if (result < 0) { 70 DLOG(WARNING) 71 << "AudioFileReader::Open() : error in avformat_find_stream_info()"; 72 return false; 73 } 74 75 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); 76 if (codec) { 77 // MP3 decodes to S16P which we don't support, tell it to use S16 instead. 78 if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P) 79 codec_context_->request_sample_fmt = AV_SAMPLE_FMT_S16; 80 81 if ((result = avcodec_open2(codec_context_, codec, NULL)) < 0) { 82 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -" 83 << " result: " << result; 84 return false; 85 } 86 87 // Ensure avcodec_open2() respected our format request. 88 if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P) { 89 DLOG(ERROR) << "AudioFileReader::Open() : unable to configure a" 90 << " supported sample format - " 91 << codec_context_->sample_fmt; 92 return false; 93 } 94 } else { 95 DLOG(WARNING) << "AudioFileReader::Open() : could not find codec -" 96 << " result: " << result; 97 return false; 98 } 99 100 // Verify the channel layout is supported by Chrome. Acts as a sanity check 101 // against invalid files. See http://crbug.com/171962 102 if (ChannelLayoutToChromeChannelLayout( 103 codec_context_->channel_layout, codec_context_->channels) == 104 CHANNEL_LAYOUT_UNSUPPORTED) { 105 return false; 106 } 107 108 // Store initial values to guard against midstream configuration changes. 109 channels_ = codec_context_->channels; 110 sample_rate_ = codec_context_->sample_rate; 111 av_sample_format_ = codec_context_->sample_fmt; 112 113 return true; 114 } 115 116 void AudioFileReader::Close() { 117 if (codec_context_) { 118 avcodec_close(codec_context_); 119 codec_context_ = NULL; 120 } 121 } 122 123 int AudioFileReader::Read(AudioBus* audio_bus) { 124 DCHECK(glue_.get() && codec_context_) << 125 "AudioFileReader::Read() : reader is not opened!"; 126 127 DCHECK_EQ(audio_bus->channels(), channels()); 128 if (audio_bus->channels() != channels()) 129 return 0; 130 131 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt); 132 133 // Holds decoded audio. 134 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame()); 135 136 // Read until we hit EOF or we've read the requested number of frames. 137 AVPacket packet; 138 int current_frame = 0; 139 bool continue_decoding = true; 140 141 while (current_frame < audio_bus->frames() && continue_decoding && 142 av_read_frame(glue_->format_context(), &packet) >= 0 && 143 av_dup_packet(&packet) >= 0) { 144 // Skip packets from other streams. 145 if (packet.stream_index != stream_index_) { 146 av_free_packet(&packet); 147 continue; 148 } 149 150 // Make a shallow copy of packet so we can slide packet.data as frames are 151 // decoded from the packet; otherwise av_free_packet() will corrupt memory. 152 AVPacket packet_temp = packet; 153 do { 154 avcodec_get_frame_defaults(av_frame.get()); 155 int frame_decoded = 0; 156 int result = avcodec_decode_audio4( 157 codec_context_, av_frame.get(), &frame_decoded, &packet_temp); 158 159 if (result < 0) { 160 DLOG(WARNING) 161 << "AudioFileReader::Read() : error in avcodec_decode_audio4() -" 162 << result; 163 continue_decoding = false; 164 break; 165 } 166 167 // Update packet size and data pointer in case we need to call the decoder 168 // with the remaining bytes from this packet. 169 packet_temp.size -= result; 170 packet_temp.data += result; 171 172 if (!frame_decoded) 173 continue; 174 175 // Determine the number of sample-frames we just decoded. Check overflow. 176 int frames_read = av_frame->nb_samples; 177 if (frames_read < 0) { 178 continue_decoding = false; 179 break; 180 } 181 182 #ifdef CHROMIUM_NO_AVFRAME_CHANNELS 183 int channels = av_get_channel_layout_nb_channels( 184 av_frame->channel_layout); 185 #else 186 int channels = av_frame->channels; 187 #endif 188 if (av_frame->sample_rate != sample_rate_ || 189 channels != channels_ || 190 av_frame->format != av_sample_format_) { 191 DLOG(ERROR) << "Unsupported midstream configuration change!" 192 << " Sample Rate: " << av_frame->sample_rate << " vs " 193 << sample_rate_ 194 << ", Channels: " << channels << " vs " 195 << channels_ 196 << ", Sample Format: " << av_frame->format << " vs " 197 << av_sample_format_; 198 199 // This is an unrecoverable error, so bail out. 200 continue_decoding = false; 201 break; 202 } 203 204 // Truncate, if necessary, if the destination isn't big enough. 205 if (current_frame + frames_read > audio_bus->frames()) 206 frames_read = audio_bus->frames() - current_frame; 207 208 // Deinterleave each channel and convert to 32bit floating-point with 209 // nominal range -1.0 -> +1.0. If the output is already in float planar 210 // format, just copy it into the AudioBus. 211 if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLT) { 212 float* decoded_audio_data = reinterpret_cast<float*>(av_frame->data[0]); 213 int channels = audio_bus->channels(); 214 for (int ch = 0; ch < channels; ++ch) { 215 float* bus_data = audio_bus->channel(ch) + current_frame; 216 for (int i = 0, offset = ch; i < frames_read; 217 ++i, offset += channels) { 218 bus_data[i] = decoded_audio_data[offset]; 219 } 220 } 221 } else if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLTP) { 222 for (int ch = 0; ch < audio_bus->channels(); ++ch) { 223 memcpy(audio_bus->channel(ch) + current_frame, 224 av_frame->extended_data[ch], sizeof(float) * frames_read); 225 } 226 } else { 227 audio_bus->FromInterleavedPartial( 228 av_frame->data[0], current_frame, frames_read, bytes_per_sample); 229 } 230 231 current_frame += frames_read; 232 } while (packet_temp.size > 0); 233 av_free_packet(&packet); 234 } 235 236 // Zero any remaining frames. 237 audio_bus->ZeroFramesPartial( 238 current_frame, audio_bus->frames() - current_frame); 239 240 // Returns the actual number of sample-frames decoded. 241 // Ideally this represents the "true" exact length of the file. 242 return current_frame; 243 } 244 245 } // namespace media 246