Use vector of CSRCs for DeliverFrame & SetCSRCs.

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

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

Patch from Changbin Shao <changbin.shao@intel.com>.

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@7734 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/rtp_rtcp/interface/rtp_rtcp.h b/modules/rtp_rtcp/interface/rtp_rtcp.h
index c1250b9..d49c8e3 100644
--- a/modules/rtp_rtcp/interface/rtp_rtcp.h
+++ b/modules/rtp_rtcp/interface/rtp_rtcp.h
@@ -220,37 +220,11 @@
     virtual void SetSSRC(const uint32_t ssrc) = 0;
 
     /*
-    *   Get CSRC
-    *
-    *   arrOfCSRC   - array of CSRCs
-    *
-    *   return -1 on failure else number of valid entries in the array
-    */
-    virtual int32_t CSRCs(
-        uint32_t arrOfCSRC[kRtpCsrcSize]) const = 0;
-
-    /*
     *   Set CSRC
     *
-    *   arrOfCSRC   - array of CSRCs
-    *   arrLength   - number of valid entries in the array
-    *
-    *   return -1 on failure else 0
+    *   csrcs   - vector of CSRCs
     */
-    virtual int32_t SetCSRCs(
-        const uint32_t arrOfCSRC[kRtpCsrcSize],
-        const uint8_t arrLength) = 0;
-
-    /*
-    *   includes CSRCs in RTP header if enabled
-    *
-    *   include CSRC - on/off
-    *
-    *    default:on
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t SetCSRCStatus(const bool include) = 0;
+    virtual void SetCsrcs(const std::vector<uint32_t>& csrcs) = 0;
 
     /*
     * Turn on/off sending RTX (RFC 4588). The modes can be set as a combination
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 7880660..c76347f 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -94,8 +94,7 @@
       void(const uint32_t ssrc));
   MOCK_CONST_METHOD1(CSRCs,
       int32_t(uint32_t arrOfCSRC[kRtpCsrcSize]));
-  MOCK_METHOD2(SetCSRCs,
-      int32_t(const uint32_t arrOfCSRC[kRtpCsrcSize], const uint8_t arrLength));
+  MOCK_METHOD1(SetCsrcs, void(const std::vector<uint32_t>& csrcs));
   MOCK_METHOD1(SetCSRCStatus,
       int32_t(const bool include));
   MOCK_METHOD1(SetRTXSendStatus,
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 9991992..3386d9b 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -114,10 +114,6 @@
 
     last_xr_rr_(),
 
-    _CSRCs(0),
-    _CSRC(),
-    _includeCSRCs(true),
-
     _sequenceNumberFIR(0),
 
     _rembBitrate(0),
@@ -1383,49 +1379,32 @@
     return 0;
 }
 
-int32_t
-RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos)
-{
-    // sanity
-    if(pos + 8 >= IP_PACKET_SIZE)
-    {
-        return -2;
-    }
-    if(_includeCSRCs)
-    {
-        // Add a bye packet
-        rtcpbuffer[pos++]=(uint8_t)0x80 + 1 + _CSRCs;  // number of SSRC+CSRCs
-        rtcpbuffer[pos++]=(uint8_t)203;
+int32_t RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos) {
+  // sanity
+  if (pos + 8 >= IP_PACKET_SIZE) {
+    return -2;
+  }
 
-        // length
-        rtcpbuffer[pos++]=(uint8_t)0;
-        rtcpbuffer[pos++]=(uint8_t)(1 + _CSRCs);
+  // Add a bye packet
+  // Number of SSRC + CSRCs.
+  rtcpbuffer[pos++] = (uint8_t)0x80 + 1 + csrcs_.size();
+  rtcpbuffer[pos++] = (uint8_t)203;
 
-        // Add our own SSRC
-        RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
-        pos += 4;
+  // length
+  rtcpbuffer[pos++] = (uint8_t)0;
+  rtcpbuffer[pos++] = (uint8_t)(1 + csrcs_.size());
 
-        // add CSRCs
-        for(int i = 0; i < _CSRCs; i++)
-        {
-          RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _CSRC[i]);
-            pos += 4;
-        }
-    } else
-    {
-        // Add a bye packet
-        rtcpbuffer[pos++]=(uint8_t)0x80 + 1;  // number of SSRC+CSRCs
-        rtcpbuffer[pos++]=(uint8_t)203;
+  // Add our own SSRC
+  RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
+  pos += 4;
 
-        // length
-        rtcpbuffer[pos++]=(uint8_t)0;
-        rtcpbuffer[pos++]=(uint8_t)1;
+  // add CSRCs
+  for (size_t i = 0; i < csrcs_.size(); i++) {
+    RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, csrcs_[i]);
+    pos += 4;
+  }
 
-        // Add our own SSRC
-        RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
-        pos += 4;
-    }
-    return 0;
+  return 0;
 }
 
 int32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer,
@@ -2013,27 +1992,10 @@
     return -1;
 }
 
-int32_t
-RTCPSender::SetCSRCStatus(const bool include)
-{
-    CriticalSectionScoped lock(_criticalSectionRTCPSender);
-    _includeCSRCs = include;
-    return 0;
-}
-
-int32_t
-RTCPSender::SetCSRCs(const uint32_t arrOfCSRC[kRtpCsrcSize],
-                    const uint8_t arrLength)
-{
-    assert(arrLength <= kRtpCsrcSize);
-    CriticalSectionScoped lock(_criticalSectionRTCPSender);
-
-    for(int i = 0; i < arrLength;i++)
-    {
-        _CSRC[i] = arrOfCSRC[i];
-    }
-    _CSRCs = arrLength;
-    return 0;
+void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
+  assert(csrcs.size() <= kRtpCsrcSize);
+  CriticalSectionScoped lock(_criticalSectionRTCPSender);
+  csrcs_ = csrcs;
 }
 
 int32_t
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index 23f720f..f06a2fe 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -167,10 +167,7 @@
 
     bool RtcpXrReceiverReferenceTime() const;
 
-    int32_t SetCSRCs(const uint32_t arrOfCSRC[kRtpCsrcSize],
-                     const uint8_t arrLength);
-
-    int32_t SetCSRCStatus(const bool include);
+    void SetCsrcs(const std::vector<uint32_t>& csrcs);
 
     void SetTargetBitrate(unsigned int target_bitrate);
 
@@ -325,9 +322,7 @@
         GUARDED_BY(_criticalSectionRTCPSender);
 
     // send CSRCs
-    uint8_t         _CSRCs GUARDED_BY(_criticalSectionRTCPSender);
-    uint32_t        _CSRC[kRtpCsrcSize] GUARDED_BY(_criticalSectionRTCPSender);
-    bool                _includeCSRCs GUARDED_BY(_criticalSectionRTCPSender);
+    std::vector<uint32_t> csrcs_ GUARDED_BY(_criticalSectionRTCPSender);
 
     // Full intra request
     uint8_t         _sequenceNumberFIR GUARDED_BY(_criticalSectionRTCPSender);
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index db10956..7483616 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -382,20 +382,7 @@
   SetRtcpReceiverSsrcs(ssrc);
 }
 
-int32_t ModuleRtpRtcpImpl::SetCSRCStatus(const bool include) {
-  rtcp_sender_.SetCSRCStatus(include);
-  rtp_sender_.SetCSRCStatus(include);
-  return 0;  // TODO(pwestin): change to void.
-}
-
-int32_t ModuleRtpRtcpImpl::CSRCs(
-  uint32_t arr_of_csrc[kRtpCsrcSize]) const {
-  return rtp_sender_.CSRCs(arr_of_csrc);
-}
-
-int32_t ModuleRtpRtcpImpl::SetCSRCs(
-    const uint32_t arr_of_csrc[kRtpCsrcSize],
-    const uint8_t arr_length) {
+void ModuleRtpRtcpImpl::SetCsrcs(const std::vector<uint32_t>& csrcs) {
   if (IsDefaultModule()) {
     // For default we need to update all child modules too.
     CriticalSectionScoped lock(critical_section_module_ptrs_.get());
@@ -404,15 +391,15 @@
     while (it != child_modules_.end()) {
       RtpRtcp* module = *it;
       if (module) {
-        module->SetCSRCs(arr_of_csrc, arr_length);
+        module->SetCsrcs(csrcs);
       }
       it++;
     }
-  } else {
-    rtcp_sender_.SetCSRCs(arr_of_csrc, arr_length);
-    rtp_sender_.SetCSRCs(arr_of_csrc, arr_length);
+    return;
   }
-  return 0;  // TODO(pwestin): change to void.
+
+  rtcp_sender_.SetCsrcs(csrcs);
+  rtp_sender_.SetCsrcs(csrcs);
 }
 
 // TODO(pbos): Handle media and RTX streams separately (separate RTCP
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index 1b7db9f..8af32f3 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -82,12 +82,7 @@
   // Configure SSRC, default is a random number.
   virtual void SetSSRC(const uint32_t ssrc) OVERRIDE;
 
-  virtual int32_t CSRCs(uint32_t arr_of_csrc[kRtpCsrcSize]) const OVERRIDE;
-
-  virtual int32_t SetCSRCs(const uint32_t arr_of_csrc[kRtpCsrcSize],
-                           const uint8_t arr_length) OVERRIDE;
-
-  virtual int32_t SetCSRCStatus(const bool include) OVERRIDE;
+  virtual void SetCsrcs(const std::vector<uint32_t>& csrcs) OVERRIDE;
 
   RTCPSender::FeedbackState GetFeedbackState();
 
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index 38ac859..f1327ac 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -145,16 +145,13 @@
       last_timestamp_time_ms_(0),
       media_has_been_sent_(false),
       last_packet_marker_bit_(false),
-      num_csrcs_(0),
       csrcs_(),
-      include_csrcs_(true),
       rtx_(kRtxOff),
       payload_type_rtx_(-1),
       target_bitrate_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
       target_bitrate_(0) {
   memset(nack_byte_count_times_, 0, sizeof(nack_byte_count_times_));
   memset(nack_byte_count_, 0, sizeof(nack_byte_count_));
-  memset(csrcs_, 0, sizeof(csrcs_));
   // We need to seed the random generator.
   srand(static_cast<uint32_t>(clock_->TimeInMilliseconds()));
   ssrc_ = ssrc_db_.CreateSSRC();  // Can't be 0.
@@ -615,14 +612,9 @@
     }
 
     uint8_t padding_packet[IP_PACKET_SIZE];
-    size_t header_length = CreateRTPHeader(padding_packet,
-                                           payload_type,
-                                           ssrc,
-                                           false,
-                                           timestamp,
-                                           sequence_number,
-                                           NULL,
-                                           0);
+    size_t header_length =
+        CreateRtpHeader(padding_packet, payload_type, ssrc, false, timestamp,
+                        sequence_number, std::vector<uint32_t>());
     assert(header_length != static_cast<size_t>(-1));
     padding_bytes_in_packet = BuildPaddingPacket(padding_packet, header_length);
     assert(padding_bytes_in_packet <= bytes);
@@ -1057,9 +1049,7 @@
 size_t RTPSender::RTPHeaderLength() const {
   CriticalSectionScoped lock(send_critsect_);
   size_t rtp_header_length = 12;
-  if (include_csrcs_) {
-    rtp_header_length += sizeof(uint32_t) * num_csrcs_;
-  }
+  rtp_header_length += sizeof(uint32_t) * csrcs_.size();
   rtp_header_length += RtpHeaderExtensionTotalLength();
   return rtp_header_length;
 }
@@ -1093,10 +1083,13 @@
   *rtx_stats = rtx_rtp_stats_;
 }
 
-int RTPSender::CreateRTPHeader(
-    uint8_t* header, int8_t payload_type, uint32_t ssrc, bool marker_bit,
-    uint32_t timestamp, uint16_t sequence_number, const uint32_t* csrcs,
-    uint8_t num_csrcs) const {
+size_t RTPSender::CreateRtpHeader(uint8_t* header,
+                                  int8_t payload_type,
+                                  uint32_t ssrc,
+                                  bool marker_bit,
+                                  uint32_t timestamp,
+                                  uint16_t sequence_number,
+                                  const std::vector<uint32_t>& csrcs) const {
   header[0] = 0x80;  // version 2.
   header[1] = static_cast<uint8_t>(payload_type);
   if (marker_bit) {
@@ -1107,22 +1100,16 @@
   RtpUtility::AssignUWord32ToBuffer(header + 8, ssrc);
   int32_t rtp_header_length = 12;
 
-  // Add the CSRCs if any.
-  if (num_csrcs > 0) {
-    if (num_csrcs > kRtpCsrcSize) {
-      // error
-      assert(false);
-      return -1;
-    }
+  if (csrcs.size() > 0) {
     uint8_t *ptr = &header[rtp_header_length];
-    for (int i = 0; i < num_csrcs; ++i) {
+    for (size_t i = 0; i < csrcs.size(); ++i) {
       RtpUtility::AssignUWord32ToBuffer(ptr, csrcs[i]);
       ptr += 4;
     }
-    header[0] = (header[0] & 0xf0) | num_csrcs;
+    header[0] = (header[0] & 0xf0) | csrcs.size();
 
     // Update length of header.
-    rtp_header_length += sizeof(uint32_t) * num_csrcs;
+    rtp_header_length += sizeof(uint32_t) * csrcs.size();
   }
 
   uint16_t len = BuildRTPHeaderExtension(header + rtp_header_length);
@@ -1155,11 +1142,8 @@
   uint32_t sequence_number = sequence_number_++;
   capture_time_ms_ = capture_time_ms;
   last_packet_marker_bit_ = marker_bit;
-  int csrcs_length = 0;
-  if (include_csrcs_)
-    csrcs_length = num_csrcs_;
-  return CreateRTPHeader(data_buffer, payload_type, ssrc_, marker_bit,
-                         timestamp_, sequence_number, csrcs_, csrcs_length);
+  return CreateRtpHeader(data_buffer, payload_type, ssrc_, marker_bit,
+                         timestamp_, sequence_number, csrcs_);
 }
 
 uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer) const {
@@ -1547,29 +1531,10 @@
   return ssrc_;
 }
 
-void RTPSender::SetCSRCStatus(const bool include) {
-  CriticalSectionScoped lock(send_critsect_);
-  include_csrcs_ = include;
-}
-
-void RTPSender::SetCSRCs(const uint32_t arr_of_csrc[kRtpCsrcSize],
-                         const uint8_t arr_length) {
-  assert(arr_length <= kRtpCsrcSize);
+void RTPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
+  assert(csrcs.size() <= kRtpCsrcSize);
   CriticalSectionScoped cs(send_critsect_);
-
-  for (int i = 0; i < arr_length; i++) {
-    csrcs_[i] = arr_of_csrc[i];
-  }
-  num_csrcs_ = arr_length;
-}
-
-int32_t RTPSender::CSRCs(uint32_t arr_of_csrc[kRtpCsrcSize]) const {
-  assert(arr_of_csrc);
-  CriticalSectionScoped cs(send_critsect_);
-  for (int i = 0; i < num_csrcs_ && i < kRtpCsrcSize; i++) {
-    arr_of_csrc[i] = csrcs_[i];
-  }
-  return num_csrcs_;
+  csrcs_ = csrcs;
 }
 
 void RTPSender::SetSequenceNumber(uint16_t seq) {
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index 4781aae..0558c19 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -126,12 +126,7 @@
   virtual uint16_t SequenceNumber() const OVERRIDE;
   void SetSequenceNumber(uint16_t seq);
 
-  int32_t CSRCs(uint32_t arr_of_csrc[kRtpCsrcSize]) const;
-
-  void SetCSRCStatus(const bool include);
-
-  void SetCSRCs(const uint32_t arr_of_csrc[kRtpCsrcSize],
-                const uint8_t arr_length);
+  void SetCsrcs(const std::vector<uint32_t>& csrcs);
 
   int32_t SetMaxPayloadLength(const size_t length,
                               const uint16_t packet_over_head);
@@ -292,10 +287,13 @@
   // time.
   typedef std::map<int64_t, int> SendDelayMap;
 
-  int CreateRTPHeader(uint8_t* header, int8_t payload_type,
-                      uint32_t ssrc, bool marker_bit,
-                      uint32_t timestamp, uint16_t sequence_number,
-                      const uint32_t* csrcs, uint8_t csrcs_length) const;
+  size_t CreateRtpHeader(uint8_t* header,
+                         int8_t payload_type,
+                         uint32_t ssrc,
+                         bool marker_bit,
+                         uint32_t timestamp,
+                         uint16_t sequence_number,
+                         const std::vector<uint32_t>& csrcs) const;
 
   void UpdateNACKBitRate(const size_t bytes, const uint32_t now);
 
@@ -395,9 +393,7 @@
   int64_t last_timestamp_time_ms_ GUARDED_BY(send_critsect_);
   bool media_has_been_sent_ 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_);
+  std::vector<uint32_t> 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_);
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.cc b/modules/rtp_rtcp/test/testAPI/test_api.cc
index 3885eb0..1621203 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -18,8 +18,8 @@
 class RtpRtcpAPITest : public ::testing::Test {
  protected:
   RtpRtcpAPITest() : module(NULL), fake_clock(123456) {
-    test_CSRC[0] = 1234;
-    test_CSRC[1] = 2345;
+    test_csrcs.push_back(1234);
+    test_csrcs.push_back(2345);
     test_id = 123;
     test_ssrc = 3456;
     test_timestamp = 4567;
@@ -50,7 +50,7 @@
   uint32_t test_ssrc;
   uint32_t test_timestamp;
   uint16_t test_sequence_number;
-  uint32_t test_CSRC[webrtc::kRtpCsrcSize];
+  std::vector<uint32_t> test_csrcs;
   SimulatedClock fake_clock;
 };
 
@@ -84,14 +84,6 @@
   EXPECT_EQ(test_ssrc, module->SSRC());
 }
 
-TEST_F(RtpRtcpAPITest, CSRC) {
-  EXPECT_EQ(0, module->SetCSRCs(test_CSRC, 2));
-  uint32_t testOfCSRC[webrtc::kRtpCsrcSize];
-  EXPECT_EQ(2, module->CSRCs(testOfCSRC));
-  EXPECT_EQ(test_CSRC[0], testOfCSRC[0]);
-  EXPECT_EQ(test_CSRC[1], testOfCSRC[1]);
-}
-
 TEST_F(RtpRtcpAPITest, RTCP) {
   EXPECT_EQ(kRtcpOff, module->RTCP());
   EXPECT_EQ(0, module->SetRTCPStatus(kRtcpCompound));
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
index 8cbdeb5..96a6691 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
@@ -66,8 +66,8 @@
 class RtpRtcpRtcpTest : public ::testing::Test {
  protected:
   RtpRtcpRtcpTest() : fake_clock(123456) {
-    test_CSRC[0] = 1234;
-    test_CSRC[1] = 2345;
+    test_csrcs.push_back(1234);
+    test_csrcs.push_back(2345);
     test_id = 123;
     test_ssrc = 3456;
     test_timestamp = 4567;
@@ -133,7 +133,8 @@
     module1->SetSSRC(test_ssrc);
     EXPECT_EQ(0, module1->SetSequenceNumber(test_sequence_number));
     EXPECT_EQ(0, module1->SetStartTimestamp(test_timestamp));
-    EXPECT_EQ(0, module1->SetCSRCs(test_CSRC, 2));
+
+    module1->SetCsrcs(test_csrcs);
     EXPECT_EQ(0, module1->SetCNAME("john.doe@test.test"));
 
     EXPECT_EQ(0, module1->SetSendingStatus(true));
@@ -197,7 +198,7 @@
   uint32_t test_ssrc;
   uint32_t test_timestamp;
   uint16_t test_sequence_number;
-  uint32_t test_CSRC[webrtc::kRtpCsrcSize];
+  std::vector<uint32_t> test_csrcs;
   SimulatedClock fake_clock;
 };
 
@@ -209,16 +210,16 @@
 TEST_F(RtpRtcpRtcpTest, RTCP_CNAME) {
   uint32_t testOfCSRC[webrtc::kRtpCsrcSize];
   EXPECT_EQ(2, rtp_receiver2_->CSRCs(testOfCSRC));
-  EXPECT_EQ(test_CSRC[0], testOfCSRC[0]);
-  EXPECT_EQ(test_CSRC[1], testOfCSRC[1]);
+  EXPECT_EQ(test_csrcs[0], testOfCSRC[0]);
+  EXPECT_EQ(test_csrcs[1], testOfCSRC[1]);
 
   // Set cname of mixed.
-  EXPECT_EQ(0, module1->AddMixedCNAME(test_CSRC[0], "john@192.168.0.1"));
-  EXPECT_EQ(0, module1->AddMixedCNAME(test_CSRC[1], "jane@192.168.0.2"));
+  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[0], "john@192.168.0.1"));
+  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
 
-  EXPECT_EQ(-1, module1->RemoveMixedCNAME(test_CSRC[0] + 1));
-  EXPECT_EQ(0, module1->RemoveMixedCNAME(test_CSRC[1]));
-  EXPECT_EQ(0, module1->AddMixedCNAME(test_CSRC[1], "jane@192.168.0.2"));
+  EXPECT_EQ(-1, module1->RemoveMixedCNAME(test_csrcs[0] + 1));
+  EXPECT_EQ(0, module1->RemoveMixedCNAME(test_csrcs[1]));
+  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
 
   // send RTCP packet, triggered by timer
   fake_clock.AdvanceTimeMilliseconds(7500);
@@ -233,10 +234,10 @@
   EXPECT_EQ(0, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
   EXPECT_EQ(0, strncmp(cName, "john.doe@test.test", RTCP_CNAME_SIZE));
 
-  EXPECT_EQ(0, module2->RemoteCNAME(test_CSRC[0], cName));
+  EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[0], cName));
   EXPECT_EQ(0, strncmp(cName, "john@192.168.0.1", RTCP_CNAME_SIZE));
 
-  EXPECT_EQ(0, module2->RemoteCNAME(test_CSRC[1], cName));
+  EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[1], cName));
   EXPECT_EQ(0, strncmp(cName, "jane@192.168.0.2", RTCP_CNAME_SIZE));
 
   EXPECT_EQ(0, module1->SetSendingStatus(false));
@@ -257,10 +258,10 @@
   reportBlock.lastSR = 6;
 
   // Set report blocks.
-  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_CSRC[0], &reportBlock));
+  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_csrcs[0], &reportBlock));
 
   reportBlock.lastSR= 7;
-  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_CSRC[1], &reportBlock));
+  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_csrcs[1], &reportBlock));
 
   uint32_t name = 't' << 24;
   name += 'e' << 16;
@@ -331,7 +332,7 @@
   EXPECT_GE(10, maxRTT);
 
   // Set report blocks.
-  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_CSRC[0], &reportBlock));
+  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_csrcs[0], &reportBlock));
 
   // Test receive report.
   EXPECT_EQ(0, module1->SetSendingStatus(false));
diff --git a/video_engine/mock/mock_vie_frame_provider_base.h b/video_engine/mock/mock_vie_frame_provider_base.h
index d4e17f4..a59fdbf 100644
--- a/video_engine/mock/mock_vie_frame_provider_base.h
+++ b/video_engine/mock/mock_vie_frame_provider_base.h
@@ -17,11 +17,10 @@
 
 class MockViEFrameCallback : public ViEFrameCallback {
  public:
-  MOCK_METHOD4(DeliverFrame,
+  MOCK_METHOD3(DeliverFrame,
                void(int id,
                     I420VideoFrame* video_frame,
-                    int num_csrcs,
-                    const uint32_t CSRC[kRtpCsrcSize]));
+                    const std::vector<uint32_t>& csrcs));
   MOCK_METHOD2(DelayChanged, void(int id, int frame_delay));
   MOCK_METHOD3(GetPreferedFrameSettings,
                int(int* width, int* height, int* frame_rate));
diff --git a/video_engine/vie_capturer.cc b/video_engine/vie_capturer.cc
index 5440b09..1c71c36 100644
--- a/video_engine/vie_capturer.cc
+++ b/video_engine/vie_capturer.cc
@@ -487,7 +487,7 @@
 
 void ViECapturer::DeliverI420Frame(I420VideoFrame* video_frame) {
   if (video_frame->native_handle() != NULL) {
-    ViEFrameProviderBase::DeliverFrame(video_frame);
+    ViEFrameProviderBase::DeliverFrame(video_frame, std::vector<uint32_t>());
     return;
   }
 
@@ -534,7 +534,7 @@
                               video_frame->height());
   }
   // Deliver the captured frame to all observers (channels, renderer or file).
-  ViEFrameProviderBase::DeliverFrame(video_frame);
+  ViEFrameProviderBase::DeliverFrame(video_frame, std::vector<uint32_t>());
 }
 
 int ViECapturer::DeregisterFrameCallback(
diff --git a/video_engine/vie_capturer_unittest.cc b/video_engine/vie_capturer_unittest.cc
index edaf13b..92ef786 100644
--- a/video_engine/vie_capturer_unittest.cc
+++ b/video_engine/vie_capturer_unittest.cc
@@ -69,7 +69,7 @@
   virtual void SetUp() {
     EXPECT_CALL(*mock_capture_module_, RegisterCaptureDataCallback(_))
         .WillRepeatedly(Invoke(this, &ViECapturerTest::SetCaptureDataCallback));
-    EXPECT_CALL(*mock_frame_callback_, DeliverFrame(_, _, _, _))
+    EXPECT_CALL(*mock_frame_callback_, DeliverFrame(_, _, _))
         .WillRepeatedly(
             WithArg<1>(Invoke(this, &ViECapturerTest::AddOutputFrame)));
 
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc
index 60ab009..2918313 100644
--- a/video_engine/vie_channel.cc
+++ b/video_engine/vie_channel.cc
@@ -1497,7 +1497,9 @@
     arr_ofCSRC[0] = vie_receiver_.GetRemoteSsrc();
     no_of_csrcs = 1;
   }
-  DeliverFrame(&video_frame, no_of_csrcs, arr_ofCSRC);
+  std::vector<uint32_t> csrcs(arr_ofCSRC, arr_ofCSRC + no_of_csrcs);
+  DeliverFrame(&video_frame, csrcs);
+
   return 0;
 }
 
diff --git a/video_engine/vie_encoder.cc b/video_engine/vie_encoder.cc
index a5ac55a..8bd40df 100644
--- a/video_engine/vie_encoder.cc
+++ b/video_engine/vie_encoder.cc
@@ -501,8 +501,7 @@
 
 void ViEEncoder::DeliverFrame(int id,
                               I420VideoFrame* video_frame,
-                              int num_csrcs,
-                              const uint32_t CSRC[kRtpCsrcSize]) {
+                              const std::vector<uint32_t>& csrcs) {
   if (default_rtp_rtcp_->SendingMedia() == false) {
     // We've paused or we have no channels attached, don't encode.
     return;
@@ -528,16 +527,16 @@
   video_frame->set_timestamp(time_stamp);
 
   // Make sure the CSRC list is correct.
-  if (num_csrcs > 0) {
-    uint32_t tempCSRC[kRtpCsrcSize];
-    for (int i = 0; i < num_csrcs; i++) {
-      if (CSRC[i] == 1) {
-        tempCSRC[i] = default_rtp_rtcp_->SSRC();
+  if (csrcs.size() > 0) {
+    std::vector<uint32_t> temp_csrcs(csrcs.size());
+    for (size_t i = 0; i < csrcs.size(); i++) {
+      if (csrcs[i] == 1) {
+        temp_csrcs[i] = default_rtp_rtcp_->SSRC();
       } else {
-        tempCSRC[i] = CSRC[i];
+        temp_csrcs[i] = csrcs[i];
       }
     }
-    default_rtp_rtcp_->SetCSRCs(tempCSRC, (uint8_t) num_csrcs);
+    default_rtp_rtcp_->SetCsrcs(temp_csrcs);
   }
 
   I420VideoFrame* decimated_frame = NULL;
diff --git a/video_engine/vie_encoder.h b/video_engine/vie_encoder.h
index effb78f..0084722 100644
--- a/video_engine/vie_encoder.h
+++ b/video_engine/vie_encoder.h
@@ -95,8 +95,7 @@
   // Implementing ViEFrameCallback.
   virtual void DeliverFrame(int id,
                             I420VideoFrame* video_frame,
-                            int num_csrcs = 0,
-                            const uint32_t CSRC[kRtpCsrcSize] = NULL) OVERRIDE;
+                            const std::vector<uint32_t>& csrcs) OVERRIDE;
   virtual void DelayChanged(int id, int frame_delay) OVERRIDE;
   virtual int GetPreferedFrameSettings(int* width,
                                        int* height,
diff --git a/video_engine/vie_frame_provider_base.cc b/video_engine/vie_frame_provider_base.cc
index a5cd838..d442cd1 100644
--- a/video_engine/vie_frame_provider_base.cc
+++ b/video_engine/vie_frame_provider_base.cc
@@ -44,10 +44,8 @@
   return id_;
 }
 
-void ViEFrameProviderBase::DeliverFrame(
-    I420VideoFrame* video_frame,
-    int num_csrcs,
-    const uint32_t CSRC[kRtpCsrcSize]) {
+void ViEFrameProviderBase::DeliverFrame(I420VideoFrame* video_frame,
+                                        const std::vector<uint32_t>& csrcs) {
 #ifdef DEBUG_
   const TickTime start_process_time = TickTime::Now();
 #endif
@@ -57,19 +55,19 @@
   if (frame_callbacks_.size() > 0) {
     if (frame_callbacks_.size() == 1) {
       // We don't have to copy the frame.
-      frame_callbacks_.front()->DeliverFrame(id_, video_frame, num_csrcs, CSRC);
+      frame_callbacks_.front()->DeliverFrame(id_, video_frame, csrcs);
     } else {
       for (FrameCallbacks::iterator it = frame_callbacks_.begin();
            it != frame_callbacks_.end(); ++it) {
         if (video_frame->native_handle() != NULL) {
-          (*it)->DeliverFrame(id_, video_frame, num_csrcs, CSRC);
+          (*it)->DeliverFrame(id_, video_frame, csrcs);
         } else {
           // Make a copy of the frame for all callbacks.
           if (!extra_frame_.get()) {
             extra_frame_.reset(new I420VideoFrame());
           }
           extra_frame_->CopyFrame(*video_frame);
-          (*it)->DeliverFrame(id_, extra_frame_.get(), num_csrcs, CSRC);
+          (*it)->DeliverFrame(id_, extra_frame_.get(), csrcs);
         }
       }
     }
diff --git a/video_engine/vie_frame_provider_base.h b/video_engine/vie_frame_provider_base.h
index e5a137b..fdb2a48 100644
--- a/video_engine/vie_frame_provider_base.h
+++ b/video_engine/vie_frame_provider_base.h
@@ -29,8 +29,7 @@
  public:
   virtual void DeliverFrame(int id,
                             I420VideoFrame* video_frame,
-                            int num_csrcs = 0,
-                            const uint32_t CSRC[kRtpCsrcSize] = NULL) = 0;
+                            const std::vector<uint32_t>& csrcs) = 0;
 
   // The capture delay has changed from the provider. |frame_delay| is given in
   // ms.
@@ -76,8 +75,7 @@
 
  protected:
   void DeliverFrame(I420VideoFrame* video_frame,
-                    int num_csrcs = 0,
-                    const uint32_t CSRC[kRtpCsrcSize] = NULL);
+                    const std::vector<uint32_t>& csrcs);
   void SetFrameDelay(int frame_delay);
   int FrameDelay();
   int GetBestFormat(int* best_width,
diff --git a/video_engine/vie_renderer.cc b/video_engine/vie_renderer.cc
index 2f1c136..5a2b7e2 100644
--- a/video_engine/vie_renderer.cc
+++ b/video_engine/vie_renderer.cc
@@ -137,8 +137,7 @@
 
 void ViERenderer::DeliverFrame(int id,
                                I420VideoFrame* video_frame,
-                               int num_csrcs,
-                               const uint32_t CSRC[kRtpCsrcSize]) {
+                               const std::vector<uint32_t>& csrcs) {
   render_callback_->RenderFrame(render_id_, *video_frame);
 }
 
diff --git a/video_engine/vie_renderer.h b/video_engine/vie_renderer.h
index 907735c..67efaee 100644
--- a/video_engine/vie_renderer.h
+++ b/video_engine/vie_renderer.h
@@ -103,8 +103,7 @@
   // Implement ViEFrameCallback
   virtual void DeliverFrame(int id,
                             I420VideoFrame* video_frame,
-                            int num_csrcs = 0,
-                            const uint32_t CSRC[kRtpCsrcSize] = NULL);
+                            const std::vector<uint32_t>& csrcs);
   virtual void DelayChanged(int id, int frame_delay);
   virtual int GetPreferedFrameSettings(int* width,
                                        int* height,