| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "media/base/audio_decoder_config.h" | |
| #include <sstream> | |
| #include "base/logging.h" | |
| #include "base/metrics/histogram.h" | |
| #include "media/audio/sample_rates.h" | |
| #include "media/base/limits.h" | |
| namespace media { | |
| AudioDecoderConfig::AudioDecoderConfig() | |
| : codec_(kUnknownAudioCodec), | |
| bits_per_channel_(0), | |
| channel_layout_(CHANNEL_LAYOUT_UNSUPPORTED), | |
| samples_per_second_(0), | |
| bytes_per_frame_(0), | |
| extra_data_size_(0), | |
| is_encrypted_(false) { | |
| } | |
| AudioDecoderConfig::AudioDecoderConfig(AudioCodec codec, | |
| int bits_per_channel, | |
| ChannelLayout channel_layout, | |
| int samples_per_second, | |
| const uint8* extra_data, | |
| size_t extra_data_size, | |
| bool is_encrypted) { | |
| Initialize(codec, bits_per_channel, channel_layout, samples_per_second, | |
| extra_data, extra_data_size, is_encrypted, true); | |
| } | |
| void AudioDecoderConfig::Initialize(AudioCodec codec, | |
| int bits_per_channel, | |
| ChannelLayout channel_layout, | |
| int samples_per_second, | |
| const uint8* extra_data, | |
| size_t extra_data_size, | |
| bool is_encrypted, | |
| bool record_stats) { | |
| CHECK((extra_data_size != 0) == (extra_data != NULL)); | |
| if (record_stats) { | |
| UMA_HISTOGRAM_ENUMERATION("Media.AudioCodec", codec, kAudioCodecMax + 1); | |
| // Fake enum histogram to get exact integral buckets. Expect to never see | |
| // any values over 32 and even that is huge. | |
| UMA_HISTOGRAM_ENUMERATION("Media.AudioBitsPerChannel", bits_per_channel, | |
| 40); | |
| UMA_HISTOGRAM_ENUMERATION("Media.AudioChannelLayout", channel_layout, | |
| CHANNEL_LAYOUT_MAX); | |
| AudioSampleRate asr = media::AsAudioSampleRate(samples_per_second); | |
| if (asr != kUnexpectedAudioSampleRate) { | |
| UMA_HISTOGRAM_ENUMERATION("Media.AudioSamplesPerSecond", asr, | |
| kUnexpectedAudioSampleRate); | |
| } else { | |
| UMA_HISTOGRAM_COUNTS( | |
| "Media.AudioSamplesPerSecondUnexpected", samples_per_second); | |
| } | |
| } | |
| codec_ = codec; | |
| bits_per_channel_ = bits_per_channel; | |
| channel_layout_ = channel_layout; | |
| samples_per_second_ = samples_per_second; | |
| extra_data_size_ = extra_data_size; | |
| if (extra_data_size_ > 0) { | |
| extra_data_.reset(new uint8[extra_data_size_]); | |
| memcpy(extra_data_.get(), extra_data, extra_data_size_); | |
| } else { | |
| extra_data_.reset(); | |
| } | |
| is_encrypted_ = is_encrypted; | |
| int channels = ChannelLayoutToChannelCount(channel_layout_); | |
| bytes_per_frame_ = channels * bits_per_channel_ / 8; | |
| } | |
| AudioDecoderConfig::~AudioDecoderConfig() {} | |
| bool AudioDecoderConfig::IsValidConfig() const { | |
| return codec_ != kUnknownAudioCodec && | |
| channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED && | |
| bits_per_channel_ > 0 && | |
| bits_per_channel_ <= limits::kMaxBitsPerSample && | |
| samples_per_second_ > 0 && | |
| samples_per_second_ <= limits::kMaxSampleRate; | |
| } | |
| bool AudioDecoderConfig::Matches(const AudioDecoderConfig& config) const { | |
| return ((codec() == config.codec()) && | |
| (bits_per_channel() == config.bits_per_channel()) && | |
| (channel_layout() == config.channel_layout()) && | |
| (samples_per_second() == config.samples_per_second()) && | |
| (extra_data_size() == config.extra_data_size()) && | |
| (!extra_data() || !memcmp(extra_data(), config.extra_data(), | |
| extra_data_size())) && | |
| (is_encrypted() == config.is_encrypted())); | |
| } | |
| std::string AudioDecoderConfig::AsHumanReadableString() const { | |
| std::ostringstream s; | |
| s << "codec: " << codec() | |
| << " bits per channel: " << bits_per_channel() | |
| << " channel layout: " << channel_layout() | |
| << " samples per second: " << samples_per_second() | |
| << " bytes per frame: " << bytes_per_frame() | |
| << " has extra data? " << (extra_data() ? "true" : "false") | |
| << " encrypted? " << (is_encrypted() ? "true" : "false"); | |
| return s.str(); | |
| } | |
| void AudioDecoderConfig::CopyFrom(const AudioDecoderConfig& audio_config) { | |
| Initialize(audio_config.codec(), | |
| audio_config.bits_per_channel(), | |
| audio_config.channel_layout(), | |
| audio_config.samples_per_second(), | |
| audio_config.extra_data(), | |
| audio_config.extra_data_size(), | |
| audio_config.is_encrypted(), | |
| false); | |
| } | |
| AudioCodec AudioDecoderConfig::codec() const { | |
| return codec_; | |
| } | |
| int AudioDecoderConfig::bits_per_channel() const { | |
| return bits_per_channel_; | |
| } | |
| ChannelLayout AudioDecoderConfig::channel_layout() const { | |
| return channel_layout_; | |
| } | |
| int AudioDecoderConfig::samples_per_second() const { | |
| return samples_per_second_; | |
| } | |
| int AudioDecoderConfig::bytes_per_frame() const { | |
| return bytes_per_frame_; | |
| } | |
| uint8* AudioDecoderConfig::extra_data() const { | |
| return extra_data_.get(); | |
| } | |
| size_t AudioDecoderConfig::extra_data_size() const { | |
| return extra_data_size_; | |
| } | |
| bool AudioDecoderConfig::is_encrypted() const { | |
| return is_encrypted_; | |
| } | |
| } // namespace media |