Add test to verify that padding only frames are passing through the RTP module.

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@3224 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/modules.gyp b/modules/modules.gyp
index 3244357..29d03ec 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -45,7 +45,6 @@
         'audio_processing/audio_processing_tests.gypi',
         'rtp_rtcp/source/rtp_rtcp_tests.gypi',
         'rtp_rtcp/test/testFec/test_fec.gypi',
-        'rtp_rtcp/test/testAPI/test_api.gypi',
         'video_coding/main/source/video_coding_test.gypi',
         'video_coding/codecs/test/video_codecs_test_framework.gypi',
         'video_coding/codecs/tools/video_codecs_tools.gypi',
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 789eaf1..051fc44 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -522,6 +522,12 @@
                  "%s invalid argument", __FUNCTION__);
     return -1;
   }
+  std::map<WebRtc_UWord32, RTCPReportBlock*>::iterator it =
+      _reportBlocks.find(SSRC);
+  if (it != _reportBlocks.end()) {
+    delete it->second;
+    _reportBlocks.erase(it);
+  }
   RTCPReportBlock* copyReportBlock = new RTCPReportBlock();
   memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock));
   _reportBlocks[SSRC] = copyReportBlock;
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi b/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi
index 74f9a2d..4ca6819 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi
+++ b/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi
@@ -22,6 +22,12 @@
         '../../../',
       ],
       'sources': [
+        '../test/testAPI/test_api.cc',
+        '../test/testAPI/test_api.h',
+        '../test/testAPI/test_api_audio.cc',
+        '../test/testAPI/test_api_nack.cc',
+        '../test/testAPI/test_api_rtcp.cc',
+        '../test/testAPI/test_api_video.cc',
         'fec_test_helper.cc',
         'fec_test_helper.h',
         'producer_fec_unittest.cc',
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.cc b/modules/rtp_rtcp/test/testAPI/test_api.cc
index f2fe144..3503af2 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -24,7 +24,7 @@
  protected:
   RtpRtcpAPITest() {
     test_CSRC[0] = 1234;
-    test_CSRC[2] = 2345;
+    test_CSRC[1] = 2345;
     test_id = 123;
     test_ssrc = 3456;
     test_timestamp = 4567;
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.gypi b/modules/rtp_rtcp/test/testAPI/test_api.gypi
deleted file mode 100644
index eaa3a72..0000000
--- a/modules/rtp_rtcp/test/testAPI/test_api.gypi
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
-#
-# Use of this source code is governed by a BSD-style license
-# that can be found in the LICENSE file in the root of the source
-# tree. An additional intellectual property rights grant can be found
-# in the file PATENTS.  All contributing project authors may
-# be found in the AUTHORS file in the root of the source tree.
-
-{
-  'targets': [
-    {
-      'target_name': 'test_rtp_rtcp_api',
-      'type': 'executable',
-      'dependencies': [
-        'rtp_rtcp',
-        '<(webrtc_root)/test/test.gyp:test_support_main',
-        '<(DEPTH)/testing/gtest.gyp:gtest',
-      ],
-      
-      'include_dirs': [
-        '../../interface',
-        '../../source',
-        '../../../../system_wrappers/interface',
-      ],
-   
-      'sources': [
-        'test_api.cc',
-        'test_api_audio.cc',
-        'test_api_nack.cc',
-        'test_api_rtcp.cc',
-        'test_api_video.cc',
-      ],
-      
-    },
-  ],
-}
-
-# Local Variables:
-# tab-width:2
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.h b/modules/rtp_rtcp/test/testAPI/test_api.h
index 6261d7f..3e4f2d6 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.h
+++ b/modules/rtp_rtcp/test/testAPI/test_api.h
@@ -77,12 +77,35 @@
 
 class RtpReceiver : public RtpData {
  public:
-   virtual WebRtc_Word32 OnReceivedPayloadData(
-       const WebRtc_UWord8* payloadData,
-       const WebRtc_UWord16 payloadSize,
-       const webrtc::WebRtcRTPHeader* rtpHeader) {
+  enum { kMaxPayloadSize = 1500 };
+
+  virtual WebRtc_Word32 OnReceivedPayloadData(
+      const WebRtc_UWord8* payloadData,
+      const WebRtc_UWord16 payloadSize,
+      const webrtc::WebRtcRTPHeader* rtpHeader) {
+    EXPECT_LE(payloadSize, kMaxPayloadSize);
+    memcpy(_payloadData, payloadData, payloadSize);
+    memcpy(&_rtpHeader, rtpHeader, sizeof(_rtpHeader));
+    _payloadSize = payloadSize;
     return 0;
   }
+
+  const WebRtc_UWord8* payload_data() const {
+    return _payloadData;
+  }
+
+  WebRtc_UWord16 payload_size() const {
+    return _payloadSize;
+  }
+
+  webrtc::WebRtcRTPHeader rtp_header() const {
+    return _rtpHeader;
+  }
+
+ private:
+  WebRtc_UWord8 _payloadData[kMaxPayloadSize];
+  WebRtc_UWord16 _payloadSize;
+  webrtc::WebRtcRTPHeader _rtpHeader;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_audio.cc b/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
index bf88ace..ce899d7 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
@@ -328,5 +328,4 @@
     fake_clock.IncrementTime(20);
     module1->Process();
   }
-  delete audioFeedback;
 }
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
index 833f867..d25d4cb 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
@@ -10,10 +10,10 @@
 
 #include <algorithm>
 #include <vector>
-#include <gtest/gtest.h>
 
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
 #include "test_api.h"
-
 #include "common_types.h"
 #include "rtp_rtcp.h"
 #include "rtp_rtcp_defines.h"
@@ -80,7 +80,7 @@
  protected:
   RtpRtcpRtcpTest() {
     test_CSRC[0] = 1234;
-    test_CSRC[2] = 2345;
+    test_CSRC[1] = 2345;
     test_id = 123;
     test_ssrc = 3456;
     test_timestamp = 4567;
@@ -97,11 +97,12 @@
 
     RtpRtcp::Configuration configuration;
     configuration.id = test_id;
-    configuration.audio = false;
+    configuration.audio = true;
     configuration.clock = &fake_clock;
     configuration.outgoing_transport = transport1;
     configuration.rtcp_feedback = myRTCPFeedback1;
     configuration.intra_frame_callback = myRTCPFeedback1;
+    configuration.incoming_data = receiver;
 
     module1 = RtpRtcp::CreateRtpRtcp(configuration);
 
@@ -150,6 +151,8 @@
   virtual void TearDown() {
     delete module1;
     delete module2;
+    delete myRTCPFeedback1;
+    delete myRTCPFeedback2;
     delete transport1;
     delete transport2;
     delete receiver;
@@ -217,6 +220,8 @@
 
 TEST_F(RtpRtcpRtcpTest, RTCP) {
   RTCPReportBlock reportBlock;
+  reportBlock.remoteSSRC = 1;
+  reportBlock.sourceSSRC = 2;
   reportBlock.cumulativeLost = 1;
   reportBlock.delaySinceLastSR = 2;
   reportBlock.extendedHighSeqNum = 3;
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_video.cc b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
index fdd3ed3..7a9d3db 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_video.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
@@ -8,88 +8,157 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <stdlib.h>
+
 #include <algorithm>
 #include <vector>
-#include <gtest/gtest.h>
 
-#include "test_api.h"
+#include "gtest/gtest.h"
+#include "webrtc/common_types.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
 
-#include "common_types.h"
-#include "rtp_rtcp.h"
-#include "rtp_rtcp_defines.h"
-
-using namespace webrtc;
+namespace webrtc {
 
 class RtpRtcpVideoTest : public ::testing::Test {
  protected:
-  RtpRtcpVideoTest() {
-    test_id = 123;
-    test_ssrc = 3456;
-    test_timestamp = 4567;
-    test_sequence_number = 2345;
+  RtpRtcpVideoTest()
+      : test_id_(123),
+        test_ssrc_(3456),
+        test_timestamp_(4567),
+        test_sequence_number_(2345) {
   }
   ~RtpRtcpVideoTest() {}
 
   virtual void SetUp() {
-    transport = new LoopBackTransport();
-    receiver = new RtpReceiver();
+    transport_ = new LoopBackTransport();
+    receiver_ = new RtpReceiver();
     RtpRtcp::Configuration configuration;
-    configuration.id = test_id;
+    configuration.id = test_id_;
     configuration.audio = false;
     configuration.clock = &fake_clock;
-    configuration.incoming_data = receiver;
-    configuration.outgoing_transport = transport;
+    configuration.incoming_data = receiver_;
+    configuration.outgoing_transport = transport_;
 
-    video_module = RtpRtcp::CreateRtpRtcp(configuration);
+    video_module_ = RtpRtcp::CreateRtpRtcp(configuration);
 
-    EXPECT_EQ(0, video_module->SetRTCPStatus(kRtcpCompound));
-    EXPECT_EQ(0, video_module->SetSSRC(test_ssrc));
-    EXPECT_EQ(0, video_module->SetNACKStatus(kNackRtcp));
-    EXPECT_EQ(0, video_module->SetStorePacketsStatus(true));
-    EXPECT_EQ(0, video_module->SetSendingStatus(true));
+    EXPECT_EQ(0, video_module_->SetRTCPStatus(kRtcpCompound));
+    EXPECT_EQ(0, video_module_->SetSSRC(test_ssrc_));
+    EXPECT_EQ(0, video_module_->SetNACKStatus(kNackRtcp));
+    EXPECT_EQ(0, video_module_->SetStorePacketsStatus(true));
+    EXPECT_EQ(0, video_module_->SetSendingStatus(true));
 
-    transport->SetSendModule(video_module);
+    transport_->SetSendModule(video_module_);
 
     VideoCodec video_codec;
     memset(&video_codec, 0, sizeof(video_codec));
     video_codec.plType = 123;
     memcpy(video_codec.plName, "I420", 5);
 
-    EXPECT_EQ(0, video_module->RegisterSendPayload(video_codec));
-    EXPECT_EQ(0, video_module->RegisterReceivePayload(video_codec));
+    EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec));
+    EXPECT_EQ(0, video_module_->RegisterReceivePayload(video_codec));
 
-    payload_data_length = sizeof(payload_data);
+    payload_data_length_ = sizeof(video_frame_);
 
-    for (int n = 0; n < payload_data_length; n++) {
-      payload_data[n] = n%10;
+    for (int n = 0; n < payload_data_length_; n++) {
+      video_frame_[n] = n%10;
     }
   }
 
-  virtual void TearDown() {
-    delete video_module;
-    delete transport;
-    delete receiver;
+  WebRtc_Word32 BuildRTPheader(WebRtc_UWord8* dataBuffer,
+                               WebRtc_UWord32 timestamp,
+                               WebRtc_UWord32 sequence_number) {
+    dataBuffer[0] = static_cast<WebRtc_UWord8>(0x80);  // version 2
+    dataBuffer[1] = static_cast<WebRtc_UWord8>(kPayloadType);
+    ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer + 2,
+                                                    sequence_number);
+    ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 4, timestamp);
+    ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 8,
+                                                    0x1234);  // SSRC.
+    WebRtc_Word32 rtpHeaderLength = 12;
+    return rtpHeaderLength;
   }
 
-  int test_id;
-  RtpRtcp* video_module;
-  LoopBackTransport* transport;
-  RtpReceiver* receiver;
-  WebRtc_UWord32 test_ssrc;
-  WebRtc_UWord32 test_timestamp;
-  WebRtc_UWord16 test_sequence_number;
-  WebRtc_UWord8  payload_data[65000];
-  int payload_data_length;
+  int PaddingPacket(uint8_t* buffer,
+                    WebRtc_UWord32 timestamp,
+                    WebRtc_UWord32 sequence_number,
+                    WebRtc_Word32 bytes) {
+    // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
+    int max_length = 224;
+
+    int padding_bytes_in_packet = max_length;
+    if (bytes < max_length) {
+      padding_bytes_in_packet = (bytes + 16) & 0xffe0;  // Keep our modulus 32.
+    }
+    // Correct seq num, timestamp and payload type.
+    int header_length = BuildRTPheader(buffer, timestamp,
+                                       sequence_number);
+    buffer[0] |= 0x20;  // Set padding bit.
+    WebRtc_Word32* data =
+        reinterpret_cast<WebRtc_Word32*>(&(buffer[header_length]));
+
+    // Fill data buffer with random data.
+    for (int j = 0; j < (padding_bytes_in_packet >> 2); j++) {
+      data[j] = rand();  // NOLINT
+    }
+    // Set number of padding bytes in the last byte of the packet.
+    buffer[header_length + padding_bytes_in_packet - 1] =
+        padding_bytes_in_packet;
+    return padding_bytes_in_packet + header_length;
+  }
+
+  virtual void TearDown() {
+    delete video_module_;
+    delete transport_;
+    delete receiver_;
+  }
+
+  int test_id_;
+  RtpRtcp* video_module_;
+  LoopBackTransport* transport_;
+  RtpReceiver* receiver_;
+  WebRtc_UWord32 test_ssrc_;
+  WebRtc_UWord32 test_timestamp_;
+  WebRtc_UWord16 test_sequence_number_;
+  WebRtc_UWord8  video_frame_[65000];
+  int payload_data_length_;
   FakeRtpRtcpClock fake_clock;
+  enum { kPayloadType = 100 };
 };
 
 TEST_F(RtpRtcpVideoTest, BasicVideo) {
   WebRtc_UWord32 timestamp = 3000;
-  EXPECT_EQ(0, video_module->SendOutgoingData(webrtc::kVideoFrameDelta, 123,
-                                             timestamp,
-                                             timestamp / 90,
-                                             payload_data,
-                                             payload_data_length));
-
+  EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123,
+                                               timestamp,
+                                               timestamp / 90,
+                                               video_frame_,
+                                               payload_data_length_));
 }
 
+TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {
+  const int kPadSize = 255;
+  uint8_t padding_packet[kPadSize];
+  uint32_t seq_num = 0;
+  uint32_t timestamp = 3000;
+  VideoCodec codec;
+  codec.codecType = kVideoCodecVP8;
+  codec.plType = kPayloadType;
+  strncpy(codec.plName, "VP8", 4);
+  EXPECT_EQ(0, video_module_->RegisterReceivePayload(codec));
+  for (int frame_idx = 0; frame_idx < 10; ++frame_idx) {
+    for (int packet_idx = 0; packet_idx < 5; ++packet_idx) {
+      int packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
+                                      kPadSize);
+      ++seq_num;
+      EXPECT_EQ(0, video_module_->IncomingPacket(padding_packet, packet_size));
+      EXPECT_EQ(0, receiver_->payload_size());
+      EXPECT_EQ(packet_size - 12, receiver_->rtp_header().header.paddingLength);
+    }
+    timestamp += 3000;
+    fake_clock.IncrementTime(33);
+  }
+}
+
+}  // namespace webrtc