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