1 /*
2 * Copyright (c) 2014 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 "modules/audio_coding/codecs/opus/opus_interface.h"
12 #include "modules/audio_coding/codecs/tools/audio_codec_speed_test.h"
13
14 using ::std::string;
15
16 namespace webrtc {
17
18 static const int kOpusBlockDurationMs = 20;
19 static const int kOpusSamplingKhz = 48;
20
21 class OpusSpeedTest : public AudioCodecSpeedTest {
22 protected:
23 OpusSpeedTest();
24 void SetUp() override;
25 void TearDown() override;
26 float EncodeABlock(int16_t* in_data,
27 uint8_t* bit_stream,
28 size_t max_bytes,
29 size_t* encoded_bytes) override;
30 float DecodeABlock(const uint8_t* bit_stream,
31 size_t encoded_bytes,
32 int16_t* out_data) override;
33 WebRtcOpusEncInst* opus_encoder_;
34 WebRtcOpusDecInst* opus_decoder_;
35 };
36
OpusSpeedTest()37 OpusSpeedTest::OpusSpeedTest()
38 : AudioCodecSpeedTest(kOpusBlockDurationMs,
39 kOpusSamplingKhz,
40 kOpusSamplingKhz),
41 opus_encoder_(NULL),
42 opus_decoder_(NULL) {}
43
SetUp()44 void OpusSpeedTest::SetUp() {
45 AudioCodecSpeedTest::SetUp();
46 // If channels_ == 1, use Opus VOIP mode, otherwise, audio mode.
47 int app = channels_ == 1 ? 0 : 1;
48 /* Create encoder memory. */
49 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, app, 48000));
50 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_, 48000));
51 /* Set bitrate. */
52 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, bit_rate_));
53 }
54
TearDown()55 void OpusSpeedTest::TearDown() {
56 AudioCodecSpeedTest::TearDown();
57 /* Free memory. */
58 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
59 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
60 }
61
EncodeABlock(int16_t * in_data,uint8_t * bit_stream,size_t max_bytes,size_t * encoded_bytes)62 float OpusSpeedTest::EncodeABlock(int16_t* in_data,
63 uint8_t* bit_stream,
64 size_t max_bytes,
65 size_t* encoded_bytes) {
66 clock_t clocks = clock();
67 int value = WebRtcOpus_Encode(opus_encoder_, in_data, input_length_sample_,
68 max_bytes, bit_stream);
69 clocks = clock() - clocks;
70 EXPECT_GT(value, 0);
71 *encoded_bytes = static_cast<size_t>(value);
72 return 1000.0 * clocks / CLOCKS_PER_SEC;
73 }
74
DecodeABlock(const uint8_t * bit_stream,size_t encoded_bytes,int16_t * out_data)75 float OpusSpeedTest::DecodeABlock(const uint8_t* bit_stream,
76 size_t encoded_bytes,
77 int16_t* out_data) {
78 int value;
79 int16_t audio_type;
80 clock_t clocks = clock();
81 value = WebRtcOpus_Decode(opus_decoder_, bit_stream, encoded_bytes, out_data,
82 &audio_type);
83 clocks = clock() - clocks;
84 EXPECT_EQ(output_length_sample_, static_cast<size_t>(value));
85 return 1000.0 * clocks / CLOCKS_PER_SEC;
86 }
87
88 /* Test audio length in second. */
89 constexpr size_t kDurationSec = 400;
90
91 #define ADD_TEST(complexity) \
92 TEST_P(OpusSpeedTest, OpusSetComplexityTest##complexity) { \
93 /* Set complexity. */ \
94 printf("Setting complexity to %d ...\n", complexity); \
95 EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, complexity)); \
96 EncodeDecode(kDurationSec); \
97 }
98
99 ADD_TEST(10)
100 ADD_TEST(9)
101 ADD_TEST(8)
102 ADD_TEST(7)
103 ADD_TEST(6)
104 ADD_TEST(5)
105 ADD_TEST(4)
106 ADD_TEST(3)
107 ADD_TEST(2)
108 ADD_TEST(1)
109 ADD_TEST(0)
110
111 #define ADD_BANDWIDTH_TEST(bandwidth) \
112 TEST_P(OpusSpeedTest, OpusSetBandwidthTest##bandwidth) { \
113 /* Set bandwidth. */ \
114 printf("Setting bandwidth to %d ...\n", bandwidth); \
115 EXPECT_EQ(0, WebRtcOpus_SetBandwidth(opus_encoder_, bandwidth)); \
116 EncodeDecode(kDurationSec); \
117 }
118
119 ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_NARROWBAND)
120 ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_MEDIUMBAND)
121 ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_WIDEBAND)
122 ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_SUPERWIDEBAND)
123 ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_FULLBAND)
124
125 // List all test cases: (channel, bit rat, filename, extension).
126 const coding_param param_set[] = {
127 std::make_tuple(1,
128 64000,
129 string("audio_coding/speech_mono_32_48kHz"),
130 string("pcm"),
131 true),
132 std::make_tuple(1,
133 32000,
134 string("audio_coding/speech_mono_32_48kHz"),
135 string("pcm"),
136 true),
137 std::make_tuple(2,
138 64000,
139 string("audio_coding/music_stereo_48kHz"),
140 string("pcm"),
141 true)};
142
143 INSTANTIATE_TEST_SUITE_P(AllTest,
144 OpusSpeedTest,
145 ::testing::ValuesIn(param_set));
146
147 } // namespace webrtc
148