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 "webrtc/modules/audio_coding/codecs/opus/opus_interface.h"
12 #include "webrtc/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 virtual float EncodeABlock(int16_t* in_data, uint8_t* bit_stream,
27 size_t max_bytes, size_t* encoded_bytes);
28 virtual float DecodeABlock(const uint8_t* bit_stream, size_t encoded_bytes,
29 int16_t* out_data);
30 WebRtcOpusEncInst* opus_encoder_;
31 WebRtcOpusDecInst* opus_decoder_;
32 };
33
OpusSpeedTest()34 OpusSpeedTest::OpusSpeedTest()
35 : AudioCodecSpeedTest(kOpusBlockDurationMs,
36 kOpusSamplingKhz,
37 kOpusSamplingKhz),
38 opus_encoder_(NULL),
39 opus_decoder_(NULL) {
40 }
41
SetUp()42 void OpusSpeedTest::SetUp() {
43 AudioCodecSpeedTest::SetUp();
44 // If channels_ == 1, use Opus VOIP mode, otherwise, audio mode.
45 int app = channels_ == 1 ? 0 : 1;
46 /* Create encoder memory. */
47 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, app));
48 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_));
49 /* Set bitrate. */
50 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, bit_rate_));
51 }
52
TearDown()53 void OpusSpeedTest::TearDown() {
54 AudioCodecSpeedTest::TearDown();
55 /* Free memory. */
56 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
57 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
58 }
59
EncodeABlock(int16_t * in_data,uint8_t * bit_stream,size_t max_bytes,size_t * encoded_bytes)60 float OpusSpeedTest::EncodeABlock(int16_t* in_data, uint8_t* bit_stream,
61 size_t max_bytes, size_t* encoded_bytes) {
62 clock_t clocks = clock();
63 int value = WebRtcOpus_Encode(opus_encoder_, in_data,
64 input_length_sample_, max_bytes,
65 bit_stream);
66 clocks = clock() - clocks;
67 EXPECT_GT(value, 0);
68 *encoded_bytes = static_cast<size_t>(value);
69 return 1000.0 * clocks / CLOCKS_PER_SEC;
70 }
71
DecodeABlock(const uint8_t * bit_stream,size_t encoded_bytes,int16_t * out_data)72 float OpusSpeedTest::DecodeABlock(const uint8_t* bit_stream,
73 size_t encoded_bytes, int16_t* out_data) {
74 int value;
75 int16_t audio_type;
76 clock_t clocks = clock();
77 value = WebRtcOpus_Decode(opus_decoder_, bit_stream, encoded_bytes, out_data,
78 &audio_type);
79 clocks = clock() - clocks;
80 EXPECT_EQ(output_length_sample_, static_cast<size_t>(value));
81 return 1000.0 * clocks / CLOCKS_PER_SEC;
82 }
83
84 #define ADD_TEST(complexity) \
85 TEST_P(OpusSpeedTest, OpusSetComplexityTest##complexity) { \
86 /* Test audio length in second. */ \
87 size_t kDurationSec = 400; \
88 /* Set complexity. */ \
89 printf("Setting complexity to %d ...\n", complexity); \
90 EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, complexity)); \
91 EncodeDecode(kDurationSec); \
92 }
93
94 ADD_TEST(10);
95 ADD_TEST(9);
96 ADD_TEST(8);
97 ADD_TEST(7);
98 ADD_TEST(6);
99 ADD_TEST(5);
100 ADD_TEST(4);
101 ADD_TEST(3);
102 ADD_TEST(2);
103 ADD_TEST(1);
104 ADD_TEST(0);
105
106 // List all test cases: (channel, bit rat, filename, extension).
107 const coding_param param_set[] =
108 {::std::tr1::make_tuple(1, 64000,
109 string("audio_coding/speech_mono_32_48kHz"),
110 string("pcm"), true),
111 ::std::tr1::make_tuple(1, 32000,
112 string("audio_coding/speech_mono_32_48kHz"),
113 string("pcm"), true),
114 ::std::tr1::make_tuple(2, 64000,
115 string("audio_coding/music_stereo_48kHz"),
116 string("pcm"), true)};
117
118 INSTANTIATE_TEST_CASE_P(AllTest, OpusSpeedTest,
119 ::testing::ValuesIn(param_set));
120
121 } // namespace webrtc
122