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