Add new methods to AudioEncoder interface
The following three methods are added:
rtp_timestamp_rate_hz()
SetTargetBitrate()
SetProjectedPacketLossRate()
Default implementations are provided, and a few overrides are
implemented. AudioEncoderCopyRed and AudioEncoderCng propagate the new
methods to the underlying speech codec.
BUG=3926
COAUTHOR:kwiberg@webrtc.org
R=tina.legrand@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/34049004
Cr-Commit-Position: refs/heads/master@{#8171}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8171 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/codecs/audio_encoder.cc b/webrtc/modules/audio_coding/codecs/audio_encoder.cc
index 916111f..20e5953 100644
--- a/webrtc/modules/audio_coding/codecs/audio_encoder.cc
+++ b/webrtc/modules/audio_coding/codecs/audio_encoder.cc
@@ -18,4 +18,8 @@
AudioEncoder::EncodedInfo::~EncodedInfo() {
}
+int AudioEncoder::rtp_timestamp_rate_hz() const {
+ return sample_rate_hz();
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/audio_encoder.h b/webrtc/modules/audio_coding/codecs/audio_encoder.h
index 5b81509..9b0c11b 100644
--- a/webrtc/modules/audio_coding/codecs/audio_encoder.h
+++ b/webrtc/modules/audio_coding/codecs/audio_encoder.h
@@ -58,7 +58,7 @@
// In case of error, false is returned, otherwise true. It is an error for the
// encoder to attempt to produce more than |max_encoded_bytes| bytes of
// output.
- bool Encode(uint32_t timestamp,
+ bool Encode(uint32_t rtp_timestamp,
const int16_t* audio,
size_t num_samples_per_channel,
size_t max_encoded_bytes,
@@ -66,11 +66,8 @@
EncodedInfo* info) {
CHECK_EQ(num_samples_per_channel,
static_cast<size_t>(sample_rate_hz() / 100));
- bool ret = EncodeInternal(timestamp,
- audio,
- max_encoded_bytes,
- encoded,
- info);
+ bool ret =
+ EncodeInternal(rtp_timestamp, audio, max_encoded_bytes, encoded, info);
CHECK_LE(info->encoded_bytes, max_encoded_bytes);
return ret;
}
@@ -80,6 +77,10 @@
virtual int sample_rate_hz() const = 0;
virtual int num_channels() const = 0;
+ // Returns the rate with which the RTP timestamps are updated. By default,
+ // this is the same as sample_rate_hz().
+ virtual int rtp_timestamp_rate_hz() const;
+
// Returns the number of 10 ms frames the encoder will put in the next
// packet. This value may only change when Encode() outputs a packet; i.e.,
// the encoder may vary the number of 10 ms frames from packet to packet, but
@@ -91,8 +92,17 @@
// Num10MsFramesInNextPacket().
virtual int Max10MsFramesInAPacket() const = 0;
+ // Changes the target bitrate. The implementation is free to alter this value,
+ // e.g., if the desired value is outside the valid range.
+ virtual void SetTargetBitrate(int bits_per_second) {}
+
+ // Tells the implementation what the projected packet loss rate is. The rate
+ // is in the range [0.0, 1.0]. This rate is typically used to adjust channel
+ // coding efforts, such as FEC.
+ virtual void SetProjectedPacketLossRate(double fraction) {}
+
protected:
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
index 9cf9098..bf5cb58 100644
--- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
+++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
@@ -74,6 +74,10 @@
return sample_rate_hz_;
}
+int AudioEncoderCng::rtp_timestamp_rate_hz() const {
+ return speech_encoder_->rtp_timestamp_rate_hz();
+}
+
int AudioEncoderCng::num_channels() const {
return num_channels_;
}
@@ -86,7 +90,17 @@
return speech_encoder_->Max10MsFramesInAPacket();
}
-bool AudioEncoderCng::EncodeInternal(uint32_t timestamp,
+void AudioEncoderCng::SetTargetBitrate(int bits_per_second) {
+ speech_encoder_->SetTargetBitrate(bits_per_second);
+}
+
+void AudioEncoderCng::SetProjectedPacketLossRate(double fraction) {
+ DCHECK_GE(fraction, 0.0);
+ DCHECK_LE(fraction, 1.0);
+ speech_encoder_->SetProjectedPacketLossRate(fraction);
+}
+
+bool AudioEncoderCng::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
@@ -99,7 +113,7 @@
const int num_samples = sample_rate_hz() / 100 * num_channels();
if (speech_buffer_.empty()) {
CHECK_EQ(frames_in_buffer_, 0);
- first_timestamp_in_buffer_ = timestamp;
+ first_timestamp_in_buffer_ = rtp_timestamp;
}
for (int i = 0; i < num_samples; ++i) {
speech_buffer_.push_back(audio[i]);
diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
index 76b9fc0..69c97d1 100644
--- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
+++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
@@ -196,6 +196,18 @@
EXPECT_EQ(17, cng_->Num10MsFramesInNextPacket());
}
+TEST_F(AudioEncoderCngTest, CheckChangeBitratePropagation) {
+ CreateCng();
+ EXPECT_CALL(mock_encoder_, SetTargetBitrate(4711));
+ cng_->SetTargetBitrate(4711);
+}
+
+TEST_F(AudioEncoderCngTest, CheckProjectedPacketLossRatePropagation) {
+ CreateCng();
+ EXPECT_CALL(mock_encoder_, SetProjectedPacketLossRate(0.5));
+ cng_->SetProjectedPacketLossRate(0.5);
+}
+
TEST_F(AudioEncoderCngTest, EncodeCallsVad) {
EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket())
.WillRepeatedly(Return(1));
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 884c047..cdfa90d 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
@@ -49,11 +49,14 @@
virtual int sample_rate_hz() const OVERRIDE;
virtual int num_channels() const OVERRIDE;
+ int rtp_timestamp_rate_hz() const override;
virtual int Num10MsFramesInNextPacket() const OVERRIDE;
virtual int Max10MsFramesInAPacket() const OVERRIDE;
+ void SetTargetBitrate(int bits_per_second) override;
+ void SetProjectedPacketLossRate(double fraction) override;
protected:
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
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 7f7b77e..5b072e4 100644
--- a/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
+++ b/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
@@ -59,14 +59,14 @@
return num_10ms_frames_per_packet_;
}
-bool AudioEncoderPcm::EncodeInternal(uint32_t timestamp,
+bool AudioEncoderPcm::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
EncodedInfo* info) {
const int num_samples = sample_rate_hz() / 100 * num_channels();
if (speech_buffer_.empty()) {
- first_timestamp_in_buffer_ = timestamp;
+ first_timestamp_in_buffer_ = rtp_timestamp;
}
for (int i = 0; i < num_samples; ++i) {
speech_buffer_.push_back(audio[i]);
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 93748b3..83e4aea 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
@@ -40,7 +40,7 @@
protected:
AudioEncoderPcm(const Config& config, int sample_rate_hz);
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
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 c483f44..08f7753 100644
--- a/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
+++ b/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
@@ -54,6 +54,11 @@
int AudioEncoderG722::sample_rate_hz() const {
return kSampleRateHz;
}
+int AudioEncoderG722::rtp_timestamp_rate_hz() const {
+ // The RTP timestamp rate for G.722 is 8000 Hz, even though it is a 16 kHz
+ // codec.
+ return kSampleRateHz / 2;
+}
int AudioEncoderG722::num_channels() const {
return num_channels_;
}
@@ -64,7 +69,7 @@
return num_10ms_frames_per_packet_;
}
-bool AudioEncoderG722::EncodeInternal(uint32_t timestamp,
+bool AudioEncoderG722::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
@@ -75,7 +80,7 @@
static_cast<size_t>(samples_per_channel) / 2 * num_channels_);
if (num_10ms_frames_buffered_ == 0)
- first_timestamp_in_buffer_ = timestamp;
+ first_timestamp_in_buffer_ = rtp_timestamp;
// Deinterleave samples and save them in each channel's buffer.
const int start = kSampleRateHz / 100 * num_10ms_frames_buffered_;
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 25fa37b..6202f1f 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
@@ -31,12 +31,13 @@
virtual ~AudioEncoderG722();
virtual int sample_rate_hz() const OVERRIDE;
+ int rtp_timestamp_rate_hz() const override;
virtual int num_channels() const OVERRIDE;
virtual int Num10MsFramesInNextPacket() const OVERRIDE;
virtual int Max10MsFramesInAPacket() const OVERRIDE;
protected:
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
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 d7dfdbc..3fb6022 100644
--- a/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
+++ b/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
@@ -52,7 +52,7 @@
return num_10ms_frames_per_packet_;
}
-bool AudioEncoderIlbc::EncodeInternal(uint32_t timestamp,
+bool AudioEncoderIlbc::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
@@ -63,7 +63,7 @@
// Save timestamp if starting a new packet.
if (num_10ms_frames_buffered_ == 0)
- first_timestamp_in_buffer_ = timestamp;
+ first_timestamp_in_buffer_ = rtp_timestamp;
// Buffer input.
std::memcpy(input_buffer_ + kSampleRateHz / 100 * num_10ms_frames_buffered_,
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 b307dd5..0ecf039 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
@@ -35,7 +35,7 @@
virtual int Max10MsFramesInAPacket() const OVERRIDE;
protected:
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
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 8187159..712d3e6 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
@@ -84,7 +84,7 @@
protected:
// AudioEncoder protected method.
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
index 6fc4dc6..5b337c1 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
@@ -120,7 +120,7 @@
}
template <typename T>
-bool AudioEncoderDecoderIsacT<T>::EncodeInternal(uint32_t timestamp,
+bool AudioEncoderDecoderIsacT<T>::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
@@ -128,7 +128,7 @@
if (!packet_in_progress_) {
// Starting a new packet; remember the timestamp for later.
packet_in_progress_ = true;
- packet_timestamp_ = timestamp;
+ packet_timestamp_ = rtp_timestamp;
}
int r;
{
diff --git a/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h b/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h
index fd7696e..758625e 100644
--- a/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h
+++ b/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h
@@ -25,6 +25,8 @@
MOCK_CONST_METHOD0(num_channels, int());
MOCK_CONST_METHOD0(Num10MsFramesInNextPacket, int());
MOCK_CONST_METHOD0(Max10MsFramesInAPacket, int());
+ MOCK_METHOD1(SetTargetBitrate, void(int));
+ MOCK_METHOD1(SetProjectedPacketLossRate, void(double));
// Note, we explicitly chose not to create a mock for the Encode method.
MOCK_METHOD5(EncodeInternal,
bool(uint32_t timestamp,
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 fce7721..d912fd7 100644
--- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
+++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
@@ -10,12 +10,16 @@
#include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"
+#include "webrtc/base/checks.h"
#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
namespace webrtc {
namespace {
+const int kMinBitrateBps = 500;
+const int kMaxBitrateBps = 512000;
+
// We always encode at 48 kHz.
const int kSampleRateHz = 48000;
@@ -36,7 +40,8 @@
: frame_size_ms(20),
num_channels(1),
payload_type(120),
- application(kVoip) {
+ application(kVoip),
+ bitrate_bps(64000) {
}
bool AudioEncoderOpus::Config::IsOk() const {
@@ -44,6 +49,8 @@
return false;
if (num_channels <= 0)
return false;
+ if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps)
+ return false;
return true;
}
@@ -54,10 +61,12 @@
payload_type_(config.payload_type),
application_(config.application),
samples_per_10ms_frame_(rtc::CheckedDivExact(kSampleRateHz, 100) *
- num_channels_) {
+ num_channels_),
+ packet_loss_rate_(0.0) {
CHECK(config.IsOk());
input_buffer_.reserve(num_10ms_frames_per_packet_ * samples_per_10ms_frame_);
CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, num_channels_, application_));
+ SetTargetBitrate(config.bitrate_bps);
}
AudioEncoderOpus::~AudioEncoderOpus() {
@@ -80,13 +89,67 @@
return num_10ms_frames_per_packet_;
}
-bool AudioEncoderOpus::EncodeInternal(uint32_t timestamp,
+void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) {
+ CHECK_EQ(WebRtcOpus_SetBitRate(
+ inst_, std::max(std::min(bits_per_second, kMaxBitrateBps),
+ kMinBitrateBps)),
+ 0);
+}
+
+void AudioEncoderOpus::SetProjectedPacketLossRate(double fraction) {
+ DCHECK_GE(fraction, 0.0);
+ DCHECK_LE(fraction, 1.0);
+ // Optimize the loss rate to configure Opus. Basically, optimized loss rate is
+ // the input loss rate rounded down to various levels, because a robustly good
+ // audio quality is achieved by lowering the packet loss down.
+ // Additionally, to prevent toggling, margins are used, i.e., when jumping to
+ // a loss rate from below, a higher threshold is used than jumping to the same
+ // level from above.
+ const double kPacketLossRate20 = 0.20;
+ const double kPacketLossRate10 = 0.10;
+ const double kPacketLossRate5 = 0.05;
+ const double kPacketLossRate1 = 0.01;
+ const double kLossRate20Margin = 0.02;
+ const double kLossRate10Margin = 0.01;
+ const double kLossRate5Margin = 0.01;
+ double opt_loss_rate;
+ if (fraction >=
+ kPacketLossRate20 +
+ kLossRate20Margin *
+ (kPacketLossRate20 - packet_loss_rate_ > 0 ? 1 : -1)) {
+ opt_loss_rate = kPacketLossRate20;
+ } else if (fraction >=
+ kPacketLossRate10 +
+ kLossRate10Margin *
+ (kPacketLossRate10 - packet_loss_rate_ > 0 ? 1 : -1)) {
+ opt_loss_rate = kPacketLossRate10;
+ } else if (fraction >=
+ kPacketLossRate5 +
+ kLossRate5Margin *
+ (kPacketLossRate5 - packet_loss_rate_ > 0 ? 1 : -1)) {
+ opt_loss_rate = kPacketLossRate5;
+ } else if (fraction >= kPacketLossRate1) {
+ opt_loss_rate = kPacketLossRate1;
+ } else {
+ opt_loss_rate = 0;
+ }
+
+ if (packet_loss_rate_ != opt_loss_rate) {
+ // Ask the encoder to change the target packet loss rate.
+ CHECK_EQ(WebRtcOpus_SetPacketLossRate(
+ inst_, static_cast<int32_t>(opt_loss_rate * 100 + .5)),
+ 0);
+ packet_loss_rate_ = opt_loss_rate;
+ }
+}
+
+bool AudioEncoderOpus::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
EncodedInfo* info) {
if (input_buffer_.empty())
- first_timestamp_in_buffer_ = timestamp;
+ first_timestamp_in_buffer_ = rtp_timestamp;
input_buffer_.insert(input_buffer_.end(), audio,
audio + samples_per_10ms_frame_);
if (input_buffer_.size() < (static_cast<size_t>(num_10ms_frames_per_packet_) *
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 e9d0fb8..c39af12 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
@@ -32,6 +32,7 @@
int num_channels;
int payload_type;
ApplicationMode application;
+ int bitrate_bps;
};
explicit AudioEncoderOpus(const Config& config);
@@ -41,9 +42,11 @@
virtual int num_channels() const OVERRIDE;
virtual int Num10MsFramesInNextPacket() const OVERRIDE;
virtual int Max10MsFramesInAPacket() const OVERRIDE;
+ void SetTargetBitrate(int bits_per_second) override;
+ void SetProjectedPacketLossRate(double fraction) override;
protected:
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
@@ -58,6 +61,7 @@
std::vector<int16_t> input_buffer_;
OpusEncInst* inst_;
uint32_t first_timestamp_in_buffer_;
+ double packet_loss_rate_;
};
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
index 73e373c..c3d5601 100644
--- a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
+++ b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
@@ -28,6 +28,10 @@
return speech_encoder_->sample_rate_hz();
}
+int AudioEncoderCopyRed::rtp_timestamp_rate_hz() const {
+ return speech_encoder_->rtp_timestamp_rate_hz();
+}
+
int AudioEncoderCopyRed::num_channels() const {
return speech_encoder_->num_channels();
}
@@ -40,12 +44,22 @@
return speech_encoder_->Max10MsFramesInAPacket();
}
-bool AudioEncoderCopyRed::EncodeInternal(uint32_t timestamp,
+void AudioEncoderCopyRed::SetTargetBitrate(int bits_per_second) {
+ speech_encoder_->SetTargetBitrate(bits_per_second);
+}
+
+void AudioEncoderCopyRed::SetProjectedPacketLossRate(double fraction) {
+ DCHECK_GE(fraction, 0.0);
+ DCHECK_LE(fraction, 1.0);
+ speech_encoder_->SetProjectedPacketLossRate(fraction);
+}
+
+bool AudioEncoderCopyRed::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
EncodedInfo* info) {
- if (!speech_encoder_->Encode(timestamp, audio,
+ if (!speech_encoder_->Encode(rtp_timestamp, audio,
static_cast<size_t>(sample_rate_hz() / 100),
max_encoded_bytes, encoded, info))
return false;
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 8d0e427..eeda94f 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
@@ -36,12 +36,15 @@
virtual ~AudioEncoderCopyRed();
virtual int sample_rate_hz() const OVERRIDE;
+ int rtp_timestamp_rate_hz() const override;
virtual int num_channels() const OVERRIDE;
virtual int Num10MsFramesInNextPacket() const OVERRIDE;
virtual int Max10MsFramesInAPacket() const OVERRIDE;
+ void SetTargetBitrate(int bits_per_second) override;
+ void SetProjectedPacketLossRate(double fraction) override;
protected:
- virtual bool EncodeInternal(uint32_t timestamp,
+ virtual bool EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
diff --git a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
index b262734..35a8b2f 100644
--- a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
+++ b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
@@ -121,6 +121,16 @@
EXPECT_EQ(17, red_->Max10MsFramesInAPacket());
}
+TEST_F(AudioEncoderCopyRedTest, CheckSetBitratePropagation) {
+ EXPECT_CALL(mock_encoder_, SetTargetBitrate(4711));
+ red_->SetTargetBitrate(4711);
+}
+
+TEST_F(AudioEncoderCopyRedTest, CheckProjectedPacketLossRatePropagation) {
+ EXPECT_CALL(mock_encoder_, SetProjectedPacketLossRate(0.5));
+ red_->SetProjectedPacketLossRate(0.5);
+}
+
// Checks that the an Encode() call is immediately propagated to the speech
// encoder.
TEST_F(AudioEncoderCopyRedTest, CheckImmediateEncode) {