* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_coding/codecs/legacy_encoded_audio_frame.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"
namespace webrtc {
enum class NetEqDecoder {
kDecoderPCMu,
kDecoderPCMa,
kDecoderPCMu_2ch,
kDecoderPCMa_2ch,
kDecoderPCM16B,
kDecoderPCM16Bwb,
kDecoderPCM16Bswb32kHz,
kDecoderPCM16Bswb48kHz,
kDecoderPCM16B_2ch,
kDecoderPCM16Bwb_2ch,
kDecoderPCM16Bswb32kHz_2ch,
kDecoderPCM16Bswb48kHz_2ch,
kDecoderPCM16B_5ch,
kDecoderG722,
};
class SplitBySamplesTest : public ::testing::TestWithParam<NetEqDecoder> {
protected:
virtual void SetUp() {
decoder_type_ = GetParam();
switch (decoder_type_) {
case NetEqDecoder::kDecoderPCMu:
case NetEqDecoder::kDecoderPCMa:
bytes_per_ms_ = 8;
samples_per_ms_ = 8;
break;
case NetEqDecoder::kDecoderPCMu_2ch:
case NetEqDecoder::kDecoderPCMa_2ch:
bytes_per_ms_ = 2 * 8;
samples_per_ms_ = 8;
break;
case NetEqDecoder::kDecoderG722:
bytes_per_ms_ = 8;
samples_per_ms_ = 16;
break;
case NetEqDecoder::kDecoderPCM16B:
bytes_per_ms_ = 16;
samples_per_ms_ = 8;
break;
case NetEqDecoder::kDecoderPCM16Bwb:
bytes_per_ms_ = 32;
samples_per_ms_ = 16;
break;
case NetEqDecoder::kDecoderPCM16Bswb32kHz:
bytes_per_ms_ = 64;
samples_per_ms_ = 32;
break;
case NetEqDecoder::kDecoderPCM16Bswb48kHz:
bytes_per_ms_ = 96;
samples_per_ms_ = 48;
break;
case NetEqDecoder::kDecoderPCM16B_2ch:
bytes_per_ms_ = 2 * 16;
samples_per_ms_ = 8;
break;
case NetEqDecoder::kDecoderPCM16Bwb_2ch:
bytes_per_ms_ = 2 * 32;
samples_per_ms_ = 16;
break;
case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch:
bytes_per_ms_ = 2 * 64;
samples_per_ms_ = 32;
break;
case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch:
bytes_per_ms_ = 2 * 96;
samples_per_ms_ = 48;
break;
case NetEqDecoder::kDecoderPCM16B_5ch:
bytes_per_ms_ = 5 * 16;
samples_per_ms_ = 8;
break;
default:
RTC_DCHECK_NOTREACHED();
break;
}
}
size_t bytes_per_ms_;
int samples_per_ms_;
NetEqDecoder decoder_type_;
};
TEST_P(SplitBySamplesTest, PayloadSizes) {
constexpr uint32_t kBaseTimestamp = 0x12345678;
struct ExpectedSplit {
size_t payload_size_ms;
size_t num_frames;
size_t frame_sizes[2];
};
ExpectedSplit expected_splits[] = {{10, 1, {10}}, {20, 1, {20}},
{30, 1, {30}}, {40, 2, {20, 20}},
{50, 2, {25, 25}}, {60, 2, {30, 30}}};
for (const auto& expected_split : expected_splits) {
const auto generate_payload = [](size_t num_bytes) {
rtc::Buffer payload(num_bytes);
uint8_t value = 0;
for (size_t i = 0; i != payload.size(); ++i, ++value) {
payload[i] = value;
}
return payload;
};
const auto results = LegacyEncodedAudioFrame::SplitBySamples(
nullptr,
generate_payload(expected_split.payload_size_ms * bytes_per_ms_),
kBaseTimestamp, bytes_per_ms_, samples_per_ms_);
EXPECT_EQ(expected_split.num_frames, results.size());
uint32_t expected_timestamp = kBaseTimestamp;
uint8_t value = 0;
for (size_t i = 0; i != expected_split.num_frames; ++i) {
const auto& result = results[i];
const LegacyEncodedAudioFrame* frame =
static_cast<const LegacyEncodedAudioFrame*>(result.frame.get());
const size_t length_bytes = expected_split.frame_sizes[i] * bytes_per_ms_;
EXPECT_EQ(length_bytes, frame->payload().size());
EXPECT_EQ(expected_timestamp, result.timestamp);
const rtc::Buffer& payload = frame->payload();
for (size_t i = 0; i != payload.size(); ++i, ++value) {
ASSERT_EQ(value, payload[i]);
}
expected_timestamp += rtc::checked_cast<uint32_t>(
expected_split.frame_sizes[i] * samples_per_ms_);
}
}
}
INSTANTIATE_TEST_SUITE_P(
LegacyEncodedAudioFrame,
SplitBySamplesTest,
::testing::Values(NetEqDecoder::kDecoderPCMu,
NetEqDecoder::kDecoderPCMa,
NetEqDecoder::kDecoderPCMu_2ch,
NetEqDecoder::kDecoderPCMa_2ch,
NetEqDecoder::kDecoderG722,
NetEqDecoder::kDecoderPCM16B,
NetEqDecoder::kDecoderPCM16Bwb,
NetEqDecoder::kDecoderPCM16Bswb32kHz,
NetEqDecoder::kDecoderPCM16Bswb48kHz,
NetEqDecoder::kDecoderPCM16B_2ch,
NetEqDecoder::kDecoderPCM16Bwb_2ch,
NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch,
NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch,
NetEqDecoder::kDecoderPCM16B_5ch));
}