Preserve RTP states for restarted VideoSendStreams.

A restarted VideoSendStream would previously be completely reset,
causing gaps in sequence numbers and potentially RTP timestamps as well.
This broke SRTP which requires fairly sequential sequence numbers.
Presumably, were this sent without SRTP, we'd still have problems on the
receiving end as the corresponding receiver is unaware of this reset.

Also adding annotation to RTPSender and addressing some unlocked
access to ssrc_, ssrc_rtx_ and rtx_.

BUG=
R=mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/20819004

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@6612 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/rtp_rtcp/interface/rtp_rtcp.h b/modules/rtp_rtcp/interface/rtp_rtcp.h
index 95c565f..da82b65 100644
--- a/modules/rtp_rtcp/interface/rtp_rtcp.h
+++ b/modules/rtp_rtcp/interface/rtp_rtcp.h
@@ -203,6 +203,10 @@
     */
     virtual int32_t SetSequenceNumber(const uint16_t seq) = 0;
 
+    virtual void SetRtpStateForSsrc(uint32_t ssrc,
+                                    const RtpState& rtp_state) = 0;
+    virtual bool GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) = 0;
+
     /*
     *   Get SSRC
     */
diff --git a/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
index 6f99f93..e1bec5f 100644
--- a/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
@@ -192,6 +192,20 @@
 
 typedef std::list<RTCPReportBlock> ReportBlockList;
 
+struct RtpState {
+  RtpState()
+      : sequence_number(0),
+        start_timestamp(0),
+        timestamp(0),
+        capture_time_ms(-1),
+        last_timestamp_time_ms(-1) {}
+  uint16_t sequence_number;
+  uint32_t start_timestamp;
+  uint32_t timestamp;
+  int64_t capture_time_ms;
+  int64_t last_timestamp_time_ms;
+};
+
 class RtpData
 {
 public:
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 03156c7..fe20c6a 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -74,6 +74,9 @@
       uint16_t());
   MOCK_METHOD1(SetSequenceNumber,
       int32_t(const uint16_t seq));
+  MOCK_METHOD2(SetRtpStateForSsrc,
+               void(uint32_t ssrc, const RtpState& rtp_state));
+  MOCK_METHOD2(GetRtpStateForSsrc, bool(uint32_t ssrc, RtpState* rtp_state));
   MOCK_CONST_METHOD0(SSRC,
       uint32_t());
   MOCK_METHOD1(SetSSRC,
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index 896bd5f..b38ae1f 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -1361,8 +1361,6 @@
 void RTCPReceiver::RegisterRtcpStatisticsCallback(
     RtcpStatisticsCallback* callback) {
   CriticalSectionScoped cs(_criticalSectionFeedbacks);
-  if (callback != NULL)
-    assert(stats_callback_ == NULL);
   stats_callback_ = callback;
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 70fe717..aff4234 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -333,6 +333,42 @@
   return 0;  // TODO(pwestin): change to void.
 }
 
+void ModuleRtpRtcpImpl::SetRtpStateForSsrc(uint32_t ssrc,
+                                           const RtpState& rtp_state) {
+  if (rtp_sender_.SSRC() == ssrc) {
+    rtp_sender_.SetRtpState(rtp_state);
+    return;
+  }
+  if (rtp_sender_.RtxSsrc() == ssrc) {
+    rtp_sender_.SetRtxRtpState(rtp_state);
+    return;
+  }
+
+  CriticalSectionScoped lock(critical_section_module_ptrs_.get());
+  for (size_t i = 0; i < child_modules_.size(); ++i) {
+    child_modules_[i]->SetRtpStateForSsrc(ssrc, rtp_state);
+  }
+}
+
+bool ModuleRtpRtcpImpl::GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) {
+  if (rtp_sender_.SSRC() == ssrc) {
+    *rtp_state = rtp_sender_.GetRtpState();
+    return true;
+  }
+
+  if (rtp_sender_.RtxSsrc() == ssrc) {
+    *rtp_state = rtp_sender_.GetRtxRtpState();
+    return true;
+  }
+
+  CriticalSectionScoped lock(critical_section_module_ptrs_.get());
+  for (size_t i = 0; i < child_modules_.size(); ++i) {
+    if (child_modules_[i]->GetRtpStateForSsrc(ssrc, rtp_state))
+      return true;
+  }
+  return false;
+}
+
 uint32_t ModuleRtpRtcpImpl::SSRC() const {
   return rtp_sender_.SSRC();
 }
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index 55826b6..c169407 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -73,6 +73,10 @@
   // Set SequenceNumber, default is a random number.
   virtual int32_t SetSequenceNumber(const uint16_t seq) OVERRIDE;
 
+  virtual void SetRtpStateForSsrc(uint32_t ssrc,
+                                  const RtpState& rtp_state) OVERRIDE;
+  virtual bool GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) OVERRIDE;
+
   virtual uint32_t SSRC() const OVERRIDE;
 
   // Configure SSRC, default is a random number.
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index c038393..919eb02 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -74,8 +74,8 @@
       rtp_stats_callback_(NULL),
       bitrate_callback_(NULL),
       // RTP variables
-      start_time_stamp_forced_(false),
-      start_time_stamp_(0),
+      start_timestamp_forced_(false),
+      start_timestamp_(0),
       ssrc_db_(*SSRCDatabase::GetSSRCDatabase()),
       remote_ssrc_(0),
       sequence_number_forced_(false),
@@ -304,12 +304,17 @@
 }
 
 uint16_t RTPSender::MaxDataPayloadLength() const {
+  int rtx;
+  {
+    CriticalSectionScoped rtx_lock(send_critsect_);
+    rtx = rtx_;
+  }
   if (audio_configured_) {
     return max_payload_length_ - RTPHeaderLength();
   } else {
     return max_payload_length_ - RTPHeaderLength()  // RTP overhead.
            - video_->FECPacketOverhead()            // FEC/ULP/RED overhead.
-           - ((rtx_) ? 2 : 0);                      // RTX overhead.
+           - ((rtx) ? 2 : 0);                       // RTX overhead.
   }
 }
 
@@ -329,6 +334,11 @@
   ssrc_rtx_ = ssrc;
 }
 
+uint32_t RTPSender::RtxSsrc() const {
+  CriticalSectionScoped cs(send_critsect_);
+  return ssrc_rtx_;
+}
+
 void RTPSender::RTXStatus(int* mode, uint32_t* ssrc,
                           int* payload_type) const {
   CriticalSectionScoped cs(send_critsect_);
@@ -389,9 +399,11 @@
     const uint8_t *payload_data, const uint32_t payload_size,
     const RTPFragmentationHeader *fragmentation,
     VideoCodecInformation *codec_info, const RTPVideoTypeHeader *rtp_type_hdr) {
+  uint32_t ssrc;
   {
     // Drop this packet if we're not sending media packets.
     CriticalSectionScoped cs(send_critsect_);
+    ssrc = ssrc_;
     if (!sending_media_) {
       return 0;
     }
@@ -435,17 +447,13 @@
   CriticalSectionScoped cs(statistics_crit_.get());
   uint32_t frame_count = ++frame_counts_[frame_type];
   if (frame_count_observer_) {
-    frame_count_observer_->FrameCountUpdated(frame_type,
-                                             frame_count,
-                                             ssrc_);
+    frame_count_observer_->FrameCountUpdated(frame_type, frame_count, ssrc);
   }
 
   return ret_val;
 }
 
 int RTPSender::SendRedundantPayloads(int payload_type, int bytes_to_send) {
-  if (!(rtx_ & kRtxRedundantPayloads))
-    return 0;
   uint8_t buffer[IP_PACKET_SIZE];
   int bytes_left = bytes_to_send;
   while (bytes_left > 0) {
@@ -493,7 +501,7 @@
     CriticalSectionScoped cs(send_critsect_);
     // Add the random RTP timestamp offset and store the capture time for
     // later calculation of the send time offset.
-    timestamp = start_time_stamp_ + capture_timestamp;
+    timestamp = start_timestamp_ + capture_timestamp;
     timestamp_ = timestamp;
     capture_time_ms_ = capture_time_ms;
     last_timestamp_time_ms_ = clock_->TimeInMilliseconds();
@@ -567,6 +575,7 @@
         ++sequence_number_rtx_;
       }
     }
+
     uint8_t padding_packet[IP_PACKET_SIZE];
     int header_length = CreateRTPHeader(padding_packet, payload_type, ssrc,
                                         false, timestamp, sequence_number, NULL,
@@ -628,6 +637,7 @@
     }
   }
 
+  CriticalSectionScoped lock(send_critsect_);
   return PrepareAndSendPacket(data_buffer, length, capture_time_ms,
                               (rtx_ & kRtxRetransmitted) > 0, true) ?
       length : -1;
@@ -784,8 +794,15 @@
   if (!retransmission && capture_time_ms > 0) {
     UpdateDelayStatistics(capture_time_ms, clock_->TimeInMilliseconds());
   }
-  return PrepareAndSendPacket(data_buffer, length, capture_time_ms,
-                              retransmission && (rtx_ & kRtxRetransmitted) > 0,
+  int rtx;
+  {
+    CriticalSectionScoped lock(send_critsect_);
+    rtx = rtx_;
+  }
+  return PrepareAndSendPacket(data_buffer,
+                              length,
+                              capture_time_ms,
+                              retransmission && (rtx & kRtxRetransmitted) > 0,
                               retransmission);
 }
 
@@ -827,12 +844,11 @@
                                bool is_retransmit) {
   StreamDataCounters* counters;
   // Get ssrc before taking statistics_crit_ to avoid possible deadlock.
-  uint32_t ssrc = SSRC();
+  uint32_t ssrc = is_rtx ? RtxSsrc() : SSRC();
 
   CriticalSectionScoped lock(statistics_crit_.get());
   if (is_rtx) {
     counters = &rtx_rtp_stats_;
-    ssrc = ssrc_rtx_;
   } else {
     counters = &rtp_stats_;
   }
@@ -874,6 +890,7 @@
   int payload_type;
   int64_t capture_time_ms;
   uint32_t timestamp;
+  int rtx;
   {
     CriticalSectionScoped cs(send_critsect_);
     if (!sending_media_) {
@@ -889,8 +906,11 @@
       capture_time_ms +=
           (clock_->TimeInMilliseconds() - last_timestamp_time_ms_);
     }
+    rtx = rtx_;
   }
-  int bytes_sent = SendRedundantPayloads(payload_type, bytes);
+  int bytes_sent = 0;
+  if ((rtx & kRtxRedundantPayloads) != 0)
+    bytes_sent = SendRedundantPayloads(payload_type, bytes);
   bytes -= bytes_sent;
   if (bytes > 0) {
     int padding_sent = SendPadData(payload_type,
@@ -899,7 +919,7 @@
                                    bytes,
                                    kDontStore,
                                    true,
-                                   rtx_ == kRtxOff);
+                                   rtx == kRtxOff);
     bytes_sent += padding_sent;
   }
   return bytes_sent;
@@ -975,6 +995,7 @@
 }
 
 uint16_t RTPSender::RTPHeaderLength() const {
+  CriticalSectionScoped lock(send_critsect_);
   uint16_t rtp_header_length = 12;
   if (include_csrcs_) {
     rtp_header_length += sizeof(uint32_t) * num_csrcs_;
@@ -989,12 +1010,19 @@
 }
 
 void RTPSender::ResetDataCounters() {
+  uint32_t ssrc;
+  uint32_t ssrc_rtx;
+  {
+    CriticalSectionScoped ssrc_lock(send_critsect_);
+    ssrc = ssrc_;
+    ssrc_rtx = ssrc_rtx_;
+  }
   CriticalSectionScoped lock(statistics_crit_.get());
   rtp_stats_ = StreamDataCounters();
   rtx_rtp_stats_ = StreamDataCounters();
   if (rtp_stats_callback_) {
-    rtp_stats_callback_->DataCountersUpdated(rtp_stats_, ssrc_);
-    rtp_stats_callback_->DataCountersUpdated(rtx_rtp_stats_, ssrc_rtx_);
+    rtp_stats_callback_->DataCountersUpdated(rtp_stats_, ssrc);
+    rtp_stats_callback_->DataCountersUpdated(rtx_rtp_stats_, ssrc_rtx);
   }
 }
 
@@ -1049,16 +1077,18 @@
   return rtp_header_length;
 }
 
-int32_t RTPSender::BuildRTPheader(
-    uint8_t *data_buffer, const int8_t payload_type,
-    const bool marker_bit, const uint32_t capture_timestamp,
-    int64_t capture_time_ms, const bool time_stamp_provided,
-    const bool inc_sequence_number) {
+int32_t RTPSender::BuildRTPheader(uint8_t* data_buffer,
+                                  const int8_t payload_type,
+                                  const bool marker_bit,
+                                  const uint32_t capture_timestamp,
+                                  int64_t capture_time_ms,
+                                  const bool timestamp_provided,
+                                  const bool inc_sequence_number) {
   assert(payload_type >= 0);
   CriticalSectionScoped cs(send_critsect_);
 
-  if (time_stamp_provided) {
-    timestamp_ = start_time_stamp_ + capture_timestamp;
+  if (timestamp_provided) {
+    timestamp_ = start_timestamp_ + capture_timestamp;
   } else {
     // Make a unique time stamp.
     // We can't inc by the actual time, since then we increase the risk of back
@@ -1380,6 +1410,7 @@
     // Will be ignored if it's already configured via API.
     SetStartTimestamp(RTPtime, false);
   } else {
+    CriticalSectionScoped lock(send_critsect_);
     if (!ssrc_forced_) {
       // Generate a new SSRC.
       ssrc_db_.ReturnSSRC(ssrc_);
@@ -1412,18 +1443,18 @@
 void RTPSender::SetStartTimestamp(uint32_t timestamp, bool force) {
   CriticalSectionScoped cs(send_critsect_);
   if (force) {
-    start_time_stamp_forced_ = force;
-    start_time_stamp_ = timestamp;
+    start_timestamp_forced_ = true;
+    start_timestamp_ = timestamp;
   } else {
-    if (!start_time_stamp_forced_) {
-      start_time_stamp_ = timestamp;
+    if (!start_timestamp_forced_) {
+      start_timestamp_ = timestamp;
     }
   }
 }
 
 uint32_t RTPSender::StartTimestamp() const {
   CriticalSectionScoped cs(send_critsect_);
-  return start_time_stamp_;
+  return start_timestamp_;
 }
 
 uint32_t RTPSender::GenerateNewSSRC() {
@@ -1460,6 +1491,7 @@
 }
 
 void RTPSender::SetCSRCStatus(const bool include) {
+  CriticalSectionScoped lock(send_critsect_);
   include_csrcs_ = include;
 }
 
@@ -1635,8 +1667,6 @@
 
 void RTPSender::RegisterFrameCountObserver(FrameCountObserver* observer) {
   CriticalSectionScoped cs(statistics_crit_.get());
-  if (observer != NULL)
-    assert(frame_count_observer_ == NULL);
   frame_count_observer_ = observer;
 }
 
@@ -1648,8 +1678,6 @@
 void RTPSender::RegisterRtpStatisticsCallback(
     StreamDataCountersCallback* callback) {
   CriticalSectionScoped cs(statistics_crit_.get());
-  if (callback != NULL)
-    assert(rtp_stats_callback_ == NULL);
   rtp_stats_callback_ = callback;
 }
 
@@ -1660,8 +1688,6 @@
 
 void RTPSender::RegisterBitrateObserver(BitrateStatisticsObserver* observer) {
   CriticalSectionScoped cs(statistics_crit_.get());
-  if (observer != NULL)
-    assert(bitrate_callback_ == NULL);
   bitrate_callback_ = observer;
 }
 
@@ -1673,9 +1699,53 @@
 uint32_t RTPSender::BitrateSent() const { return bitrate_sent_.BitrateLast(); }
 
 void RTPSender::BitrateUpdated(const BitrateStatistics& stats) {
+  uint32_t ssrc;
+  {
+    CriticalSectionScoped ssrc_lock(send_critsect_);
+    ssrc = ssrc_;
+  }
   CriticalSectionScoped cs(statistics_crit_.get());
   if (bitrate_callback_) {
-    bitrate_callback_->Notify(stats, ssrc_);
+    bitrate_callback_->Notify(stats, ssrc);
   }
 }
+
+void RTPSender::SetRtpState(const RtpState& rtp_state) {
+  SetStartTimestamp(rtp_state.start_timestamp, true);
+  CriticalSectionScoped lock(send_critsect_);
+  sequence_number_ = rtp_state.sequence_number;
+  sequence_number_forced_ = true;
+  timestamp_ = rtp_state.timestamp;
+  capture_time_ms_ = rtp_state.capture_time_ms;
+  last_timestamp_time_ms_ = rtp_state.last_timestamp_time_ms;
+}
+
+RtpState RTPSender::GetRtpState() const {
+  CriticalSectionScoped lock(send_critsect_);
+
+  RtpState state;
+  state.sequence_number = sequence_number_;
+  state.start_timestamp = start_timestamp_;
+  state.timestamp = timestamp_;
+  state.capture_time_ms = capture_time_ms_;
+  state.last_timestamp_time_ms = last_timestamp_time_ms_;
+
+  return state;
+}
+
+void RTPSender::SetRtxRtpState(const RtpState& rtp_state) {
+  CriticalSectionScoped lock(send_critsect_);
+  sequence_number_rtx_ = rtp_state.sequence_number;
+}
+
+RtpState RTPSender::GetRtxRtpState() const {
+  CriticalSectionScoped lock(send_critsect_);
+
+  RtpState state;
+  state.sequence_number = sequence_number_rtx_;
+  state.start_timestamp = start_timestamp_;
+
+  return state;
+}
+
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index 291e619..78d3a2a 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -43,12 +43,13 @@
   virtual uint32_t SSRC() const = 0;
   virtual uint32_t Timestamp() const = 0;
 
-  virtual int32_t BuildRTPheader(
-      uint8_t *data_buffer, const int8_t payload_type,
-      const bool marker_bit, const uint32_t capture_time_stamp,
-      int64_t capture_time_ms,
-      const bool time_stamp_provided = true,
-      const bool inc_sequence_number = true) = 0;
+  virtual int32_t BuildRTPheader(uint8_t* data_buffer,
+                                 const int8_t payload_type,
+                                 const bool marker_bit,
+                                 const uint32_t capture_timestamp,
+                                 int64_t capture_time_ms,
+                                 const bool timestamp_provided = true,
+                                 const bool inc_sequence_number = true) = 0;
 
   virtual uint16_t RTPHeaderLength() const = 0;
   virtual uint16_t IncrementSequenceNumber() = 0;
@@ -132,13 +133,15 @@
   int32_t SetMaxPayloadLength(const uint16_t length,
                               const uint16_t packet_over_head);
 
-  int32_t SendOutgoingData(
-      const FrameType frame_type, const int8_t payload_type,
-      const uint32_t time_stamp, int64_t capture_time_ms,
-      const uint8_t *payload_data, const uint32_t payload_size,
-      const RTPFragmentationHeader *fragmentation,
-      VideoCodecInformation *codec_info = NULL,
-      const RTPVideoTypeHeader * rtp_type_hdr = NULL);
+  int32_t SendOutgoingData(const FrameType frame_type,
+                           const int8_t payload_type,
+                           const uint32_t timestamp,
+                           int64_t capture_time_ms,
+                           const uint8_t* payload_data,
+                           const uint32_t payload_size,
+                           const RTPFragmentationHeader* fragmentation,
+                           VideoCodecInformation* codec_info = NULL,
+                           const RTPVideoTypeHeader* rtp_type_hdr = NULL);
 
   // RTP header extension
   int32_t SetTransmissionTimeOffset(
@@ -189,16 +192,19 @@
 
   void RTXStatus(int* mode, uint32_t* ssrc, int* payload_type) const;
 
+  uint32_t RtxSsrc() const;
   void SetRtxSsrc(uint32_t ssrc);
 
   void SetRtxPayloadType(int payloadType);
 
   // Functions wrapping RTPSenderInterface.
   virtual int32_t BuildRTPheader(
-      uint8_t *data_buffer, const int8_t payload_type,
-      const bool marker_bit, const uint32_t capture_time_stamp,
+      uint8_t* data_buffer,
+      const int8_t payload_type,
+      const bool marker_bit,
+      const uint32_t capture_timestamp,
       int64_t capture_time_ms,
-      const bool time_stamp_provided = true,
+      const bool timestamp_provided = true,
       const bool inc_sequence_number = true) OVERRIDE;
 
   virtual uint16_t RTPHeaderLength() const OVERRIDE;
@@ -277,6 +283,11 @@
 
   virtual void BitrateUpdated(const BitrateStatistics& stats) OVERRIDE;
 
+  void SetRtpState(const RtpState& rtp_state);
+  RtpState GetRtpState() const;
+  void SetRtxRtpState(const RtpState& rtp_state);
+  RtpState GetRtxRtpState() const;
+
  protected:
   int32_t CheckPayloadType(const int8_t payload_type,
                            RtpVideoCodecTypes *video_type);
@@ -363,34 +374,34 @@
 
   // Statistics
   scoped_ptr<CriticalSectionWrapper> statistics_crit_;
-  SendDelayMap send_delays_;
-  std::map<FrameType, uint32_t> frame_counts_;
-  FrameCountObserver* frame_count_observer_;
-  StreamDataCounters rtp_stats_;
-  StreamDataCounters rtx_rtp_stats_;
-  StreamDataCountersCallback* rtp_stats_callback_;
-  BitrateStatisticsObserver* bitrate_callback_;
+  SendDelayMap send_delays_ GUARDED_BY(statistics_crit_);
+  std::map<FrameType, uint32_t> frame_counts_ GUARDED_BY(statistics_crit_);
+  FrameCountObserver* frame_count_observer_ GUARDED_BY(statistics_crit_);
+  StreamDataCounters rtp_stats_ GUARDED_BY(statistics_crit_);
+  StreamDataCounters rtx_rtp_stats_ GUARDED_BY(statistics_crit_);
+  StreamDataCountersCallback* rtp_stats_callback_ GUARDED_BY(statistics_crit_);
+  BitrateStatisticsObserver* bitrate_callback_ GUARDED_BY(statistics_crit_);
 
   // RTP variables
-  bool start_time_stamp_forced_;
-  uint32_t start_time_stamp_;
-  SSRCDatabase &ssrc_db_;
-  uint32_t remote_ssrc_;
-  bool sequence_number_forced_;
-  uint16_t sequence_number_;
-  uint16_t sequence_number_rtx_;
-  bool ssrc_forced_;
-  uint32_t ssrc_;
-  uint32_t timestamp_;
-  int64_t capture_time_ms_;
-  int64_t last_timestamp_time_ms_;
-  bool last_packet_marker_bit_;
-  uint8_t num_csrcs_;
-  uint32_t csrcs_[kRtpCsrcSize];
-  bool include_csrcs_;
-  int rtx_;
-  uint32_t ssrc_rtx_;
-  int payload_type_rtx_;
+  bool start_timestamp_forced_ GUARDED_BY(send_critsect_);
+  uint32_t start_timestamp_ GUARDED_BY(send_critsect_);
+  SSRCDatabase& ssrc_db_ GUARDED_BY(send_critsect_);
+  uint32_t remote_ssrc_ GUARDED_BY(send_critsect_);
+  bool sequence_number_forced_ GUARDED_BY(send_critsect_);
+  uint16_t sequence_number_ GUARDED_BY(send_critsect_);
+  uint16_t sequence_number_rtx_ GUARDED_BY(send_critsect_);
+  bool ssrc_forced_ GUARDED_BY(send_critsect_);
+  uint32_t ssrc_ GUARDED_BY(send_critsect_);
+  uint32_t timestamp_ GUARDED_BY(send_critsect_);
+  int64_t capture_time_ms_ GUARDED_BY(send_critsect_);
+  int64_t last_timestamp_time_ms_ GUARDED_BY(send_critsect_);
+  bool last_packet_marker_bit_ GUARDED_BY(send_critsect_);
+  uint8_t num_csrcs_ GUARDED_BY(send_critsect_);
+  uint32_t csrcs_[kRtpCsrcSize] GUARDED_BY(send_critsect_);
+  bool include_csrcs_ GUARDED_BY(send_critsect_);
+  int rtx_ GUARDED_BY(send_critsect_);
+  uint32_t ssrc_rtx_ GUARDED_BY(send_critsect_);
+  int payload_type_rtx_ GUARDED_BY(send_critsect_);
 
   // Note: Don't access this variable directly, always go through
   // SetTargetBitrateKbps or GetTargetBitrateKbps. Also remember