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