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 "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
12
13 #include <limits>
14
15 #include "webrtc/base/checks.h"
16 #include "webrtc/common_types.h"
17 #include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h"
18
19 namespace webrtc {
20
21 namespace {
22
23 template <typename T>
CreateConfig(const CodecInst & codec_inst)24 typename T::Config CreateConfig(const CodecInst& codec_inst) {
25 typename T::Config config;
26 config.frame_size_ms = codec_inst.pacsize / 8;
27 config.num_channels = codec_inst.channels;
28 config.payload_type = codec_inst.pltype;
29 return config;
30 }
31
32 } // namespace
33
IsOk() const34 bool AudioEncoderPcm::Config::IsOk() const {
35 return (frame_size_ms % 10 == 0) && (num_channels >= 1);
36 }
37
AudioEncoderPcm(const Config & config,int sample_rate_hz)38 AudioEncoderPcm::AudioEncoderPcm(const Config& config, int sample_rate_hz)
39 : sample_rate_hz_(sample_rate_hz),
40 num_channels_(config.num_channels),
41 payload_type_(config.payload_type),
42 num_10ms_frames_per_packet_(
43 static_cast<size_t>(config.frame_size_ms / 10)),
44 full_frame_samples_(
45 config.num_channels * config.frame_size_ms * sample_rate_hz / 1000),
46 first_timestamp_in_buffer_(0) {
47 RTC_CHECK_GT(sample_rate_hz, 0) << "Sample rate must be larger than 0 Hz";
48 RTC_CHECK_EQ(config.frame_size_ms % 10, 0)
49 << "Frame size must be an integer multiple of 10 ms.";
50 speech_buffer_.reserve(full_frame_samples_);
51 }
52
53 AudioEncoderPcm::~AudioEncoderPcm() = default;
54
MaxEncodedBytes() const55 size_t AudioEncoderPcm::MaxEncodedBytes() const {
56 return full_frame_samples_ * BytesPerSample();
57 }
58
SampleRateHz() const59 int AudioEncoderPcm::SampleRateHz() const {
60 return sample_rate_hz_;
61 }
62
NumChannels() const63 size_t AudioEncoderPcm::NumChannels() const {
64 return num_channels_;
65 }
66
Num10MsFramesInNextPacket() const67 size_t AudioEncoderPcm::Num10MsFramesInNextPacket() const {
68 return num_10ms_frames_per_packet_;
69 }
70
Max10MsFramesInAPacket() const71 size_t AudioEncoderPcm::Max10MsFramesInAPacket() const {
72 return num_10ms_frames_per_packet_;
73 }
74
GetTargetBitrate() const75 int AudioEncoderPcm::GetTargetBitrate() const {
76 return static_cast<int>(
77 8 * BytesPerSample() * SampleRateHz() * NumChannels());
78 }
79
EncodeInternal(uint32_t rtp_timestamp,rtc::ArrayView<const int16_t> audio,size_t max_encoded_bytes,uint8_t * encoded)80 AudioEncoder::EncodedInfo AudioEncoderPcm::EncodeInternal(
81 uint32_t rtp_timestamp,
82 rtc::ArrayView<const int16_t> audio,
83 size_t max_encoded_bytes,
84 uint8_t* encoded) {
85 if (speech_buffer_.empty()) {
86 first_timestamp_in_buffer_ = rtp_timestamp;
87 }
88 speech_buffer_.insert(speech_buffer_.end(), audio.begin(), audio.end());
89 if (speech_buffer_.size() < full_frame_samples_) {
90 return EncodedInfo();
91 }
92 RTC_CHECK_EQ(speech_buffer_.size(), full_frame_samples_);
93 RTC_CHECK_GE(max_encoded_bytes, full_frame_samples_);
94 EncodedInfo info;
95 info.encoded_timestamp = first_timestamp_in_buffer_;
96 info.payload_type = payload_type_;
97 info.encoded_bytes =
98 EncodeCall(&speech_buffer_[0], full_frame_samples_, encoded);
99 speech_buffer_.clear();
100 return info;
101 }
102
Reset()103 void AudioEncoderPcm::Reset() {
104 speech_buffer_.clear();
105 }
106
AudioEncoderPcmA(const CodecInst & codec_inst)107 AudioEncoderPcmA::AudioEncoderPcmA(const CodecInst& codec_inst)
108 : AudioEncoderPcmA(CreateConfig<AudioEncoderPcmA>(codec_inst)) {}
109
EncodeCall(const int16_t * audio,size_t input_len,uint8_t * encoded)110 size_t AudioEncoderPcmA::EncodeCall(const int16_t* audio,
111 size_t input_len,
112 uint8_t* encoded) {
113 return WebRtcG711_EncodeA(audio, input_len, encoded);
114 }
115
BytesPerSample() const116 size_t AudioEncoderPcmA::BytesPerSample() const {
117 return 1;
118 }
119
AudioEncoderPcmU(const CodecInst & codec_inst)120 AudioEncoderPcmU::AudioEncoderPcmU(const CodecInst& codec_inst)
121 : AudioEncoderPcmU(CreateConfig<AudioEncoderPcmU>(codec_inst)) {}
122
EncodeCall(const int16_t * audio,size_t input_len,uint8_t * encoded)123 size_t AudioEncoderPcmU::EncodeCall(const int16_t* audio,
124 size_t input_len,
125 uint8_t* encoded) {
126 return WebRtcG711_EncodeU(audio, input_len, encoded);
127 }
128
BytesPerSample() const129 size_t AudioEncoderPcmU::BytesPerSample() const {
130 return 1;
131 }
132
133 } // namespace webrtc
134