[rtp_rtcp] rtcp::Tmmbn moved into own file
explicetly unchanged.

BUG=webrtc:5260
R=åsapersson

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

Cr-Commit-Position: refs/heads/master@{#11201}
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index e3698e2..729f567 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -313,6 +313,7 @@
                 'rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc',
                 'rtp_rtcp/source/rtcp_packet/report_block_unittest.cc',
                 'rtp_rtcp/source/rtcp_packet/rrtr_unittest.cc',
+                'rtp_rtcp/source/rtcp_packet/tmmbn_unittest.cc',
                 'rtp_rtcp/source/rtcp_packet/transport_feedback_unittest.cc',
                 'rtp_rtcp/source/rtcp_packet/voip_metric_unittest.cc',
                 'rtp_rtcp/source/rtcp_receiver_unittest.cc',
diff --git a/webrtc/modules/rtp_rtcp/BUILD.gn b/webrtc/modules/rtp_rtcp/BUILD.gn
index 41d3014..a404093 100644
--- a/webrtc/modules/rtp_rtcp/BUILD.gn
+++ b/webrtc/modules/rtp_rtcp/BUILD.gn
@@ -68,6 +68,8 @@
     "source/rtcp_packet/rrtr.h",
     "source/rtcp_packet/rtpfb.cc",
     "source/rtcp_packet/rtpfb.h",
+    "source/rtcp_packet/tmmbn.cc",
+    "source/rtcp_packet/tmmbn.h",
     "source/rtcp_packet/transport_feedback.cc",
     "source/rtcp_packet/transport_feedback.h",
     "source/rtcp_packet/voip_metric.cc",
diff --git a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
index 3419d7f..febc31d 100644
--- a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
+++ b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
@@ -63,6 +63,8 @@
         'source/rtcp_packet/rrtr.h',
         'source/rtcp_packet/rtpfb.cc',
         'source/rtcp_packet/rtpfb.h',
+        'source/rtcp_packet/tmmbn.cc',
+        'source/rtcp_packet/tmmbn.h',
         'source/rtcp_packet/transport_feedback.cc',
         'source/rtcp_packet/transport_feedback.h',
         'source/rtcp_packet/voip_metric.cc',
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
index 7a9fb9b..1126bea 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
@@ -39,8 +39,6 @@
 using webrtc::RTCPUtility::RTCPPacketReportBlockItem;
 using webrtc::RTCPUtility::RTCPPacketRTPFBNACK;
 using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem;
-using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN;
-using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBNItem;
 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR;
 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem;
 using webrtc::RTCPUtility::RTCPPacketSR;
@@ -297,29 +295,6 @@
   CreateTmmbrItem(tmmbr_item, buffer, pos);
 }
 
-// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
-//
-// FCI:
-//
-//    0                   1                   2                   3
-//    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//   |                              SSRC                             |
-//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//   | MxTBR Exp |  MxTBR Mantissa                 |Measured Overhead|
-//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateTmmbn(const RTCPPacketRTPFBTMMBN& tmmbn,
-                 const std::vector<RTCPPacketRTPFBTMMBRItem>& tmmbn_items,
-                 uint8_t* buffer,
-                 size_t* pos) {
-  AssignUWord32(buffer, pos, tmmbn.SenderSSRC);
-  AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0);
-  for (uint8_t i = 0; i < tmmbn_items.size(); ++i) {
-    CreateTmmbrItem(tmmbn_items[i], buffer, pos);
-  }
-}
-
 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
 //
 //    0                   1                   2                   3
@@ -664,34 +639,6 @@
   return true;
 }
 
-bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) {
-  assert(overhead <= 0x1ff);
-  if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) {
-    LOG(LS_WARNING) << "Max TMMBN size reached.";
-    return false;
-  }
-  RTCPPacketRTPFBTMMBRItem tmmbn_item;
-  tmmbn_item.SSRC = ssrc;
-  tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps;
-  tmmbn_item.MeasuredOverhead = overhead;
-  tmmbn_items_.push_back(tmmbn_item);
-  return true;
-}
-
-bool Tmmbn::Create(uint8_t* packet,
-                   size_t* index,
-                   size_t max_length,
-                   RtcpPacket::PacketReadyCallback* callback) const {
-  while (*index + BlockLength() > max_length) {
-    if (!OnBufferFull(packet, index, callback))
-      return false;
-  }
-  const uint8_t kFmt = 4;
-  CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index);
-  CreateTmmbn(tmmbn_, tmmbn_items_, packet, index);
-  return true;
-}
-
 bool Xr::Create(uint8_t* packet,
                 size_t* index,
                 size_t max_length,
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
index 5aa3340..22d8ed1 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
@@ -479,52 +479,6 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr);
 };
 
-// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
-//
-// FCI:
-//
-//    0                   1                   2                   3
-//    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//   |                              SSRC                             |
-//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//   | MxTBR Exp |  MxTBR Mantissa                 |Measured Overhead|
-//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-class Tmmbn : public RtcpPacket {
- public:
-  Tmmbn() : RtcpPacket() {
-    memset(&tmmbn_, 0, sizeof(tmmbn_));
-  }
-
-  virtual ~Tmmbn() {}
-
-  void From(uint32_t ssrc) {
-    tmmbn_.SenderSSRC = ssrc;
-  }
-  // Max 50 TMMBR can be added per TMMBN.
-  bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead);
-
- protected:
-  bool Create(uint8_t* packet,
-              size_t* index,
-              size_t max_length,
-              RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
-  static const int kMaxNumberOfTmmbrs = 50;
-
-  size_t BlockLength() const {
-    const size_t kFciLen = 8;
-    return kCommonFbFmtLength + kFciLen * tmmbn_items_.size();
-  }
-
-  RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_;
-  std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbn);
-};
-
 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
 //
 //    0                   1                   2                   3
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
new file mode 100644
index 0000000..fd0219c
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
@@ -0,0 +1,119 @@
+/*
+ *  Copyright (c) 2016 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.
+ */
+
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
+
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::RTCPUtility::PT_RTPFB;
+using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN;
+using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem;
+
+namespace webrtc {
+namespace rtcp {
+namespace {
+const uint32_t kUnusedMediaSourceSsrc0 = 0;
+void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) {
+  buffer[(*offset)++] = value;
+}
+void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
+  ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value);
+  *offset += 4;
+}
+
+void ComputeMantissaAnd6bitBase2Exponent(uint32_t input_base10,
+                                         uint8_t bits_mantissa,
+                                         uint32_t* mantissa,
+                                         uint8_t* exp) {
+  // input_base10 = mantissa * 2^exp
+  assert(bits_mantissa <= 32);
+  uint32_t mantissa_max = (1 << bits_mantissa) - 1;
+  uint8_t exponent = 0;
+  for (uint32_t i = 0; i < 64; ++i) {
+    if (input_base10 <= (mantissa_max << i)) {
+      exponent = i;
+      break;
+    }
+  }
+  *exp = exponent;
+  *mantissa = (input_base10 >> exponent);
+}
+
+void CreateTmmbrItem(const RTCPPacketRTPFBTMMBRItem& tmmbr_item,
+                     uint8_t* buffer,
+                     size_t* pos) {
+  uint32_t bitrate_bps = tmmbr_item.MaxTotalMediaBitRate * 1000;
+  uint32_t mantissa = 0;
+  uint8_t exp = 0;
+  ComputeMantissaAnd6bitBase2Exponent(bitrate_bps, 17, &mantissa, &exp);
+
+  AssignUWord32(buffer, pos, tmmbr_item.SSRC);
+  AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 15) & 0x03));
+  AssignUWord8(buffer, pos, mantissa >> 7);
+  AssignUWord8(buffer, pos, (mantissa << 1) +
+                            ((tmmbr_item.MeasuredOverhead >> 8) & 0x01));
+  AssignUWord8(buffer, pos, tmmbr_item.MeasuredOverhead);
+}
+
+// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
+//
+// FCI:
+//
+//    0                   1                   2                   3
+//    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//   |                              SSRC                             |
+//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//   | MxTBR Exp |  MxTBR Mantissa                 |Measured Overhead|
+//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+void CreateTmmbn(const RTCPPacketRTPFBTMMBN& tmmbn,
+                 const std::vector<RTCPPacketRTPFBTMMBRItem>& tmmbn_items,
+                 uint8_t* buffer,
+                 size_t* pos) {
+  AssignUWord32(buffer, pos, tmmbn.SenderSSRC);
+  AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0);
+  for (uint8_t i = 0; i < tmmbn_items.size(); ++i) {
+    CreateTmmbrItem(tmmbn_items[i], buffer, pos);
+  }
+}
+}  // namespace
+
+bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) {
+  assert(overhead <= 0x1ff);
+  if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) {
+    LOG(LS_WARNING) << "Max TMMBN size reached.";
+    return false;
+  }
+  RTCPPacketRTPFBTMMBRItem tmmbn_item;
+  tmmbn_item.SSRC = ssrc;
+  tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps;
+  tmmbn_item.MeasuredOverhead = overhead;
+  tmmbn_items_.push_back(tmmbn_item);
+  return true;
+}
+
+bool Tmmbn::Create(uint8_t* packet,
+                   size_t* index,
+                   size_t max_length,
+                   RtcpPacket::PacketReadyCallback* callback) const {
+  while (*index + BlockLength() > max_length) {
+    if (!OnBufferFull(packet, index, callback))
+      return false;
+  }
+  const uint8_t kFmt = 4;
+  CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index);
+  CreateTmmbn(tmmbn_, tmmbn_items_, packet, index);
+  return true;
+}
+
+}  // namespace rtcp
+}  // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h
new file mode 100644
index 0000000..82bf9dd
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TMMBN_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TMMBN_H_
+
+#include <vector>
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
+class Tmmbn : public RtcpPacket {
+ public:
+  Tmmbn() : RtcpPacket() {
+    memset(&tmmbn_, 0, sizeof(tmmbn_));
+  }
+
+  virtual ~Tmmbn() {}
+
+  void From(uint32_t ssrc) {
+    tmmbn_.SenderSSRC = ssrc;
+  }
+  // Max 50 TMMBR can be added per TMMBN.
+  bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead);
+
+ protected:
+  bool Create(uint8_t* packet,
+              size_t* index,
+              size_t max_length,
+              RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+  static const int kMaxNumberOfTmmbrs = 50;
+
+  size_t BlockLength() const {
+    const size_t kFciLen = 8;
+    return kCommonFbFmtLength + kFciLen * tmmbn_items_.size();
+  }
+
+  RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_;
+  std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_;
+
+  RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbn);
+};
+
+}  // namespace rtcp
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TMMBN_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn_unittest.cc
new file mode 100644
index 0000000..32d64a9
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn_unittest.cc
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (c) 2016 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.
+ */
+
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/test/rtcp_packet_parser.h"
+
+using webrtc::rtcp::RawPacket;
+using webrtc::rtcp::Tmmbn;
+using webrtc::test::RtcpPacketParser;
+
+namespace webrtc {
+const uint32_t kSenderSsrc = 0x12345678;
+const uint32_t kRemoteSsrc = 0x23456789;
+
+TEST(RtcpPacketTest, TmmbnWithNoItem) {
+  Tmmbn tmmbn;
+  tmmbn.From(kSenderSsrc);
+
+  rtc::scoped_ptr<RawPacket> packet(tmmbn.Build());
+  RtcpPacketParser parser;
+  parser.Parse(packet->Buffer(), packet->Length());
+  EXPECT_EQ(1, parser.tmmbn()->num_packets());
+  EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc());
+  EXPECT_EQ(0, parser.tmmbn_items()->num_packets());
+}
+
+TEST(RtcpPacketTest, TmmbnWithOneItem) {
+  Tmmbn tmmbn;
+  tmmbn.From(kSenderSsrc);
+  EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc, 312, 60));
+
+  rtc::scoped_ptr<RawPacket> packet(tmmbn.Build());
+  RtcpPacketParser parser;
+  parser.Parse(packet->Buffer(), packet->Length());
+  EXPECT_EQ(1, parser.tmmbn()->num_packets());
+  EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc());
+  EXPECT_EQ(1, parser.tmmbn_items()->num_packets());
+  EXPECT_EQ(kRemoteSsrc, parser.tmmbn_items()->Ssrc(0));
+  EXPECT_EQ(312U, parser.tmmbn_items()->BitrateKbps(0));
+  EXPECT_EQ(60U, parser.tmmbn_items()->Overhead(0));
+}
+
+TEST(RtcpPacketTest, TmmbnWithTwoItems) {
+  Tmmbn tmmbn;
+  tmmbn.From(kSenderSsrc);
+  EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc, 312, 60));
+  EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc + 1, 1288, 40));
+
+  rtc::scoped_ptr<RawPacket> packet(tmmbn.Build());
+  RtcpPacketParser parser;
+  parser.Parse(packet->Buffer(), packet->Length());
+  EXPECT_EQ(1, parser.tmmbn()->num_packets());
+  EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc());
+  EXPECT_EQ(2, parser.tmmbn_items()->num_packets());
+  EXPECT_EQ(kRemoteSsrc, parser.tmmbn_items()->Ssrc(0));
+  EXPECT_EQ(312U, parser.tmmbn_items()->BitrateKbps(0));
+  EXPECT_EQ(60U, parser.tmmbn_items()->Overhead(0));
+  EXPECT_EQ(kRemoteSsrc + 1, parser.tmmbn_items()->Ssrc(1));
+  EXPECT_EQ(1288U, parser.tmmbn_items()->BitrateKbps(1));
+  EXPECT_EQ(40U, parser.tmmbn_items()->Overhead(1));
+}
+
+TEST(RtcpPacketTest, TmmbnWithTooManyItems) {
+  Tmmbn tmmbn;
+  tmmbn.From(kSenderSsrc);
+  const int kMaxTmmbrItems = 50;
+  for (int i = 0; i < kMaxTmmbrItems; ++i)
+    EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc + i, 312, 60));
+
+  EXPECT_FALSE(tmmbn.WithTmmbr(kRemoteSsrc + kMaxTmmbrItems, 312, 60));
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
index 78b0523..1d47004 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
@@ -35,7 +35,6 @@
 using webrtc::rtcp::Sdes;
 using webrtc::rtcp::SenderReport;
 using webrtc::rtcp::Sli;
-using webrtc::rtcp::Tmmbn;
 using webrtc::rtcp::Tmmbr;
 using webrtc::rtcp::VoipMetric;
 using webrtc::rtcp::Xr;
@@ -514,64 +513,6 @@
   EXPECT_EQ(60U, parser.tmmbr_item()->Overhead());
 }
 
-TEST(RtcpPacketTest, TmmbnWithNoItem) {
-  Tmmbn tmmbn;
-  tmmbn.From(kSenderSsrc);
-
-  rtc::scoped_ptr<RawPacket> packet(tmmbn.Build());
-  RtcpPacketParser parser;
-  parser.Parse(packet->Buffer(), packet->Length());
-  EXPECT_EQ(1, parser.tmmbn()->num_packets());
-  EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc());
-  EXPECT_EQ(0, parser.tmmbn_items()->num_packets());
-}
-
-TEST(RtcpPacketTest, TmmbnWithOneItem) {
-  Tmmbn tmmbn;
-  tmmbn.From(kSenderSsrc);
-  EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc, 312, 60));
-
-  rtc::scoped_ptr<RawPacket> packet(tmmbn.Build());
-  RtcpPacketParser parser;
-  parser.Parse(packet->Buffer(), packet->Length());
-  EXPECT_EQ(1, parser.tmmbn()->num_packets());
-  EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc());
-  EXPECT_EQ(1, parser.tmmbn_items()->num_packets());
-  EXPECT_EQ(kRemoteSsrc, parser.tmmbn_items()->Ssrc(0));
-  EXPECT_EQ(312U, parser.tmmbn_items()->BitrateKbps(0));
-  EXPECT_EQ(60U, parser.tmmbn_items()->Overhead(0));
-}
-
-TEST(RtcpPacketTest, TmmbnWithTwoItems) {
-  Tmmbn tmmbn;
-  tmmbn.From(kSenderSsrc);
-  EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc, 312, 60));
-  EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc + 1, 1288, 40));
-
-  rtc::scoped_ptr<RawPacket> packet(tmmbn.Build());
-  RtcpPacketParser parser;
-  parser.Parse(packet->Buffer(), packet->Length());
-  EXPECT_EQ(1, parser.tmmbn()->num_packets());
-  EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc());
-  EXPECT_EQ(2, parser.tmmbn_items()->num_packets());
-  EXPECT_EQ(kRemoteSsrc, parser.tmmbn_items()->Ssrc(0));
-  EXPECT_EQ(312U, parser.tmmbn_items()->BitrateKbps(0));
-  EXPECT_EQ(60U, parser.tmmbn_items()->Overhead(0));
-  EXPECT_EQ(kRemoteSsrc + 1, parser.tmmbn_items()->Ssrc(1));
-  EXPECT_EQ(1288U, parser.tmmbn_items()->BitrateKbps(1));
-  EXPECT_EQ(40U, parser.tmmbn_items()->Overhead(1));
-}
-
-TEST(RtcpPacketTest, TmmbnWithTooManyItems) {
-  Tmmbn tmmbn;
-  tmmbn.From(kSenderSsrc);
-  const int kMaxTmmbrItems = 50;
-  for (int i = 0; i < kMaxTmmbrItems; ++i)
-    EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc + i, 312, 60));
-
-  EXPECT_FALSE(tmmbn.WithTmmbr(kRemoteSsrc + kMaxTmmbrItems, 312, 60));
-}
-
 TEST(RtcpPacketTest, XrWithNoReportBlocks) {
   Xr xr;
   xr.From(kSenderSsrc);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
index a4f6f39..e3cb16d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -27,6 +27,7 @@
 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"