Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc

Issue 2934833002: G722 implementation of the AudioEncoderFactoryTemplate API (Closed)
Patch Set: rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h" 11 #include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 14
15 #include <limits> 15 #include <limits>
16 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
17 #include "webrtc/base/safe_conversions.h" 17 #include "webrtc/base/safe_conversions.h"
18 #include "webrtc/base/string_to_number.h" 18 #include "webrtc/base/string_to_number.h"
19 #include "webrtc/common_types.h" 19 #include "webrtc/common_types.h"
20 #include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" 20 #include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h"
21 21
22 namespace webrtc { 22 namespace webrtc {
23 23
24 namespace { 24 namespace {
25 25
26 const size_t kSampleRateHz = 16000; 26 const size_t kSampleRateHz = 16000;
27 27
28 AudioEncoderG722::Config CreateConfig(const CodecInst& codec_inst) { 28 AudioEncoderG722Config CreateConfig(const CodecInst& codec_inst) {
29 AudioEncoderG722::Config config; 29 AudioEncoderG722Config config;
30 config.num_channels = codec_inst.channels; 30 config.num_channels = rtc::dchecked_cast<int>(codec_inst.channels);
31 config.frame_size_ms = codec_inst.pacsize / 16; 31 config.frame_size_ms = codec_inst.pacsize / 16;
32 config.payload_type = codec_inst.pltype;
33 return config; 32 return config;
34 } 33 }
35 34
36 AudioEncoderG722::Config CreateConfig(int payload_type, 35 } // namespace
37 const SdpAudioFormat& format) { 36
38 AudioEncoderG722::Config config; 37 rtc::Optional<AudioEncoderG722Config> AudioEncoderG722Impl::SdpToConfig(
39 config.payload_type = payload_type; 38 const SdpAudioFormat& format) {
40 config.num_channels = format.num_channels; 39 if (STR_CASE_CMP(format.name.c_str(), "g722") != 0 ||
40 format.clockrate_hz != 8000) {
41 return rtc::Optional<AudioEncoderG722Config>();
42 }
43
44 AudioEncoderG722Config config;
45 config.num_channels = rtc::dchecked_cast<int>(format.num_channels);
41 auto ptime_iter = format.parameters.find("ptime"); 46 auto ptime_iter = format.parameters.find("ptime");
42 if (ptime_iter != format.parameters.end()) { 47 if (ptime_iter != format.parameters.end()) {
43 auto ptime = rtc::StringToNumber<int>(ptime_iter->second); 48 auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
44 if (ptime && *ptime > 0) { 49 if (ptime && *ptime > 0) {
45 const int whole_packets = *ptime / 10; 50 const int whole_packets = *ptime / 10;
46 config.frame_size_ms = std::max(10, std::min(whole_packets * 10, 60)); 51 config.frame_size_ms = std::max(10, std::min(whole_packets * 10, 60));
47 } 52 }
48 } 53 }
49 return config; 54 return config.IsOk() ? rtc::Optional<AudioEncoderG722Config>(config)
55 : rtc::Optional<AudioEncoderG722Config>();
50 } 56 }
51 57
52 } // namespace 58 AudioEncoderG722Impl::AudioEncoderG722Impl(const AudioEncoderG722Config& config,
53 59 int payload_type)
54 bool AudioEncoderG722::Config::IsOk() const {
55 return (frame_size_ms > 0) && (frame_size_ms % 10 == 0) &&
56 (num_channels >= 1);
57 }
58
59 AudioEncoderG722::AudioEncoderG722(const Config& config)
60 : num_channels_(config.num_channels), 60 : num_channels_(config.num_channels),
61 payload_type_(config.payload_type), 61 payload_type_(payload_type),
62 num_10ms_frames_per_packet_( 62 num_10ms_frames_per_packet_(
63 static_cast<size_t>(config.frame_size_ms / 10)), 63 static_cast<size_t>(config.frame_size_ms / 10)),
64 num_10ms_frames_buffered_(0), 64 num_10ms_frames_buffered_(0),
65 first_timestamp_in_buffer_(0), 65 first_timestamp_in_buffer_(0),
66 encoders_(new EncoderState[num_channels_]), 66 encoders_(new EncoderState[num_channels_]),
67 interleave_buffer_(2 * num_channels_) { 67 interleave_buffer_(2 * num_channels_) {
68 RTC_CHECK(config.IsOk()); 68 RTC_CHECK(config.IsOk());
69 const size_t samples_per_channel = 69 const size_t samples_per_channel =
70 kSampleRateHz / 100 * num_10ms_frames_per_packet_; 70 kSampleRateHz / 100 * num_10ms_frames_per_packet_;
71 for (size_t i = 0; i < num_channels_; ++i) { 71 for (size_t i = 0; i < num_channels_; ++i) {
72 encoders_[i].speech_buffer.reset(new int16_t[samples_per_channel]); 72 encoders_[i].speech_buffer.reset(new int16_t[samples_per_channel]);
73 encoders_[i].encoded_buffer.SetSize(samples_per_channel / 2); 73 encoders_[i].encoded_buffer.SetSize(samples_per_channel / 2);
74 } 74 }
75 Reset(); 75 Reset();
76 } 76 }
77 77
78 AudioEncoderG722::AudioEncoderG722(const CodecInst& codec_inst) 78 AudioEncoderG722Impl::AudioEncoderG722Impl(const CodecInst& codec_inst)
79 : AudioEncoderG722(CreateConfig(codec_inst)) {} 79 : AudioEncoderG722Impl(CreateConfig(codec_inst), codec_inst.pltype) {}
80 80
81 AudioEncoderG722::AudioEncoderG722(int payload_type, 81 AudioEncoderG722Impl::AudioEncoderG722Impl(int payload_type,
82 const SdpAudioFormat& format) 82 const SdpAudioFormat& format)
83 : AudioEncoderG722(CreateConfig(payload_type, format)) {} 83 : AudioEncoderG722Impl(*SdpToConfig(format), payload_type) {}
84 84
85 AudioEncoderG722::~AudioEncoderG722() = default; 85 AudioEncoderG722Impl::~AudioEncoderG722Impl() = default;
86 86
87 rtc::Optional<AudioCodecInfo> AudioEncoderG722::QueryAudioEncoder( 87 rtc::Optional<AudioCodecInfo> AudioEncoderG722Impl::QueryAudioEncoder(
88 const SdpAudioFormat& format) { 88 const SdpAudioFormat& format) {
89 if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0) { 89 if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0) {
90 Config config = CreateConfig(0, format); 90 const auto config_opt = SdpToConfig(format);
91 if (format.clockrate_hz == 8000 && config.IsOk()) { 91 if (format.clockrate_hz == 8000 && config_opt) {
92 RTC_DCHECK(config_opt->IsOk());
92 return rtc::Optional<AudioCodecInfo>( 93 return rtc::Optional<AudioCodecInfo>(
93 {rtc::dchecked_cast<int>(kSampleRateHz), config.num_channels, 64000}); 94 {rtc::dchecked_cast<int>(kSampleRateHz),
95 rtc::dchecked_cast<size_t>(config_opt->num_channels), 64000});
94 } 96 }
95 } 97 }
96 return rtc::Optional<AudioCodecInfo>(); 98 return rtc::Optional<AudioCodecInfo>();
97 } 99 }
98 100
99 int AudioEncoderG722::SampleRateHz() const { 101 int AudioEncoderG722Impl::SampleRateHz() const {
100 return kSampleRateHz; 102 return kSampleRateHz;
101 } 103 }
102 104
103 size_t AudioEncoderG722::NumChannels() const { 105 size_t AudioEncoderG722Impl::NumChannels() const {
104 return num_channels_; 106 return num_channels_;
105 } 107 }
106 108
107 int AudioEncoderG722::RtpTimestampRateHz() const { 109 int AudioEncoderG722Impl::RtpTimestampRateHz() const {
108 // The RTP timestamp rate for G.722 is 8000 Hz, even though it is a 16 kHz 110 // The RTP timestamp rate for G.722 is 8000 Hz, even though it is a 16 kHz
109 // codec. 111 // codec.
110 return kSampleRateHz / 2; 112 return kSampleRateHz / 2;
111 } 113 }
112 114
113 size_t AudioEncoderG722::Num10MsFramesInNextPacket() const { 115 size_t AudioEncoderG722Impl::Num10MsFramesInNextPacket() const {
114 return num_10ms_frames_per_packet_; 116 return num_10ms_frames_per_packet_;
115 } 117 }
116 118
117 size_t AudioEncoderG722::Max10MsFramesInAPacket() const { 119 size_t AudioEncoderG722Impl::Max10MsFramesInAPacket() const {
118 return num_10ms_frames_per_packet_; 120 return num_10ms_frames_per_packet_;
119 } 121 }
120 122
121 int AudioEncoderG722::GetTargetBitrate() const { 123 int AudioEncoderG722Impl::GetTargetBitrate() const {
122 // 4 bits/sample, 16000 samples/s/channel. 124 // 4 bits/sample, 16000 samples/s/channel.
123 return static_cast<int>(64000 * NumChannels()); 125 return static_cast<int>(64000 * NumChannels());
124 } 126 }
125 127
126 void AudioEncoderG722::Reset() { 128 void AudioEncoderG722Impl::Reset() {
127 num_10ms_frames_buffered_ = 0; 129 num_10ms_frames_buffered_ = 0;
128 for (size_t i = 0; i < num_channels_; ++i) 130 for (size_t i = 0; i < num_channels_; ++i)
129 RTC_CHECK_EQ(0, WebRtcG722_EncoderInit(encoders_[i].encoder)); 131 RTC_CHECK_EQ(0, WebRtcG722_EncoderInit(encoders_[i].encoder));
130 } 132 }
131 133
132 AudioEncoder::EncodedInfo AudioEncoderG722::EncodeImpl( 134 AudioEncoder::EncodedInfo AudioEncoderG722Impl::EncodeImpl(
133 uint32_t rtp_timestamp, 135 uint32_t rtp_timestamp,
134 rtc::ArrayView<const int16_t> audio, 136 rtc::ArrayView<const int16_t> audio,
135 rtc::Buffer* encoded) { 137 rtc::Buffer* encoded) {
136 if (num_10ms_frames_buffered_ == 0) 138 if (num_10ms_frames_buffered_ == 0)
137 first_timestamp_in_buffer_ = rtp_timestamp; 139 first_timestamp_in_buffer_ = rtp_timestamp;
138 140
139 // Deinterleave samples and save them in each channel's buffer. 141 // Deinterleave samples and save them in each channel's buffer.
140 const size_t start = kSampleRateHz / 100 * num_10ms_frames_buffered_; 142 const size_t start = kSampleRateHz / 100 * num_10ms_frames_buffered_;
141 for (size_t i = 0; i < kSampleRateHz / 100; ++i) 143 for (size_t i = 0; i < kSampleRateHz / 100; ++i)
142 for (size_t j = 0; j < num_channels_; ++j) 144 for (size_t j = 0; j < num_channels_; ++j)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 180 }
179 181
180 return bytes_to_encode; 182 return bytes_to_encode;
181 }); 183 });
182 info.encoded_timestamp = first_timestamp_in_buffer_; 184 info.encoded_timestamp = first_timestamp_in_buffer_;
183 info.payload_type = payload_type_; 185 info.payload_type = payload_type_;
184 info.encoder_type = CodecType::kG722; 186 info.encoder_type = CodecType::kG722;
185 return info; 187 return info;
186 } 188 }
187 189
188 AudioEncoderG722::EncoderState::EncoderState() { 190 AudioEncoderG722Impl::EncoderState::EncoderState() {
189 RTC_CHECK_EQ(0, WebRtcG722_CreateEncoder(&encoder)); 191 RTC_CHECK_EQ(0, WebRtcG722_CreateEncoder(&encoder));
190 } 192 }
191 193
192 AudioEncoderG722::EncoderState::~EncoderState() { 194 AudioEncoderG722Impl::EncoderState::~EncoderState() {
193 RTC_CHECK_EQ(0, WebRtcG722_FreeEncoder(encoder)); 195 RTC_CHECK_EQ(0, WebRtcG722_FreeEncoder(encoder));
194 } 196 }
195 197
196 size_t AudioEncoderG722::SamplesPerChannel() const { 198 size_t AudioEncoderG722Impl::SamplesPerChannel() const {
197 return kSampleRateHz / 100 * num_10ms_frames_per_packet_; 199 return kSampleRateHz / 100 * num_10ms_frames_per_packet_;
198 } 200 }
199 201
200 } // namespace webrtc 202 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698