• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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