Line data Source code
1 : /*
2 : * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 : *
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
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
12 :
13 : #include <vector>
14 :
15 : #include "webrtc/base/checks.h"
16 : #include "webrtc/base/optional.h"
17 : #include "webrtc/common_types.h"
18 : #include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h"
19 : #include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
20 : #ifdef WEBRTC_CODEC_G722
21 : #include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h"
22 : #endif
23 : #ifdef WEBRTC_CODEC_ILBC
24 : #include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h"
25 : #endif
26 : #ifdef WEBRTC_CODEC_ISACFX
27 : #include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"
28 : #endif
29 : #ifdef WEBRTC_CODEC_ISAC
30 : #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"
31 : #endif
32 : #ifdef WEBRTC_CODEC_OPUS
33 : #include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h"
34 : #endif
35 : #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h"
36 :
37 : namespace webrtc {
38 :
39 : namespace {
40 :
41 : struct NamedDecoderConstructor {
42 : const char* name;
43 : std::unique_ptr<AudioDecoder> (*constructor)(const SdpAudioFormat&);
44 : };
45 :
46 0 : std::unique_ptr<AudioDecoder> Unique(AudioDecoder* d) {
47 0 : return std::unique_ptr<AudioDecoder>(d);
48 : }
49 :
50 : // TODO(kwiberg): These factory functions should probably be moved to each
51 : // decoder.
52 : NamedDecoderConstructor decoder_constructors[] = {
53 : {"pcmu",
54 3 : [](const SdpAudioFormat& format) {
55 0 : return format.clockrate_hz == 8000 && format.num_channels >= 1
56 0 : ? Unique(new AudioDecoderPcmU(format.num_channels))
57 : : nullptr;
58 3 : }},
59 : {"pcma",
60 3 : [](const SdpAudioFormat& format) {
61 0 : return format.clockrate_hz == 8000 && format.num_channels >= 1
62 0 : ? Unique(new AudioDecoderPcmA(format.num_channels))
63 : : nullptr;
64 3 : }},
65 : #ifdef WEBRTC_CODEC_ILBC
66 : {"ilbc",
67 : [](const SdpAudioFormat& format) {
68 : return format.clockrate_hz == 8000 && format.num_channels == 1
69 : ? Unique(new AudioDecoderIlbc)
70 : : nullptr;
71 : }},
72 : #endif
73 : #if defined(WEBRTC_CODEC_ISACFX)
74 : {"isac",
75 : [](const SdpAudioFormat& format) {
76 : return format.clockrate_hz == 16000 && format.num_channels == 1
77 : ? Unique(new AudioDecoderIsacFix(format.clockrate_hz))
78 : : nullptr;
79 : }},
80 : #elif defined(WEBRTC_CODEC_ISAC)
81 : {"isac",
82 : [](const SdpAudioFormat& format) {
83 : return (format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
84 : format.num_channels == 1
85 : ? Unique(new AudioDecoderIsac(format.clockrate_hz))
86 : : nullptr;
87 : }},
88 : #endif
89 : {"l16",
90 3 : [](const SdpAudioFormat& format) {
91 0 : return format.num_channels >= 1
92 0 : ? Unique(new AudioDecoderPcm16B(format.clockrate_hz,
93 0 : format.num_channels))
94 : : nullptr;
95 3 : }},
96 : #ifdef WEBRTC_CODEC_G722
97 : {"g722",
98 : [](const SdpAudioFormat& format) {
99 : if (format.clockrate_hz == 8000) {
100 : if (format.num_channels == 1)
101 : return Unique(new AudioDecoderG722);
102 : if (format.num_channels == 2)
103 : return Unique(new AudioDecoderG722Stereo);
104 : }
105 : return Unique(nullptr);
106 : }},
107 : #endif
108 : #ifdef WEBRTC_CODEC_OPUS
109 : {"opus",
110 3 : [](const SdpAudioFormat& format) {
111 0 : rtc::Optional<int> num_channels = [&] {
112 0 : auto stereo = format.parameters.find("stereo");
113 0 : if (stereo != format.parameters.end()) {
114 0 : if (stereo->second == "0") {
115 0 : return rtc::Optional<int>(1);
116 0 : } else if (stereo->second == "1") {
117 0 : return rtc::Optional<int>(2);
118 : }
119 : }
120 0 : return rtc::Optional<int>();
121 0 : }();
122 0 : return format.clockrate_hz == 48000 && format.num_channels == 2 &&
123 0 : num_channels
124 0 : ? Unique(new AudioDecoderOpus(*num_channels))
125 0 : : nullptr;
126 3 : }},
127 : #endif
128 3 : };
129 :
130 0 : class BuiltinAudioDecoderFactory : public AudioDecoderFactory {
131 : public:
132 0 : std::vector<AudioCodecSpec> GetSupportedDecoders() override {
133 : static std::vector<AudioCodecSpec> specs = {
134 : #ifdef WEBRTC_CODEC_OPUS
135 : { { "opus", 48000, 2, {
136 : {"minptime", "10" },
137 : {"useinbandfec", "1" }
138 : }
139 : }, false
140 : },
141 : #endif
142 : #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
143 : { { "isac", 16000, 1 }, true },
144 : #endif
145 : #if (defined(WEBRTC_CODEC_ISAC))
146 : { { "isac", 32000, 1 }, true },
147 : #endif
148 : #ifdef WEBRTC_CODEC_G722
149 : { { "G722", 8000, 1 }, true },
150 : #endif
151 : #ifdef WEBRTC_CODEC_ILBC
152 : { { "iLBC", 8000, 1 }, true },
153 : #endif
154 : { { "PCMU", 8000, 1 }, true },
155 : { { "PCMA", 8000, 1 }, true }
156 0 : };
157 :
158 0 : return specs;
159 : }
160 :
161 0 : std::unique_ptr<AudioDecoder> MakeAudioDecoder(
162 : const SdpAudioFormat& format) override {
163 0 : for (const auto& dc : decoder_constructors) {
164 0 : if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) {
165 0 : std::unique_ptr<AudioDecoder> dec = dc.constructor(format);
166 0 : if (dec) {
167 : const int expected_sample_rate_hz =
168 0 : STR_CASE_CMP(format.name.c_str(), "g722") == 0
169 0 : ? 2 * format.clockrate_hz
170 0 : : format.clockrate_hz;
171 0 : RTC_CHECK_EQ(expected_sample_rate_hz, dec->SampleRateHz());
172 : }
173 0 : return dec;
174 : }
175 : }
176 0 : return nullptr;
177 : }
178 : };
179 :
180 : } // namespace
181 :
182 0 : rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
183 : return rtc::scoped_refptr<AudioDecoderFactory>(
184 0 : new rtc::RefCountedObject<BuiltinAudioDecoderFactory>);
185 : }
186 :
187 9 : } // namespace webrtc
|