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 <cmath>
8
9#include "base/logging.h"
10#include "base/time/time.h"
11#include "media/base/audio_bus.h"
12#include "media/ffmpeg/ffmpeg_common.h"
13#include "media/filters/ffmpeg_glue.h"
14
15namespace media {
16
17AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol)
18    : codec_context_(NULL),
19      stream_index_(0),
20      protocol_(protocol),
21      channels_(0),
22      sample_rate_(0),
23      end_padding_(0),
24      av_sample_format_(0) {
25}
26
27AudioFileReader::~AudioFileReader() {
28  Close();
29}
30
31bool AudioFileReader::Open() {
32  if (!OpenDemuxer())
33    return false;
34  return OpenDecoder();
35}
36
37bool AudioFileReader::OpenDemuxer() {
38  glue_.reset(new FFmpegGlue(protocol_));
39  AVFormatContext* format_context = glue_->format_context();
40
41  // Open FFmpeg AVFormatContext.
42  if (!glue_->OpenContext()) {
43    DLOG(WARNING) << "AudioFileReader::Open() : error in avformat_open_input()";
44    return false;
45  }
46
47  // Get the codec context.
48  codec_context_ = NULL;
49  for (size_t i = 0; i < format_context->nb_streams; ++i) {
50    AVCodecContext* c = format_context->streams[i]->codec;
51    if (c->codec_type == AVMEDIA_TYPE_AUDIO) {
52      codec_context_ = c;
53      stream_index_ = i;
54      break;
55    }
56  }
57
58  // Get the codec.
59  if (!codec_context_)
60    return false;
61
62  const int result = avformat_find_stream_info(format_context, NULL);
63  if (result < 0) {
64    DLOG(WARNING)
65        << "AudioFileReader::Open() : error in avformat_find_stream_info()";
66    return false;
67  }
68
69  // Attempt to extract end padding for mp3 files.
70  if (strcmp(format_context->iformat->name, "mp3") == 0 &&
71      (av_opt_get_int(format_context->priv_data, "end_pad", 0, &end_padding_) <
72           0 ||
73       end_padding_ < 0)) {
74    end_padding_ = 0;
75  }
76  return true;
77}
78
79bool AudioFileReader::OpenDecoder() {
80  AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
81  if (codec) {
82    // MP3 decodes to S16P which we don't support, tell it to use S16 instead.
83    if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P)
84      codec_context_->request_sample_fmt = AV_SAMPLE_FMT_S16;
85
86    const int result = avcodec_open2(codec_context_, codec, NULL);
87    if (result < 0) {
88      DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -"
89                    << " result: " << result;
90      return false;
91    }
92
93    // Ensure avcodec_open2() respected our format request.
94    if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P) {
95      DLOG(ERROR) << "AudioFileReader::Open() : unable to configure a"
96                  << " supported sample format - "
97                  << codec_context_->sample_fmt;
98      return false;
99    }
100  } else {
101    DLOG(WARNING) << "AudioFileReader::Open() : could not find codec.";
102    return false;
103  }
104
105  // Verify the channel layout is supported by Chrome.  Acts as a sanity check
106  // against invalid files.  See http://crbug.com/171962
107  if (ChannelLayoutToChromeChannelLayout(
108          codec_context_->channel_layout, codec_context_->channels) ==
109      CHANNEL_LAYOUT_UNSUPPORTED) {
110    return false;
111  }
112
113  // Store initial values to guard against midstream configuration changes.
114  channels_ = codec_context_->channels;
115  sample_rate_ = codec_context_->sample_rate;
116  av_sample_format_ = codec_context_->sample_fmt;
117  return true;
118}
119
120void AudioFileReader::Close() {
121  // |codec_context_| is a stream inside glue_->format_context(), so it is
122  // closed when |glue_| is disposed.
123  glue_.reset();
124  codec_context_ = NULL;
125}
126
127int AudioFileReader::Read(AudioBus* audio_bus) {
128  DCHECK(glue_.get() && codec_context_) <<
129      "AudioFileReader::Read() : reader is not opened!";
130
131  DCHECK_EQ(audio_bus->channels(), channels());
132  if (audio_bus->channels() != channels())
133    return 0;
134
135  size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt);
136
137  // Holds decoded audio.
138  scoped_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame(av_frame_alloc());
139
140  // Read until we hit EOF or we've read the requested number of frames.
141  AVPacket packet;
142  int current_frame = 0;
143  bool continue_decoding = true;
144
145  while (current_frame < audio_bus->frames() && continue_decoding &&
146         ReadPacket(&packet)) {
147    // Make a shallow copy of packet so we can slide packet.data as frames are
148    // decoded from the packet; otherwise av_free_packet() will corrupt memory.
149    AVPacket packet_temp = packet;
150    do {
151      // Reset frame to default values.
152      av_frame_unref(av_frame.get());
153
154      int frame_decoded = 0;
155      int result = avcodec_decode_audio4(
156          codec_context_, av_frame.get(), &frame_decoded, &packet_temp);
157
158      if (result < 0) {
159        DLOG(WARNING)
160            << "AudioFileReader::Read() : error in avcodec_decode_audio4() -"
161            << result;
162        break;
163      }
164
165      // Update packet size and data pointer in case we need to call the decoder
166      // with the remaining bytes from this packet.
167      packet_temp.size -= result;
168      packet_temp.data += result;
169
170      if (!frame_decoded)
171        continue;
172
173      // Determine the number of sample-frames we just decoded.  Check overflow.
174      int frames_read = av_frame->nb_samples;
175      if (frames_read < 0) {
176        continue_decoding = false;
177        break;
178      }
179
180#ifdef CHROMIUM_NO_AVFRAME_CHANNELS
181      int channels = av_get_channel_layout_nb_channels(
182          av_frame->channel_layout);
183#else
184      int channels = av_frame->channels;
185#endif
186      if (av_frame->sample_rate != sample_rate_ ||
187          channels != channels_ ||
188          av_frame->format != av_sample_format_) {
189        DLOG(ERROR) << "Unsupported midstream configuration change!"
190                    << " Sample Rate: " << av_frame->sample_rate << " vs "
191                    << sample_rate_
192                    << ", Channels: " << channels << " vs "
193                    << channels_
194                    << ", Sample Format: " << av_frame->format << " vs "
195                    << av_sample_format_;
196
197        // This is an unrecoverable error, so bail out.
198        continue_decoding = false;
199        break;
200      }
201
202      // Truncate, if necessary, if the destination isn't big enough.
203      if (current_frame + frames_read > audio_bus->frames()) {
204        DLOG(ERROR) << "Truncating decoded data due to output size.";
205        frames_read = audio_bus->frames() - current_frame;
206      }
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  // If decoding completed successfully try to strip end padding.
237  if (continue_decoding && end_padding_ <= current_frame) {
238    DCHECK_GE(end_padding_, 0);
239    current_frame -= end_padding_;
240  }
241
242  // Zero any remaining frames.
243  audio_bus->ZeroFramesPartial(
244      current_frame, audio_bus->frames() - current_frame);
245
246  // Returns the actual number of sample-frames decoded.
247  // Ideally this represents the "true" exact length of the file.
248  return current_frame;
249}
250
251base::TimeDelta AudioFileReader::GetDuration() const {
252  const AVRational av_time_base = {1, AV_TIME_BASE};
253
254  // Add one microsecond to avoid rounding-down errors which can occur when
255  // |duration| has been calculated from an exact number of sample-frames.
256  // One microsecond is much less than the time of a single sample-frame
257  // at any real-world sample-rate.
258  return ConvertFromTimeBase(av_time_base,
259                             glue_->format_context()->duration + 1);
260}
261
262int AudioFileReader::GetNumberOfFrames() const {
263  return static_cast<int>(ceil(GetDuration().InSecondsF() * sample_rate()));
264}
265
266bool AudioFileReader::OpenDemuxerForTesting() {
267  return OpenDemuxer();
268}
269
270bool AudioFileReader::ReadPacketForTesting(AVPacket* output_packet) {
271  return ReadPacket(output_packet);
272}
273
274bool AudioFileReader::ReadPacket(AVPacket* output_packet) {
275  while (av_read_frame(glue_->format_context(), output_packet) >= 0 &&
276         av_dup_packet(output_packet) >= 0) {
277    // Skip packets from other streams.
278    if (output_packet->stream_index != stream_index_) {
279      av_free_packet(output_packet);
280      continue;
281    }
282    return true;
283  }
284  return false;
285}
286
287bool AudioFileReader::SeekForTesting(base::TimeDelta seek_time) {
288  return av_seek_frame(glue_->format_context(),
289                       stream_index_,
290                       ConvertToTimeBase(codec_context_->time_base, seek_time),
291                       AVSEEK_FLAG_BACKWARD) >= 0;
292}
293
294const AVStream* AudioFileReader::GetAVStreamForTesting() const {
295  return glue_->format_context()->streams[stream_index_];
296}
297
298}  // namespace media
299