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/base/audio_decoder_config.h"
6
7 #include "base/logging.h"
8 #include "media/base/limits.h"
9 #include "media/base/media_util.h"
10
11 namespace media {
12
AudioDecoderConfig()13 AudioDecoderConfig::AudioDecoderConfig() {}
14
AudioDecoderConfig(AudioCodec codec,SampleFormat sample_format,ChannelLayout channel_layout,int samples_per_second,const std::vector<uint8_t> & extra_data,EncryptionScheme encryption_scheme)15 AudioDecoderConfig::AudioDecoderConfig(AudioCodec codec,
16 SampleFormat sample_format,
17 ChannelLayout channel_layout,
18 int samples_per_second,
19 const std::vector<uint8_t>& extra_data,
20 EncryptionScheme encryption_scheme) {
21 Initialize(codec, sample_format, channel_layout, samples_per_second,
22 extra_data, encryption_scheme, base::TimeDelta(), 0);
23 }
24
25 AudioDecoderConfig::AudioDecoderConfig(const AudioDecoderConfig& other) =
26 default;
27
Initialize(AudioCodec codec,SampleFormat sample_format,ChannelLayout channel_layout,int samples_per_second,const std::vector<uint8_t> & extra_data,EncryptionScheme encryption_scheme,base::TimeDelta seek_preroll,int codec_delay)28 void AudioDecoderConfig::Initialize(AudioCodec codec,
29 SampleFormat sample_format,
30 ChannelLayout channel_layout,
31 int samples_per_second,
32 const std::vector<uint8_t>& extra_data,
33 EncryptionScheme encryption_scheme,
34 base::TimeDelta seek_preroll,
35 int codec_delay) {
36 codec_ = codec;
37 channel_layout_ = channel_layout;
38 samples_per_second_ = samples_per_second;
39 sample_format_ = sample_format;
40 bytes_per_channel_ = SampleFormatToBytesPerChannel(sample_format);
41 extra_data_ = extra_data;
42 encryption_scheme_ = encryption_scheme;
43 seek_preroll_ = seek_preroll;
44 codec_delay_ = codec_delay;
45
46 // If |channel_layout_| is CHANNEL_LAYOUT_DISCRETE, |channels_| and
47 // |bytes_per_frame_| will be overwritten in SetChannelsForDiscrete()
48 channels_ = ChannelLayoutToChannelCount(channel_layout_);
49 bytes_per_frame_ = channels_ * bytes_per_channel_;
50
51 should_discard_decoder_delay_ = true;
52 }
53
54 AudioDecoderConfig::~AudioDecoderConfig() = default;
55
IsValidConfig() const56 bool AudioDecoderConfig::IsValidConfig() const {
57 return codec_ != kUnknownAudioCodec &&
58 channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED &&
59 bytes_per_channel_ > 0 &&
60 bytes_per_channel_ <= limits::kMaxBytesPerSample &&
61 samples_per_second_ > 0 &&
62 samples_per_second_ <= limits::kMaxSampleRate &&
63 sample_format_ != kUnknownSampleFormat &&
64 seek_preroll_ >= base::TimeDelta() && codec_delay_ >= 0;
65 }
66
Matches(const AudioDecoderConfig & config) const67 bool AudioDecoderConfig::Matches(const AudioDecoderConfig& config) const {
68 return ((codec() == config.codec()) &&
69 (bytes_per_channel() == config.bytes_per_channel()) &&
70 (channel_layout() == config.channel_layout()) &&
71 (samples_per_second() == config.samples_per_second()) &&
72 (extra_data() == config.extra_data()) &&
73 (encryption_scheme() == config.encryption_scheme()) &&
74 (sample_format() == config.sample_format()) &&
75 (seek_preroll() == config.seek_preroll()) &&
76 (codec_delay() == config.codec_delay()) &&
77 (should_discard_decoder_delay() ==
78 config.should_discard_decoder_delay()) &&
79 (profile() == config.profile()));
80 }
81
AsHumanReadableString() const82 std::string AudioDecoderConfig::AsHumanReadableString() const {
83 std::ostringstream s;
84 s << "codec: " << GetCodecName(codec())
85 << ", profile: " << GetProfileName(profile())
86 << ", bytes_per_channel: " << bytes_per_channel()
87 << ", channel_layout: " << ChannelLayoutToString(channel_layout())
88 << ", channels: " << channels()
89 << ", samples_per_second: " << samples_per_second()
90 << ", sample_format: " << SampleFormatToString(sample_format())
91 << ", bytes_per_frame: " << bytes_per_frame()
92 << ", seek_preroll: " << seek_preroll().InMicroseconds() << "us"
93 << ", codec_delay: " << codec_delay()
94 << ", has extra data: " << (extra_data().empty() ? "false" : "true")
95 << ", encryption scheme: " << encryption_scheme()
96 << ", discard decoder delay: "
97 << (should_discard_decoder_delay() ? "true" : "false");
98 return s.str();
99 }
100
SetChannelsForDiscrete(int channels)101 void AudioDecoderConfig::SetChannelsForDiscrete(int channels) {
102 DCHECK(channel_layout_ == CHANNEL_LAYOUT_DISCRETE ||
103 channels == ChannelLayoutToChannelCount(channel_layout_));
104 if (channels <= 0 || channels >= limits::kMaxChannels) {
105 DVLOG(1) << __func__ << ": Unsupported number of channels: " << channels;
106 return;
107 }
108 channels_ = channels;
109 bytes_per_frame_ = channels_ * bytes_per_channel_;
110 }
111
SetIsEncrypted(bool is_encrypted)112 void AudioDecoderConfig::SetIsEncrypted(bool is_encrypted) {
113 if (!is_encrypted) {
114 DCHECK_NE(encryption_scheme_, EncryptionScheme::kUnencrypted)
115 << "Config is already clear.";
116 encryption_scheme_ = EncryptionScheme::kUnencrypted;
117 } else {
118 DCHECK_EQ(encryption_scheme_, EncryptionScheme::kUnencrypted)
119 << "Config is already encrypted.";
120 // TODO(xhwang): This is only used to guide decoder selection, so set
121 // a common encryption scheme that should be supported by all decrypting
122 // decoders. We should be able to remove this when we support switching
123 // decoders at run time. See http://crbug.com/695595
124 encryption_scheme_ = EncryptionScheme::kCenc;
125 }
126 }
127
128 } // namespace media
129