1 /*
2 * Copyright (c) 2014 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/g711/audio_encoder_pcm.h"
12
13 #include <cstdint>
14
15 #include "modules/audio_coding/codecs/g711/g711_interface.h"
16 #include "rtc_base/checks.h"
17
18 namespace webrtc {
19
IsOk() const20 bool AudioEncoderPcm::Config::IsOk() const {
21 return (frame_size_ms % 10 == 0) && (num_channels >= 1);
22 }
23
AudioEncoderPcm(const Config & config,int sample_rate_hz)24 AudioEncoderPcm::AudioEncoderPcm(const Config& config, int sample_rate_hz)
25 : sample_rate_hz_(sample_rate_hz),
26 num_channels_(config.num_channels),
27 payload_type_(config.payload_type),
28 num_10ms_frames_per_packet_(
29 static_cast<size_t>(config.frame_size_ms / 10)),
30 full_frame_samples_(config.num_channels * config.frame_size_ms *
31 sample_rate_hz / 1000),
32 first_timestamp_in_buffer_(0) {
33 RTC_CHECK_GT(sample_rate_hz, 0) << "Sample rate must be larger than 0 Hz";
34 RTC_CHECK_EQ(config.frame_size_ms % 10, 0)
35 << "Frame size must be an integer multiple of 10 ms.";
36 speech_buffer_.reserve(full_frame_samples_);
37 }
38
39 AudioEncoderPcm::~AudioEncoderPcm() = default;
40
SampleRateHz() const41 int AudioEncoderPcm::SampleRateHz() const {
42 return sample_rate_hz_;
43 }
44
NumChannels() const45 size_t AudioEncoderPcm::NumChannels() const {
46 return num_channels_;
47 }
48
Num10MsFramesInNextPacket() const49 size_t AudioEncoderPcm::Num10MsFramesInNextPacket() const {
50 return num_10ms_frames_per_packet_;
51 }
52
Max10MsFramesInAPacket() const53 size_t AudioEncoderPcm::Max10MsFramesInAPacket() const {
54 return num_10ms_frames_per_packet_;
55 }
56
GetTargetBitrate() const57 int AudioEncoderPcm::GetTargetBitrate() const {
58 return static_cast<int>(8 * BytesPerSample() * SampleRateHz() *
59 NumChannels());
60 }
61
EncodeImpl(uint32_t rtp_timestamp,rtc::ArrayView<const int16_t> audio,rtc::Buffer * encoded)62 AudioEncoder::EncodedInfo AudioEncoderPcm::EncodeImpl(
63 uint32_t rtp_timestamp,
64 rtc::ArrayView<const int16_t> audio,
65 rtc::Buffer* encoded) {
66 if (speech_buffer_.empty()) {
67 first_timestamp_in_buffer_ = rtp_timestamp;
68 }
69 speech_buffer_.insert(speech_buffer_.end(), audio.begin(), audio.end());
70 if (speech_buffer_.size() < full_frame_samples_) {
71 return EncodedInfo();
72 }
73 RTC_CHECK_EQ(speech_buffer_.size(), full_frame_samples_);
74 EncodedInfo info;
75 info.encoded_timestamp = first_timestamp_in_buffer_;
76 info.payload_type = payload_type_;
77 info.encoded_bytes = encoded->AppendData(
78 full_frame_samples_ * BytesPerSample(),
79 [&](rtc::ArrayView<uint8_t> encoded) {
80 return EncodeCall(&speech_buffer_[0], full_frame_samples_,
81 encoded.data());
82 });
83 speech_buffer_.clear();
84 info.encoder_type = GetCodecType();
85 return info;
86 }
87
Reset()88 void AudioEncoderPcm::Reset() {
89 speech_buffer_.clear();
90 }
91
92 absl::optional<std::pair<TimeDelta, TimeDelta>>
GetFrameLengthRange() const93 AudioEncoderPcm::GetFrameLengthRange() const {
94 return {{TimeDelta::Millis(num_10ms_frames_per_packet_ * 10),
95 TimeDelta::Millis(num_10ms_frames_per_packet_ * 10)}};
96 }
97
EncodeCall(const int16_t * audio,size_t input_len,uint8_t * encoded)98 size_t AudioEncoderPcmA::EncodeCall(const int16_t* audio,
99 size_t input_len,
100 uint8_t* encoded) {
101 return WebRtcG711_EncodeA(audio, input_len, encoded);
102 }
103
BytesPerSample() const104 size_t AudioEncoderPcmA::BytesPerSample() const {
105 return 1;
106 }
107
GetCodecType() const108 AudioEncoder::CodecType AudioEncoderPcmA::GetCodecType() const {
109 return AudioEncoder::CodecType::kPcmA;
110 }
111
EncodeCall(const int16_t * audio,size_t input_len,uint8_t * encoded)112 size_t AudioEncoderPcmU::EncodeCall(const int16_t* audio,
113 size_t input_len,
114 uint8_t* encoded) {
115 return WebRtcG711_EncodeU(audio, input_len, encoded);
116 }
117
BytesPerSample() const118 size_t AudioEncoderPcmU::BytesPerSample() const {
119 return 1;
120 }
121
GetCodecType() const122 AudioEncoder::CodecType AudioEncoderPcmU::GetCodecType() const {
123 return AudioEncoder::CodecType::kPcmU;
124 }
125
126 } // namespace webrtc
127