Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: media/mp4/aac.cc

Issue 10795050: Fix MediaSource code so it can handle HE-AAC content that uses implicit signalling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/mp4/aac.h ('k') | media/mp4/aac_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_; 77 // Read extension configuration.
75
76 // Read extension configuration
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 and
147 // Table 1.22. (Table 1.11 refers to the capping to 48000, Table 1.22 refers
148 // to SBR doubling the AAC sample rate.)
149 // TODO(acolwell) : Extend sample rate cap to 96kHz for Level 5 content.
150 DCHECK_GT(frequency_, 0);
151 return std::min(2 * frequency_, 48000);
135 } 152 }
136 153
137 ChannelLayout AAC::channel_layout() const { 154 ChannelLayout AAC::channel_layout() const {
138 return channel_layout_; 155 return channel_layout_;
139 } 156 }
140 157
141 bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const { 158 bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const {
142 size_t size = buffer->size() + 7; 159 size_t size = buffer->size() + 7;
143 160
144 DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && 161 DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf &&
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 254
238 RCHECK(bit_reader->ReadBits(1, &dummy)); // extensionFlag3 255 RCHECK(bit_reader->ReadBits(1, &dummy)); // extensionFlag3
239 } 256 }
240 257
241 return true; 258 return true;
242 } 259 }
243 260
244 } // namespace mp4 261 } // namespace mp4
245 262
246 } // namespace media 263 } // namespace media
OLDNEW
« no previous file with comments | « media/mp4/aac.h ('k') | media/mp4/aac_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698