1 /*
2 * Copyright (c) 2016 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/legacy_encoded_audio_frame.h"
12
13 #include "rtc_base/numerics/safe_conversions.h"
14 #include "test/gtest.h"
15
16 namespace webrtc {
17
18 enum class NetEqDecoder {
19 kDecoderPCMu,
20 kDecoderPCMa,
21 kDecoderPCMu_2ch,
22 kDecoderPCMa_2ch,
23 kDecoderPCM16B,
24 kDecoderPCM16Bwb,
25 kDecoderPCM16Bswb32kHz,
26 kDecoderPCM16Bswb48kHz,
27 kDecoderPCM16B_2ch,
28 kDecoderPCM16Bwb_2ch,
29 kDecoderPCM16Bswb32kHz_2ch,
30 kDecoderPCM16Bswb48kHz_2ch,
31 kDecoderPCM16B_5ch,
32 kDecoderG722,
33 };
34
35 class SplitBySamplesTest : public ::testing::TestWithParam<NetEqDecoder> {
36 protected:
SetUp()37 virtual void SetUp() {
38 decoder_type_ = GetParam();
39 switch (decoder_type_) {
40 case NetEqDecoder::kDecoderPCMu:
41 case NetEqDecoder::kDecoderPCMa:
42 bytes_per_ms_ = 8;
43 samples_per_ms_ = 8;
44 break;
45 case NetEqDecoder::kDecoderPCMu_2ch:
46 case NetEqDecoder::kDecoderPCMa_2ch:
47 bytes_per_ms_ = 2 * 8;
48 samples_per_ms_ = 8;
49 break;
50 case NetEqDecoder::kDecoderG722:
51 bytes_per_ms_ = 8;
52 samples_per_ms_ = 16;
53 break;
54 case NetEqDecoder::kDecoderPCM16B:
55 bytes_per_ms_ = 16;
56 samples_per_ms_ = 8;
57 break;
58 case NetEqDecoder::kDecoderPCM16Bwb:
59 bytes_per_ms_ = 32;
60 samples_per_ms_ = 16;
61 break;
62 case NetEqDecoder::kDecoderPCM16Bswb32kHz:
63 bytes_per_ms_ = 64;
64 samples_per_ms_ = 32;
65 break;
66 case NetEqDecoder::kDecoderPCM16Bswb48kHz:
67 bytes_per_ms_ = 96;
68 samples_per_ms_ = 48;
69 break;
70 case NetEqDecoder::kDecoderPCM16B_2ch:
71 bytes_per_ms_ = 2 * 16;
72 samples_per_ms_ = 8;
73 break;
74 case NetEqDecoder::kDecoderPCM16Bwb_2ch:
75 bytes_per_ms_ = 2 * 32;
76 samples_per_ms_ = 16;
77 break;
78 case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch:
79 bytes_per_ms_ = 2 * 64;
80 samples_per_ms_ = 32;
81 break;
82 case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch:
83 bytes_per_ms_ = 2 * 96;
84 samples_per_ms_ = 48;
85 break;
86 case NetEqDecoder::kDecoderPCM16B_5ch:
87 bytes_per_ms_ = 5 * 16;
88 samples_per_ms_ = 8;
89 break;
90 default:
91 assert(false);
92 break;
93 }
94 }
95 size_t bytes_per_ms_;
96 int samples_per_ms_;
97 NetEqDecoder decoder_type_;
98 };
99
100 // Test splitting sample-based payloads.
TEST_P(SplitBySamplesTest,PayloadSizes)101 TEST_P(SplitBySamplesTest, PayloadSizes) {
102 constexpr uint32_t kBaseTimestamp = 0x12345678;
103 struct ExpectedSplit {
104 size_t payload_size_ms;
105 size_t num_frames;
106 // For simplicity. We only expect up to two packets per split.
107 size_t frame_sizes[2];
108 };
109 // The payloads are expected to be split as follows:
110 // 10 ms -> 10 ms
111 // 20 ms -> 20 ms
112 // 30 ms -> 30 ms
113 // 40 ms -> 20 + 20 ms
114 // 50 ms -> 25 + 25 ms
115 // 60 ms -> 30 + 30 ms
116 ExpectedSplit expected_splits[] = {{10, 1, {10}}, {20, 1, {20}},
117 {30, 1, {30}}, {40, 2, {20, 20}},
118 {50, 2, {25, 25}}, {60, 2, {30, 30}}};
119
120 for (const auto& expected_split : expected_splits) {
121 // The payload values are set to steadily increase (modulo 256), so that the
122 // resulting frames can be checked and we can be reasonably certain no
123 // sample was missed or repeated.
124 const auto generate_payload = [](size_t num_bytes) {
125 rtc::Buffer payload(num_bytes);
126 uint8_t value = 0;
127 // Allow wrap-around of value in counter below.
128 for (size_t i = 0; i != payload.size(); ++i, ++value) {
129 payload[i] = value;
130 }
131 return payload;
132 };
133
134 const auto results = LegacyEncodedAudioFrame::SplitBySamples(
135 nullptr,
136 generate_payload(expected_split.payload_size_ms * bytes_per_ms_),
137 kBaseTimestamp, bytes_per_ms_, samples_per_ms_);
138
139 EXPECT_EQ(expected_split.num_frames, results.size());
140 uint32_t expected_timestamp = kBaseTimestamp;
141 uint32_t expected_byte_offset = 0;
142 uint8_t value = 0;
143 for (size_t i = 0; i != expected_split.num_frames; ++i) {
144 const auto& result = results[i];
145 const LegacyEncodedAudioFrame* frame =
146 static_cast<const LegacyEncodedAudioFrame*>(result.frame.get());
147 const size_t length_bytes = expected_split.frame_sizes[i] * bytes_per_ms_;
148 EXPECT_EQ(length_bytes, frame->payload().size());
149 EXPECT_EQ(expected_timestamp, result.timestamp);
150 const rtc::Buffer& payload = frame->payload();
151 // Allow wrap-around of value in counter below.
152 for (size_t i = 0; i != payload.size(); ++i, ++value) {
153 ASSERT_EQ(value, payload[i]);
154 }
155
156 expected_timestamp += rtc::checked_cast<uint32_t>(
157 expected_split.frame_sizes[i] * samples_per_ms_);
158 expected_byte_offset += rtc::checked_cast<uint32_t>(length_bytes);
159 }
160 }
161 }
162
163 INSTANTIATE_TEST_SUITE_P(
164 LegacyEncodedAudioFrame,
165 SplitBySamplesTest,
166 ::testing::Values(NetEqDecoder::kDecoderPCMu,
167 NetEqDecoder::kDecoderPCMa,
168 NetEqDecoder::kDecoderPCMu_2ch,
169 NetEqDecoder::kDecoderPCMa_2ch,
170 NetEqDecoder::kDecoderG722,
171 NetEqDecoder::kDecoderPCM16B,
172 NetEqDecoder::kDecoderPCM16Bwb,
173 NetEqDecoder::kDecoderPCM16Bswb32kHz,
174 NetEqDecoder::kDecoderPCM16Bswb48kHz,
175 NetEqDecoder::kDecoderPCM16B_2ch,
176 NetEqDecoder::kDecoderPCM16Bwb_2ch,
177 NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch,
178 NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch,
179 NetEqDecoder::kDecoderPCM16B_5ch));
180
181 } // namespace webrtc
182