OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... | |
33 #include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" | 33 #include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" |
34 #endif | 34 #endif |
35 #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" | 35 #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" |
36 | 36 |
37 namespace webrtc { | 37 namespace webrtc { |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
41 struct NamedDecoderConstructor { | 41 struct NamedDecoderConstructor { |
42 const char* name; | 42 const char* name; |
43 std::unique_ptr<AudioDecoder> (*constructor)(const SdpAudioFormat&); | 43 |
44 // If |format| is good, return true and (if |out| isn't null) reset |*out| to | |
45 // a new decoder object. If the |format| is not good, return false. | |
46 bool (*constructor)(const SdpAudioFormat& format, | |
47 std::unique_ptr<AudioDecoder>* out); | |
44 }; | 48 }; |
45 | 49 |
46 std::unique_ptr<AudioDecoder> Unique(AudioDecoder* d) { | |
47 return std::unique_ptr<AudioDecoder>(d); | |
48 } | |
49 | |
50 // TODO(kwiberg): These factory functions should probably be moved to each | 50 // TODO(kwiberg): These factory functions should probably be moved to each |
51 // decoder. | 51 // decoder. |
52 NamedDecoderConstructor decoder_constructors[] = { | 52 NamedDecoderConstructor decoder_constructors[] = { |
53 {"pcmu", | 53 {"pcmu", |
54 [](const SdpAudioFormat& format) { | 54 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
55 return format.clockrate_hz == 8000 && format.num_channels >= 1 | 55 if (format.clockrate_hz == 8000 && format.num_channels >= 1) { |
56 ? Unique(new AudioDecoderPcmU(format.num_channels)) | 56 if (out) { |
57 : nullptr; | 57 out->reset(new AudioDecoderPcmU(format.num_channels)); |
58 } | |
59 return true; | |
60 } else { | |
61 return false; | |
62 } | |
58 }}, | 63 }}, |
59 {"pcma", | 64 {"pcma", |
60 [](const SdpAudioFormat& format) { | 65 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
61 return format.clockrate_hz == 8000 && format.num_channels >= 1 | 66 if (format.clockrate_hz == 8000 && format.num_channels >= 1) { |
62 ? Unique(new AudioDecoderPcmA(format.num_channels)) | 67 if (out) { |
63 : nullptr; | 68 out->reset(new AudioDecoderPcmA(format.num_channels)); |
69 } | |
70 return true; | |
71 } else { | |
72 return false; | |
73 } | |
64 }}, | 74 }}, |
65 #ifdef WEBRTC_CODEC_ILBC | 75 #ifdef WEBRTC_CODEC_ILBC |
66 {"ilbc", | 76 {"ilbc", |
67 [](const SdpAudioFormat& format) { | 77 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
68 return format.clockrate_hz == 8000 && format.num_channels == 1 | 78 if (format.clockrate_hz == 8000 && format.num_channels == 1) { |
69 ? Unique(new AudioDecoderIlbc) | 79 if (out) { |
70 : nullptr; | 80 out->reset(new AudioDecoderIlbc); |
81 } | |
82 return true; | |
83 } else { | |
84 return false; | |
85 } | |
71 }}, | 86 }}, |
72 #endif | 87 #endif |
73 #if defined(WEBRTC_CODEC_ISACFX) | 88 #if defined(WEBRTC_CODEC_ISACFX) |
74 {"isac", | 89 {"isac", |
75 [](const SdpAudioFormat& format) { | 90 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
76 return format.clockrate_hz == 16000 && format.num_channels == 1 | 91 if (format.clockrate_hz == 16000 && format.num_channels == 1) { |
77 ? Unique(new AudioDecoderIsacFix(format.clockrate_hz)) | 92 if (out) { |
78 : nullptr; | 93 out->reset(new AudioDecoderIsacFix(format.clockrate_hz)); |
94 } | |
95 return true; | |
96 } else { | |
97 return false; | |
98 } | |
79 }}, | 99 }}, |
80 #elif defined(WEBRTC_CODEC_ISAC) | 100 #elif defined(WEBRTC_CODEC_ISAC) |
81 {"isac", | 101 {"isac", |
82 [](const SdpAudioFormat& format) { | 102 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
83 return (format.clockrate_hz == 16000 || format.clockrate_hz == 32000) && | 103 if ((format.clockrate_hz == 16000 || format.clockrate_hz == 32000) && |
84 format.num_channels == 1 | 104 format.num_channels == 1) { |
85 ? Unique(new AudioDecoderIsac(format.clockrate_hz)) | 105 if (out) { |
86 : nullptr; | 106 out->reset(new AudioDecoderIsac(format.clockrate_hz)); |
107 } | |
108 return true; | |
109 } else { | |
110 return false; | |
111 } | |
87 }}, | 112 }}, |
88 #endif | 113 #endif |
89 {"l16", | 114 {"l16", |
90 [](const SdpAudioFormat& format) { | 115 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
91 return format.num_channels >= 1 | 116 if (format.num_channels >= 1) { |
92 ? Unique(new AudioDecoderPcm16B(format.clockrate_hz, | 117 if (out) { |
93 format.num_channels)) | 118 out->reset(new AudioDecoderPcm16B(format.clockrate_hz, |
94 : nullptr; | 119 format.num_channels)); |
120 } | |
121 return true; | |
122 } else { | |
123 return false; | |
124 } | |
95 }}, | 125 }}, |
96 #ifdef WEBRTC_CODEC_G722 | 126 #ifdef WEBRTC_CODEC_G722 |
97 {"g722", | 127 {"g722", |
98 [](const SdpAudioFormat& format) { | 128 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
99 if (format.clockrate_hz == 8000) { | 129 if (format.clockrate_hz == 8000) { |
100 if (format.num_channels == 1) | 130 if (format.num_channels == 1) { |
101 return Unique(new AudioDecoderG722); | 131 if (out) { |
102 if (format.num_channels == 2) | 132 out->reset(new AudioDecoderG722); |
103 return Unique(new AudioDecoderG722Stereo); | 133 } |
134 return true; | |
135 } else if (format.num_channels == 2) { | |
136 if (out) { | |
137 out->reset(new AudioDecoderG722Stereo); | |
138 } | |
139 return true; | |
140 } | |
104 } | 141 } |
105 return Unique(nullptr); | 142 return false; |
106 }}, | 143 }}, |
107 #endif | 144 #endif |
108 #ifdef WEBRTC_CODEC_OPUS | 145 #ifdef WEBRTC_CODEC_OPUS |
109 {"opus", | 146 {"opus", |
110 [](const SdpAudioFormat& format) { | 147 [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |
111 rtc::Optional<int> num_channels = [&] { | 148 const rtc::Optional<int> num_channels = [&] { |
112 auto stereo = format.parameters.find("stereo"); | 149 auto stereo = format.parameters.find("stereo"); |
113 if (stereo != format.parameters.end()) { | 150 if (stereo != format.parameters.end()) { |
114 if (stereo->second == "0") { | 151 if (stereo->second == "0") { |
115 return rtc::Optional<int>(1); | 152 return rtc::Optional<int>(1); |
116 } else if (stereo->second == "1") { | 153 } else if (stereo->second == "1") { |
117 return rtc::Optional<int>(2); | 154 return rtc::Optional<int>(2); |
155 } else { | |
156 return rtc::Optional<int>(); // Bad stereo parameter. | |
118 } | 157 } |
119 } | 158 } |
120 return rtc::Optional<int>(); | 159 return rtc::Optional<int>(1); // Default to mono. |
121 }(); | 160 }(); |
122 return format.clockrate_hz == 48000 && format.num_channels == 2 && | 161 if (format.clockrate_hz == 48000 && format.num_channels == 2 && |
123 num_channels | 162 num_channels) { |
124 ? Unique(new AudioDecoderOpus(*num_channels)) | 163 if (out) { |
125 : nullptr; | 164 out->reset(new AudioDecoderOpus(*num_channels)); |
165 } | |
166 return true; | |
167 } else { | |
168 return false; | |
169 } | |
126 }}, | 170 }}, |
127 #endif | 171 #endif |
128 }; | 172 }; |
129 | 173 |
130 class BuiltinAudioDecoderFactory : public AudioDecoderFactory { | 174 class BuiltinAudioDecoderFactory : public AudioDecoderFactory { |
131 public: | 175 public: |
132 std::vector<AudioCodecSpec> GetSupportedDecoders() override { | 176 std::vector<AudioCodecSpec> GetSupportedDecoders() override { |
133 static std::vector<AudioCodecSpec> specs = { | 177 static std::vector<AudioCodecSpec> specs = { |
134 #ifdef WEBRTC_CODEC_OPUS | 178 #ifdef WEBRTC_CODEC_OPUS |
135 { { "opus", 48000, 2, { | 179 {{"opus", |
136 {"minptime", "10" }, | 180 48000, |
137 {"useinbandfec", "1" } | 181 2, |
138 } | 182 { {"minptime", "10"}, |
139 }, false | 183 {"stereo", "0"}, |
140 }, | 184 { "useinbandfec", |
185 "1" } }}, | |
186 false}, | |
141 #endif | 187 #endif |
142 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) | 188 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) |
143 { { "isac", 16000, 1 }, true }, | 189 {{"isac", 16000, 1}, true}, |
144 #endif | 190 #endif |
145 #if (defined(WEBRTC_CODEC_ISAC)) | 191 #if (defined(WEBRTC_CODEC_ISAC)) |
146 { { "isac", 32000, 1 }, true }, | 192 {{"isac", 32000, 1}, true}, |
147 #endif | 193 #endif |
148 #ifdef WEBRTC_CODEC_G722 | 194 #ifdef WEBRTC_CODEC_G722 |
149 { { "G722", 8000, 1 }, true }, | 195 {{"G722", 8000, 1}, true}, |
150 #endif | 196 #endif |
151 #ifdef WEBRTC_CODEC_ILBC | 197 #ifdef WEBRTC_CODEC_ILBC |
152 { { "iLBC", 8000, 1 }, true }, | 198 {{"iLBC", 8000, 1}, true}, |
153 #endif | 199 #endif |
154 { { "PCMU", 8000, 1 }, true }, | 200 {{"PCMU", 8000, 1}, true}, |
155 { { "PCMA", 8000, 1 }, true } | 201 {{"PCMA", 8000, 1}, true} |
156 }; | 202 }; |
157 | 203 |
158 return specs; | 204 return specs; |
159 } | 205 } |
160 | 206 |
207 bool IsSupportedDecoder(const SdpAudioFormat& format) override { | |
208 for (const auto& dc : decoder_constructors) { | |
209 if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { | |
210 return dc.constructor(format, nullptr); | |
211 } | |
212 } | |
213 return false; | |
214 } | |
215 | |
161 std::unique_ptr<AudioDecoder> MakeAudioDecoder( | 216 std::unique_ptr<AudioDecoder> MakeAudioDecoder( |
162 const SdpAudioFormat& format) override { | 217 const SdpAudioFormat& format) override { |
163 for (const auto& dc : decoder_constructors) { | 218 for (const auto& dc : decoder_constructors) { |
164 if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { | 219 if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { |
165 std::unique_ptr<AudioDecoder> dec = dc.constructor(format); | 220 std::unique_ptr<AudioDecoder> dec; |
the sun
2016/12/15 15:34:13
nit: dec -> decoder
kwiberg-webrtc
2016/12/16 14:20:54
Done.
| |
221 bool ok = dc.constructor(format, &dec); | |
222 RTC_CHECK_EQ(ok, dec != nullptr); | |
the sun
2016/12/15 15:34:13
That's a DCHECK, since you're testing the logic, n
kwiberg-webrtc
2016/12/16 14:20:54
Done.
| |
166 if (dec) { | 223 if (dec) { |
167 const int expected_sample_rate_hz = | 224 const int expected_sample_rate_hz = |
168 STR_CASE_CMP(format.name.c_str(), "g722") == 0 | 225 STR_CASE_CMP(format.name.c_str(), "g722") == 0 |
169 ? 2 * format.clockrate_hz | 226 ? 2 * format.clockrate_hz |
170 : format.clockrate_hz; | 227 : format.clockrate_hz; |
171 RTC_CHECK_EQ(expected_sample_rate_hz, dec->SampleRateHz()); | 228 RTC_CHECK_EQ(expected_sample_rate_hz, dec->SampleRateHz()); |
172 } | 229 } |
173 return dec; | 230 return dec; |
174 } | 231 } |
175 } | 232 } |
176 return nullptr; | 233 return nullptr; |
177 } | 234 } |
178 }; | 235 }; |
179 | 236 |
180 } // namespace | 237 } // namespace |
181 | 238 |
182 rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() { | 239 rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() { |
183 return rtc::scoped_refptr<AudioDecoderFactory>( | 240 return rtc::scoped_refptr<AudioDecoderFactory>( |
184 new rtc::RefCountedObject<BuiltinAudioDecoderFactory>); | 241 new rtc::RefCountedObject<BuiltinAudioDecoderFactory>); |
185 } | 242 } |
186 | 243 |
187 } // namespace webrtc | 244 } // namespace webrtc |
OLD | NEW |