Home | History | Annotate | Download | only in webm
      1 // Copyright 2014 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/formats/webm/webm_audio_client.h"
      6 
      7 #include "media/base/audio_decoder_config.h"
      8 #include "media/base/channel_layout.h"
      9 #include "media/formats/webm/webm_constants.h"
     10 
     11 namespace media {
     12 
     13 WebMAudioClient::WebMAudioClient(const LogCB& log_cb)
     14     : log_cb_(log_cb) {
     15   Reset();
     16 }
     17 
     18 WebMAudioClient::~WebMAudioClient() {
     19 }
     20 
     21 void WebMAudioClient::Reset() {
     22   channels_ = -1;
     23   samples_per_second_ = -1;
     24   output_samples_per_second_ = -1;
     25 }
     26 
     27 bool WebMAudioClient::InitializeConfig(
     28     const std::string& codec_id, const std::vector<uint8>& codec_private,
     29     int64 seek_preroll, int64 codec_delay, bool is_encrypted,
     30     AudioDecoderConfig* config) {
     31   DCHECK(config);
     32   SampleFormat sample_format = kSampleFormatPlanarF32;
     33 
     34   AudioCodec audio_codec = kUnknownAudioCodec;
     35   if (codec_id == "A_VORBIS") {
     36     audio_codec = kCodecVorbis;
     37   } else if (codec_id == "A_OPUS") {
     38     audio_codec = kCodecOpus;
     39   } else {
     40     MEDIA_LOG(log_cb_) << "Unsupported audio codec_id " << codec_id;
     41     return false;
     42   }
     43 
     44   if (samples_per_second_ <= 0)
     45     return false;
     46 
     47   // Set channel layout default if a Channels element was not present.
     48   if (channels_ == -1)
     49     channels_ = 1;
     50 
     51   ChannelLayout channel_layout =  GuessChannelLayout(channels_);
     52 
     53   if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) {
     54     MEDIA_LOG(log_cb_) << "Unsupported channel count " << channels_;
     55     return false;
     56   }
     57 
     58   int samples_per_second = samples_per_second_;
     59   if (output_samples_per_second_ > 0)
     60     samples_per_second = output_samples_per_second_;
     61 
     62   // Always use 48kHz for OPUS.  See the "Input Sample Rate" section of the
     63   // spec: http://tools.ietf.org/html/draft-terriberry-oggopus-01#page-11
     64   if (audio_codec == kCodecOpus) {
     65     samples_per_second = 48000;
     66     sample_format = kSampleFormatF32;
     67   }
     68 
     69   const uint8* extra_data = NULL;
     70   size_t extra_data_size = 0;
     71   if (codec_private.size() > 0) {
     72     extra_data = &codec_private[0];
     73     extra_data_size = codec_private.size();
     74   }
     75 
     76   // Convert |codec_delay| from nanoseconds into frames.
     77   int codec_delay_in_frames = 0;
     78   if (codec_delay != -1) {
     79     codec_delay_in_frames =
     80         0.5 +
     81         samples_per_second * (static_cast<double>(codec_delay) /
     82                               base::Time::kNanosecondsPerSecond);
     83   }
     84 
     85   config->Initialize(
     86       audio_codec,
     87       sample_format,
     88       channel_layout,
     89       samples_per_second,
     90       extra_data,
     91       extra_data_size,
     92       is_encrypted,
     93       true,
     94       base::TimeDelta::FromMicroseconds(
     95           (seek_preroll != -1 ? seek_preroll : 0) / 1000),
     96       codec_delay_in_frames);
     97   return config->IsValidConfig();
     98 }
     99 
    100 bool WebMAudioClient::OnUInt(int id, int64 val) {
    101   if (id == kWebMIdChannels) {
    102     if (channels_ != -1) {
    103       MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
    104                          << " specified. (" << channels_ << " and " << val
    105                          << ")";
    106       return false;
    107     }
    108 
    109     channels_ = val;
    110   }
    111   return true;
    112 }
    113 
    114 bool WebMAudioClient::OnFloat(int id, double val) {
    115   double* dst = NULL;
    116 
    117   switch (id) {
    118     case kWebMIdSamplingFrequency:
    119       dst = &samples_per_second_;
    120       break;
    121     case kWebMIdOutputSamplingFrequency:
    122       dst = &output_samples_per_second_;
    123       break;
    124     default:
    125       return true;
    126   }
    127 
    128   if (val <= 0)
    129     return false;
    130 
    131   if (*dst != -1) {
    132     MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
    133                        << " specified (" << *dst << " and " << val << ")";
    134     return false;
    135   }
    136 
    137   *dst = val;
    138   return true;
    139 }
    140 
    141 }  // namespace media
    142