Adding two new stats to VoiceReceiverInfo
There have been requests of two new stats namely speech_expand_rate and secondary_decoded_rate. BUG=3867 R=henrik.lundin@webrtc.org, henrika@webrtc.org, tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/40789004 Cr-Commit-Position: refs/heads/master@{#8415} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8415 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
8fbdcfd73f
commit
c0bd7be0df
@ -779,6 +779,8 @@ struct VoiceReceiverInfo : public MediaReceiverInfo {
|
||||
delay_estimate_ms(0),
|
||||
audio_level(0),
|
||||
expand_rate(0),
|
||||
speech_expand_rate(0),
|
||||
secondary_decoded_rate(0),
|
||||
decoding_calls_to_silence_generator(0),
|
||||
decoding_calls_to_neteq(0),
|
||||
decoding_normal(0),
|
||||
@ -794,8 +796,12 @@ struct VoiceReceiverInfo : public MediaReceiverInfo {
|
||||
int jitter_buffer_preferred_ms;
|
||||
int delay_estimate_ms;
|
||||
int audio_level;
|
||||
// fraction of synthesized speech inserted through pre-emptive expansion
|
||||
// fraction of synthesized audio inserted through expansion.
|
||||
float expand_rate;
|
||||
// fraction of synthesized speech inserted through expansion.
|
||||
float speech_expand_rate;
|
||||
// fraction of data out of secondary decoding, including FEC and RED.
|
||||
float secondary_decoded_rate;
|
||||
int decoding_calls_to_silence_generator;
|
||||
int decoding_calls_to_neteq;
|
||||
int decoding_normal;
|
||||
|
@ -65,6 +65,25 @@ static const int kOpusBandwidthWb = 8000;
|
||||
static const int kOpusBandwidthSwb = 12000;
|
||||
static const int kOpusBandwidthFb = 20000;
|
||||
|
||||
static const webrtc::NetworkStatistics kNetStats = {
|
||||
1, // uint16_t currentBufferSize;
|
||||
2, // uint16_t preferredBufferSize;
|
||||
true, // bool jitterPeaksFound;
|
||||
1234, // uint16_t currentPacketLossRate;
|
||||
567, // uint16_t currentDiscardRate;
|
||||
8901, // uint16_t currentExpandRate;
|
||||
234, // uint16_t currentSpeechExpandRate;
|
||||
5678, // uint16_t currentPreemptiveRate;
|
||||
9012, // uint16_t currentAccelerateRate;
|
||||
3456, // uint16_t currentSecondaryDecodedRate;
|
||||
7890, // int32_t clockDriftPPM;
|
||||
54, // meanWaitingTimeMs;
|
||||
32, // int medianWaitingTimeMs;
|
||||
1, // int minWaitingTimeMs;
|
||||
98, // int maxWaitingTimeMs;
|
||||
7654, // int addedSamples;
|
||||
}; // These random but non-trivial numbers are used for testing.
|
||||
|
||||
// Verify the header extension ID, if enabled, is within the bounds specified in
|
||||
// [RFC5285]: 1-14 inclusive.
|
||||
#define WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id) \
|
||||
@ -823,7 +842,13 @@ class FakeWebRtcVoiceEngine
|
||||
virtual bool BuiltInAECIsAvailable() const { return false; }
|
||||
|
||||
// webrtc::VoENetEqStats
|
||||
WEBRTC_STUB(GetNetworkStatistics, (int, webrtc::NetworkStatistics&));
|
||||
WEBRTC_FUNC(GetNetworkStatistics, (int channel,
|
||||
webrtc::NetworkStatistics& ns)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
memcpy(&ns, &kNetStats, sizeof(webrtc::NetworkStatistics));
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBRTC_FUNC_CONST(GetDecodingCallStatistics, (int channel,
|
||||
webrtc::AudioDecodingCallStats*)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
|
@ -3413,6 +3413,10 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
|
||||
rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize;
|
||||
rinfo.expand_rate =
|
||||
static_cast<float>(ns.currentExpandRate) / (1 << 14);
|
||||
rinfo.speech_expand_rate =
|
||||
static_cast<float>(ns.currentSpeechExpandRate) / (1 << 14);
|
||||
rinfo.secondary_decoded_rate =
|
||||
static_cast<float>(ns.currentSecondaryDecodedRate) / (1 << 14);
|
||||
}
|
||||
|
||||
webrtc::AudioDecodingCallStats ds;
|
||||
|
@ -1992,6 +1992,12 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
|
||||
EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
|
||||
EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
|
||||
EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
|
||||
EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
|
||||
(1 << 14), info.receivers[0].expand_rate);
|
||||
EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
|
||||
(1 << 14), info.receivers[0].speech_expand_rate);
|
||||
EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
|
||||
(1 << 14), info.receivers[0].secondary_decoded_rate);
|
||||
}
|
||||
|
||||
// Test that we can add and remove receive streams, and do proper send/playout.
|
||||
@ -2319,6 +2325,12 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
|
||||
EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
|
||||
EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
|
||||
EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
|
||||
EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
|
||||
(1 << 14), info.receivers[0].expand_rate);
|
||||
EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
|
||||
(1 << 14), info.receivers[0].speech_expand_rate);
|
||||
EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
|
||||
(1 << 14), info.receivers[0].secondary_decoded_rate);
|
||||
// TODO(sriniv): Add testing for more receiver fields.
|
||||
}
|
||||
|
||||
|
@ -346,14 +346,19 @@ struct NetworkStatistics // NETEQ statistics
|
||||
uint16_t currentPacketLossRate;
|
||||
// Late loss rate; fraction between 0 and 1, scaled to Q14.
|
||||
uint16_t currentDiscardRate;
|
||||
// fraction (of original stream) of synthesized speech inserted through
|
||||
// fraction (of original stream) of synthesized audio inserted through
|
||||
// expansion (in Q14)
|
||||
uint16_t currentExpandRate;
|
||||
// fraction (of original stream) of synthesized speech inserted through
|
||||
// expansion (in Q14)
|
||||
uint16_t currentSpeechExpandRate;
|
||||
// fraction of synthesized speech inserted through pre-emptive expansion
|
||||
// (in Q14)
|
||||
uint16_t currentPreemptiveRate;
|
||||
// fraction of data removed through acceleration (in Q14)
|
||||
uint16_t currentAccelerateRate;
|
||||
// fraction of data coming from secondary decoding (in Q14)
|
||||
uint16_t currentSecondaryDecodedRate;
|
||||
// clock-drift in parts-per-million (negative or positive)
|
||||
int32_t clockDriftPPM;
|
||||
// average packet waiting time in the jitter buffer (ms)
|
||||
|
@ -639,7 +639,7 @@ int AcmReceiver::LastAudioCodec(CodecInst* codec) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AcmReceiver::NetworkStatistics(ACMNetworkStatistics* acm_stat) {
|
||||
void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
|
||||
NetEqNetworkStatistics neteq_stat;
|
||||
// NetEq function always returns zero, so we don't check the return value.
|
||||
neteq_->NetworkStatistics(&neteq_stat);
|
||||
@ -650,8 +650,10 @@ void AcmReceiver::NetworkStatistics(ACMNetworkStatistics* acm_stat) {
|
||||
acm_stat->currentPacketLossRate = neteq_stat.packet_loss_rate;
|
||||
acm_stat->currentDiscardRate = neteq_stat.packet_discard_rate;
|
||||
acm_stat->currentExpandRate = neteq_stat.expand_rate;
|
||||
acm_stat->currentSpeechExpandRate = neteq_stat.speech_expand_rate;
|
||||
acm_stat->currentPreemptiveRate = neteq_stat.preemptive_rate;
|
||||
acm_stat->currentAccelerateRate = neteq_stat.accelerate_rate;
|
||||
acm_stat->currentSecondaryDecodedRate = neteq_stat.secondary_decoded_rate;
|
||||
acm_stat->clockDriftPPM = neteq_stat.clockdrift_ppm;
|
||||
acm_stat->addedSamples = neteq_stat.added_zero_samples;
|
||||
|
||||
|
@ -191,7 +191,7 @@ class AcmReceiver {
|
||||
// Output:
|
||||
// - statistics : The current network statistics.
|
||||
//
|
||||
void NetworkStatistics(ACMNetworkStatistics* statistics);
|
||||
void GetNetworkStatistics(NetworkStatistics* statistics);
|
||||
|
||||
//
|
||||
// Enable post-decoding VAD.
|
||||
|
@ -1451,8 +1451,8 @@ int AudioCodingModuleImpl::PlayoutData10Ms(int desired_freq_hz,
|
||||
|
||||
// TODO(turajs) change the return value to void. Also change the corresponding
|
||||
// NetEq function.
|
||||
int AudioCodingModuleImpl::NetworkStatistics(ACMNetworkStatistics* statistics) {
|
||||
receiver_.NetworkStatistics(statistics);
|
||||
int AudioCodingModuleImpl::GetNetworkStatistics(NetworkStatistics* statistics) {
|
||||
receiver_.GetNetworkStatistics(statistics);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1841,8 +1841,8 @@ bool AudioCodingImpl::Get10MsAudio(AudioFrame* audio_frame) {
|
||||
return acm_old_->PlayoutData10Ms(playout_frequency_hz_, audio_frame) == 0;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::NetworkStatistics(
|
||||
ACMNetworkStatistics* network_statistics) {
|
||||
bool AudioCodingImpl::GetNetworkStatistics(
|
||||
NetworkStatistics* network_statistics) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ class AudioCodingModuleImpl : public AudioCodingModule {
|
||||
// Statistics
|
||||
//
|
||||
|
||||
virtual int NetworkStatistics(ACMNetworkStatistics* statistics) OVERRIDE;
|
||||
virtual int GetNetworkStatistics(NetworkStatistics* statistics) OVERRIDE;
|
||||
|
||||
// GET RED payload for iSAC. The method id called when 'this' ACM is
|
||||
// the default ACM.
|
||||
@ -418,8 +418,8 @@ class AudioCodingImpl : public AudioCoding {
|
||||
|
||||
virtual bool Get10MsAudio(AudioFrame* audio_frame) OVERRIDE;
|
||||
|
||||
virtual bool NetworkStatistics(
|
||||
ACMNetworkStatistics* network_statistics) OVERRIDE;
|
||||
virtual bool GetNetworkStatistics(
|
||||
NetworkStatistics* network_statistics) OVERRIDE;
|
||||
|
||||
virtual bool EnableNack(size_t max_nack_list_size) OVERRIDE;
|
||||
|
||||
|
@ -909,7 +909,7 @@ class AudioCodingModule: public Module {
|
||||
//
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// int32_t NetworkStatistics()
|
||||
// int32_t GetNetworkStatistics()
|
||||
// Get network statistics. Note that the internal statistics of NetEq are
|
||||
// reset by this call.
|
||||
//
|
||||
@ -920,8 +920,8 @@ class AudioCodingModule: public Module {
|
||||
// -1 if failed to set the network statistics,
|
||||
// 0 if statistics are set successfully.
|
||||
//
|
||||
virtual int32_t NetworkStatistics(
|
||||
ACMNetworkStatistics* network_statistics) = 0;
|
||||
virtual int32_t GetNetworkStatistics(
|
||||
NetworkStatistics* network_statistics) = 0;
|
||||
|
||||
//
|
||||
// Set an initial delay for playout.
|
||||
@ -1107,7 +1107,7 @@ class AudioCoding {
|
||||
|
||||
// Returns the network statistics. Note that the internal statistics of NetEq
|
||||
// are reset by this call. Returns true if successful, false otherwise.
|
||||
virtual bool NetworkStatistics(ACMNetworkStatistics* network_statistics) = 0;
|
||||
virtual bool GetNetworkStatistics(NetworkStatistics* network_statistics) = 0;
|
||||
|
||||
// Enables NACK and sets the maximum size of the NACK list. If NACK is already
|
||||
// enabled then the maximum NACK list size is modified accordingly. Returns
|
||||
|
@ -144,48 +144,6 @@ enum ACMAMRPackingFormat {
|
||||
AMRFileStorage = 2
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Struct containing network statistics
|
||||
//
|
||||
// -currentBufferSize : current jitter buffer size in ms
|
||||
// -preferredBufferSize : preferred (optimal) buffer size in ms
|
||||
// -jitterPeaksFound : indicate if peaky-jitter mode is engaged, that is,
|
||||
// if severe but sparse network delays have occurred.
|
||||
// -currentPacketLossRate : loss rate (network + late) (in Q14)
|
||||
// -currentDiscardRate : late loss rate (in Q14)
|
||||
// -currentExpandRate : fraction (of original stream) of synthesized
|
||||
// speech inserted through expansion (in Q14)
|
||||
// -currentPreemptiveRate : fraction of synthesized speech inserted through
|
||||
// pre-emptive expansion (in Q14)
|
||||
// -currentAccelerateRate : fraction of data removed through acceleration
|
||||
// (in Q14)
|
||||
// -clockDriftPPM : clock-drift between sender and receiver in parts-
|
||||
// per-million. Positive means that receiver sample
|
||||
// rate is higher than sender sample rate.
|
||||
// -meanWaitingTimeMs : average packet waiting time in the buffer
|
||||
// -medianWaitingTimeMs : median packet waiting time in the buffer
|
||||
// -minWaitingTimeMs : min packet waiting time in the buffer
|
||||
// -maxWaitingTimeMs : max packet waiting time in the buffer
|
||||
// -addedSamples : samples inserted because of packet loss in off mode
|
||||
typedef struct {
|
||||
uint16_t currentBufferSize;
|
||||
uint16_t preferredBufferSize;
|
||||
bool jitterPeaksFound;
|
||||
uint16_t currentPacketLossRate;
|
||||
uint16_t currentDiscardRate;
|
||||
uint16_t currentExpandRate;
|
||||
uint16_t currentPreemptiveRate;
|
||||
uint16_t currentAccelerateRate;
|
||||
int32_t clockDriftPPM;
|
||||
int meanWaitingTimeMs;
|
||||
int medianWaitingTimeMs;
|
||||
int minWaitingTimeMs;
|
||||
int maxWaitingTimeMs;
|
||||
int addedSamples;
|
||||
} ACMNetworkStatistics;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Enumeration of background noise mode a mapping from NetEQ interface.
|
||||
|
@ -785,8 +785,8 @@ void APITest::TestDelay(char side) {
|
||||
|
||||
*myMinDelay = (rand() % 1000) + 1;
|
||||
|
||||
ACMNetworkStatistics networkStat;
|
||||
CHECK_ERROR_MT(myACM->NetworkStatistics(&networkStat));
|
||||
NetworkStatistics networkStat;
|
||||
CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
|
||||
|
||||
if (!_randomTest) {
|
||||
fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
|
||||
@ -803,10 +803,14 @@ void APITest::TestDelay(char side) {
|
||||
networkStat.currentDiscardRate);
|
||||
fprintf(stdout, "expand rate............. %d\n",
|
||||
networkStat.currentExpandRate);
|
||||
fprintf(stdout, "speech expand rate...... %d\n",
|
||||
networkStat.currentSpeechExpandRate);
|
||||
fprintf(stdout, "Preemptive rate......... %d\n",
|
||||
networkStat.currentPreemptiveRate);
|
||||
fprintf(stdout, "Accelerate rate......... %d\n",
|
||||
networkStat.currentAccelerateRate);
|
||||
fprintf(stdout, "Secondary decoded rate.. %d\n",
|
||||
networkStat.currentSecondaryDecodedRate);
|
||||
fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
|
||||
fprintf(stdout, "Mean waiting time....... %d\n",
|
||||
networkStat.meanWaitingTimeMs);
|
||||
|
@ -196,8 +196,8 @@ class DelayTest {
|
||||
|
||||
// Print delay information every 16 frame
|
||||
if ((num_frames & 0x3F) == 0x3F) {
|
||||
ACMNetworkStatistics statistics;
|
||||
acm_b_->NetworkStatistics(&statistics);
|
||||
NetworkStatistics statistics;
|
||||
acm_b_->GetNetworkStatistics(&statistics);
|
||||
fprintf(stdout, "delay: min=%3d max=%3d mean=%3d median=%3d"
|
||||
" ts-based average = %6.3f, "
|
||||
"curr buff-lev = %4u opt buff-lev = %4u \n",
|
||||
|
@ -219,8 +219,8 @@ class InsertPacketWithTiming {
|
||||
|
||||
// Jitter buffer delay.
|
||||
void Delay(int* optimal_delay, int* current_delay) {
|
||||
ACMNetworkStatistics statistics;
|
||||
receive_acm_->NetworkStatistics(&statistics);
|
||||
NetworkStatistics statistics;
|
||||
receive_acm_->GetNetworkStatistics(&statistics);
|
||||
*optimal_delay = statistics.preferredBufferSize;
|
||||
*current_delay = statistics.currentBufferSize;
|
||||
}
|
||||
|
@ -185,8 +185,8 @@ class TargetDelayTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
int GetCurrentOptimalDelayMs() {
|
||||
ACMNetworkStatistics stats;
|
||||
acm_->NetworkStatistics(&stats);
|
||||
NetworkStatistics stats;
|
||||
acm_->GetNetworkStatistics(&stats);
|
||||
return stats.preferredBufferSize;
|
||||
}
|
||||
|
||||
|
@ -3686,12 +3686,7 @@ Channel::GetNetworkStatistics(NetworkStatistics& stats)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
|
||||
"Channel::GetNetworkStatistics()");
|
||||
ACMNetworkStatistics acm_stats;
|
||||
int return_value = audio_coding_->NetworkStatistics(&acm_stats);
|
||||
if (return_value >= 0) {
|
||||
memcpy(&stats, &acm_stats, sizeof(NetworkStatistics));
|
||||
}
|
||||
return return_value;
|
||||
return audio_coding_->GetNetworkStatistics(&stats);
|
||||
}
|
||||
|
||||
void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const {
|
||||
|
@ -23,31 +23,35 @@ TEST_F(NetEQStatsTest, ManualPrintStatisticsAfterRunningAWhile) {
|
||||
|
||||
TEST_LOG("Inspect these statistics and ensure they make sense.\n");
|
||||
|
||||
TEST_LOG(" currentAccelerateRate = %hu \n",
|
||||
TEST_LOG(" currentAccelerateRate = %hu \n",
|
||||
network_statistics.currentAccelerateRate);
|
||||
TEST_LOG(" currentBufferSize = %hu \n",
|
||||
TEST_LOG(" currentBufferSize = %hu \n",
|
||||
network_statistics.currentBufferSize);
|
||||
TEST_LOG(" currentDiscardRate = %hu \n",
|
||||
TEST_LOG(" currentSecondaryDecodedRate = %hu \n",
|
||||
network_statistics.currentSecondaryDecodedRate);
|
||||
TEST_LOG(" currentDiscardRate = %hu \n",
|
||||
network_statistics.currentDiscardRate);
|
||||
TEST_LOG(" currentExpandRate = %hu \n",
|
||||
TEST_LOG(" currentExpandRate = %hu \n",
|
||||
network_statistics.currentExpandRate);
|
||||
TEST_LOG(" currentPacketLossRate = %hu \n",
|
||||
TEST_LOG(" currentPacketLossRate = %hu \n",
|
||||
network_statistics.currentPacketLossRate);
|
||||
TEST_LOG(" currentPreemptiveRate = %hu \n",
|
||||
TEST_LOG(" currentPreemptiveRate = %hu \n",
|
||||
network_statistics.currentPreemptiveRate);
|
||||
TEST_LOG(" preferredBufferSize = %hu \n",
|
||||
TEST_LOG(" currentSpeechExpandRate = %hu \n",
|
||||
network_statistics.currentSpeechExpandRate);
|
||||
TEST_LOG(" preferredBufferSize = %hu \n",
|
||||
network_statistics.preferredBufferSize);
|
||||
TEST_LOG(" jitterPeaksFound = %i \n",
|
||||
TEST_LOG(" jitterPeaksFound = %i \n",
|
||||
network_statistics.jitterPeaksFound);
|
||||
TEST_LOG(" clockDriftPPM = %i \n",
|
||||
TEST_LOG(" clockDriftPPM = %i \n",
|
||||
network_statistics.clockDriftPPM);
|
||||
TEST_LOG(" meanWaitingTimeMs = %i \n",
|
||||
TEST_LOG(" meanWaitingTimeMs = %i \n",
|
||||
network_statistics.meanWaitingTimeMs);
|
||||
TEST_LOG(" medianWaitingTimeMs = %i \n",
|
||||
TEST_LOG(" medianWaitingTimeMs = %i \n",
|
||||
network_statistics.medianWaitingTimeMs);
|
||||
TEST_LOG(" minWaitingTimeMs = %i \n",
|
||||
TEST_LOG(" minWaitingTimeMs = %i \n",
|
||||
network_statistics.minWaitingTimeMs);
|
||||
TEST_LOG(" maxWaitingTimeMs = %i \n",
|
||||
TEST_LOG(" maxWaitingTimeMs = %i \n",
|
||||
network_statistics.maxWaitingTimeMs);
|
||||
|
||||
// This is only set to a non-zero value in off-mode.
|
||||
|
Loading…
Reference in New Issue
Block a user