xref: /aosp_15_r20/external/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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