Fix the chain that propagates the audio frame's rtp and ntp timestamp including:
* In AudioCodingModuleImpl::PlayoutData10Ms, don't reset the timestamp got from GetAudio.
* When there're more than one participant, set AudioFrame's RTP timestamp to 0.
* Copy ntp_time_ms_ in AudioFrame::CopyFrom method.
* In RemixAndResample, pass src frame's timestamp_ and ntp_time_ms_ to the dst frame.
* Fix how |elapsed_time_ms| is computed in channel.cc by adding GetPlayoutFrequency.
Tweaks on ntp_time_ms_:
* Init ntp_time_ms_ to -1 in AudioFrame ctor.
* When there're more than one participant, set AudioFrame's ntp_time_ms_ to an invalid value. I.e. we don't support ntp_time_ms_ in multiple participants case before the mixing is moved to chrome.
Added elapsed_time_ms to AudioFrame and pass it to chrome, where we don't have the information about the rtp timestmp's sample rate, i.e. can't convert rtp timestamp to ms.
BUG=3111
R=henrik.lundin@webrtc.org, turaj@webrtc.org, xians@webrtc.org
TBR=andrew
andrew to take another look on audio_conference_mixer_impl.cc
Review URL: https://webrtc-codereview.appspot.com/14559004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@6346 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/neteq4/interface/neteq.h b/webrtc/modules/audio_coding/neteq4/interface/neteq.h
index 763da31..79a5dfb 100644
--- a/webrtc/modules/audio_coding/neteq4/interface/neteq.h
+++ b/webrtc/modules/audio_coding/neteq4/interface/neteq.h
@@ -228,8 +228,9 @@
// Disables post-decode VAD.
virtual void DisableVad() = 0;
- // Returns the RTP timestamp for the last sample delivered by GetAudio().
- virtual uint32_t PlayoutTimestamp() = 0;
+ // Gets the RTP timestamp for the last sample delivered by GetAudio().
+ // Returns true if the RTP timestamp is valid, otherwise false.
+ virtual bool GetPlayoutTimestamp(uint32_t* timestamp) = 0;
// Not implemented.
virtual int SetTargetNumberOfChannels() = 0;
diff --git a/webrtc/modules/audio_coding/neteq4/neteq_impl.cc b/webrtc/modules/audio_coding/neteq4/neteq_impl.cc
index 963a820..f860766 100644
--- a/webrtc/modules/audio_coding/neteq4/neteq_impl.cc
+++ b/webrtc/modules/audio_coding/neteq4/neteq_impl.cc
@@ -335,9 +335,15 @@
vad_->Disable();
}
-uint32_t NetEqImpl::PlayoutTimestamp() {
+bool NetEqImpl::GetPlayoutTimestamp(uint32_t* timestamp) {
CriticalSectionScoped lock(crit_sect_.get());
- return timestamp_scaler_->ToExternal(playout_timestamp_);
+ if (first_packet_) {
+ // We don't have a valid RTP timestamp until we have decoded our first
+ // RTP packet.
+ return false;
+ }
+ *timestamp = timestamp_scaler_->ToExternal(playout_timestamp_);
+ return true;
}
int NetEqImpl::LastError() {
diff --git a/webrtc/modules/audio_coding/neteq4/neteq_impl.h b/webrtc/modules/audio_coding/neteq4/neteq_impl.h
index 751de66..822a523 100644
--- a/webrtc/modules/audio_coding/neteq4/neteq_impl.h
+++ b/webrtc/modules/audio_coding/neteq4/neteq_impl.h
@@ -166,8 +166,7 @@
// Disables post-decode VAD.
virtual void DisableVad();
- // Returns the RTP timestamp for the last sample delivered by GetAudio().
- virtual uint32_t PlayoutTimestamp();
+ virtual bool GetPlayoutTimestamp(uint32_t* timestamp);
virtual int SetTargetNumberOfChannels() { return kNotImplemented; }
diff --git a/webrtc/modules/audio_coding/neteq4/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq4/neteq_impl_unittest.cc
index aedd8d5..26279aa 100644
--- a/webrtc/modules/audio_coding/neteq4/neteq_impl_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq4/neteq_impl_unittest.cc
@@ -477,8 +477,10 @@
// The value of the last of the output samples is the same as the number of
// samples played from the decoded packet. Thus, this number + the RTP
// timestamp should match the playout timestamp.
+ uint32_t timestamp = 0;
+ EXPECT_TRUE(neteq_->GetPlayoutTimestamp(×tamp));
EXPECT_EQ(rtp_header.header.timestamp + output[samples_per_channel - 1],
- neteq_->PlayoutTimestamp());
+ timestamp);
// Check the timestamp for the last value in the sync buffer. This should
// be one full frame length ahead of the RTP timestamp.
diff --git a/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc
index f66a3cf..c1a7e16 100644
--- a/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc
@@ -228,6 +228,8 @@
void DuplicateCng();
+ uint32_t PlayoutTimestamp();
+
NetEq* neteq_;
FILE* rtp_fp_;
unsigned int sim_clock_;
@@ -736,7 +738,7 @@
}
EXPECT_EQ(kOutputNormal, type);
- int32_t delay_before = timestamp - neteq_->PlayoutTimestamp();
+ int32_t delay_before = timestamp - PlayoutTimestamp();
// Insert CNG for 1 minute (= 60000 ms).
const int kCngPeriodMs = 100;
@@ -829,7 +831,7 @@
// Check that the speech starts again within reasonable time.
double time_until_speech_returns_ms = t_ms - speech_restart_time_ms;
EXPECT_LT(time_until_speech_returns_ms, max_time_to_speech_ms);
- int32_t delay_after = timestamp - neteq_->PlayoutTimestamp();
+ int32_t delay_after = timestamp - PlayoutTimestamp();
// Compare delay before and after, and make sure it differs less than 20 ms.
EXPECT_LE(delay_after, delay_before + delay_tolerance_ms * 16);
EXPECT_GE(delay_after, delay_before - delay_tolerance_ms * 16);
@@ -1310,7 +1312,7 @@
ASSERT_EQ(1, num_channels);
// Expect delay (in samples) to be less than 2 packets.
- EXPECT_LE(timestamp - neteq_->PlayoutTimestamp(),
+ EXPECT_LE(timestamp - PlayoutTimestamp(),
static_cast<uint32_t>(kSamples * 2));
}
// Make sure we have actually tested wrap-around.
@@ -1391,7 +1393,7 @@
kMaxBlockSize, out_data_, &out_len, &num_channels, &type));
ASSERT_EQ(kBlockSize16kHz, out_len);
EXPECT_EQ(kOutputCNG, type);
- EXPECT_EQ(timestamp - algorithmic_delay_samples, neteq_->PlayoutTimestamp());
+ EXPECT_EQ(timestamp - algorithmic_delay_samples, PlayoutTimestamp());
// Insert the same CNG packet again. Note that at this point it is old, since
// we have already decoded the first copy of it.
@@ -1406,7 +1408,7 @@
ASSERT_EQ(kBlockSize16kHz, out_len);
EXPECT_EQ(kOutputCNG, type);
EXPECT_EQ(timestamp - algorithmic_delay_samples,
- neteq_->PlayoutTimestamp());
+ PlayoutTimestamp());
}
// Insert speech again.
@@ -1422,7 +1424,13 @@
ASSERT_EQ(kBlockSize16kHz, out_len);
EXPECT_EQ(kOutputNormal, type);
EXPECT_EQ(timestamp + kSamples - algorithmic_delay_samples,
- neteq_->PlayoutTimestamp());
+ PlayoutTimestamp());
+}
+
+uint32_t NetEqDecodingTest::PlayoutTimestamp() {
+ uint32_t playout_timestamp = 0;
+ EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&playout_timestamp));
+ return playout_timestamp;
}
TEST_F(NetEqDecodingTest, DiscardDuplicateCng) { DuplicateCng(); }