Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/mp4/aac.h" | 5 #include "media/mp4/aac.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 8 | |
| 7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 8 #include "media/base/bit_reader.h" | 10 #include "media/base/bit_reader.h" |
| 9 #include "media/mp4/rcheck.h" | 11 #include "media/mp4/rcheck.h" |
| 10 | 12 |
| 11 // The following conversion table is extracted from ISO 14496 Part 3 - | 13 // The following conversion table is extracted from ISO 14496 Part 3 - |
| 12 // Table 1.16 - Sampling Frequency Index. | 14 // Table 1.16 - Sampling Frequency Index. |
| 13 static const uint32 kFrequencyMap[] = { | 15 static const int kFrequencyMap[] = { |
| 14 96000, 88200, 64000, 48000, 44100, 32000, 24000, | 16 96000, 88200, 64000, 48000, 44100, 32000, 24000, |
| 15 22050, 16000, 12000, 11025, 8000, 7350 | 17 22050, 16000, 12000, 11025, 8000, 7350 |
| 16 }; | 18 }; |
| 17 | 19 |
| 18 static ChannelLayout GetChannelLayout(uint8 channel_config) { | 20 static ChannelLayout GetChannelLayout(uint8 channel_config) { |
| 19 switch (channel_config) { | 21 switch (channel_config) { |
| 20 case 1: | 22 case 1: |
| 21 return CHANNEL_LAYOUT_MONO; | 23 return CHANNEL_LAYOUT_MONO; |
| 22 case 2: | 24 case 2: |
| 23 return CHANNEL_LAYOUT_STEREO; | 25 return CHANNEL_LAYOUT_STEREO; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 37 | 39 |
| 38 return CHANNEL_LAYOUT_UNSUPPORTED; | 40 return CHANNEL_LAYOUT_UNSUPPORTED; |
| 39 } | 41 } |
| 40 | 42 |
| 41 namespace media { | 43 namespace media { |
| 42 | 44 |
| 43 namespace mp4 { | 45 namespace mp4 { |
| 44 | 46 |
| 45 AAC::AAC() | 47 AAC::AAC() |
| 46 : profile_(0), frequency_index_(0), channel_config_(0), frequency_(0), | 48 : profile_(0), frequency_index_(0), channel_config_(0), frequency_(0), |
| 47 channel_layout_(CHANNEL_LAYOUT_UNSUPPORTED) { | 49 extension_frequency_(0), channel_layout_(CHANNEL_LAYOUT_UNSUPPORTED) { |
| 48 } | 50 } |
| 49 | 51 |
| 50 AAC::~AAC() { | 52 AAC::~AAC() { |
| 51 } | 53 } |
| 52 | 54 |
| 53 bool AAC::Parse(const std::vector<uint8>& data) { | 55 bool AAC::Parse(const std::vector<uint8>& data) { |
| 54 if (data.empty()) | 56 if (data.empty()) |
| 55 return false; | 57 return false; |
| 56 | 58 |
| 57 BitReader reader(&data[0], data.size()); | 59 BitReader reader(&data[0], data.size()); |
| 58 uint8 extension_type = 0; | 60 uint8 extension_type = 0; |
| 59 bool ps_present = false; | 61 bool ps_present = false; |
| 60 uint8 extension_frequency_index; | 62 uint8 extension_frequency_index = 0xff; |
| 61 | 63 |
| 62 frequency_ = 0; | 64 frequency_ = 0; |
| 65 extension_frequency_ = 0; | |
| 63 | 66 |
| 64 // The following code is written according to ISO 14496 Part 3 Table 1.13 - | 67 // The following code is written according to ISO 14496 Part 3 Table 1.13 - |
| 65 // Syntax of AudioSpecificConfig. | 68 // Syntax of AudioSpecificConfig. |
| 66 | 69 |
| 67 // Read base configuration | 70 // Read base configuration |
| 68 RCHECK(reader.ReadBits(5, &profile_)); | 71 RCHECK(reader.ReadBits(5, &profile_)); |
| 69 RCHECK(reader.ReadBits(4, &frequency_index_)); | 72 RCHECK(reader.ReadBits(4, &frequency_index_)); |
| 70 if (frequency_index_ == 0xf) | 73 if (frequency_index_ == 0xf) |
| 71 RCHECK(reader.ReadBits(24, &frequency_)); | 74 RCHECK(reader.ReadBits(24, &frequency_)); |
| 72 RCHECK(reader.ReadBits(4, &channel_config_)); | 75 RCHECK(reader.ReadBits(4, &channel_config_)); |
| 73 | 76 |
| 74 extension_frequency_index = frequency_index_; | |
| 75 | |
| 76 // Read extension configuration | 77 // Read extension configuration |
|
vrk (LEFT CHROMIUM)
2012/07/20 23:08:48
nit: period at end
acolwell GONE FROM CHROMIUM
2012/07/20 23:20:05
Done.
| |
| 77 if (profile_ == 5 || profile_ == 29) { | 78 if (profile_ == 5 || profile_ == 29) { |
| 78 ps_present = (profile_ == 29); | 79 ps_present = (profile_ == 29); |
| 79 extension_type = 5; | 80 extension_type = 5; |
| 80 RCHECK(reader.ReadBits(4, &extension_frequency_index)); | 81 RCHECK(reader.ReadBits(4, &extension_frequency_index)); |
| 81 if (extension_frequency_index == 0xf) | 82 if (extension_frequency_index == 0xf) |
| 82 RCHECK(reader.ReadBits(24, &frequency_)); | 83 RCHECK(reader.ReadBits(24, &extension_frequency_)); |
| 83 RCHECK(reader.ReadBits(5, &profile_)); | 84 RCHECK(reader.ReadBits(5, &profile_)); |
| 84 } | 85 } |
| 85 | 86 |
| 86 RCHECK(SkipDecoderGASpecificConfig(&reader)); | 87 RCHECK(SkipDecoderGASpecificConfig(&reader)); |
| 87 RCHECK(SkipErrorSpecificConfig()); | 88 RCHECK(SkipErrorSpecificConfig()); |
| 88 | 89 |
| 89 // Read extension configuration again | 90 // Read extension configuration again |
| 90 if (extension_type != 5) { | 91 if (extension_type != 5) { |
| 91 uint16 sync_extension_type; | 92 uint16 sync_extension_type; |
| 92 uint8 sbr_present_flag; | 93 uint8 sbr_present_flag; |
| 93 uint8 ps_present_flag; | 94 uint8 ps_present_flag; |
| 94 | 95 |
| 95 if (reader.ReadBits(11, &sync_extension_type) && | 96 if (reader.ReadBits(11, &sync_extension_type) && |
| 96 sync_extension_type == 0x2b7) { | 97 sync_extension_type == 0x2b7) { |
| 97 if (reader.ReadBits(5, &extension_type) && extension_type == 5) { | 98 if (reader.ReadBits(5, &extension_type) && extension_type == 5) { |
| 98 RCHECK(reader.ReadBits(1, &sbr_present_flag)); | 99 RCHECK(reader.ReadBits(1, &sbr_present_flag)); |
| 99 | 100 |
| 100 if (sbr_present_flag) { | 101 if (sbr_present_flag) { |
| 101 RCHECK(reader.ReadBits(4, &extension_frequency_index)); | 102 RCHECK(reader.ReadBits(4, &extension_frequency_index)); |
| 102 | 103 |
| 103 if (extension_frequency_index == 0xf) | 104 if (extension_frequency_index == 0xf) |
| 104 RCHECK(reader.ReadBits(24, &frequency_)); | 105 RCHECK(reader.ReadBits(24, &extension_frequency_)); |
| 105 | 106 |
| 106 RCHECK(reader.ReadBits(11, &sync_extension_type)); | 107 RCHECK(reader.ReadBits(11, &sync_extension_type)); |
| 107 | 108 |
| 108 if (sync_extension_type == 0x548) { | 109 if (sync_extension_type == 0x548) { |
| 109 RCHECK(reader.ReadBits(1, &ps_present_flag)); | 110 RCHECK(reader.ReadBits(1, &ps_present_flag)); |
| 110 ps_present = ps_present_flag != 0; | 111 ps_present = ps_present_flag != 0; |
| 111 } | 112 } |
| 112 } | 113 } |
| 113 } | 114 } |
| 114 } | 115 } |
| 115 } | 116 } |
| 116 | 117 |
| 117 if (frequency_ == 0) { | 118 if (frequency_ == 0) { |
| 119 RCHECK(frequency_index_ < arraysize(kFrequencyMap)); | |
| 120 frequency_ = kFrequencyMap[frequency_index_]; | |
| 121 } | |
| 122 | |
| 123 if (extension_frequency_ == 0 && extension_frequency_index != 0xff) { | |
| 118 RCHECK(extension_frequency_index < arraysize(kFrequencyMap)); | 124 RCHECK(extension_frequency_index < arraysize(kFrequencyMap)); |
| 119 frequency_ = kFrequencyMap[extension_frequency_index]; | 125 extension_frequency_ = kFrequencyMap[extension_frequency_index]; |
| 120 } | 126 } |
| 121 | 127 |
| 122 // When Parametric Stereo is on, mono will be played as stereo. | 128 // When Parametric Stereo is on, mono will be played as stereo. |
| 123 if (ps_present && channel_config_ == 1) | 129 if (ps_present && channel_config_ == 1) |
| 124 channel_layout_ = GetChannelLayout(2); | 130 channel_layout_ = GetChannelLayout(2); |
| 125 else | 131 else |
| 126 channel_layout_ = GetChannelLayout(channel_config_); | 132 channel_layout_ = GetChannelLayout(channel_config_); |
| 127 | 133 |
| 128 return frequency_ != 0 && channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED && | 134 return frequency_ != 0 && channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED && |
| 129 profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && | 135 profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && |
| 130 channel_config_ <= 7; | 136 channel_config_ <= 7; |
| 131 } | 137 } |
| 132 | 138 |
| 133 uint32 AAC::frequency() const { | 139 int AAC::GetOutputSamplesPerSecond(bool sbr_in_mimetype) const { |
| 134 return frequency_; | 140 if (extension_frequency_ > 0) |
| 141 return extension_frequency_; | |
| 142 | |
| 143 if (!sbr_in_mimetype) | |
| 144 return frequency_; | |
| 145 | |
| 146 // The following code is written according to ISO 14496 Part 3 Table 1.11. | |
|
vrk (LEFT CHROMIUM)
2012/07/20 23:08:48
nit: Also include Table 1.22. (Table 1.11 refers t
acolwell GONE FROM CHROMIUM
2012/07/20 23:20:05
Done.
| |
| 147 // TODO(acolwell) : Extend sample rate cap to 96kHz for Level 5 content. | |
| 148 DCHECK_GT(frequency_, 0); | |
| 149 return std::min(2 * frequency_, 48000); | |
| 135 } | 150 } |
| 136 | 151 |
| 137 ChannelLayout AAC::channel_layout() const { | 152 ChannelLayout AAC::channel_layout() const { |
| 138 return channel_layout_; | 153 return channel_layout_; |
| 139 } | 154 } |
| 140 | 155 |
| 141 bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const { | 156 bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const { |
| 142 size_t size = buffer->size() + 7; | 157 size_t size = buffer->size() + 7; |
| 143 | 158 |
| 144 DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && | 159 DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 | 252 |
| 238 RCHECK(bit_reader->ReadBits(1, &dummy)); // extensionFlag3 | 253 RCHECK(bit_reader->ReadBits(1, &dummy)); // extensionFlag3 |
| 239 } | 254 } |
| 240 | 255 |
| 241 return true; | 256 return true; |
| 242 } | 257 } |
| 243 | 258 |
| 244 } // namespace mp4 | 259 } // namespace mp4 |
| 245 | 260 |
| 246 } // namespace media | 261 } // namespace media |
| OLD | NEW |