1 /*
2 * Copyright (c) 2019 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 "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
12
13 #include "modules/audio_coding/codecs/opus/audio_coder_opus_common.h"
14 #include "test/gmock.h"
15 #include "test/gtest.h"
16
17 namespace webrtc {
18 using ::testing::NiceMock;
19 using ::testing::Return;
20
TEST(AudioDecoderMultiOpusTest,GetFormatParameter)21 TEST(AudioDecoderMultiOpusTest, GetFormatParameter) {
22 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
23 {{"channel_mapping", "0,1,2,3"},
24 {"coupled_streams", "2"},
25 {"num_streams", "2"}});
26
27 EXPECT_EQ(GetFormatParameter(sdp_format, "channel_mapping"),
28 absl::optional<std::string>("0,1,2,3"));
29
30 EXPECT_EQ(GetFormatParameter<int>(sdp_format, "coupled_streams"),
31 absl::optional<int>(2));
32
33 EXPECT_EQ(GetFormatParameter(sdp_format, "missing"), absl::nullopt);
34
35 EXPECT_EQ(GetFormatParameter<int>(sdp_format, "channel_mapping"),
36 absl::nullopt);
37 }
38
TEST(AudioDecoderMultiOpusTest,InvalidChannelMappings)39 TEST(AudioDecoderMultiOpusTest, InvalidChannelMappings) {
40 {
41 // Can't use channel 3 if there are only 2 channels.
42 const SdpAudioFormat sdp_format("multiopus", 48000, 2,
43 {{"channel_mapping", "3,0"},
44 {"coupled_streams", "1"},
45 {"num_streams", "2"}});
46 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
47 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
48 ASSERT_TRUE(decoder_config.has_value());
49 EXPECT_FALSE(decoder_config->IsOk());
50
51 const std::unique_ptr<AudioDecoder> opus_decoder =
52 AudioDecoderMultiChannelOpus::MakeAudioDecoder(*decoder_config);
53
54 EXPECT_FALSE(opus_decoder);
55 }
56 {
57 // The mapping is too long. There are only 5 channels, but 6 elements in the
58 // mapping.
59 const SdpAudioFormat sdp_format("multiopus", 48000, 5,
60 {{"channel_mapping", "0,1,2,3,4,5"},
61 {"coupled_streams", "0"},
62 {"num_streams", "2"}});
63 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
64 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
65 ASSERT_TRUE(decoder_config.has_value());
66 EXPECT_FALSE(decoder_config->IsOk());
67
68 const std::unique_ptr<AudioDecoder> opus_decoder =
69 AudioDecoderMultiChannelOpus::MakeAudioDecoder(*decoder_config);
70
71 EXPECT_FALSE(opus_decoder);
72 }
73 {
74 // The mapping doesn't parse correctly.
75 const SdpAudioFormat sdp_format(
76 "multiopus", 48000, 5,
77 {{"channel_mapping", "0,1,two,3,4"}, {"coupled_streams", "0"}});
78 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
79 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
80 EXPECT_FALSE(decoder_config.has_value());
81 }
82 }
83
TEST(AudioDecoderMultiOpusTest,ValidSdpToConfigProducesCorrectConfig)84 TEST(AudioDecoderMultiOpusTest, ValidSdpToConfigProducesCorrectConfig) {
85 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
86 {{"channel_mapping", "3,1,2,0"},
87 {"coupled_streams", "2"},
88 {"num_streams", "2"}});
89
90 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
91 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
92
93 ASSERT_TRUE(decoder_config.has_value());
94 EXPECT_TRUE(decoder_config->IsOk());
95 EXPECT_EQ(decoder_config->coupled_streams, 2);
96 EXPECT_THAT(decoder_config->channel_mapping,
97 ::testing::ContainerEq(std::vector<unsigned char>({3, 1, 2, 0})));
98 }
99
TEST(AudioDecoderMultiOpusTest,InvalidSdpToConfigDoesNotProduceConfig)100 TEST(AudioDecoderMultiOpusTest, InvalidSdpToConfigDoesNotProduceConfig) {
101 {
102 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
103 {{"channel_mapping", "0,1,2,3"},
104 {"coupled_stream", "2"},
105 {"num_streams", "2"}});
106
107 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
108 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
109
110 EXPECT_FALSE(decoder_config.has_value());
111 }
112
113 {
114 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
115 {{"channel_mapping", "0,1,2 3"},
116 {"coupled_streams", "2"},
117 {"num_streams", "2"}});
118
119 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
120 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
121
122 EXPECT_FALSE(decoder_config.has_value());
123 }
124 }
125
TEST(AudioDecoderMultiOpusTest,CodecsCanBeCreated)126 TEST(AudioDecoderMultiOpusTest, CodecsCanBeCreated) {
127 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
128 {{"channel_mapping", "0,1,2,3"},
129 {"coupled_streams", "2"},
130 {"num_streams", "2"}});
131
132 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
133 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
134
135 ASSERT_TRUE(decoder_config.has_value());
136
137 const std::unique_ptr<AudioDecoder> opus_decoder =
138 AudioDecoderMultiChannelOpus::MakeAudioDecoder(*decoder_config);
139
140 EXPECT_TRUE(opus_decoder);
141 }
142
TEST(AudioDecoderMultiOpusTest,AdvertisedCodecsCanBeCreated)143 TEST(AudioDecoderMultiOpusTest, AdvertisedCodecsCanBeCreated) {
144 std::vector<AudioCodecSpec> specs;
145 AudioDecoderMultiChannelOpus::AppendSupportedDecoders(&specs);
146
147 EXPECT_FALSE(specs.empty());
148
149 for (const AudioCodecSpec& spec : specs) {
150 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
151 AudioDecoderMultiChannelOpus::SdpToConfig(spec.format);
152 ASSERT_TRUE(decoder_config.has_value());
153
154 const std::unique_ptr<AudioDecoder> opus_decoder =
155 AudioDecoderMultiChannelOpus::MakeAudioDecoder(*decoder_config);
156
157 EXPECT_TRUE(opus_decoder);
158 }
159 }
160 } // namespace webrtc
161