Line data Source code
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>
24 0 : typename T::Config CreateConfig(const CodecInst& codec_inst) {
25 0 : typename T::Config config;
26 0 : config.frame_size_ms = codec_inst.pacsize / 8;
27 0 : config.num_channels = codec_inst.channels;
28 0 : config.payload_type = codec_inst.pltype;
29 0 : return config;
30 : }
31 :
32 : } // namespace
33 :
34 0 : bool AudioEncoderPcm::Config::IsOk() const {
35 0 : return (frame_size_ms % 10 == 0) && (num_channels >= 1);
36 : }
37 :
38 0 : AudioEncoderPcm::AudioEncoderPcm(const Config& config, int sample_rate_hz)
39 : : sample_rate_hz_(sample_rate_hz),
40 0 : num_channels_(config.num_channels),
41 0 : payload_type_(config.payload_type),
42 : num_10ms_frames_per_packet_(
43 0 : static_cast<size_t>(config.frame_size_ms / 10)),
44 : full_frame_samples_(
45 0 : config.num_channels * config.frame_size_ms * sample_rate_hz / 1000),
46 0 : first_timestamp_in_buffer_(0) {
47 0 : RTC_CHECK_GT(sample_rate_hz, 0) << "Sample rate must be larger than 0 Hz";
48 0 : RTC_CHECK_EQ(config.frame_size_ms % 10, 0)
49 0 : << "Frame size must be an integer multiple of 10 ms.";
50 0 : speech_buffer_.reserve(full_frame_samples_);
51 0 : }
52 :
53 : AudioEncoderPcm::~AudioEncoderPcm() = default;
54 :
55 0 : int AudioEncoderPcm::SampleRateHz() const {
56 0 : return sample_rate_hz_;
57 : }
58 :
59 0 : size_t AudioEncoderPcm::NumChannels() const {
60 0 : return num_channels_;
61 : }
62 :
63 0 : size_t AudioEncoderPcm::Num10MsFramesInNextPacket() const {
64 0 : return num_10ms_frames_per_packet_;
65 : }
66 :
67 0 : size_t AudioEncoderPcm::Max10MsFramesInAPacket() const {
68 0 : return num_10ms_frames_per_packet_;
69 : }
70 :
71 0 : int AudioEncoderPcm::GetTargetBitrate() const {
72 : return static_cast<int>(
73 0 : 8 * BytesPerSample() * SampleRateHz() * NumChannels());
74 : }
75 :
76 0 : AudioEncoder::EncodedInfo AudioEncoderPcm::EncodeImpl(
77 : uint32_t rtp_timestamp,
78 : rtc::ArrayView<const int16_t> audio,
79 : rtc::Buffer* encoded) {
80 0 : if (speech_buffer_.empty()) {
81 0 : first_timestamp_in_buffer_ = rtp_timestamp;
82 : }
83 0 : speech_buffer_.insert(speech_buffer_.end(), audio.begin(), audio.end());
84 0 : if (speech_buffer_.size() < full_frame_samples_) {
85 0 : return EncodedInfo();
86 : }
87 0 : RTC_CHECK_EQ(speech_buffer_.size(), full_frame_samples_);
88 0 : EncodedInfo info;
89 0 : info.encoded_timestamp = first_timestamp_in_buffer_;
90 0 : info.payload_type = payload_type_;
91 0 : info.encoded_bytes =
92 0 : encoded->AppendData(full_frame_samples_ * BytesPerSample(),
93 0 : [&] (rtc::ArrayView<uint8_t> encoded) {
94 0 : return EncodeCall(&speech_buffer_[0],
95 0 : full_frame_samples_,
96 0 : encoded.data());
97 0 : });
98 0 : speech_buffer_.clear();
99 0 : info.encoder_type = GetCodecType();
100 0 : return info;
101 : }
102 :
103 0 : void AudioEncoderPcm::Reset() {
104 0 : speech_buffer_.clear();
105 0 : }
106 :
107 0 : AudioEncoderPcmA::AudioEncoderPcmA(const CodecInst& codec_inst)
108 0 : : AudioEncoderPcmA(CreateConfig<AudioEncoderPcmA>(codec_inst)) {}
109 :
110 0 : size_t AudioEncoderPcmA::EncodeCall(const int16_t* audio,
111 : size_t input_len,
112 : uint8_t* encoded) {
113 0 : return WebRtcG711_EncodeA(audio, input_len, encoded);
114 : }
115 :
116 0 : size_t AudioEncoderPcmA::BytesPerSample() const {
117 0 : return 1;
118 : }
119 :
120 0 : AudioEncoder::CodecType AudioEncoderPcmA::GetCodecType() const {
121 0 : return AudioEncoder::CodecType::kPcmA;
122 : }
123 :
124 0 : AudioEncoderPcmU::AudioEncoderPcmU(const CodecInst& codec_inst)
125 0 : : AudioEncoderPcmU(CreateConfig<AudioEncoderPcmU>(codec_inst)) {}
126 :
127 0 : size_t AudioEncoderPcmU::EncodeCall(const int16_t* audio,
128 : size_t input_len,
129 : uint8_t* encoded) {
130 0 : return WebRtcG711_EncodeU(audio, input_len, encoded);
131 : }
132 :
133 0 : size_t AudioEncoderPcmU::BytesPerSample() const {
134 0 : return 1;
135 : }
136 :
137 0 : AudioEncoder::CodecType AudioEncoderPcmU::GetCodecType() const {
138 0 : return AudioEncoder::CodecType::kPcmU;
139 : }
140 :
141 : } // namespace webrtc
|