blob: bd653b7979b1bb4a65296cc4ae3214e6f0f90568 [file] [log] [blame]
solenbergdb3c9b02017-06-28 02:05:04 -07001/*
2 * Copyright (c) 2017 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h"
solenbergdb3c9b02017-06-28 02:05:04 -070012
13#include <memory>
14#include <vector>
15
Niels Möller2edab4c2018-10-22 09:48:08 +020016#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010018#include "rtc_base/numerics/safe_conversions.h"
19#include "rtc_base/numerics/safe_minmax.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/string_to_number.h"
solenbergdb3c9b02017-06-28 02:05:04 -070021
22namespace webrtc {
23namespace {
24int GetIlbcBitrate(int ptime) {
25 switch (ptime) {
26 case 20:
27 case 40:
28 // 38 bytes per frame of 20 ms => 15200 bits/s.
29 return 15200;
30 case 30:
31 case 60:
32 // 50 bytes per frame of 30 ms => (approx) 13333 bits/s.
33 return 13333;
34 default:
35 FATAL();
36 }
37}
38} // namespace
39
Danil Chapovalov0bc58cf2018-06-21 13:32:56 +020040absl::optional<AudioEncoderIlbcConfig> AudioEncoderIlbc::SdpToConfig(
solenbergdb3c9b02017-06-28 02:05:04 -070041 const SdpAudioFormat& format) {
Niels Möller2edab4c2018-10-22 09:48:08 +020042 if (!absl::EqualsIgnoreCase(format.name.c_str(), "ILBC") ||
kwibergd1d79f62017-08-25 22:22:42 -070043 format.clockrate_hz != 8000 || format.num_channels != 1) {
Danil Chapovalov0bc58cf2018-06-21 13:32:56 +020044 return absl::nullopt;
kwibergd1d79f62017-08-25 22:22:42 -070045 }
46
47 AudioEncoderIlbcConfig config;
48 auto ptime_iter = format.parameters.find("ptime");
49 if (ptime_iter != format.parameters.end()) {
50 auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
51 if (ptime && *ptime > 0) {
52 const int whole_packets = *ptime / 10;
53 config.frame_size_ms = rtc::SafeClamp<int>(whole_packets * 10, 20, 60);
54 }
55 }
Danil Chapovalov0bc58cf2018-06-21 13:32:56 +020056 return config.IsOk() ? absl::optional<AudioEncoderIlbcConfig>(config)
57 : absl::nullopt;
solenbergdb3c9b02017-06-28 02:05:04 -070058}
59
60void AudioEncoderIlbc::AppendSupportedEncoders(
61 std::vector<AudioCodecSpec>* specs) {
62 const SdpAudioFormat fmt = {"ILBC", 8000, 1};
63 const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
64 specs->push_back({fmt, info});
65}
66
67AudioCodecInfo AudioEncoderIlbc::QueryAudioEncoder(
68 const AudioEncoderIlbcConfig& config) {
69 RTC_DCHECK(config.IsOk());
70 return {8000, 1, GetIlbcBitrate(config.frame_size_ms)};
71}
72
73std::unique_ptr<AudioEncoder> AudioEncoderIlbc::MakeAudioEncoder(
74 const AudioEncoderIlbcConfig& config,
Karl Wiberg17668ec2018-03-01 15:13:27 +010075 int payload_type,
Danil Chapovalov0bc58cf2018-06-21 13:32:56 +020076 absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
solenbergdb3c9b02017-06-28 02:05:04 -070077 RTC_DCHECK(config.IsOk());
Mirko Bonadei317a1f02019-09-17 17:06:18 +020078 return std::make_unique<AudioEncoderIlbcImpl>(config, payload_type);
solenbergdb3c9b02017-06-28 02:05:04 -070079}
80
81} // namespace webrtc