audio_encoder_g722.cc (5622B)
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/g722/audio_encoder_g722.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/audio_codecs/g722/audio_encoder_g722_config.h" 21 #include "api/units/time_delta.h" 22 #include "modules/audio_coding/codecs/g722/g722_interface.h" 23 #include "rtc_base/buffer.h" 24 #include "rtc_base/checks.h" 25 26 namespace webrtc { 27 28 namespace { 29 30 const size_t kSampleRateHz = 16000; 31 32 } // namespace 33 34 AudioEncoderG722Impl::AudioEncoderG722Impl(const AudioEncoderG722Config& config, 35 int payload_type) 36 : num_channels_(config.num_channels), 37 payload_type_(payload_type), 38 num_10ms_frames_per_packet_( 39 static_cast<size_t>(config.frame_size_ms / 10)), 40 num_10ms_frames_buffered_(0), 41 first_timestamp_in_buffer_(0), 42 encoders_(new EncoderState[num_channels_]), 43 interleave_buffer_(2 * num_channels_) { 44 RTC_CHECK(config.IsOk()); 45 const size_t samples_per_channel = 46 kSampleRateHz / 100 * num_10ms_frames_per_packet_; 47 for (size_t i = 0; i < num_channels_; ++i) { 48 encoders_[i].speech_buffer.reset(new int16_t[samples_per_channel]); 49 encoders_[i].encoded_buffer.SetSize(samples_per_channel / 2); 50 } 51 Reset(); 52 } 53 54 AudioEncoderG722Impl::~AudioEncoderG722Impl() = default; 55 56 int AudioEncoderG722Impl::SampleRateHz() const { 57 return kSampleRateHz; 58 } 59 60 size_t AudioEncoderG722Impl::NumChannels() const { 61 return num_channels_; 62 } 63 64 int AudioEncoderG722Impl::RtpTimestampRateHz() const { 65 // The RTP timestamp rate for G.722 is 8000 Hz, even though it is a 16 kHz 66 // codec. 67 return kSampleRateHz / 2; 68 } 69 70 size_t AudioEncoderG722Impl::Num10MsFramesInNextPacket() const { 71 return num_10ms_frames_per_packet_; 72 } 73 74 size_t AudioEncoderG722Impl::Max10MsFramesInAPacket() const { 75 return num_10ms_frames_per_packet_; 76 } 77 78 int AudioEncoderG722Impl::GetTargetBitrate() const { 79 // 4 bits/sample, 16000 samples/s/channel. 80 return static_cast<int>(64000 * NumChannels()); 81 } 82 83 void AudioEncoderG722Impl::Reset() { 84 num_10ms_frames_buffered_ = 0; 85 for (size_t i = 0; i < num_channels_; ++i) 86 RTC_CHECK_EQ(0, WebRtcG722_EncoderInit(encoders_[i].encoder)); 87 } 88 89 std::optional<std::pair<TimeDelta, TimeDelta>> 90 AudioEncoderG722Impl::GetFrameLengthRange() const { 91 return {{TimeDelta::Millis(num_10ms_frames_per_packet_ * 10), 92 TimeDelta::Millis(num_10ms_frames_per_packet_ * 10)}}; 93 } 94 95 AudioEncoder::EncodedInfo AudioEncoderG722Impl::EncodeImpl( 96 uint32_t rtp_timestamp, 97 ArrayView<const int16_t> audio, 98 Buffer* encoded) { 99 if (num_10ms_frames_buffered_ == 0) 100 first_timestamp_in_buffer_ = rtp_timestamp; 101 102 // Deinterleave samples and save them in each channel's buffer. 103 const size_t start = kSampleRateHz / 100 * num_10ms_frames_buffered_; 104 for (size_t i = 0; i < kSampleRateHz / 100; ++i) 105 for (size_t j = 0; j < num_channels_; ++j) 106 encoders_[j].speech_buffer[start + i] = audio[i * num_channels_ + j]; 107 108 // If we don't yet have enough samples for a packet, we're done for now. 109 if (++num_10ms_frames_buffered_ < num_10ms_frames_per_packet_) { 110 return EncodedInfo(); 111 } 112 113 // Encode each channel separately. 114 RTC_CHECK_EQ(num_10ms_frames_buffered_, num_10ms_frames_per_packet_); 115 num_10ms_frames_buffered_ = 0; 116 const size_t samples_per_channel = SamplesPerChannel(); 117 for (size_t i = 0; i < num_channels_; ++i) { 118 const size_t bytes_encoded = WebRtcG722_Encode( 119 encoders_[i].encoder, encoders_[i].speech_buffer.get(), 120 samples_per_channel, encoders_[i].encoded_buffer.data()); 121 RTC_CHECK_EQ(bytes_encoded, samples_per_channel / 2); 122 } 123 124 const size_t bytes_to_encode = samples_per_channel / 2 * num_channels_; 125 EncodedInfo info; 126 info.encoded_bytes = 127 encoded->AppendData(bytes_to_encode, [&](ArrayView<uint8_t> encoded) { 128 // Interleave the encoded bytes of the different channels. Each separate 129 // channel and the interleaved stream encodes two samples per byte, most 130 // significant half first. 131 for (size_t i = 0; i < samples_per_channel / 2; ++i) { 132 for (size_t j = 0; j < num_channels_; ++j) { 133 uint8_t two_samples = encoders_[j].encoded_buffer.data()[i]; 134 interleave_buffer_.data()[j] = two_samples >> 4; 135 interleave_buffer_.data()[num_channels_ + j] = two_samples & 0xf; 136 } 137 for (size_t j = 0; j < num_channels_; ++j) 138 encoded[i * num_channels_ + j] = 139 interleave_buffer_.data()[2 * j] << 4 | 140 interleave_buffer_.data()[2 * j + 1]; 141 } 142 143 return bytes_to_encode; 144 }); 145 info.encoded_timestamp = first_timestamp_in_buffer_; 146 info.payload_type = payload_type_; 147 info.encoder_type = CodecType::kG722; 148 return info; 149 } 150 151 AudioEncoderG722Impl::EncoderState::EncoderState() { 152 RTC_CHECK_EQ(0, WebRtcG722_CreateEncoder(&encoder)); 153 } 154 155 AudioEncoderG722Impl::EncoderState::~EncoderState() { 156 RTC_CHECK_EQ(0, WebRtcG722_FreeEncoder(encoder)); 157 } 158 159 size_t AudioEncoderG722Impl::SamplesPerChannel() const { 160 return kSampleRateHz / 100 * num_10ms_frames_per_packet_; 161 } 162 163 } // namespace webrtc