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

Side by Side Diff: webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.cc

Issue 2516993002: Pass SdpAudioFormat through Channel, without converting to CodecInst (Closed)
Patch Set: opus default stereo Created 4 years 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
OLDNEW
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
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>(2); // Default to stereo.
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, {
ossu 2016/12/19 10:38:26 Should we use stereo by default w/ Opus? If so, I
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698