encode_neteq_input.cc (3295B)
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 <cstddef> 14 #include <cstdint> 15 #include <memory> 16 #include <optional> 17 #include <utility> 18 19 #include "api/audio_codecs/audio_encoder.h" 20 #include "api/units/timestamp.h" 21 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 22 #include "rtc_base/buffer.h" 23 #include "rtc_base/checks.h" 24 #include "rtc_base/numerics/safe_conversions.h" 25 26 namespace webrtc { 27 namespace test { 28 29 EncodeNetEqInput::EncodeNetEqInput(std::unique_ptr<Generator> generator, 30 std::unique_ptr<AudioEncoder> encoder, 31 int64_t input_duration_ms) 32 : generator_(std::move(generator)), 33 encoder_(std::move(encoder)), 34 input_duration_ms_(input_duration_ms) { 35 CreatePacket(); 36 } 37 38 EncodeNetEqInput::~EncodeNetEqInput() = default; 39 40 std::optional<int64_t> EncodeNetEqInput::NextPacketTime() const { 41 RTC_DCHECK(packet_data_); 42 return packet_data_->arrival_time().ms(); 43 } 44 45 std::optional<int64_t> EncodeNetEqInput::NextOutputEventTime() const { 46 return next_output_event_ms_; 47 } 48 49 std::unique_ptr<RtpPacketReceived> EncodeNetEqInput::PopPacket() { 50 RTC_DCHECK(packet_data_); 51 // Grab the packet to return... 52 std::unique_ptr<RtpPacketReceived> packet_to_return = std::move(packet_data_); 53 // ... and line up the next packet for future use. 54 CreatePacket(); 55 56 return packet_to_return; 57 } 58 59 void EncodeNetEqInput::AdvanceOutputEvent() { 60 next_output_event_ms_ += kOutputPeriodMs; 61 } 62 63 bool EncodeNetEqInput::ended() const { 64 return next_output_event_ms_ > input_duration_ms_; 65 } 66 67 const RtpPacketReceived* EncodeNetEqInput::NextPacket() const { 68 RTC_DCHECK(packet_data_); 69 return packet_data_.get(); 70 } 71 72 void EncodeNetEqInput::CreatePacket() { 73 // Create a new PacketData object. 74 RTC_DCHECK(!packet_data_); 75 packet_data_ = std::make_unique<RtpPacketReceived>(); 76 77 // Loop until we get a packet. 78 AudioEncoder::EncodedInfo info; 79 RTC_DCHECK(!info.send_even_if_empty); 80 int num_blocks = 0; 81 Buffer payload; 82 while (payload.empty() && !info.send_even_if_empty) { 83 const size_t num_samples = CheckedDivExact( 84 static_cast<int>(encoder_->SampleRateHz() * kOutputPeriodMs), 1000); 85 86 info = encoder_->Encode(rtp_timestamp_, generator_->Generate(num_samples), 87 &payload); 88 89 rtp_timestamp_ += 90 dchecked_cast<uint32_t>(num_samples * encoder_->RtpTimestampRateHz() / 91 encoder_->SampleRateHz()); 92 ++num_blocks; 93 } 94 packet_data_->SetPayload(payload); 95 packet_data_->SetTimestamp(info.encoded_timestamp); 96 packet_data_->SetPayloadType(info.payload_type); 97 packet_data_->SetSequenceNumber(sequence_number_++); 98 packet_data_->set_arrival_time(Timestamp::Millis(next_packet_time_ms_)); 99 next_packet_time_ms_ += num_blocks * kOutputPeriodMs; 100 } 101 102 } // namespace test 103 } // namespace webrtc