Home | History | Annotate | Download | only in filters
      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 
     15 namespace media {
     16 
     17 AudioFileReader::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 
     27 AudioFileReader::~AudioFileReader() {
     28   Close();
     29 }
     30 
     31 bool AudioFileReader::Open() {
     32   if (!OpenDemuxer())
     33     return false;
     34   return OpenDecoder();
     35 }
     36 
     37 bool 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 
     79 bool 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 
    120 void 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 
    127 int 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 
    251 base::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 
    262 int AudioFileReader::GetNumberOfFrames() const {
    263   return static_cast<int>(ceil(GetDuration().InSecondsF() * sample_rate()));
    264 }
    265 
    266 bool AudioFileReader::OpenDemuxerForTesting() {
    267   return OpenDemuxer();
    268 }
    269 
    270 bool AudioFileReader::ReadPacketForTesting(AVPacket* output_packet) {
    271   return ReadPacket(output_packet);
    272 }
    273 
    274 bool 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 
    287 bool 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 
    294 const AVStream* AudioFileReader::GetAVStreamForTesting() const {
    295   return glue_->format_context()->streams[stream_index_];
    296 }
    297 
    298 }  // namespace media
    299