Bug 981680 - Upstream webrtc patch for avsync (r5102). rs=jesup, a=sledru
authorRandell Jesup <rjesup@jesup.org>
Tue, 11 Mar 2014 00:36:12 -0400
changeset 183304 db6787d76538644bd663339f2dba5016b3de7bbe
parent 183303 ffbf8e6aa0f229150384de2d6f23f4819284da12
child 183305 5afb2b0805a59fb64177a07f246cc3e9c99402b0
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup, sledru
bugs981680
milestone29.0a2
Bug 981680 - Upstream webrtc patch for avsync (r5102). rs=jesup, a=sledru
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_receiver.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc
media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
media/webrtc/trunk/webrtc/video_engine/vie_receiver.cc
media/webrtc/trunk/webrtc/video_engine/vie_receiver.h
media/webrtc/trunk/webrtc/video_engine/vie_sync_module.cc
media/webrtc/trunk/webrtc/voice_engine/channel.cc
media/webrtc/trunk/webrtc/voice_engine/channel.h
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_receiver.h
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_receiver.h
@@ -77,20 +77,22 @@ class RtpReceiver {
                                  bool in_order) = 0;
 
   // Returns the currently configured NACK method.
   virtual NACKMethod NACK() const = 0;
 
   // Turn negative acknowledgement (NACK) requests on/off.
   virtual void SetNACKStatus(const NACKMethod method) = 0;
 
-  // Returns the last received timestamp.
-  virtual uint32_t Timestamp() const = 0;
-  // Returns the time in milliseconds when the last timestamp was received.
-  virtual int32_t LastReceivedTimeMs() const = 0;
+  // Gets the last received timestamp. Returns true if a packet has been
+  // received, false otherwise.
+  virtual bool Timestamp(uint32_t* timestamp) const = 0;
+  // Gets the time in milliseconds when the last timestamp was received.
+  // Returns true if a packet has been received, false otherwise.
+  virtual bool LastReceivedTimeMs(int64_t* receive_time_ms) const = 0;
 
   // Returns the remote SSRC of the currently received RTP stream.
   virtual uint32_t SSRC() const = 0;
 
   // Returns the current remote CSRCs.
   virtual int32_t CSRCs(uint32_t array_of_csrc[kRtpCsrcSize]) const = 0;
 
   // Returns the current energy of the RTP stream received.
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc
@@ -75,17 +75,17 @@ RtpReceiverImpl::RtpReceiverImpl(int32_t
       critical_section_rtp_receiver_(
         CriticalSectionWrapper::CreateCriticalSection()),
       last_receive_time_(0),
       last_received_payload_length_(0),
       ssrc_(0),
       num_csrcs_(0),
       current_remote_csrc_(),
       last_received_timestamp_(0),
-      last_received_frame_time_ms_(0),
+      last_received_frame_time_ms_(-1),
       last_received_sequence_number_(0),
       nack_method_(kNackOff) {
   assert(incoming_audio_messages_callback);
   assert(incoming_messages_callback);
 
   memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_));
 
   WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
@@ -223,28 +223,30 @@ bool RtpReceiverImpl::IncomingRtpPacket(
   WebRtcRTPHeader webrtc_rtp_header;
   memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header));
   webrtc_rtp_header.header = rtp_header;
   CheckCSRC(webrtc_rtp_header);
 
   uint16_t payload_data_length = payload_length - rtp_header.paddingLength;
 
   bool is_first_packet_in_frame = false;
-  bool is_first_packet = false;
   {
     CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
-    is_first_packet_in_frame =
+    if (HaveReceivedFrame()) {
+      is_first_packet_in_frame =
           last_received_sequence_number_ + 1 == rtp_header.sequenceNumber &&
-          Timestamp() != rtp_header.timestamp;
-    is_first_packet = is_first_packet_in_frame || last_receive_time_ == 0;
+          last_received_timestamp_ != rtp_header.timestamp;
+    } else {
+      is_first_packet_in_frame = true;
+    }
   }
 
   int32_t ret_val = rtp_media_receiver_->ParseRtpPacket(
       &webrtc_rtp_header, payload_specific, is_red, payload, payload_length,
-      clock_->TimeInMilliseconds(), is_first_packet);
+      clock_->TimeInMilliseconds(), is_first_packet_in_frame);
 
   if (ret_val < 0) {
     return false;
   }
 
   {
     CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
 
@@ -261,24 +263,34 @@ bool RtpReceiverImpl::IncomingRtpPacket(
   }
   return true;
 }
 
 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
   return rtp_media_receiver_->GetTelephoneEventHandler();
 }
 
-uint32_t RtpReceiverImpl::Timestamp() const {
+bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const {
   CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
-  return last_received_timestamp_;
+  if (!HaveReceivedFrame())
+    return false;
+  *timestamp = last_received_timestamp_;
+  return true;
 }
 
-int32_t RtpReceiverImpl::LastReceivedTimeMs() const {
+bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const {
   CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
-  return last_received_frame_time_ms_;
+  if (!HaveReceivedFrame())
+    return false;
+  *receive_time_ms = last_received_frame_time_ms_;
+  return true;
+}
+
+bool RtpReceiverImpl::HaveReceivedFrame() const {
+  return last_received_frame_time_ms_ >= 0;
 }
 
 // Implementation note: must not hold critsect when called.
 void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
   bool new_ssrc = false;
   bool re_initialize_decoder = false;
   char payload_name[RTP_PAYLOAD_NAME_SIZE];
   uint8_t channels = 1;
@@ -293,17 +305,17 @@ void RtpReceiverImpl::CheckSSRCChanged(c
         (last_received_payload_type == -1 && ssrc_ == 0)) {
       // We need the payload_type_ to make the call if the remote SSRC is 0.
       new_ssrc = true;
 
       cb_rtp_feedback_->ResetStatistics(ssrc_);
 
       last_received_timestamp_ = 0;
       last_received_sequence_number_ = 0;
-      last_received_frame_time_ms_ = 0;
+      last_received_frame_time_ms_ = -1;
 
       // Do we have a SSRC? Then the stream is restarted.
       if (ssrc_ != 0) {
         // Do we have the same codec? Then re-initialize coder.
         if (rtp_header.payloadType == last_received_payload_type) {
           re_initialize_decoder = true;
 
           Payload* payload;
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h
@@ -53,18 +53,18 @@ class RtpReceiverImpl : public RtpReceiv
       bool in_order);
 
   NACKMethod NACK() const;
 
   // Turn negative acknowledgement requests on/off.
   void SetNACKStatus(const NACKMethod method);
 
   // Returns the last received timestamp.
-  virtual uint32_t Timestamp() const;
-  int32_t LastReceivedTimeMs() const;
+  bool Timestamp(uint32_t* timestamp) const;
+  bool LastReceivedTimeMs(int64_t* receive_time_ms) const;
 
   uint32_t SSRC() const;
 
   int32_t CSRCs(uint32_t array_of_csrc[kRtpCsrcSize]) const;
 
   int32_t Energy(uint8_t array_of_energy[kRtpCsrcSize]) const;
 
   // RTX.
@@ -72,16 +72,18 @@ class RtpReceiverImpl : public RtpReceiv
 
   void RTXStatus(bool* enable, uint32_t* ssrc, int* payload_type) const;
 
   void SetRtxPayloadType(int payload_type);
 
   TelephoneEventHandler* GetTelephoneEventHandler();
 
  private:
+  bool HaveReceivedFrame() const;
+
   RtpVideoCodecTypes VideoCodecType() const;
 
   void CheckSSRCChanged(const RTPHeader& rtp_header);
   void CheckCSRC(const WebRtcRTPHeader& rtp_header);
   int32_t CheckPayloadChanged(const RTPHeader& rtp_header,
                               const int8_t first_payload_byte,
                               bool& is_red,
                               PayloadUnion* payload,
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
@@ -227,17 +227,19 @@ TEST_F(RtpRtcpAudioTest, Basic) {
       (voice_codec.rate < 0) ? 0 : voice_codec.rate));
   printf("4\n");
 
   const uint8_t test[5] = "test";
   EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96,
                                          0, -1, test, 4));
 
   EXPECT_EQ(test_ssrc, rtp_receiver2_->SSRC());
-  EXPECT_EQ(test_timestamp, rtp_receiver2_->Timestamp());
+  uint32_t timestamp;
+  EXPECT_TRUE(rtp_receiver2_->Timestamp(&timestamp));
+  EXPECT_EQ(test_timestamp, timestamp);
 }
 
 TEST_F(RtpRtcpAudioTest, RED) {
   CodecInst voice_codec;
   memset(&voice_codec, 0, sizeof(voice_codec));
   voice_codec.pltype = 96;
   voice_codec.plfreq = 8000;
   memcpy(voice_codec.plname, "PCMU", 5);
--- a/media/webrtc/trunk/webrtc/video_engine/vie_receiver.cc
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_receiver.cc
@@ -256,21 +256,22 @@ int ViEReceiver::InsertRTPPacket(const i
                  "Incoming packet: Invalid RTP header");
     return -1;
   }
   int payload_length = received_packet_length - header.headerLength;
   remote_bitrate_estimator_->IncomingPacket(TickTime::MillisecondTimestamp(),
                                             payload_length, header);
   header.payload_type_frequency = kVideoPayloadTypeFrequency;
 
+  bool in_order = IsPacketInOrder(header);
   rtp_receive_statistics_->IncomingPacket(header, received_packet_length,
-                                          IsPacketRetransmitted(header));
+      IsPacketRetransmitted(header, in_order));
   rtp_payload_registry_->SetIncomingPayloadType(header);
   return ReceivePacket(received_packet, received_packet_length, header,
-                       IsPacketInOrder(header)) ? 0 : -1;
+                       in_order) ? 0 : -1;
 }
 
 bool ViEReceiver::ReceivePacket(const uint8_t* packet,
                                 int packet_length,
                                 const RTPHeader& header,
                                 bool in_order) {
   if (rtp_payload_registry_->IsEncapsulated(header)) {
     return ParseAndHandleEncapsulatingHeader(packet, packet_length, header);
@@ -463,23 +464,24 @@ ReceiveStatistics* ViEReceiver::GetRecei
 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const {
   StreamStatistician* statistician =
       rtp_receive_statistics_->GetStatistician(header.ssrc);
   if (!statistician)
     return false;
   return statistician->IsPacketInOrder(header.sequenceNumber);
 }
 
-bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header) const {
+bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header,
+                                        bool in_order) const {
   // Retransmissions are handled separately if RTX is enabled.
   if (rtp_payload_registry_->RtxEnabled())
     return false;
   StreamStatistician* statistician =
       rtp_receive_statistics_->GetStatistician(header.ssrc);
   if (!statistician)
     return false;
   // Check if this is a retransmission.
   uint16_t min_rtt = 0;
   rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
-  return !IsPacketInOrder(header) &&
+  return !in_order &&
       statistician->IsRetransmitOfOldPacket(header, min_rtt);
 }
 }  // namespace webrtc
--- a/media/webrtc/trunk/webrtc/video_engine/vie_receiver.h
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_receiver.h
@@ -94,17 +94,17 @@ class ViEReceiver : public RtpData {
                      const RTPHeader& header, bool in_order);
   // Parses and handles for instance RTX and RED headers.
   // This function assumes that it's being called from only one thread.
   bool ParseAndHandleEncapsulatingHeader(const uint8_t* packet,
                                          int packet_length,
                                          const RTPHeader& header);
   int InsertRTCPPacket(const int8_t* rtcp_packet, int rtcp_packet_length);
   bool IsPacketInOrder(const RTPHeader& header) const;
-  bool IsPacketRetransmitted(const RTPHeader& header) const;
+  bool IsPacketRetransmitted(const RTPHeader& header, bool in_order) const;
 
   scoped_ptr<CriticalSectionWrapper> receive_cs_;
   const int32_t channel_id_;
   scoped_ptr<RtpHeaderParser> rtp_header_parser_;
   scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
   scoped_ptr<RtpReceiver> rtp_receiver_;
   scoped_ptr<ReceiveStatistics> rtp_receive_statistics_;
   scoped_ptr<FecReceiver> fec_receiver_;
--- a/media/webrtc/trunk/webrtc/video_engine/vie_sync_module.cc
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_sync_module.cc
@@ -21,18 +21,20 @@
 #include "webrtc/voice_engine/include/voe_video_sync.h"
 
 namespace webrtc {
 
 enum { kSyncInterval = 1000};
 
 int UpdateMeasurements(StreamSynchronization::Measurements* stream,
                        const RtpRtcp& rtp_rtcp, const RtpReceiver& receiver) {
-  stream->latest_timestamp = receiver.Timestamp();
-  stream->latest_receive_time_ms = receiver.LastReceivedTimeMs();
+  if (!receiver.Timestamp(&stream->latest_timestamp))
+    return -1;
+  if (!receiver.LastReceivedTimeMs(&stream->latest_receive_time_ms))
+    return -1;
   synchronization::RtcpMeasurement measurement;
   if (0 != rtp_rtcp.RemoteNTP(&measurement.ntp_secs,
                               &measurement.ntp_frac,
                               NULL,
                               NULL,
                               &measurement.rtp_timestamp)) {
     return -1;
   }
--- a/media/webrtc/trunk/webrtc/voice_engine/channel.cc
+++ b/media/webrtc/trunk/webrtc/voice_engine/channel.cc
@@ -2190,21 +2190,21 @@ int32_t Channel::ReceivedRTPPacket(const
     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId,
                  "Incoming packet: invalid RTP header");
     return -1;
   }
   header.payload_type_frequency =
       rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType);
   if (header.payload_type_frequency < 0)
     return -1;
+  bool in_order = IsPacketInOrder(header);
   rtp_receive_statistics_->IncomingPacket(header, length,
-                                          IsPacketRetransmitted(header));
+      IsPacketRetransmitted(header, in_order));
   rtp_payload_registry_->SetIncomingPayloadType(header);
-  return ReceivePacket(received_packet, length, header,
-                       IsPacketInOrder(header)) ? 0 : -1;
+  return ReceivePacket(received_packet, length, header, in_order) ? 0 : -1;
 }
 
 bool Channel::ReceivePacket(const uint8_t* packet,
                             int packet_length,
                             const RTPHeader& header,
                             bool in_order) {
   if (rtp_payload_registry_->IsEncapsulated(header)) {
     return HandleEncapsulation(packet, packet_length, header);
@@ -2254,28 +2254,29 @@ bool Channel::HandleEncapsulation(const 
 bool Channel::IsPacketInOrder(const RTPHeader& header) const {
   StreamStatistician* statistician =
       rtp_receive_statistics_->GetStatistician(header.ssrc);
   if (!statistician)
     return false;
   return statistician->IsPacketInOrder(header.sequenceNumber);
 }
 
-bool Channel::IsPacketRetransmitted(const RTPHeader& header) const {
+bool Channel::IsPacketRetransmitted(const RTPHeader& header,
+                                    bool in_order) const {
   // Retransmissions are handled separately if RTX is enabled.
   if (rtp_payload_registry_->RtxEnabled())
     return false;
   StreamStatistician* statistician =
       rtp_receive_statistics_->GetStatistician(header.ssrc);
   if (!statistician)
     return false;
   // Check if this is a retransmission.
   uint16_t min_rtt = 0;
   _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
-  return !IsPacketInOrder(header) &&
+  return !in_order &&
       statistician->IsRetransmitOfOldPacket(header, min_rtt);
 }
 
 int32_t Channel::ReceivedRTCPPacket(const int8_t* data, int32_t length) {
   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
                "Channel::ReceivedRTCPPacket()");
   // Store playout timestamp for the received RTCP packet
   UpdatePlayoutTimestamp(true);
--- a/media/webrtc/trunk/webrtc/voice_engine/channel.h
+++ b/media/webrtc/trunk/webrtc/voice_engine/channel.h
@@ -430,17 +430,17 @@ public:
 
 private:
     bool ReceivePacket(const uint8_t* packet, int packet_length,
                        const RTPHeader& header, bool in_order);
     bool HandleEncapsulation(const uint8_t* packet,
                              int packet_length,
                              const RTPHeader& header);
     bool IsPacketInOrder(const RTPHeader& header) const;
-    bool IsPacketRetransmitted(const RTPHeader& header) const;
+    bool IsPacketRetransmitted(const RTPHeader& header, bool in_order) const;
     int ResendPackets(const uint16_t* sequence_numbers, int length);
     int InsertInbandDtmfTone();
     int32_t MixOrReplaceAudioWithFile(int mixingFrequency);
     int32_t MixAudioWithFile(AudioFrame& audioFrame, int mixingFrequency);
     void UpdateDeadOrAliveCounters(bool alive);
     int32_t SendPacketRaw(const void *data, int len, bool RTCP);
     void UpdatePacketDelay(uint32_t timestamp,
                            uint16_t sequenceNumber);