15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_decoder_config.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/time/time.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/sample_rates.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/limits.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "media/base/sample_format.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioDecoderConfig::AudioDecoderConfig() 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : codec_(kUnknownAudioCodec), 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sample_format_(kUnknownSampleFormat), 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_per_channel_(0), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_layout_(CHANNEL_LAYOUT_UNSUPPORTED), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples_per_second_(0), 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_per_frame_(0), 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch is_encrypted_(false), 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch codec_delay_(0) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioDecoderConfig::AudioDecoderConfig(AudioCodec codec, 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SampleFormat sample_format, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelLayout channel_layout, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int samples_per_second, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* extra_data, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t extra_data_size, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_encrypted) { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(codec, sample_format, channel_layout, samples_per_second, 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) extra_data, extra_data_size, is_encrypted, true, 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::TimeDelta(), 0); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecoderConfig::Initialize(AudioCodec codec, 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SampleFormat sample_format, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelLayout channel_layout, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int samples_per_second, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* extra_data, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t extra_data_size, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_encrypted, 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool record_stats, 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeDelta seek_preroll, 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int codec_delay) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK((extra_data_size != 0) == (extra_data != NULL)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (record_stats) { 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.AudioCodec", codec, kAudioCodecMax + 1); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.AudioSampleFormat", sample_format, 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSampleFormatMax + 1); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.AudioChannelLayout", channel_layout, 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHANNEL_LAYOUT_MAX + 1); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AudioSampleRate asr; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ToAudioSampleRate(samples_per_second, &asr)) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.AudioSamplesPerSecond", asr, 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kAudioSampleRateMax + 1); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Media.AudioSamplesPerSecondUnexpected", samples_per_second); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_ = codec; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_layout_ = channel_layout; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples_per_second_ = samples_per_second; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sample_format_ = sample_format; 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_per_channel_ = SampleFormatToBytesPerChannel(sample_format); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extra_data_.assign(extra_data, extra_data + extra_data_size); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_encrypted_ = is_encrypted; 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) seek_preroll_ = seek_preroll; 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) codec_delay_ = codec_delay; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int channels = ChannelLayoutToChannelCount(channel_layout_); 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_per_frame_ = channels * bytes_per_channel_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioDecoderConfig::~AudioDecoderConfig() {} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioDecoderConfig::IsValidConfig() const { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return codec_ != kUnknownAudioCodec && 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED && 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_per_channel_ > 0 && 877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_per_channel_ <= limits::kMaxBytesPerSample && 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) samples_per_second_ > 0 && 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) samples_per_second_ <= limits::kMaxSampleRate && 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sample_format_ != kUnknownSampleFormat && 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) seek_preroll_ >= base::TimeDelta() && 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch codec_delay_ >= 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioDecoderConfig::Matches(const AudioDecoderConfig& config) const { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((codec() == config.codec()) && 977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (bytes_per_channel() == config.bytes_per_channel()) && 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (channel_layout() == config.channel_layout()) && 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (samples_per_second() == config.samples_per_second()) && 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (extra_data_size() == config.extra_data_size()) && 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!extra_data() || !memcmp(extra_data(), config.extra_data(), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_data_size())) && 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (is_encrypted() == config.is_encrypted()) && 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) (sample_format() == config.sample_format()) && 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) (seek_preroll() == config.seek_preroll()) && 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) (codec_delay() == config.codec_delay())); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)std::string AudioDecoderConfig::AsHumanReadableString() const { 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::ostringstream s; 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) s << "codec: " << codec() 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " bytes_per_channel: " << bytes_per_channel() 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " channel_layout: " << channel_layout() 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " samples_per_second: " << samples_per_second() 11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " sample_format: " << sample_format() 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " bytes_per_frame: " << bytes_per_frame() 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " seek_preroll: " << seek_preroll().InMilliseconds() << "ms" 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << " codec_delay: " << codec_delay() 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " has extra data? " << (extra_data() ? "true" : "false") 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << " encrypted? " << (is_encrypted() ? "true" : "false"); 12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return s.str(); 12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 125