Add a PacketOptions struct to webrtc::Transport.

This allows us to pass packet meta data, such as transport sequence
number, to libjingle and further down to the socket implementation. A
similar struct already exist in libjingle, see rtc::PacketOptions in asyncpacketsocket.h.

BUG=4173

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

Cr-Commit-Position: refs/heads/master@{#10144}
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index 7b29001..2f06340 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -1658,7 +1658,9 @@
   }
 }
 
-bool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) {
+bool WebRtcVideoChannel2::SendRtp(const uint8_t* data,
+                                  size_t len,
+                                  const webrtc::PacketOptions& options) {
   rtc::Buffer packet(data, len, kMaxRtpPacketLen);
   return MediaChannel::SendPacket(&packet);
 }
diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h
index 6b36642..0fc28d1 100644
--- a/talk/media/webrtc/webrtcvideoengine2.h
+++ b/talk/media/webrtc/webrtcvideoengine2.h
@@ -464,7 +464,9 @@
   void Construct(webrtc::Call* call, WebRtcVideoEngine2* engine);
   void SetDefaultOptions();
 
-  bool SendRtp(const uint8_t* data, size_t len) override;
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const webrtc::PacketOptions& options) override;
   bool SendRtcp(const uint8_t* data, size_t len) override;
 
   void StartAllSendStreams();
diff --git a/talk/media/webrtc/webrtcvoiceengine.h b/talk/media/webrtc/webrtcvoiceengine.h
index 7950024..69e88e4 100644
--- a/talk/media/webrtc/webrtcvoiceengine.h
+++ b/talk/media/webrtc/webrtcvoiceengine.h
@@ -223,7 +223,9 @@
   bool GetStats(VoiceMediaInfo* info) override;
 
   // implements Transport interface
-  bool SendRtp(const uint8_t* data, size_t len) override {
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const webrtc::PacketOptions& options) override {
     rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len,
                        kMaxRtpPacketLen);
     return VoiceMediaChannel::SendPacket(&packet);
diff --git a/webrtc/call/transport_adapter.cc b/webrtc/call/transport_adapter.cc
index e57591a..5e59b7b 100644
--- a/webrtc/call/transport_adapter.cc
+++ b/webrtc/call/transport_adapter.cc
@@ -20,11 +20,13 @@
   RTC_DCHECK(nullptr != transport);
 }
 
-bool TransportAdapter::SendRtp(const uint8_t* packet, size_t length) {
+bool TransportAdapter::SendRtp(const uint8_t* packet,
+                               size_t length,
+                               const PacketOptions& options) {
   if (enabled_.Value() == 0)
     return false;
 
-  return transport_->SendRtp(packet, length);
+  return transport_->SendRtp(packet, length, options);
 }
 
 bool TransportAdapter::SendRtcp(const uint8_t* packet, size_t length) {
diff --git a/webrtc/call/transport_adapter.h b/webrtc/call/transport_adapter.h
index 07ea716..72f9baa 100644
--- a/webrtc/call/transport_adapter.h
+++ b/webrtc/call/transport_adapter.h
@@ -21,7 +21,9 @@
  public:
   explicit TransportAdapter(Transport* transport);
 
-  bool SendRtp(const uint8_t* packet, size_t length) override;
+  bool SendRtp(const uint8_t* packet,
+               size_t length,
+               const PacketOptions& options) override;
   bool SendRtcp(const uint8_t* packet, size_t length) override;
 
   void Enable();
diff --git a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
index b243385..483ee13 100644
--- a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
@@ -96,7 +96,9 @@
     packet_loss_ = 0;
   }
 
-  bool SendRtp(const uint8_t* data, size_t len) override {
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const PacketOptions& options) override {
     count_++;
     const unsigned char* ptr = static_cast<const unsigned  char*>(data);
     uint32_t ssrc = (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11];
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
index 554e6ad..7a7645f 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
@@ -32,7 +32,9 @@
     rtcp_receiver_(rtcp_receiver) {
   }
 
-  bool SendRtp(const uint8_t* /*data*/, size_t /*len*/) override {
+  bool SendRtp(const uint8_t* /*data*/,
+               size_t /*len*/,
+               const PacketOptions& options) override {
     return false;
   }
   bool SendRtcp(const uint8_t* packet, size_t packetLength) override {
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index cdbc47d..1581845 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -39,7 +39,9 @@
   void SetRTCPReceiver(RTCPReceiver* rtcp_receiver) {
     rtcp_receiver_ = rtcp_receiver;
   }
-  bool SendRtp(const uint8_t* /*data*/, size_t /*len*/) override {
+  bool SendRtp(const uint8_t* /*data*/,
+               size_t /*len*/,
+               const PacketOptions& options) override {
     ADD_FAILURE();  // FAIL() gives a compile error.
     return false;
   }
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index 0da2101..ba42c8d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -199,7 +199,9 @@
  public:
   TestTransport() {}
 
-  bool SendRtp(const uint8_t* /*data*/, size_t /*len*/) override {
+  bool SendRtp(const uint8_t* /*data*/,
+               size_t /*len*/,
+               const PacketOptions& options) override {
     return false;
   }
   bool SendRtcp(const uint8_t* data, size_t len) override {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index f6103b3..03b91a9 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -61,7 +61,9 @@
     clock_ = clock;
     delay_ms_ = delay_ms;
   }
-  bool SendRtp(const uint8_t* data, size_t len) override {
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const PacketOptions& options) override {
     RTPHeader header;
     rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
     EXPECT_TRUE(parser->Parse(static_cast<const uint8_t*>(data), len, &header));
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
index ae292a0..252ffb2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -662,18 +662,18 @@
 
     UpdateAbsoluteSendTime(padding_packet, length, rtp_header, now_ms);
 
-    uint16_t transport_seq = 0;
+    PacketOptions options;
     if (using_transport_seq) {
-      transport_seq =
+      options.packet_id =
           UpdateTransportSequenceNumber(padding_packet, length, rtp_header);
     }
 
-    if (!SendPacketToNetwork(padding_packet, length))
+    if (!SendPacketToNetwork(padding_packet, length, options))
       break;
 
     if (using_transport_seq && transport_feedback_observer_) {
-      transport_feedback_observer_->OnPacketSent(
-          PacketInfo(0, now_ms, transport_seq, length, true));
+      transport_feedback_observer_->OnPacketSent(PacketInfo(
+          0, now_ms, options.packet_id, length, true));
     }
 
     bytes_sent += padding_bytes_in_packet;
@@ -732,11 +732,14 @@
   return static_cast<int32_t>(length);
 }
 
-bool RTPSender::SendPacketToNetwork(const uint8_t *packet, size_t size) {
+bool RTPSender::SendPacketToNetwork(const uint8_t* packet,
+                                    size_t size,
+                                    const PacketOptions& options) {
   int bytes_sent = -1;
   if (transport_) {
-    bytes_sent =
-        transport_->SendRtp(packet, size) ? static_cast<int>(size) : -1;
+    bytes_sent = transport_->SendRtp(packet, size, options)
+                     ? static_cast<int>(size)
+                     : -1;
   }
   TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
                        "RTPSender::SendPacketToNetwork", "size", size, "sent",
@@ -916,25 +919,25 @@
                                diff_ms);
   UpdateAbsoluteSendTime(buffer_to_send_ptr, length, rtp_header, now_ms);
 
-  uint16_t transport_seq = 0;
   // TODO(sprang): Potentially too much overhead in IsRegistered()?
   bool using_transport_seq = rtp_header_extension_map_.IsRegistered(
                                  kRtpExtensionTransportSequenceNumber) &&
                              transport_sequence_number_allocator_ &&
                              !is_retransmit;
+  PacketOptions options;
   if (using_transport_seq) {
-    transport_seq =
+    options.packet_id =
         UpdateTransportSequenceNumber(buffer_to_send_ptr, length, rtp_header);
   }
 
-  bool ret = SendPacketToNetwork(buffer_to_send_ptr, length);
+  bool ret = SendPacketToNetwork(buffer_to_send_ptr, length, options);
   if (ret) {
     CriticalSectionScoped lock(send_critsect_.get());
     media_has_been_sent_ = true;
   }
   if (using_transport_seq && transport_feedback_observer_) {
     transport_feedback_observer_->OnPacketSent(
-        PacketInfo(0, now_ms, transport_seq, length, true));
+        PacketInfo(0, now_ms, options.packet_id, length, true));
   }
   UpdateRtpStats(buffer_to_send_ptr, length, rtp_header, send_over_rtx,
                  is_retransmit);
@@ -1058,7 +1061,7 @@
   }
 
   size_t length = payload_length + rtp_header_length;
-  bool sent = SendPacketToNetwork(buffer, length);
+  bool sent = SendPacketToNetwork(buffer, length, PacketOptions());
 
   if (storage != kDontStore) {
     // Mark the packet as sent in the history even if send failed. Dropping a
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
index 564300f..57516f8 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
@@ -350,7 +350,9 @@
   void BuildRtxPacket(uint8_t* buffer, size_t* length,
                       uint8_t* buffer_rtx);
 
-  bool SendPacketToNetwork(const uint8_t *packet, size_t size);
+  bool SendPacketToNetwork(const uint8_t* packet,
+                           size_t size,
+                           const PacketOptions& options);
 
   void UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms);
 
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 0403ce8..305ea13 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -78,7 +78,9 @@
   ~LoopbackTransportTest() {
     STLDeleteContainerPointers(sent_packets_.begin(), sent_packets_.end());
   }
-  bool SendRtp(const uint8_t *data, size_t len) override {
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const PacketOptions& options) override {
     packets_sent_++;
     rtc::Buffer* buffer =
         new rtc::Buffer(reinterpret_cast<const uint8_t*>(data), len);
@@ -864,25 +866,26 @@
   // Send 10 packets of increasing size.
   for (size_t i = 0; i < kNumPayloadSizes; ++i) {
     int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
-    EXPECT_CALL(transport, SendRtp(_, _)).WillOnce(testing::Return(true));
+    EXPECT_CALL(transport, SendRtp(_, _, _)).WillOnce(testing::Return(true));
     SendPacket(capture_time_ms, kPayloadSizes[i]);
     rtp_sender_->TimeToSendPacket(seq_num++, capture_time_ms, false);
     fake_clock_.AdvanceTimeMilliseconds(33);
   }
   // The amount of padding to send it too small to send a payload packet.
-  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len))
+  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
       .WillOnce(testing::Return(true));
   EXPECT_EQ(kMaxPaddingSize, rtp_sender_->TimeToSendPadding(49));
 
   EXPECT_CALL(transport,
-              SendRtp(_, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize))
+              SendRtp(_, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize, _))
       .WillOnce(testing::Return(true));
   EXPECT_EQ(kPayloadSizes[0], rtp_sender_->TimeToSendPadding(500));
 
   EXPECT_CALL(transport, SendRtp(_, kPayloadSizes[kNumPayloadSizes - 1] +
-                                           rtp_header_len + kRtxHeaderSize))
+                                        rtp_header_len + kRtxHeaderSize,
+                                 _))
       .WillOnce(testing::Return(true));
-  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len))
+  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
       .WillOnce(testing::Return(true));
   EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kMaxPaddingSize,
             rtp_sender_->TimeToSendPadding(999));
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
index 361f45d..0270e55 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -31,7 +31,9 @@
   packet_loss_ = n;
 }
 
-bool LoopBackTransport::SendRtp(const uint8_t* data, size_t len) {
+bool LoopBackTransport::SendRtp(const uint8_t* data,
+                                size_t len,
+                                const PacketOptions& options) {
   count_++;
   if (packet_loss_ > 0) {
     if ((count_ % packet_loss_) == 0) {
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h
index 8397e63..73334a8 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h
@@ -36,7 +36,9 @@
                      RtpReceiver* receiver,
                      ReceiveStatistics* receive_statistics);
   void DropEveryNthPacket(int n);
-  bool SendRtp(const uint8_t* data, size_t len) override;
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const PacketOptions& options) override;
   bool SendRtcp(const uint8_t* data, size_t len) override;
 
  private:
diff --git a/webrtc/test/channel_transport/udp_transport_impl.cc b/webrtc/test/channel_transport/udp_transport_impl.cc
index f66f4ef..a530ec6 100644
--- a/webrtc/test/channel_transport/udp_transport_impl.cc
+++ b/webrtc/test/channel_transport/udp_transport_impl.cc
@@ -1931,7 +1931,9 @@
     return -1;
 }
 
-bool UdpTransportImpl::SendRtp(const uint8_t* data, size_t length) {
+bool UdpTransportImpl::SendRtp(const uint8_t* data,
+                               size_t length,
+                               const PacketOptions& packet_options) {
     WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, "%s", __FUNCTION__);
 
     CriticalSectionScoped cs(_crit);
diff --git a/webrtc/test/channel_transport/udp_transport_impl.h b/webrtc/test/channel_transport/udp_transport_impl.h
index 80562f3..f80ee02 100644
--- a/webrtc/test/channel_transport/udp_transport_impl.h
+++ b/webrtc/test/channel_transport/udp_transport_impl.h
@@ -116,7 +116,9 @@
                              size_t length,
                              uint16_t rtcpPort) override;
     // Transport functions
-    bool SendRtp(const uint8_t* data, size_t length) override;
+    bool SendRtp(const uint8_t* data,
+                 size_t length,
+                 const PacketOptions& packet_options) override;
     bool SendRtcp(const uint8_t* data, size_t length) override;
 
     // UdpTransport functions continue.
diff --git a/webrtc/test/direct_transport.cc b/webrtc/test/direct_transport.cc
index d0f797c..1f92e92 100644
--- a/webrtc/test/direct_transport.cc
+++ b/webrtc/test/direct_transport.cc
@@ -57,7 +57,9 @@
   fake_network_.SetReceiver(receiver);
 }
 
-bool DirectTransport::SendRtp(const uint8_t* data, size_t length) {
+bool DirectTransport::SendRtp(const uint8_t* data,
+                              size_t length,
+                              const PacketOptions& options) {
   fake_network_.SendPacket(data, length);
   packet_event_->Set();
   return true;
diff --git a/webrtc/test/direct_transport.h b/webrtc/test/direct_transport.h
index a0aaecb..1c6f937 100644
--- a/webrtc/test/direct_transport.h
+++ b/webrtc/test/direct_transport.h
@@ -39,7 +39,9 @@
   virtual void StopSending();
   virtual void SetReceiver(PacketReceiver* receiver);
 
-  bool SendRtp(const uint8_t* data, size_t length) override;
+  bool SendRtp(const uint8_t* data,
+               size_t length,
+               const PacketOptions& options) override;
   bool SendRtcp(const uint8_t* data, size_t length) override;
 
  private:
diff --git a/webrtc/test/layer_filtering_transport.cc b/webrtc/test/layer_filtering_transport.cc
index 5ad3f8c..d6f3591 100644
--- a/webrtc/test/layer_filtering_transport.cc
+++ b/webrtc/test/layer_filtering_transport.cc
@@ -33,10 +33,12 @@
       current_seq_num_(10000) {
 }  // TODO(ivica): random seq num?
 
-bool LayerFilteringTransport::SendRtp(const uint8_t* packet, size_t length) {
+bool LayerFilteringTransport::SendRtp(const uint8_t* packet,
+                                      size_t length,
+                                      const PacketOptions& options) {
   if (tl_discard_threshold_ == 0 && sl_discard_threshold_ == 0) {
     // Nothing to change, forward the packet immediately.
-    return test::DirectTransport::SendRtp(packet, length);
+    return test::DirectTransport::SendRtp(packet, length, options);
   }
 
   bool set_marker_bit = false;
@@ -93,7 +95,7 @@
 
   ++current_seq_num_;  // Increase only if packet not discarded.
 
-  return test::DirectTransport::SendRtp(temp_buffer, length);
+  return test::DirectTransport::SendRtp(temp_buffer, length, options);
 }
 
 }  // namespace test
diff --git a/webrtc/test/layer_filtering_transport.h b/webrtc/test/layer_filtering_transport.h
index 96a2cba..68994ae 100644
--- a/webrtc/test/layer_filtering_transport.h
+++ b/webrtc/test/layer_filtering_transport.h
@@ -24,7 +24,9 @@
                           uint8_t vp9_video_payload_type,
                           uint8_t tl_discard_threshold,
                           uint8_t sl_discard_threshold);
-  bool SendRtp(const uint8_t* data, size_t length) override;
+  bool SendRtp(const uint8_t* data,
+               size_t length,
+               const PacketOptions& options) override;
 
  private:
   // Used to distinguish between VP8 and VP9.
diff --git a/webrtc/test/mock_transport.h b/webrtc/test/mock_transport.h
index ca08809..4937134 100644
--- a/webrtc/test/mock_transport.h
+++ b/webrtc/test/mock_transport.h
@@ -18,7 +18,10 @@
 
 class MockTransport : public Transport {
  public:
-  MOCK_METHOD2(SendRtp, bool(const uint8_t* data, size_t len));
+  MOCK_METHOD3(SendRtp,
+               bool(const uint8_t* data,
+                    size_t len,
+                    const PacketOptions& options));
   MOCK_METHOD2(SendRtcp, bool(const uint8_t* data, size_t len));
 };
 }  // namespace webrtc
diff --git a/webrtc/test/null_transport.cc b/webrtc/test/null_transport.cc
index 3cba638..7fa36d1 100644
--- a/webrtc/test/null_transport.cc
+++ b/webrtc/test/null_transport.cc
@@ -12,7 +12,9 @@
 namespace webrtc {
 namespace test {
 
-bool NullTransport::SendRtp(const uint8_t* packet, size_t length) {
+bool NullTransport::SendRtp(const uint8_t* packet,
+                            size_t length,
+                            const PacketOptions& options) {
   return true;
 }
 
diff --git a/webrtc/test/null_transport.h b/webrtc/test/null_transport.h
index a60d8cb..f4b7046 100644
--- a/webrtc/test/null_transport.h
+++ b/webrtc/test/null_transport.h
@@ -19,7 +19,9 @@
 namespace test {
 class NullTransport : public Transport {
  public:
-  bool SendRtp(const uint8_t* packet, size_t length) override;
+  bool SendRtp(const uint8_t* packet,
+               size_t length,
+               const PacketOptions& options) override;
   bool SendRtcp(const uint8_t* packet, size_t length) override;
 };
 }  // namespace test
diff --git a/webrtc/test/rtp_rtcp_observer.h b/webrtc/test/rtp_rtcp_observer.h
index 24f7256..97aa7b6 100644
--- a/webrtc/test/rtp_rtcp_observer.h
+++ b/webrtc/test/rtp_rtcp_observer.h
@@ -126,7 +126,9 @@
           on_rtcp_(on_rtcp) {}
 
   private:
-   bool SendRtp(const uint8_t* packet, size_t length) override {
+   bool SendRtp(const uint8_t* packet,
+                size_t length,
+                const PacketOptions& options) override {
       EXPECT_FALSE(RtpHeaderParser::IsRtcp(packet, length));
       Action action;
       {
@@ -138,7 +140,7 @@
           // Drop packet silently.
           return true;
         case SEND_PACKET:
-          return test::DirectTransport::SendRtp(packet, length);
+          return test::DirectTransport::SendRtp(packet, length, options);
       }
       return true;  // Will never happen, makes compiler happy.
     }
diff --git a/webrtc/transport.h b/webrtc/transport.h
index 86b3e2e..7b62f65 100644
--- a/webrtc/transport.h
+++ b/webrtc/transport.h
@@ -17,9 +17,17 @@
 
 namespace webrtc {
 
+struct PacketOptions {
+  // A 16 bits positive id. Negative ids are invalid and should be interpreted
+  // as packet_id not being set.
+  int packet_id = -1;
+};
+
 class Transport {
  public:
-  virtual bool SendRtp(const uint8_t* packet, size_t length) = 0;
+  virtual bool SendRtp(const uint8_t* packet,
+                       size_t length,
+                       const PacketOptions& options) = 0;
   virtual bool SendRtcp(const uint8_t* packet, size_t length) = 0;
 
  protected:
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index c729f2a..305dcb0 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -61,7 +61,9 @@
  protected:
   class UnusedTransport : public Transport {
    private:
-    bool SendRtp(const uint8_t* packet, size_t length) override {
+    bool SendRtp(const uint8_t* packet,
+                 size_t length,
+                 const PacketOptions& options) override {
       ADD_FAILURE() << "Unexpected RTP sent.";
       return false;
     }
@@ -1351,13 +1353,17 @@
     }
     virtual ~RtpExtensionHeaderObserver() {}
 
-    bool SendRtp(const uint8_t* data, size_t length) override {
+    bool SendRtp(const uint8_t* data,
+                 size_t length,
+                 const PacketOptions& options) override {
       if (IsDone())
         return false;
 
       RTPHeader header;
       EXPECT_TRUE(parser_->Parse(data, length, &header));
       if (header.extension.hasTransportSequenceNumber) {
+        EXPECT_EQ(options.packet_id,
+                  header.extension.transportSequenceNumber);
         if (!streams_observed_.empty()) {
           EXPECT_EQ(static_cast<uint16_t>(last_seq_ + 1),
                     header.extension.transportSequenceNumber);
@@ -1377,7 +1383,7 @@
         if (IsDone())
           done_->Set();
       }
-      return test::DirectTransport::SendRtp(data, length);
+      return test::DirectTransport::SendRtp(data, length, options);
     }
 
     bool IsDone() {
diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc
index 488532d..c452e11 100644
--- a/webrtc/video/video_quality_test.cc
+++ b/webrtc/video/video_quality_test.cc
@@ -138,7 +138,9 @@
     input_->IncomingCapturedFrame(video_frame);
   }
 
-  bool SendRtp(const uint8_t* packet, size_t length) override {
+  bool SendRtp(const uint8_t* packet,
+               size_t length,
+               const PacketOptions& options) override {
     rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
     RTPHeader header;
     parser->Parse(packet, length, &header);
@@ -156,7 +158,7 @@
           length - (header.headerLength + header.paddingLength);
     }
 
-    return transport_->SendRtp(packet, length);
+    return transport_->SendRtp(packet, length, options);
   }
 
   bool SendRtcp(const uint8_t* packet, size_t length) override {
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index 3392d85..e4dc320 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -214,9 +214,9 @@
     return 0;
 }
 
-bool
-Channel::SendRtp(const uint8_t *data, size_t len)
-{
+bool Channel::SendRtp(const uint8_t* data,
+                      size_t len,
+                      const PacketOptions& options) {
     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
                  "Channel::SendPacket(channel=%d, len=%" PRIuS ")", len);
 
@@ -233,7 +233,7 @@
     uint8_t* bufferToSendPtr = (uint8_t*)data;
     size_t bufferLength = len;
 
-    if (!_transportPtr->SendRtp(bufferToSendPtr, bufferLength)) {
+    if (!_transportPtr->SendRtp(bufferToSendPtr, bufferLength, options)) {
       std::string transport_name =
           _externalTransport ? "external transport" : "WebRtc sockets";
       WEBRTC_TRACE(kTraceError, kTraceVoice,
diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h
index e7e6d76..a550738 100644
--- a/webrtc/voice_engine/channel.h
+++ b/webrtc/voice_engine/channel.h
@@ -378,7 +378,9 @@
                               uint8_t volume) override;
 
     // From Transport (called by the RTP/RTCP module)
-    bool SendRtp(const uint8_t* data, size_t len) override;
+    bool SendRtp(const uint8_t* data,
+                 size_t len,
+                 const PacketOptions& packet_options) override;
     bool SendRtcp(const uint8_t* data, size_t len) override;
 
     // From MixerParticipant
diff --git a/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc b/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc
index 30ef265..581a768 100644
--- a/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc
+++ b/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc
@@ -108,7 +108,9 @@
   EXPECT_TRUE(webrtc::VoiceEngine::Delete(local_voe_));
 }
 
-bool ConferenceTransport::SendRtp(const uint8_t* data, size_t len) {
+bool ConferenceTransport::SendRtp(const uint8_t* data,
+                                  size_t len,
+                                  const webrtc::PacketOptions& options) {
   StorePacket(Packet::Rtp, data, len);
   return true;
 }
diff --git a/webrtc/voice_engine/test/auto_test/fakes/conference_transport.h b/webrtc/voice_engine/test/auto_test/fakes/conference_transport.h
index 2a770b2..602f07f 100644
--- a/webrtc/voice_engine/test/auto_test/fakes/conference_transport.h
+++ b/webrtc/voice_engine/test/auto_test/fakes/conference_transport.h
@@ -98,7 +98,9 @@
   bool GetReceiverStatistics(unsigned int id, webrtc::CallStatistics* stats);
 
   // Inherit from class webrtc::Transport.
-  bool SendRtp(const uint8_t *data, size_t len) override;
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const webrtc::PacketOptions& options) override;
   bool SendRtcp(const uint8_t *data, size_t len) override;
 
  private:
diff --git a/webrtc/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h b/webrtc/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h
index 422e550..c3bd9e8 100644
--- a/webrtc/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h
+++ b/webrtc/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h
@@ -41,7 +41,9 @@
 
   ~LoopBackTransport() { thread_->Stop(); }
 
-  bool SendRtp(const uint8_t* data, size_t len) override {
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const webrtc::PacketOptions& options) override {
     StorePacket(Packet::Rtp, data, len);
     return true;
   }
diff --git a/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_extensions.cc b/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_extensions.cc
index d4700a9..bc6ce56 100644
--- a/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_extensions.cc
+++ b/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_extensions.cc
@@ -28,7 +28,9 @@
         audio_level_id_(-1),
         absolute_sender_time_id_(-1) {}
 
-  bool SendRtp(const uint8_t* data, size_t len) override {
+  bool SendRtp(const uint8_t* data,
+               size_t len,
+               const webrtc::PacketOptions& options) override {
     webrtc::RTPHeader header;
     if (parser_->Parse(reinterpret_cast<const uint8_t*>(data), len, &header)) {
       bool ok = true;