Change NetEq::GetPlayoutTimestamp to return an rtc::Optional<uint32_t>

This is in preparation for changes to when the playout timestamp is
valid.

BUG=webrtc:5669

Review URL: https://codereview.webrtc.org/1853183002

Cr-Commit-Position: refs/heads/master@{#12256}
diff --git a/webrtc/modules/audio_coding/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/acm2/acm_receiver.cc
index 5649f07..925e99c 100644
--- a/webrtc/modules/audio_coding/acm2/acm_receiver.cc
+++ b/webrtc/modules/audio_coding/acm2/acm_receiver.cc
@@ -196,9 +196,10 @@
   // |GetPlayoutTimestamp|, which is the timestamp of the last sample of
   // |audio_frame|.
   // TODO(henrik.lundin) Move setting of audio_frame->timestamp_ inside NetEq.
-  uint32_t playout_timestamp = 0;
-  if (GetPlayoutTimestamp(&playout_timestamp)) {
-    audio_frame->timestamp_ = playout_timestamp -
+  rtc::Optional<uint32_t> playout_timestamp = GetPlayoutTimestamp();
+  if (playout_timestamp) {
+    audio_frame->timestamp_ =
+        *playout_timestamp -
         static_cast<uint32_t>(audio_frame->samples_per_channel_);
   } else {
     // Remain 0 until we have a valid |playout_timestamp|.
@@ -318,8 +319,8 @@
   return 0;
 }
 
-bool AcmReceiver::GetPlayoutTimestamp(uint32_t* timestamp) {
-  return neteq_->GetPlayoutTimestamp(timestamp);
+rtc::Optional<uint32_t> AcmReceiver::GetPlayoutTimestamp() {
+  return neteq_->GetPlayoutTimestamp();
 }
 
 int AcmReceiver::LastAudioCodec(CodecInst* codec) const {
diff --git a/webrtc/modules/audio_coding/acm2/acm_receiver.h b/webrtc/modules/audio_coding/acm2/acm_receiver.h
index 77eb563..6fec1ff 100644
--- a/webrtc/modules/audio_coding/acm2/acm_receiver.h
+++ b/webrtc/modules/audio_coding/acm2/acm_receiver.h
@@ -195,11 +195,9 @@
   //
   int RemoveAllCodecs();
 
-  //
-  // Gets the RTP timestamp of the last sample delivered by GetAudio().
-  // Returns true if the RTP timestamp is valid, otherwise false.
-  //
-  bool GetPlayoutTimestamp(uint32_t* timestamp);
+  // Returns the RTP timestamp for the last sample delivered by GetAudio().
+  // The return value will be empty if no valid timestamp is available.
+  rtc::Optional<uint32_t> GetPlayoutTimestamp();
 
   //
   // Get the audio codec associated with the last non-CNG/non-DTMF received
diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.cc
index d30daaa..254c2f4 100644
--- a/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.cc
+++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.cc
@@ -902,8 +902,16 @@
   return encoder_stack_->SetDtx(false) ? 0 : -1;
 }
 
-int AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) {
-  return receiver_.GetPlayoutTimestamp(timestamp) ? 0 : -1;
+int32_t AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) {
+  rtc::Optional<uint32_t> ts = PlayoutTimestamp();
+  if (!ts)
+    return -1;
+  *timestamp = *ts;
+  return 0;
+}
+
+rtc::Optional<uint32_t> AudioCodingModuleImpl::PlayoutTimestamp() {
+  return receiver_.GetPlayoutTimestamp();
 }
 
 bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const {
diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h
index e463d29..63dfb81 100644
--- a/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h
+++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h
@@ -157,8 +157,9 @@
   // Smallest latency NetEq will maintain.
   int LeastRequiredDelayMs() const override;
 
-  // Get playout timestamp.
-  int PlayoutTimestamp(uint32_t* timestamp) override;
+  RTC_DEPRECATED int32_t PlayoutTimestamp(uint32_t* timestamp) override;
+
+  rtc::Optional<uint32_t> PlayoutTimestamp() override;
 
   // Get 10 milliseconds of raw audio data to play out, and
   // automatic resample to the requested frequency if > 0.
diff --git a/webrtc/modules/audio_coding/include/audio_coding_module.h b/webrtc/modules/audio_coding/include/audio_coding_module.h
index 305d8ea..381e35e 100644
--- a/webrtc/modules/audio_coding/include/audio_coding_module.h
+++ b/webrtc/modules/audio_coding/include/audio_coding_module.h
@@ -14,6 +14,7 @@
 #include <string>
 #include <vector>
 
+#include "webrtc/base/deprecation.h"
 #include "webrtc/base/optional.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h"
@@ -647,7 +648,6 @@
   //
   virtual int LeastRequiredDelayMs() const = 0;
 
-  ///////////////////////////////////////////////////////////////////////////
   // int32_t PlayoutTimestamp()
   // The send timestamp of an RTP packet is associated with the decoded
   // audio of the packet in question. This function returns the timestamp of
@@ -660,8 +660,16 @@
   //    0 if the output is a correct timestamp.
   //   -1 if failed to output the correct timestamp.
   //
-  // TODO(tlegrand): Change function to return the timestamp.
-  virtual int32_t PlayoutTimestamp(uint32_t* timestamp) = 0;
+  RTC_DEPRECATED virtual int32_t PlayoutTimestamp(uint32_t* timestamp) = 0;
+
+  ///////////////////////////////////////////////////////////////////////////
+  // int32_t PlayoutTimestamp()
+  // The send timestamp of an RTP packet is associated with the decoded
+  // audio of the packet in question. This function returns the timestamp of
+  // the latest audio obtained by calling PlayoutData10ms(), or empty if no
+  // valid timestamp is available.
+  //
+  virtual rtc::Optional<uint32_t> PlayoutTimestamp() = 0;
 
   ///////////////////////////////////////////////////////////////////////////
   // int32_t PlayoutData10Ms(
diff --git a/webrtc/modules/audio_coding/neteq/include/neteq.h b/webrtc/modules/audio_coding/neteq/include/neteq.h
index 5e06d48..5b52424 100644
--- a/webrtc/modules/audio_coding/neteq/include/neteq.h
+++ b/webrtc/modules/audio_coding/neteq/include/neteq.h
@@ -16,6 +16,7 @@
 #include <string>
 
 #include "webrtc/base/constructormagic.h"
+#include "webrtc/base/optional.h"
 #include "webrtc/common_types.h"
 #include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
 #include "webrtc/typedefs.h"
@@ -243,9 +244,9 @@
   // Disables post-decode VAD.
   virtual void DisableVad() = 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;
+  // Returns the RTP timestamp for the last sample delivered by GetAudio().
+  // The return value will be empty if no valid timestamp is available.
+  virtual rtc::Optional<uint32_t> GetPlayoutTimestamp() = 0;
 
   // Returns the sample rate in Hz of the audio produced in the last GetAudio
   // call. If GetAudio has not been called yet, the configured sample rate
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
index aa97381..b4dfc99 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
@@ -401,15 +401,15 @@
   vad_->Disable();
 }
 
-bool NetEqImpl::GetPlayoutTimestamp(uint32_t* timestamp) {
+rtc::Optional<uint32_t> NetEqImpl::GetPlayoutTimestamp() {
   rtc::CritScope lock(&crit_sect_);
   if (first_packet_) {
     // We don't have a valid RTP timestamp until we have decoded our first
     // RTP packet.
-    return false;
+    return rtc::Optional<uint32_t>();
   }
-  *timestamp = timestamp_scaler_->ToExternal(playout_timestamp_);
-  return true;
+  return rtc::Optional<uint32_t>(
+      timestamp_scaler_->ToExternal(playout_timestamp_));
 }
 
 int NetEqImpl::last_output_sample_rate_hz() const {
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.h b/webrtc/modules/audio_coding/neteq/neteq_impl.h
index 514fdaa..737efd4 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.h
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.h
@@ -160,7 +160,7 @@
   // Disables post-decode VAD.
   void DisableVad() override;
 
-  bool GetPlayoutTimestamp(uint32_t* timestamp) override;
+  rtc::Optional<uint32_t> GetPlayoutTimestamp() override;
 
   int last_output_sample_rate_hz() const override;
 
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
index e1eb403..1353d10 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -478,11 +478,11 @@
   // 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(&timestamp));
-  EXPECT_EQ(rtp_header.header.timestamp +
-                output.data_[output.samples_per_channel_ - 1],
-            timestamp);
+  // Wrap the expected value in an rtc::Optional to compare them as such.
+  EXPECT_EQ(
+      rtc::Optional<uint32_t>(rtp_header.header.timestamp +
+                              output.data_[output.samples_per_channel_ - 1]),
+      neteq_->GetPlayoutTimestamp());
 
   // Check the timestamp for the last value in the sync buffer. This should
   // be one full frame length ahead of the RTP timestamp.
@@ -714,8 +714,6 @@
 
   const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
   AudioFrame output;
-  uint32_t timestamp;
-  uint32_t last_timestamp;
   AudioFrame::SpeechType expected_type[8] = {
       AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech,
       AudioFrame::kCNG, AudioFrame::kCNG,
@@ -731,16 +729,19 @@
   };
 
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
-  EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&last_timestamp));
+  rtc::Optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
+  ASSERT_TRUE(last_timestamp);
 
   for (size_t i = 1; i < 6; ++i) {
     ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
     EXPECT_EQ(1u, output.num_channels_);
     EXPECT_EQ(expected_type[i - 1], output.speech_type_);
-    EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&timestamp));
+    rtc::Optional<uint32_t> timestamp = neteq_->GetPlayoutTimestamp();
+    EXPECT_TRUE(timestamp);
     EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
-    EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&timestamp));
-    EXPECT_EQ(timestamp, last_timestamp + expected_timestamp_increment[i]);
+    timestamp = neteq_->GetPlayoutTimestamp();
+    ASSERT_TRUE(timestamp);
+    EXPECT_EQ(*timestamp, *last_timestamp + expected_timestamp_increment[i]);
     last_timestamp = timestamp;
   }
 
@@ -756,8 +757,9 @@
     EXPECT_EQ(1u, output.num_channels_);
     EXPECT_EQ(expected_type[i - 1], output.speech_type_);
     EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
-    EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&timestamp));
-    EXPECT_EQ(timestamp, last_timestamp + expected_timestamp_increment[i]);
+    rtc::Optional<uint32_t> timestamp = neteq_->GetPlayoutTimestamp();
+    ASSERT_TRUE(timestamp);
+    EXPECT_EQ(*timestamp, *last_timestamp + expected_timestamp_increment[i]);
     last_timestamp = timestamp;
   }
 
diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
index 340cf58..00a878c 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
@@ -1522,9 +1522,9 @@
 }
 
 uint32_t NetEqDecodingTest::PlayoutTimestamp() {
-  uint32_t playout_timestamp = 0;
-  EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&playout_timestamp));
-  return playout_timestamp;
+  rtc::Optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
+  EXPECT_TRUE(playout_timestamp);
+  return playout_timestamp.value_or(0);
 }
 
 TEST_F(NetEqDecodingTest, DiscardDuplicateCng) { DuplicateCng(); }
@@ -1570,5 +1570,4 @@
   // Verify speech output.
   EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
 }
-
 }  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/test/APITest.cc b/webrtc/modules/audio_coding/test/APITest.cc
index bf04d7c..a2506ba 100644
--- a/webrtc/modules/audio_coding/test/APITest.cc
+++ b/webrtc/modules/audio_coding/test/APITest.cc
@@ -666,7 +666,6 @@
   EventTimerWrapper* myEvent = EventTimerWrapper::Create();
 
   uint32_t inTimestamp = 0;
-  uint32_t outTimestamp = 0;
   double estimDelay = 0;
 
   double averageEstimDelay = 0;
@@ -688,7 +687,8 @@
   CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
 
   inTimestamp = myChannel->LastInTimestamp();
-  CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
+  rtc::Optional<uint32_t> outTimestamp = myACM->PlayoutTimestamp();
+  CHECK_ERROR_MT(outTimestamp ? 0 : -1);
 
   if (!_randomTest) {
     myEvent->StartTimer(true, 30);
@@ -698,11 +698,12 @@
       myEvent->Wait(1000);
 
       inTimestamp = myChannel->LastInTimestamp();
-      CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
+      outTimestamp = myACM->PlayoutTimestamp();
+      CHECK_ERROR_MT(outTimestamp ? 0 : -1);
 
       //std::cout << outTimestamp << std::endl << std::flush;
-      estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
-          / ((double) myACM->ReceiveFrequency() / 1000.0);
+      estimDelay = (double)((uint32_t)(inTimestamp - *outTimestamp)) /
+                   ((double)myACM->ReceiveFrequency() / 1000.0);
 
       estimDelayCB.Update(estimDelay);
 
diff --git a/webrtc/modules/audio_coding/test/delay_test.cc b/webrtc/modules/audio_coding/test/delay_test.cc
index 7288d50..8fa1fb1 100644
--- a/webrtc/modules/audio_coding/test/delay_test.cc
+++ b/webrtc/modules/audio_coding/test/delay_test.cc
@@ -180,7 +180,6 @@
 
     int num_frames = 0;
     int in_file_frames = 0;
-    uint32_t playout_ts;
     uint32_t received_ts;
     double average_delay = 0;
     double inst_delay_sec = 0;
@@ -209,10 +208,11 @@
       out_file_b_.Write10MsData(
           audio_frame.data_,
           audio_frame.samples_per_channel_ * audio_frame.num_channels_);
-      acm_b_->PlayoutTimestamp(&playout_ts);
       received_ts = channel_a2b_->LastInTimestamp();
-      inst_delay_sec = static_cast<uint32_t>(received_ts - playout_ts)
-          / static_cast<double>(encoding_sample_rate_hz_);
+      rtc::Optional<uint32_t> playout_timestamp = acm_b_->PlayoutTimestamp();
+      ASSERT_TRUE(playout_timestamp);
+      inst_delay_sec = static_cast<uint32_t>(received_ts - *playout_timestamp) /
+                       static_cast<double>(encoding_sample_rate_hz_);
 
       if (num_frames > 10)
         average_delay = 0.95 * average_delay + 0.05 * inst_delay_sec;