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", 48000, 2, { |
136 {"minptime", "10" }, | 180 {"minptime", "10" }, |
137 {"useinbandfec", "1" } | 181 {"useinbandfec", "1" } |
138 } | 182 } |
139 }, false | 183 }, false |
140 }, | 184 }, |
141 #endif | 185 #endif |
142 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) | 186 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) |
143 { { "isac", 16000, 1 }, true }, | 187 {{"isac", 16000, 1}, true}, |
144 #endif | 188 #endif |
145 #if (defined(WEBRTC_CODEC_ISAC)) | 189 #if (defined(WEBRTC_CODEC_ISAC)) |
146 { { "isac", 32000, 1 }, true }, | 190 {{"isac", 32000, 1}, true}, |
147 #endif | 191 #endif |
148 #ifdef WEBRTC_CODEC_G722 | 192 #ifdef WEBRTC_CODEC_G722 |
149 { { "G722", 8000, 1 }, true }, | 193 {{"G722", 8000, 1}, true}, |
150 #endif | 194 #endif |
151 #ifdef WEBRTC_CODEC_ILBC | 195 #ifdef WEBRTC_CODEC_ILBC |
152 { { "iLBC", 8000, 1 }, true }, | 196 {{"iLBC", 8000, 1}, true}, |
153 #endif | 197 #endif |
154 { { "PCMU", 8000, 1 }, true }, | 198 {{"PCMU", 8000, 1}, true}, |
155 { { "PCMA", 8000, 1 }, true } | 199 {{"PCMA", 8000, 1}, true} |
156 }; | 200 }; |
157 | 201 |
158 return specs; | 202 return specs; |
159 } | 203 } |
160 | 204 |
| 205 bool IsSupportedDecoder(const SdpAudioFormat& format) override { |
| 206 for (const auto& dc : decoder_constructors) { |
| 207 if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { |
| 208 return dc.constructor(format, nullptr); |
| 209 } |
| 210 } |
| 211 return false; |
| 212 } |
| 213 |
161 std::unique_ptr<AudioDecoder> MakeAudioDecoder( | 214 std::unique_ptr<AudioDecoder> MakeAudioDecoder( |
162 const SdpAudioFormat& format) override { | 215 const SdpAudioFormat& format) override { |
163 for (const auto& dc : decoder_constructors) { | 216 for (const auto& dc : decoder_constructors) { |
164 if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { | 217 if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { |
165 std::unique_ptr<AudioDecoder> dec = dc.constructor(format); | 218 std::unique_ptr<AudioDecoder> decoder; |
166 if (dec) { | 219 bool ok = dc.constructor(format, &decoder); |
| 220 RTC_DCHECK_EQ(ok, decoder != nullptr); |
| 221 if (decoder) { |
167 const int expected_sample_rate_hz = | 222 const int expected_sample_rate_hz = |
168 STR_CASE_CMP(format.name.c_str(), "g722") == 0 | 223 STR_CASE_CMP(format.name.c_str(), "g722") == 0 |
169 ? 2 * format.clockrate_hz | 224 ? 2 * format.clockrate_hz |
170 : format.clockrate_hz; | 225 : format.clockrate_hz; |
171 RTC_CHECK_EQ(expected_sample_rate_hz, dec->SampleRateHz()); | 226 RTC_CHECK_EQ(expected_sample_rate_hz, decoder->SampleRateHz()); |
172 } | 227 } |
173 return dec; | 228 return decoder; |
174 } | 229 } |
175 } | 230 } |
176 return nullptr; | 231 return nullptr; |
177 } | 232 } |
178 }; | 233 }; |
179 | 234 |
180 } // namespace | 235 } // namespace |
181 | 236 |
182 rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() { | 237 rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() { |
183 return rtc::scoped_refptr<AudioDecoderFactory>( | 238 return rtc::scoped_refptr<AudioDecoderFactory>( |
184 new rtc::RefCountedObject<BuiltinAudioDecoderFactory>); | 239 new rtc::RefCountedObject<BuiltinAudioDecoderFactory>); |
185 } | 240 } |
186 | 241 |
187 } // namespace webrtc | 242 } // namespace webrtc |
OLD | NEW |