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 EXPECT_FALSE(decoder_config.has_value());
49 }
50 {
51 // The mapping is too long. There are only 5 channels, but 6 elements in the
52 // mapping.
53 const SdpAudioFormat sdp_format("multiopus", 48000, 5,
54 {{"channel_mapping", "0,1,2,3,4,5"},
55 {"coupled_streams", "0"},
56 {"num_streams", "2"}});
57 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
58 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
59 EXPECT_FALSE(decoder_config.has_value());
60 }
61 {
62 // The mapping doesn't parse correctly.
63 const SdpAudioFormat sdp_format(
64 "multiopus", 48000, 5,
65 {{"channel_mapping", "0,1,two,3,4"}, {"coupled_streams", "0"}});
66 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
67 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
68 EXPECT_FALSE(decoder_config.has_value());
69 }
70 }
71
TEST(AudioDecoderMultiOpusTest,ValidSdpToConfigProducesCorrectConfig)72 TEST(AudioDecoderMultiOpusTest, ValidSdpToConfigProducesCorrectConfig) {
73 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
74 {{"channel_mapping", "3,1,2,0"},
75 {"coupled_streams", "2"},
76 {"num_streams", "2"}});
77
78 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
79 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
80
81 ASSERT_TRUE(decoder_config.has_value());
82 EXPECT_TRUE(decoder_config->IsOk());
83 EXPECT_EQ(decoder_config->coupled_streams, 2);
84 EXPECT_THAT(decoder_config->channel_mapping,
85 ::testing::ContainerEq(std::vector<unsigned char>({3, 1, 2, 0})));
86 }
87
TEST(AudioDecoderMultiOpusTest,InvalidSdpToConfigDoesNotProduceConfig)88 TEST(AudioDecoderMultiOpusTest, InvalidSdpToConfigDoesNotProduceConfig) {
89 {
90 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
91 {{"channel_mapping", "0,1,2,3"},
92 {"coupled_stream", "2"},
93 {"num_streams", "2"}});
94
95 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
96 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
97
98 EXPECT_FALSE(decoder_config.has_value());
99 }
100
101 {
102 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
103 {{"channel_mapping", "0,1,2 3"},
104 {"coupled_streams", "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
TEST(AudioDecoderMultiOpusTest,CodecsCanBeCreated)114 TEST(AudioDecoderMultiOpusTest, CodecsCanBeCreated) {
115 const SdpAudioFormat sdp_format("multiopus", 48000, 4,
116 {{"channel_mapping", "0,1,2,3"},
117 {"coupled_streams", "2"},
118 {"num_streams", "2"}});
119
120 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
121 AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
122
123 ASSERT_TRUE(decoder_config.has_value());
124
125 const std::unique_ptr<AudioDecoder> opus_decoder =
126 AudioDecoderMultiChannelOpus::MakeAudioDecoder(*decoder_config);
127
128 EXPECT_TRUE(opus_decoder);
129 }
130
TEST(AudioDecoderMultiOpusTest,AdvertisedCodecsCanBeCreated)131 TEST(AudioDecoderMultiOpusTest, AdvertisedCodecsCanBeCreated) {
132 std::vector<AudioCodecSpec> specs;
133 AudioDecoderMultiChannelOpus::AppendSupportedDecoders(&specs);
134
135 EXPECT_FALSE(specs.empty());
136
137 for (const AudioCodecSpec& spec : specs) {
138 const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
139 AudioDecoderMultiChannelOpus::SdpToConfig(spec.format);
140 ASSERT_TRUE(decoder_config.has_value());
141
142 const std::unique_ptr<AudioDecoder> opus_decoder =
143 AudioDecoderMultiChannelOpus::MakeAudioDecoder(*decoder_config);
144
145 EXPECT_TRUE(opus_decoder);
146 }
147 }
148 } // namespace webrtc
149