aboutsummaryrefslogtreecommitdiff
path: root/webrtc
diff options
context:
space:
mode:
authorKarl Wiberg <kwiberg@webrtc.org>2015-05-07 12:35:12 +0200
committerKarl Wiberg <kwiberg@webrtc.org>2015-05-07 10:35:18 +0000
commitdcccab3ebb623df74fbb1425da2cb9d9a42439fa (patch)
treeb895b8c79cbd4186fc675e435848a1f7a8c1160d /webrtc
parent81ea54eaac82b36b7208a02fd37a469d7d0bd9d0 (diff)
downloadwebrtc-dcccab3ebb623df74fbb1425da2cb9d9a42439fa.tar.gz
New interface: AudioEncoderMutable
With implementations for all codecs. It has no users yet. This new interface is the same as AudioEncoder (in fact it is a subclass) but it allows changing some parameters after construction. COAUTHOR=henrik.lundin@webrtc.org BUG=4228 R=jmarusic@webrtc.org, minyue@webrtc.org Review URL: https://webrtc-codereview.appspot.com/51679004 Cr-Commit-Position: refs/heads/master@{#9149}
Diffstat (limited to 'webrtc')
-rw-r--r--webrtc/modules/audio_coding/codecs/audio_encoder.h35
-rw-r--r--webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h96
-rw-r--r--webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h2
-rw-r--r--webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc26
-rw-r--r--webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h25
-rw-r--r--webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc22
-rw-r--r--webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h12
-rw-r--r--webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc29
-rw-r--r--webrtc/modules/audio_coding/codecs/ilbc/interface/audio_encoder_ilbc.h12
-rw-r--r--webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h9
-rw-r--r--webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h42
-rw-r--r--webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc110
-rw-r--r--webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h42
-rw-r--r--webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc111
-rw-r--r--webrtc/modules/audio_coding/codecs/opus/audio_encoder_mutable_opus_test.cc114
-rw-r--r--webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc62
-rw-r--r--webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h21
-rw-r--r--webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc27
-rw-r--r--webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h11
-rw-r--r--webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h2
-rw-r--r--webrtc/modules/modules.gyp1
21 files changed, 784 insertions, 27 deletions
diff --git a/webrtc/modules/audio_coding/codecs/audio_encoder.h b/webrtc/modules/audio_coding/codecs/audio_encoder.h
index e8a2c6ea1e..b5cf827306 100644
--- a/webrtc/modules/audio_coding/codecs/audio_encoder.h
+++ b/webrtc/modules/audio_coding/codecs/audio_encoder.h
@@ -105,12 +105,45 @@ class AudioEncoder {
// coding efforts, such as FEC.
virtual void SetProjectedPacketLossRate(double fraction) {}
- protected:
+ // This is the encode function that the inherited classes must implement. It
+ // is called from Encode in the base class.
virtual EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded) = 0;
};
+class AudioEncoderMutable : public AudioEncoder {
+ public:
+ enum Application { kApplicationSpeech, kApplicationAudio };
+
+ // Discards unprocessed audio data.
+ virtual void Reset() = 0;
+
+ // Enables codec-internal FEC, if the implementation supports it.
+ virtual bool SetFec(bool enable) = 0;
+
+ // Enables or disables codec-internal VAD/DTX, if the implementation supports
+ // it. Otherwise, false is returned. If |force| is true, other configurations
+ // may be changed to allow the operation.
+ virtual bool SetDtx(bool enable, bool force) = 0;
+
+ // Sets the application mode. The implementation is free to disregard this
+ // setting. If |force| is true, other configurations may be changed to allow
+ // the operation.
+ virtual bool SetApplication(Application application, bool force) = 0;
+
+ // Sets an upper limit on the payload size produced by the encoder. The
+ // implementation is free to disregard this setting.
+ virtual void SetMaxPayloadSize(int max_payload_size_bytes) = 0;
+
+ // Sets the maximum rate which the codec may not exceed for any packet.
+ virtual void SetMaxRate(int max_rate_bps) = 0;
+
+ // Informs the encoder about the maximum sample rate which the decoder will
+ // use when decoding the bitstream. The implementation is free to disregard
+ // this hint.
+ virtual bool SetMaxPlaybackRate(int frequency_hz) = 0;
+};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_ENCODER_H_
diff --git a/webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h b/webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h
new file mode 100644
index 0000000000..3de4046464
--- /dev/null
+++ b/webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_ENCODER_MUTABLE_IMPL_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_ENCODER_MUTABLE_IMPL_H_
+
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
+
+namespace webrtc {
+
+// This is a convenient base class for implementations of AudioEncoderMutable.
+// T is the type of the encoder state; it has to look like an AudioEncoder
+// subclass whose constructor takes a single T::Config parameter. If P is
+// given, this class will inherit from it instead of directly from
+// AudioEncoderMutable.
+template <typename T, typename P = AudioEncoderMutable>
+class AudioEncoderMutableImpl : public P {
+ public:
+ void Reset() override { Reconstruct(config_); }
+
+ bool SetFec(bool enable) override { return false; }
+
+ bool SetDtx(bool enable, bool force) override { return false; }
+
+ bool SetApplication(AudioEncoderMutable::Application application,
+ bool force) override {
+ return false;
+ }
+
+ void SetMaxPayloadSize(int max_payload_size_bytes) override {}
+
+ void SetMaxRate(int max_rate_bps) override {}
+
+ bool SetMaxPlaybackRate(int frequency_hz) override { return false; }
+
+ AudioEncoderMutable::EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
+ const int16_t* audio,
+ size_t max_encoded_bytes,
+ uint8_t* encoded) override {
+ return encoder_->EncodeInternal(rtp_timestamp, audio, max_encoded_bytes,
+ encoded);
+ }
+ int SampleRateHz() const override { return encoder_->SampleRateHz(); }
+ int NumChannels() const override { return encoder_->NumChannels(); }
+ size_t MaxEncodedBytes() const override {
+ return encoder_->MaxEncodedBytes();
+ }
+ int RtpTimestampRateHz() const override {
+ return encoder_->RtpTimestampRateHz();
+ }
+ int Num10MsFramesInNextPacket() const override {
+ return encoder_->Num10MsFramesInNextPacket();
+ }
+ int Max10MsFramesInAPacket() const override {
+ return encoder_->Max10MsFramesInAPacket();
+ }
+ void SetTargetBitrate(int bits_per_second) override {
+ encoder_->SetTargetBitrate(bits_per_second);
+ }
+ void SetProjectedPacketLossRate(double fraction) override {
+ encoder_->SetProjectedPacketLossRate(fraction);
+ }
+
+ protected:
+ explicit AudioEncoderMutableImpl(const typename T::Config& config) {
+ Reconstruct(config);
+ }
+
+ bool Reconstruct(const typename T::Config& config) {
+ if (!config.IsOk())
+ return false;
+ config_ = config;
+ encoder_.reset(new T(config_));
+ return true;
+ }
+
+ const typename T::Config& config() const { return config_; }
+ T* encoder() { return encoder_.get(); }
+ const T* encoder() const { return encoder_.get(); }
+
+ private:
+ rtc::scoped_ptr<T> encoder_;
+ typename T::Config config_;
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_ENCODER_MUTABLE_IMPL_H_
diff --git a/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h b/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h
index daecd51ff3..831758b8d3 100644
--- a/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h
+++ b/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h
@@ -54,8 +54,6 @@ class AudioEncoderCng final : public AudioEncoder {
int Max10MsFramesInAPacket() const override;
void SetTargetBitrate(int bits_per_second) override;
void SetProjectedPacketLossRate(double fraction) override;
-
- protected:
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
diff --git a/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc b/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
index 5c45fa5178..0a3a6398fc 100644
--- a/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
+++ b/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
@@ -13,6 +13,7 @@
#include <limits>
#include "webrtc/base/checks.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h"
namespace webrtc {
@@ -28,6 +29,10 @@ int16_t NumSamplesPerFrame(int num_channels,
}
} // namespace
+bool AudioEncoderPcm::Config::IsOk() const {
+ return (frame_size_ms % 10 == 0) && (num_channels >= 1);
+}
+
AudioEncoderPcm::AudioEncoderPcm(const Config& config, int sample_rate_hz)
: sample_rate_hz_(sample_rate_hz),
num_channels_(config.num_channels),
@@ -105,4 +110,25 @@ int16_t AudioEncoderPcmU::EncodeCall(const int16_t* audio,
return WebRtcG711_EncodeU(audio, static_cast<int16_t>(input_len), encoded);
}
+namespace {
+template <typename T>
+typename T::Config CreateConfig(const CodecInst& codec_inst) {
+ typename T::Config config;
+ config.frame_size_ms = codec_inst.pacsize / 8;
+ config.num_channels = codec_inst.channels;
+ config.payload_type = codec_inst.pltype;
+ return config;
+}
+} // namespace
+
+AudioEncoderMutablePcmU::AudioEncoderMutablePcmU(const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderPcmU>(
+ CreateConfig<AudioEncoderPcmU>(codec_inst)) {
+}
+
+AudioEncoderMutablePcmA::AudioEncoderMutablePcmA(const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderPcmA>(
+ CreateConfig<AudioEncoderPcmA>(codec_inst)) {
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h b/webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h
index 6e588ecfcd..870b4ddfb6 100644
--- a/webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h
+++ b/webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h
@@ -13,7 +13,9 @@
#include <vector>
+#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h"
namespace webrtc {
@@ -21,6 +23,8 @@ class AudioEncoderPcm : public AudioEncoder {
public:
struct Config {
public:
+ bool IsOk() const;
+
int frame_size_ms;
int num_channels;
int payload_type;
@@ -37,15 +41,14 @@ class AudioEncoderPcm : public AudioEncoder {
size_t MaxEncodedBytes() const override;
int Num10MsFramesInNextPacket() const override;
int Max10MsFramesInAPacket() const override;
-
- protected:
- AudioEncoderPcm(const Config& config, int sample_rate_hz);
-
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded) override;
+ protected:
+ AudioEncoderPcm(const Config& config, int sample_rate_hz);
+
virtual int16_t EncodeCall(const int16_t* audio,
size_t input_len,
uint8_t* encoded) = 0;
@@ -96,5 +99,19 @@ class AudioEncoderPcmU : public AudioEncoderPcm {
static const int kSampleRateHz = 8000;
};
+struct CodecInst;
+
+class AudioEncoderMutablePcmU
+ : public AudioEncoderMutableImpl<AudioEncoderPcmU> {
+ public:
+ explicit AudioEncoderMutablePcmU(const CodecInst& codec_inst);
+};
+
+class AudioEncoderMutablePcmA
+ : public AudioEncoderMutableImpl<AudioEncoderPcmA> {
+ public:
+ explicit AudioEncoderMutablePcmA(const CodecInst& codec_inst);
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_ENCODER_PCM_H_
diff --git a/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc b/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
index a9fa25f0ef..effb4058f4 100644
--- a/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
+++ b/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
@@ -12,6 +12,7 @@
#include <limits>
#include "webrtc/base/checks.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h"
namespace webrtc {
@@ -22,6 +23,10 @@ const int kSampleRateHz = 16000;
} // namespace
+bool AudioEncoderG722::Config::IsOk() const {
+ return (frame_size_ms % 10 == 0) && (num_channels >= 1);
+}
+
AudioEncoderG722::EncoderState::EncoderState() {
CHECK_EQ(0, WebRtcG722_CreateEncoder(&encoder));
CHECK_EQ(0, WebRtcG722_EncoderInit(encoder));
@@ -39,8 +44,7 @@ AudioEncoderG722::AudioEncoderG722(const Config& config)
first_timestamp_in_buffer_(0),
encoders_(new EncoderState[num_channels_]),
interleave_buffer_(2 * num_channels_) {
- CHECK_EQ(config.frame_size_ms % 10, 0)
- << "Frame size must be an integer multiple of 10 ms.";
+ CHECK(config.IsOk());
const int samples_per_channel =
kSampleRateHz / 100 * num_10ms_frames_per_packet_;
for (int i = 0; i < num_channels_; ++i) {
@@ -134,4 +138,18 @@ int AudioEncoderG722::SamplesPerChannel() const {
return kSampleRateHz / 100 * num_10ms_frames_per_packet_;
}
+namespace {
+AudioEncoderG722::Config CreateConfig(const CodecInst& codec_inst) {
+ AudioEncoderG722::Config config;
+ config.num_channels = codec_inst.channels;
+ config.frame_size_ms = codec_inst.pacsize / 16;
+ config.payload_type = codec_inst.pltype;
+ return config;
+}
+} // namespace
+
+AudioEncoderMutableG722::AudioEncoderMutableG722(const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderG722>(CreateConfig(codec_inst)) {
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h b/webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h
index ba6e5dde67..f5e0a9899f 100644
--- a/webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h
+++ b/webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h
@@ -14,6 +14,7 @@
#include "webrtc/base/buffer.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h"
#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h"
namespace webrtc {
@@ -22,6 +23,7 @@ class AudioEncoderG722 : public AudioEncoder {
public:
struct Config {
Config() : payload_type(9), frame_size_ms(20), num_channels(1) {}
+ bool IsOk() const;
int payload_type;
int frame_size_ms;
@@ -37,8 +39,6 @@ class AudioEncoderG722 : public AudioEncoder {
int RtpTimestampRateHz() const override;
int Num10MsFramesInNextPacket() const override;
int Max10MsFramesInAPacket() const override;
-
- protected:
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
@@ -65,5 +65,13 @@ class AudioEncoderG722 : public AudioEncoder {
rtc::Buffer interleave_buffer_;
};
+struct CodecInst;
+
+class AudioEncoderMutableG722
+ : public AudioEncoderMutableImpl<AudioEncoderG722> {
+ public:
+ explicit AudioEncoderMutableG722(const CodecInst& codec_inst);
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_INCLUDE_AUDIO_ENCODER_G722_H_
diff --git a/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc b/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
index fad531f6bb..4fea44babd 100644
--- a/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
+++ b/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
@@ -13,6 +13,7 @@
#include <cstring>
#include <limits>
#include "webrtc/base/checks.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/ilbc/interface/ilbc.h"
namespace webrtc {
@@ -23,15 +24,20 @@ const int kSampleRateHz = 8000;
} // namespace
+bool AudioEncoderIlbc::Config::IsOk() const {
+ if (!(frame_size_ms == 20 || frame_size_ms == 30 || frame_size_ms == 40 ||
+ frame_size_ms == 60))
+ return false;
+ if (kSampleRateHz / 100 * (frame_size_ms / 10) > kMaxSamplesPerPacket)
+ return false;
+ return true;
+}
+
AudioEncoderIlbc::AudioEncoderIlbc(const Config& config)
: payload_type_(config.payload_type),
num_10ms_frames_per_packet_(config.frame_size_ms / 10),
num_10ms_frames_buffered_(0) {
- CHECK(config.frame_size_ms == 20 || config.frame_size_ms == 30 ||
- config.frame_size_ms == 40 || config.frame_size_ms == 60)
- << "Frame size must be 20, 30, 40, or 60 ms.";
- DCHECK_LE(kSampleRateHz / 100 * num_10ms_frames_per_packet_,
- kMaxSamplesPerPacket);
+ CHECK(config.IsOk());
CHECK_EQ(0, WebRtcIlbcfix_EncoderCreate(&encoder_));
const int encoder_frame_size_ms = config.frame_size_ms > 30
? config.frame_size_ms / 2
@@ -112,4 +118,17 @@ size_t AudioEncoderIlbc::RequiredOutputSizeBytes() const {
}
}
+namespace {
+AudioEncoderIlbc::Config CreateConfig(const CodecInst& codec_inst) {
+ AudioEncoderIlbc::Config config;
+ config.frame_size_ms = codec_inst.pacsize / 8;
+ config.payload_type = codec_inst.pltype;
+ return config;
+}
+} // namespace
+
+AudioEncoderMutableIlbc::AudioEncoderMutableIlbc(const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderIlbc>(CreateConfig(codec_inst)) {
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/ilbc/interface/audio_encoder_ilbc.h b/webrtc/modules/audio_coding/codecs/ilbc/interface/audio_encoder_ilbc.h
index 91d17b4f85..c172db1b8f 100644
--- a/webrtc/modules/audio_coding/codecs/ilbc/interface/audio_encoder_ilbc.h
+++ b/webrtc/modules/audio_coding/codecs/ilbc/interface/audio_encoder_ilbc.h
@@ -13,6 +13,7 @@
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h"
#include "webrtc/modules/audio_coding/codecs/ilbc/interface/ilbc.h"
namespace webrtc {
@@ -21,6 +22,7 @@ class AudioEncoderIlbc : public AudioEncoder {
public:
struct Config {
Config() : payload_type(102), frame_size_ms(30) {}
+ bool IsOk() const;
int payload_type;
int frame_size_ms; // Valid values are 20, 30, 40, and 60 ms.
@@ -36,8 +38,6 @@ class AudioEncoderIlbc : public AudioEncoder {
size_t MaxEncodedBytes() const override;
int Num10MsFramesInNextPacket() const override;
int Max10MsFramesInAPacket() const override;
-
- protected:
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
@@ -55,5 +55,13 @@ class AudioEncoderIlbc : public AudioEncoder {
IlbcEncoderInstance* encoder_;
};
+struct CodecInst;
+
+class AudioEncoderMutableIlbc
+ : public AudioEncoderMutableImpl<AudioEncoderIlbc> {
+ public:
+ explicit AudioEncoderMutableIlbc(const CodecInst& codec_inst);
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INTERFACE_AUDIO_ENCODER_ILBC_H_
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
index ad531667f5..b67a9b09fc 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
@@ -72,7 +72,6 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder {
int ErrorCode() override;
size_t Channels() const override { return 1; }
- protected:
// AudioEncoder protected method.
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
@@ -117,5 +116,13 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder {
DISALLOW_COPY_AND_ASSIGN(AudioEncoderDecoderIsacT);
};
+struct CodecInst;
+
+class AudioEncoderDecoderMutableIsac : public AudioEncoderMutable,
+ public AudioDecoder {
+ public:
+ virtual void UpdateSettings(const CodecInst& codec_inst) = 0;
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_H_
diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h b/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
index d12c1678b8..bf9f875d78 100644
--- a/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
+++ b/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
@@ -12,6 +12,8 @@
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_AUDIO_ENCODER_ISACFIX_H_
#include "webrtc/base/checks.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h"
#include "webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
@@ -104,5 +106,45 @@ struct IsacFix {
typedef AudioEncoderDecoderIsacT<IsacFix> AudioEncoderDecoderIsacFix;
+struct CodecInst;
+
+class AudioEncoderDecoderMutableIsacFix
+ : public AudioEncoderMutableImpl<AudioEncoderDecoderIsacFix,
+ AudioEncoderDecoderMutableIsac> {
+ public:
+ explicit AudioEncoderDecoderMutableIsacFix(const CodecInst& codec_inst);
+ void UpdateSettings(const CodecInst& codec_inst) override;
+ void SetMaxPayloadSize(int max_payload_size_bytes) override;
+ void SetMaxRate(int max_rate_bps) override;
+
+ // From AudioDecoder.
+ int Decode(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) override;
+ int DecodeRedundant(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) override;
+ bool HasDecodePlc() const override;
+ int DecodePlc(int num_frames, int16_t* decoded) override;
+ int Init() override;
+ int IncomingPacket(const uint8_t* payload,
+ size_t payload_len,
+ uint16_t rtp_sequence_number,
+ uint32_t rtp_timestamp,
+ uint32_t arrival_timestamp) override;
+ int ErrorCode() override;
+ int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override;
+ int PacketDurationRedundant(const uint8_t* encoded,
+ size_t encoded_len) const override;
+ bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override;
+ size_t Channels() const override;
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_AUDIO_ENCODER_ISACFIX_H_
diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc b/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc
index d0aea26e44..4003b26e70 100644
--- a/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc
+++ b/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc
@@ -10,6 +10,7 @@
#include "webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h"
namespace webrtc {
@@ -20,4 +21,113 @@ const uint16_t IsacFix::kFixSampleRate;
// AudioEncoderDecoderIsacFix.
template class AudioEncoderDecoderIsacT<IsacFix>;
+namespace {
+AudioEncoderDecoderIsacFix::Config CreateConfig(const CodecInst& codec_inst) {
+ AudioEncoderDecoderIsacFix::Config config;
+ config.payload_type = codec_inst.pltype;
+ config.sample_rate_hz = codec_inst.plfreq;
+ config.frame_size_ms =
+ rtc::CheckedDivExact(1000 * codec_inst.pacsize, config.sample_rate_hz);
+ if (codec_inst.rate != -1)
+ config.bit_rate = codec_inst.rate;
+ config.adaptive_mode = (codec_inst.rate == -1);
+ return config;
+}
+} // namespace
+
+AudioEncoderDecoderMutableIsacFix::AudioEncoderDecoderMutableIsacFix(
+ const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderDecoderIsacFix,
+ AudioEncoderDecoderMutableIsac>(
+ CreateConfig(codec_inst)) {
+}
+
+void AudioEncoderDecoderMutableIsacFix::UpdateSettings(
+ const CodecInst& codec_inst) {
+ bool success = Reconstruct(CreateConfig(codec_inst));
+ DCHECK(success);
+}
+
+void AudioEncoderDecoderMutableIsacFix::SetMaxPayloadSize(
+ int max_payload_size_bytes) {
+ auto conf = config();
+ conf.max_payload_size_bytes = max_payload_size_bytes;
+ Reconstruct(conf);
+}
+
+void AudioEncoderDecoderMutableIsacFix::SetMaxRate(int max_rate_bps) {
+ auto conf = config();
+ conf.max_bit_rate = max_rate_bps;
+ Reconstruct(conf);
+}
+
+int AudioEncoderDecoderMutableIsacFix::Decode(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) {
+ return encoder()->Decode(encoded, encoded_len, sample_rate_hz,
+ max_decoded_bytes, decoded, speech_type);
+}
+
+int AudioEncoderDecoderMutableIsacFix::DecodeRedundant(
+ const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) {
+ return encoder()->DecodeRedundant(encoded, encoded_len, sample_rate_hz,
+ max_decoded_bytes, decoded, speech_type);
+}
+
+bool AudioEncoderDecoderMutableIsacFix::HasDecodePlc() const {
+ return encoder()->HasDecodePlc();
+}
+
+int AudioEncoderDecoderMutableIsacFix::DecodePlc(int num_frames,
+ int16_t* decoded) {
+ return encoder()->DecodePlc(num_frames, decoded);
+}
+
+int AudioEncoderDecoderMutableIsacFix::Init() {
+ return encoder()->Init();
+}
+
+int AudioEncoderDecoderMutableIsacFix::IncomingPacket(
+ const uint8_t* payload,
+ size_t payload_len,
+ uint16_t rtp_sequence_number,
+ uint32_t rtp_timestamp,
+ uint32_t arrival_timestamp) {
+ return encoder()->IncomingPacket(payload, payload_len, rtp_sequence_number,
+ rtp_timestamp, arrival_timestamp);
+}
+
+int AudioEncoderDecoderMutableIsacFix::ErrorCode() {
+ return encoder()->ErrorCode();
+}
+
+int AudioEncoderDecoderMutableIsacFix::PacketDuration(
+ const uint8_t* encoded,
+ size_t encoded_len) const {
+ return encoder()->PacketDuration(encoded, encoded_len);
+}
+
+int AudioEncoderDecoderMutableIsacFix::PacketDurationRedundant(
+ const uint8_t* encoded,
+ size_t encoded_len) const {
+ return encoder()->PacketDurationRedundant(encoded, encoded_len);
+}
+
+bool AudioEncoderDecoderMutableIsacFix::PacketHasFec(const uint8_t* encoded,
+ size_t encoded_len) const {
+ return encoder()->PacketHasFec(encoded, encoded_len);
+}
+
+size_t AudioEncoderDecoderMutableIsacFix::Channels() const {
+ return encoder()->Channels();
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h b/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
index 7d8ac7951b..5a75807469 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
+++ b/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
@@ -12,6 +12,8 @@
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_AUDIO_ENCODER_ISAC_H_
#include "webrtc/base/checks.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h"
#include "webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h"
@@ -102,5 +104,45 @@ struct IsacFloat {
typedef AudioEncoderDecoderIsacT<IsacFloat> AudioEncoderDecoderIsac;
+struct CodecInst;
+
+class AudioEncoderDecoderMutableIsacFloat
+ : public AudioEncoderMutableImpl<AudioEncoderDecoderIsac,
+ AudioEncoderDecoderMutableIsac> {
+ public:
+ explicit AudioEncoderDecoderMutableIsacFloat(const CodecInst& codec_inst);
+ void UpdateSettings(const CodecInst& codec_inst) override;
+ void SetMaxPayloadSize(int max_payload_size_bytes) override;
+ void SetMaxRate(int max_rate_bps) override;
+
+ // From AudioDecoder.
+ int Decode(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) override;
+ int DecodeRedundant(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) override;
+ bool HasDecodePlc() const override;
+ int DecodePlc(int num_frames, int16_t* decoded) override;
+ int Init() override;
+ int IncomingPacket(const uint8_t* payload,
+ size_t payload_len,
+ uint16_t rtp_sequence_number,
+ uint32_t rtp_timestamp,
+ uint32_t arrival_timestamp) override;
+ int ErrorCode() override;
+ int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override;
+ int PacketDurationRedundant(const uint8_t* encoded,
+ size_t encoded_len) const override;
+ bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override;
+ size_t Channels() const override;
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_AUDIO_ENCODER_ISAC_H_
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
index ba08603637..b2c1241e76 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
+++ b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
@@ -10,6 +10,7 @@
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h"
namespace webrtc {
@@ -18,4 +19,114 @@ namespace webrtc {
// AudioEncoderDecoderIsac.
template class AudioEncoderDecoderIsacT<IsacFloat>;
+namespace {
+AudioEncoderDecoderIsac::Config CreateConfig(const CodecInst& codec_inst) {
+ AudioEncoderDecoderIsac::Config config;
+ config.payload_type = codec_inst.pltype;
+ config.sample_rate_hz = codec_inst.plfreq;
+ config.frame_size_ms =
+ rtc::CheckedDivExact(1000 * codec_inst.pacsize, config.sample_rate_hz);
+ if (codec_inst.rate != -1)
+ config.bit_rate = codec_inst.rate;
+ config.adaptive_mode = (codec_inst.rate == -1);
+ return config;
+}
+} // namespace
+
+AudioEncoderDecoderMutableIsacFloat::AudioEncoderDecoderMutableIsacFloat(
+ const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderDecoderIsac,
+ AudioEncoderDecoderMutableIsac>(
+ CreateConfig(codec_inst)) {
+}
+
+void AudioEncoderDecoderMutableIsacFloat::UpdateSettings(
+ const CodecInst& codec_inst) {
+ bool success = Reconstruct(CreateConfig(codec_inst));
+ DCHECK(success);
+}
+
+void AudioEncoderDecoderMutableIsacFloat::SetMaxPayloadSize(
+ int max_payload_size_bytes) {
+ auto conf = config();
+ conf.max_payload_size_bytes = max_payload_size_bytes;
+ Reconstruct(conf);
+}
+
+void AudioEncoderDecoderMutableIsacFloat::SetMaxRate(int max_rate_bps) {
+ auto conf = config();
+ conf.max_bit_rate = max_rate_bps;
+ Reconstruct(conf);
+}
+
+int AudioEncoderDecoderMutableIsacFloat::Decode(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) {
+ return encoder()->Decode(encoded, encoded_len, sample_rate_hz,
+ max_decoded_bytes, decoded, speech_type);
+}
+
+int AudioEncoderDecoderMutableIsacFloat::DecodeRedundant(
+ const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) {
+ return encoder()->DecodeRedundant(encoded, encoded_len, sample_rate_hz,
+ max_decoded_bytes, decoded, speech_type);
+}
+
+bool AudioEncoderDecoderMutableIsacFloat::HasDecodePlc() const {
+ return encoder()->HasDecodePlc();
+}
+
+int AudioEncoderDecoderMutableIsacFloat::DecodePlc(int num_frames,
+ int16_t* decoded) {
+ return encoder()->DecodePlc(num_frames, decoded);
+}
+
+int AudioEncoderDecoderMutableIsacFloat::Init() {
+ return encoder()->Init();
+}
+
+int AudioEncoderDecoderMutableIsacFloat::IncomingPacket(
+ const uint8_t* payload,
+ size_t payload_len,
+ uint16_t rtp_sequence_number,
+ uint32_t rtp_timestamp,
+ uint32_t arrival_timestamp) {
+ return encoder()->IncomingPacket(payload, payload_len, rtp_sequence_number,
+ rtp_timestamp, arrival_timestamp);
+}
+
+int AudioEncoderDecoderMutableIsacFloat::ErrorCode() {
+ return encoder()->ErrorCode();
+}
+
+int AudioEncoderDecoderMutableIsacFloat::PacketDuration(
+ const uint8_t* encoded,
+ size_t encoded_len) const {
+ return encoder()->PacketDuration(encoded, encoded_len);
+}
+
+int AudioEncoderDecoderMutableIsacFloat::PacketDurationRedundant(
+ const uint8_t* encoded,
+ size_t encoded_len) const {
+ return encoder()->PacketDurationRedundant(encoded, encoded_len);
+}
+
+bool AudioEncoderDecoderMutableIsacFloat::PacketHasFec(
+ const uint8_t* encoded,
+ size_t encoded_len) const {
+ return encoder()->PacketHasFec(encoded, encoded_len);
+}
+
+size_t AudioEncoderDecoderMutableIsacFloat::Channels() const {
+ return encoder()->Channels();
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_mutable_opus_test.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_mutable_opus_test.cc
new file mode 100644
index 0000000000..ddb5f1ea80
--- /dev/null
+++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_mutable_opus_test.cc
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/common_types.h"
+#include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"
+
+namespace webrtc {
+namespace acm2 {
+
+#ifdef WEBRTC_CODEC_OPUS
+namespace {
+const CodecInst kDefaultOpusCodecInst = {105, "opus", 48000, 960, 1, 32000};
+} // namespace
+
+class AudioEncoderMutableOpusTest : public ::testing::Test {
+ protected:
+ AudioEncoderMutableOpusTest() : codec_inst_(kDefaultOpusCodecInst) {}
+
+ void CreateCodec(int num_channels) {
+ codec_inst_.channels = num_channels;
+ encoder_.reset(new AudioEncoderMutableOpus(codec_inst_));
+ auto expected_app =
+ num_channels == 1 ? AudioEncoderOpus::kVoip : AudioEncoderOpus::kAudio;
+ EXPECT_EQ(expected_app, encoder_->application());
+ }
+
+ CodecInst codec_inst_;
+ rtc::scoped_ptr<AudioEncoderMutableOpus> encoder_;
+};
+
+TEST_F(AudioEncoderMutableOpusTest, DefaultApplicationModeMono) {
+ CreateCodec(1);
+}
+
+TEST_F(AudioEncoderMutableOpusTest, DefaultApplicationModeStereo) {
+ CreateCodec(2);
+}
+
+TEST_F(AudioEncoderMutableOpusTest, ChangeApplicationMode) {
+ CreateCodec(2);
+ EXPECT_TRUE(
+ encoder_->SetApplication(AudioEncoderMutable::kApplicationSpeech, false));
+ EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application());
+}
+
+TEST_F(AudioEncoderMutableOpusTest, ResetWontChangeApplicationMode) {
+ CreateCodec(2);
+
+ // Trigger a reset.
+ encoder_->Reset();
+ // Verify that the mode is still kAudio.
+ EXPECT_EQ(AudioEncoderOpus::kAudio, encoder_->application());
+
+ // Now change to kVoip.
+ EXPECT_TRUE(
+ encoder_->SetApplication(AudioEncoderMutable::kApplicationSpeech, false));
+ EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application());
+
+ // Trigger a reset again.
+ encoder_->Reset();
+ // Verify that the mode is still kVoip.
+ EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application());
+}
+
+TEST_F(AudioEncoderMutableOpusTest, ToggleDtx) {
+ CreateCodec(2);
+
+ // DTX is not allowed in audio mode, if mode forcing flag is false.
+ EXPECT_FALSE(encoder_->SetDtx(true, false));
+ EXPECT_EQ(AudioEncoderOpus::kAudio, encoder_->application());
+
+ // DTX will be on, if mode forcing flag is true. Then application mode is
+ // switched to kVoip.
+ EXPECT_TRUE(encoder_->SetDtx(true, true));
+ EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application());
+
+ // Audio mode is not allowed when DTX is on, and DTX forcing flag is false.
+ EXPECT_FALSE(
+ encoder_->SetApplication(AudioEncoderMutable::kApplicationAudio, false));
+ EXPECT_TRUE(encoder_->dtx_enabled());
+
+ // Audio mode will be set, if DTX forcing flag is true. Then DTX is switched
+ // off.
+ EXPECT_TRUE(
+ encoder_->SetApplication(AudioEncoderMutable::kApplicationAudio, true));
+ EXPECT_FALSE(encoder_->dtx_enabled());
+
+ // Now we set VOIP mode. The DTX forcing flag has no effect.
+ EXPECT_TRUE(
+ encoder_->SetApplication(AudioEncoderMutable::kApplicationSpeech, true));
+ EXPECT_FALSE(encoder_->dtx_enabled());
+
+ // In VOIP mode, we can enable DTX with mode forcing flag being false.
+ EXPECT_TRUE(encoder_->SetDtx(true, false));
+
+ // Turn off DTX.
+ EXPECT_TRUE(encoder_->SetDtx(false, false));
+
+ // When DTX is off, we can set Audio mode with DTX forcing flag being false.
+ EXPECT_TRUE(
+ encoder_->SetApplication(AudioEncoderMutable::kApplicationAudio, false));
+}
+#endif // WEBRTC_CODEC_OPUS
+
+} // namespace acm2
+} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
index 941e635b17..a3a34bf340 100644
--- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
+++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
@@ -11,6 +11,7 @@
#include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"
#include "webrtc/base/checks.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
namespace webrtc {
@@ -199,20 +200,73 @@ AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeInternal(
CHECK_EQ(input_buffer_.size(),
static_cast<size_t>(num_10ms_frames_per_packet_) *
samples_per_10ms_frame_);
- int16_t r = WebRtcOpus_Encode(
+ int16_t status = WebRtcOpus_Encode(
inst_, &input_buffer_[0],
rtc::CheckedDivExact(CastInt16(input_buffer_.size()),
static_cast<int16_t>(num_channels_)),
ClampInt16(max_encoded_bytes), encoded);
- CHECK_GE(r, 0); // Fails only if fed invalid data.
+ CHECK_GE(status, 0); // Fails only if fed invalid data.
input_buffer_.clear();
EncodedInfo info;
- info.encoded_bytes = r;
+ info.encoded_bytes = status;
info.encoded_timestamp = first_timestamp_in_buffer_;
info.payload_type = payload_type_;
info.send_even_if_empty = true; // Allows Opus to send empty packets.
- info.speech = r > 0;
+ info.speech = (status > 0);
return info;
}
+namespace {
+AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) {
+ AudioEncoderOpus::Config config;
+ config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48);
+ config.num_channels = codec_inst.channels;
+ config.bitrate_bps = codec_inst.rate;
+ config.payload_type = codec_inst.pltype;
+ config.application = (config.num_channels == 1 ? AudioEncoderOpus::kVoip
+ : AudioEncoderOpus::kAudio);
+ return config;
+}
+} // namespace
+
+AudioEncoderMutableOpus::AudioEncoderMutableOpus(const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderOpus>(CreateConfig(codec_inst)) {
+}
+
+bool AudioEncoderMutableOpus::SetFec(bool enable) {
+ auto conf = config();
+ conf.fec_enabled = enable;
+ return Reconstruct(conf);
+}
+
+bool AudioEncoderMutableOpus::SetDtx(bool enable, bool force) {
+ auto conf = config();
+ if (enable && force)
+ conf.application = AudioEncoderOpus::kVoip;
+ conf.dtx_enabled = enable;
+ return Reconstruct(conf);
+}
+
+bool AudioEncoderMutableOpus::SetApplication(Application application,
+ bool force) {
+ auto conf = config();
+ switch (application) {
+ case kApplicationSpeech:
+ conf.application = AudioEncoderOpus::kVoip;
+ break;
+ case kApplicationAudio:
+ if (force)
+ conf.dtx_enabled = false;
+ conf.application = AudioEncoderOpus::kAudio;
+ break;
+ }
+ return Reconstruct(conf);
+}
+
+bool AudioEncoderMutableOpus::SetMaxPlaybackRate(int frequency_hz) {
+ auto conf = config();
+ conf.max_playback_rate_hz = frequency_hz;
+ return Reconstruct(conf);
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h b/webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
index bd76b4900a..8d123a9537 100644
--- a/webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
+++ b/webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
@@ -13,6 +13,8 @@
#include <vector>
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h"
#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
@@ -56,8 +58,6 @@ class AudioEncoderOpus final : public AudioEncoder {
double packet_loss_rate() const { return packet_loss_rate_; }
ApplicationMode application() const { return application_; }
bool dtx_enabled() const { return dtx_enabled_; }
-
- protected:
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
@@ -77,5 +77,22 @@ class AudioEncoderOpus final : public AudioEncoder {
double packet_loss_rate_;
};
+struct CodecInst;
+
+class AudioEncoderMutableOpus
+ : public AudioEncoderMutableImpl<AudioEncoderOpus> {
+ public:
+ explicit AudioEncoderMutableOpus(const CodecInst& codec_inst);
+ bool SetFec(bool enable) override;
+ bool SetDtx(bool enable, bool force) override;
+ bool SetApplication(Application application, bool force) override;
+ bool SetMaxPlaybackRate(int frequency_hz) override;
+ AudioEncoderOpus::ApplicationMode application() const {
+ return encoder()->application();
+ }
+ double packet_loss_rate() const { return encoder()->packet_loss_rate(); }
+ bool dtx_enabled() const { return encoder()->dtx_enabled(); }
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INTERFACE_AUDIO_ENCODER_OPUS_H_
diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc b/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc
index f761922201..491fdfdb14 100644
--- a/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc
+++ b/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc
@@ -9,14 +9,41 @@
*/
#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
namespace webrtc {
+bool AudioEncoderPcm16B::Config::IsOk() const {
+ if ((sample_rate_hz != 8000) && (sample_rate_hz != 16000) &&
+ (sample_rate_hz != 32000) && (sample_rate_hz != 48000))
+ return false;
+ return AudioEncoderPcm::Config::IsOk();
+}
+
int16_t AudioEncoderPcm16B::EncodeCall(const int16_t* audio,
size_t input_len,
uint8_t* encoded) {
return WebRtcPcm16b_Encode(audio, static_cast<int16_t>(input_len), encoded);
}
+namespace {
+AudioEncoderPcm16B::Config CreateConfig(const CodecInst& codec_inst) {
+ AudioEncoderPcm16B::Config config;
+ config.num_channels = codec_inst.channels;
+ config.sample_rate_hz = codec_inst.plfreq;
+ config.frame_size_ms = rtc::CheckedDivExact(
+ codec_inst.pacsize, rtc::CheckedDivExact(config.sample_rate_hz, 1000));
+ config.payload_type = codec_inst.pltype;
+ return config;
+}
+} // namespace
+
+AudioEncoderMutablePcm16B::AudioEncoderMutablePcm16B(
+ const CodecInst& codec_inst)
+ : AudioEncoderMutableImpl<AudioEncoderPcm16B>(CreateConfig(codec_inst)) {
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h b/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h
index 99ecd249c1..f1e1c51da8 100644
--- a/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h
+++ b/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h
@@ -11,6 +11,8 @@
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_ENCODER_PCM16B_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_ENCODER_PCM16B_H_
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder_mutable_impl.h"
#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h"
namespace webrtc {
@@ -20,6 +22,7 @@ class AudioEncoderPcm16B : public AudioEncoderPcm {
struct Config : public AudioEncoderPcm::Config {
public:
Config() : AudioEncoderPcm::Config(107), sample_rate_hz(8000) {}
+ bool IsOk() const;
int sample_rate_hz;
};
@@ -33,5 +36,13 @@ class AudioEncoderPcm16B : public AudioEncoderPcm {
uint8_t* encoded) override;
};
+struct CodecInst;
+
+class AudioEncoderMutablePcm16B
+ : public AudioEncoderMutableImpl<AudioEncoderPcm16B> {
+ public:
+ explicit AudioEncoderMutablePcm16B(const CodecInst& codec_inst);
+};
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_ENCODER_PCM16B_H_
diff --git a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
index 99e5ee2a3e..49ab948fab 100644
--- a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
+++ b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
@@ -44,8 +44,6 @@ class AudioEncoderCopyRed : public AudioEncoder {
int Max10MsFramesInAPacket() const override;
void SetTargetBitrate(int bits_per_second) override;
void SetProjectedPacketLossRate(double fraction) override;
-
- protected:
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index 5fbd501641..e97d8527dd 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -96,6 +96,7 @@
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
'audio_coding/main/acm2/acm_generic_codec_test.cc',
'audio_coding/main/acm2/acm_generic_codec_opus_test.cc',
+ 'audio_coding/codecs/opus/audio_encoder_mutable_opus_test.cc',
'audio_coding/main/acm2/acm_receiver_unittest.cc',
'audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc',
'audio_coding/main/acm2/audio_coding_module_unittest.cc',