Enqueue packet in pacer if sending fails

If a packet cannot be sent while pacer is in use it should be
queued. This avoid packet loss due to congestion.

BUG=1930
R=pwestin@webrtc.org, wu@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4250 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
index 2110429..5d11448 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
+++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
@@ -486,7 +486,7 @@
         const RTPFragmentationHeader* fragmentation = NULL,
         const RTPVideoHeader* rtpVideoHdr = NULL) = 0;
 
-    virtual void TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number,
+    virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number,
                                   int64_t capture_time_ms) = 0;
 
     virtual int TimeToSendPadding(int bytes) = 0;
diff --git a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 34d3ca4..0d39f8b 100644
--- a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -156,7 +156,7 @@
               const RTPFragmentationHeader* fragmentation,
               const RTPVideoHeader* rtpVideoHdr));
   MOCK_METHOD3(TimeToSendPacket,
-      void(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms));
+      bool(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms));
   MOCK_METHOD1(TimeToSendPadding,
       int(int bytes));
   MOCK_METHOD3(RegisterRtcpObservers,
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index c5defe8..99cadf2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -967,7 +967,7 @@
   return ret_val;
 }
 
-void ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc,
+bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc,
                                          uint16_t sequence_number,
                                          int64_t capture_time_ms) {
   WEBRTC_TRACE(
@@ -985,19 +985,21 @@
   if (no_child_modules) {
     // Don't send from default module.
     if (SendingMedia() && ssrc == rtp_sender_.SSRC()) {
-      rtp_sender_.TimeToSendPacket(sequence_number, capture_time_ms);
+      return rtp_sender_.TimeToSendPacket(sequence_number, capture_time_ms);
     }
   } else {
     CriticalSectionScoped lock(critical_section_module_ptrs_.get());
     std::list<ModuleRtpRtcpImpl*>::iterator it = child_modules_.begin();
     while (it != child_modules_.end()) {
       if ((*it)->SendingMedia() && ssrc == (*it)->rtp_sender_.SSRC()) {
-        (*it)->rtp_sender_.TimeToSendPacket(sequence_number, capture_time_ms);
-        return;
+        return (*it)->rtp_sender_.TimeToSendPacket(sequence_number,
+                                                   capture_time_ms);
       }
       ++it;
     }
   }
+  // No RTP sender is interested in sending this packet.
+  return true;
 }
 
 int ModuleRtpRtcpImpl::TimeToSendPadding(int bytes) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index 891d5b8..c70f7cb 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -188,7 +188,7 @@
       const RTPFragmentationHeader* fragmentation = NULL,
       const RTPVideoHeader* rtp_video_hdr = NULL);
 
-  virtual void TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number,
+  virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number,
                                 int64_t capture_time_ms);
   // Returns the number of padding bytes actually sent, which can be more or
   // less than |bytes|.
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
index 07a3f1b..744bbe2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -701,7 +701,7 @@
 }
 
 // Called from pacer when we can send the packet.
-void RTPSender::TimeToSendPacket(uint16_t sequence_number,
+bool RTPSender::TimeToSendPacket(uint16_t sequence_number,
                                  int64_t capture_time_ms) {
   StorageType type;
   uint16_t length = IP_PACKET_SIZE;
@@ -709,11 +709,13 @@
   int64_t stored_time_ms;
 
   if (packet_history_ == NULL) {
-    return;
+    // Packet cannot be found. Allow sending to continue.
+    return true;
   }
   if (!packet_history_->GetRTPPacket(sequence_number, 0, data_buffer, &length,
                                      &stored_time_ms, &type)) {
-    return;
+    // Packet cannot be found. Allow sending to continue.
+    return true;
   }
   assert(length > 0);
 
@@ -736,7 +738,7 @@
                                       rtp_header.sequenceNumber,
                                       rtp_header.headerLength);
   }
-  SendPacketToNetwork(data_buffer, length);
+  return SendPacketToNetwork(data_buffer, length);
 }
 
 int RTPSender::TimeToSendPadding(int bytes) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
index 1efba85..61dc1c5 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
@@ -165,7 +165,7 @@
                               const RTPHeader &rtp_header,
                               const int64_t now_ms) const;
 
-  void TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms);
+  bool TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms);
   int TimeToSendPadding(int bytes);
 
   // NACK.