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/neteq/tools/encode_neteq_input.h"
12
13 #include <utility>
14
15 #include "rtc_base/checks.h"
16 #include "rtc_base/numerics/safe_conversions.h"
17
18 namespace webrtc {
19 namespace test {
20
EncodeNetEqInput(std::unique_ptr<Generator> generator,std::unique_ptr<AudioEncoder> encoder,int64_t input_duration_ms)21 EncodeNetEqInput::EncodeNetEqInput(std::unique_ptr<Generator> generator,
22 std::unique_ptr<AudioEncoder> encoder,
23 int64_t input_duration_ms)
24 : generator_(std::move(generator)),
25 encoder_(std::move(encoder)),
26 input_duration_ms_(input_duration_ms) {
27 CreatePacket();
28 }
29
30 EncodeNetEqInput::~EncodeNetEqInput() = default;
31
NextPacketTime() const32 absl::optional<int64_t> EncodeNetEqInput::NextPacketTime() const {
33 RTC_DCHECK(packet_data_);
34 return static_cast<int64_t>(packet_data_->time_ms);
35 }
36
NextOutputEventTime() const37 absl::optional<int64_t> EncodeNetEqInput::NextOutputEventTime() const {
38 return next_output_event_ms_;
39 }
40
PopPacket()41 std::unique_ptr<NetEqInput::PacketData> EncodeNetEqInput::PopPacket() {
42 RTC_DCHECK(packet_data_);
43 // Grab the packet to return...
44 std::unique_ptr<PacketData> packet_to_return = std::move(packet_data_);
45 // ... and line up the next packet for future use.
46 CreatePacket();
47
48 return packet_to_return;
49 }
50
AdvanceOutputEvent()51 void EncodeNetEqInput::AdvanceOutputEvent() {
52 next_output_event_ms_ += kOutputPeriodMs;
53 }
54
ended() const55 bool EncodeNetEqInput::ended() const {
56 return next_output_event_ms_ > input_duration_ms_;
57 }
58
NextHeader() const59 absl::optional<RTPHeader> EncodeNetEqInput::NextHeader() const {
60 RTC_DCHECK(packet_data_);
61 return packet_data_->header;
62 }
63
CreatePacket()64 void EncodeNetEqInput::CreatePacket() {
65 // Create a new PacketData object.
66 RTC_DCHECK(!packet_data_);
67 packet_data_.reset(new NetEqInput::PacketData);
68 RTC_DCHECK_EQ(packet_data_->payload.size(), 0);
69
70 // Loop until we get a packet.
71 AudioEncoder::EncodedInfo info;
72 RTC_DCHECK(!info.send_even_if_empty);
73 int num_blocks = 0;
74 while (packet_data_->payload.size() == 0 && !info.send_even_if_empty) {
75 const size_t num_samples = rtc::CheckedDivExact(
76 static_cast<int>(encoder_->SampleRateHz() * kOutputPeriodMs), 1000);
77
78 info = encoder_->Encode(rtp_timestamp_, generator_->Generate(num_samples),
79 &packet_data_->payload);
80
81 rtp_timestamp_ += rtc::dchecked_cast<uint32_t>(
82 num_samples * encoder_->RtpTimestampRateHz() /
83 encoder_->SampleRateHz());
84 ++num_blocks;
85 }
86 packet_data_->header.timestamp = info.encoded_timestamp;
87 packet_data_->header.payloadType = info.payload_type;
88 packet_data_->header.sequenceNumber = sequence_number_++;
89 packet_data_->time_ms = next_packet_time_ms_;
90 next_packet_time_ms_ += num_blocks * kOutputPeriodMs;
91 }
92
93 } // namespace test
94 } // namespace webrtc
95