1 // Copyright (c) 2013 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/webm/webm_audio_client.h" 6 7 #include "media/base/audio_decoder_config.h" 8 #include "media/base/channel_layout.h" 9 #include "media/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 33 AudioCodec audio_codec = kUnknownAudioCodec; 34 if (codec_id == "A_VORBIS") { 35 audio_codec = kCodecVorbis; 36 } else if (codec_id == "A_OPUS") { 37 audio_codec = kCodecOpus; 38 } else { 39 MEDIA_LOG(log_cb_) << "Unsupported audio codec_id " << codec_id; 40 return false; 41 } 42 43 if (samples_per_second_ <= 0) 44 return false; 45 46 // Set channel layout default if a Channels element was not present. 47 if (channels_ == -1) 48 channels_ = 1; 49 50 ChannelLayout channel_layout = GuessChannelLayout(channels_); 51 52 if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) { 53 MEDIA_LOG(log_cb_) << "Unsupported channel count " << channels_; 54 return false; 55 } 56 57 int samples_per_second = samples_per_second_; 58 if (output_samples_per_second_ > 0) 59 samples_per_second = output_samples_per_second_; 60 61 const uint8* extra_data = NULL; 62 size_t extra_data_size = 0; 63 if (codec_private.size() > 0) { 64 extra_data = &codec_private[0]; 65 extra_data_size = codec_private.size(); 66 } 67 68 config->Initialize( 69 audio_codec, 70 (audio_codec == kCodecOpus) ? kSampleFormatS16 : kSampleFormatPlanarF32, 71 channel_layout, 72 samples_per_second, extra_data, extra_data_size, is_encrypted, true, 73 base::TimeDelta::FromMicroseconds( 74 (seek_preroll != -1 ? seek_preroll : 0) / 1000), 75 base::TimeDelta::FromMicroseconds( 76 (codec_delay != -1 ? codec_delay : 0) / 1000)); 77 return config->IsValidConfig(); 78 } 79 80 bool WebMAudioClient::OnUInt(int id, int64 val) { 81 if (id == kWebMIdChannels) { 82 if (channels_ != -1) { 83 MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id 84 << " specified. (" << channels_ << " and " << val 85 << ")"; 86 return false; 87 } 88 89 channels_ = val; 90 } 91 return true; 92 } 93 94 bool WebMAudioClient::OnFloat(int id, double val) { 95 double* dst = NULL; 96 97 switch (id) { 98 case kWebMIdSamplingFrequency: 99 dst = &samples_per_second_; 100 break; 101 case kWebMIdOutputSamplingFrequency: 102 dst = &output_samples_per_second_; 103 break; 104 default: 105 return true; 106 } 107 108 if (val <= 0) 109 return false; 110 111 if (*dst != -1) { 112 MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id 113 << " specified (" << *dst << " and " << val << ")"; 114 return false; 115 } 116 117 *dst = val; 118 return true; 119 } 120 121 } // namespace media 122