Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / media / cast / rtcp / rtcp_sender.cc
index c56dcb9..af9042f 100644 (file)
@@ -9,18 +9,20 @@
 
 #include "base/logging.h"
 #include "media/cast/cast_environment.h"
+#include "media/cast/rtcp/receiver_rtcp_event_subscriber.h"
+#include "media/cast/rtcp/rtcp_defines.h"
 #include "media/cast/rtcp/rtcp_utility.h"
 #include "media/cast/transport/cast_transport_defines.h"
 #include "media/cast/transport/pacing/paced_sender.h"
 #include "net/base/big_endian.h"
 
-static const size_t kRtcpCastLogHeaderSize = 12;
-static const size_t kRtcpSenderFrameLogSize = 4;
-static const size_t kRtcpReceiverFrameLogSize = 8;
-static const size_t kRtcpReceiverEventLogSize = 4;
-
 namespace {
 
+using media::cast::kRtcpCastLogHeaderSize;
+using media::cast::kRtcpSenderFrameLogSize;
+using media::cast::kRtcpReceiverFrameLogSize;
+using media::cast::kRtcpReceiverEventLogSize;
+
 // Converts a log event type to an integer value.
 int ConvertEventTypeToWireFormat(const media::cast::CastLoggingEvent& event) {
   switch (event) {
@@ -40,8 +42,10 @@ int ConvertEventTypeToWireFormat(const media::cast::CastLoggingEvent& event) {
       return 7;
     case media::cast::kVideoPacketReceived:
       return 8;
-    case media::cast::kDuplicatePacketReceived:
+    case media::cast::kDuplicateAudioPacketReceived:
       return 9;
+    case media::cast::kDuplicateVideoPacketReceived:
+      return 10;
     default:
       return 0;  // Not an interesting event.
   }
@@ -65,21 +69,20 @@ uint16 MergeEventTypeAndTimestampForWireFormat(
 
 bool ScanRtcpReceiverLogMessage(
     const media::cast::RtcpReceiverLogMessage& receiver_log_message,
-    size_t start_size,
-    size_t* number_of_frames,
-    size_t* total_number_of_messages_to_send,
-    size_t* rtcp_log_size) {
+    size_t start_size, size_t* number_of_frames,
+    size_t* total_number_of_messages_to_send, size_t* rtcp_log_size) {
   if (receiver_log_message.empty()) return false;
 
   size_t remaining_space = media::cast::kMaxIpPacketSize - start_size;
 
   // We must have space for at least one message
   DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize +
-      kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize)
+                                 kRtcpReceiverFrameLogSize +
+                                 kRtcpReceiverEventLogSize)
       << "Not enough buffer space";
 
   if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize +
-      kRtcpReceiverEventLogSize) {
+                            kRtcpReceiverEventLogSize) {
     return false;
   }
   // Account for the RTCP header for an application-defined packet.
@@ -95,12 +98,12 @@ bool ScanRtcpReceiverLogMessage(
     size_t messages_in_frame = frame_it->event_log_messages_.size();
     size_t remaining_space_in_messages =
         remaining_space / kRtcpReceiverEventLogSize;
-    size_t messages_to_send = std::min(messages_in_frame,
-                                       remaining_space_in_messages);
+    size_t messages_to_send =
+        std::min(messages_in_frame, remaining_space_in_messages);
     if (messages_to_send > media::cast::kRtcpMaxReceiverLogMessages) {
       // We can't send more than 256 messages.
-      remaining_space -= media::cast::kRtcpMaxReceiverLogMessages *
-          kRtcpReceiverEventLogSize;
+      remaining_space -=
+          media::cast::kRtcpMaxReceiverLogMessages * kRtcpReceiverEventLogSize;
       *total_number_of_messages_to_send +=
           media::cast::kRtcpMaxReceiverLogMessages;
       break;
@@ -114,11 +117,11 @@ bool ScanRtcpReceiverLogMessage(
       break;
     }
   }
-  *rtcp_log_size = kRtcpCastLogHeaderSize +
-      *number_of_frames * kRtcpReceiverFrameLogSize +
+  *rtcp_log_size =
+      kRtcpCastLogHeaderSize + *number_of_frames * kRtcpReceiverFrameLogSize +
       *total_number_of_messages_to_send * kRtcpReceiverEventLogSize;
-  DCHECK_GE(media::cast::kMaxIpPacketSize,
-            start_size + *rtcp_log_size) << "Not enough buffer space";
+  DCHECK_GE(media::cast::kMaxIpPacketSize, start_size + *rtcp_log_size)
+      << "Not enough buffer space";
 
   VLOG(1) << "number of frames " << *number_of_frames;
   VLOG(1) << "total messages to send " << *total_number_of_messages_to_send;
@@ -133,12 +136,11 @@ namespace cast {
 // TODO(mikhal): This is only used by the receiver. Consider renaming.
 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment,
                        transport::PacedPacketSender* outgoing_transport,
-                       uint32 sending_ssrc,
-                       const std::string& c_name)
-     : ssrc_(sending_ssrc),
-       c_name_(c_name),
-       transport_(outgoing_transport),
-       cast_environment_(cast_environment) {
+                       uint32 sending_ssrc, const std::string& c_name)
+    : ssrc_(sending_ssrc),
+      c_name_(c_name),
+      transport_(outgoing_transport),
+      cast_environment_(cast_environment) {
   DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config";
 }
 
@@ -154,16 +156,13 @@ void RtcpSender::SendRtcpFromRtpReceiver(
     const transport::RtcpReportBlock* report_block,
     const RtcpReceiverReferenceTimeReport* rrtr,
     const RtcpCastMessage* cast_message,
-    RtcpReceiverLogMessage* receiver_log) {
-  if (packet_type_flags & kRtcpSr ||
-      packet_type_flags & kRtcpDlrr ||
+    ReceiverRtcpEventSubscriber* event_subscriber) {
+  if (packet_type_flags & kRtcpSr || packet_type_flags & kRtcpDlrr ||
       packet_type_flags & kRtcpSenderLog) {
     NOTREACHED() << "Invalid argument";
   }
-  if (packet_type_flags & kRtcpPli ||
-      packet_type_flags & kRtcpRpsi ||
-      packet_type_flags & kRtcpRemb ||
-      packet_type_flags & kRtcpNack) {
+  if (packet_type_flags & kRtcpPli || packet_type_flags & kRtcpRpsi ||
+      packet_type_flags & kRtcpRemb || packet_type_flags & kRtcpNack) {
     // Implement these for webrtc interop.
     NOTIMPLEMENTED();
   }
@@ -188,8 +187,10 @@ void RtcpSender::SendRtcpFromRtpReceiver(
     BuildCast(cast_message, &packet);
   }
   if (packet_type_flags & kRtcpReceiverLog) {
-    DCHECK(receiver_log) << "Invalid argument";
-    BuildReceiverLog(receiver_log, &packet);
+    DCHECK(event_subscriber) << "Invalid argument";
+    RtcpReceiverLogMessage receiver_log;
+    event_subscriber->GetReceiverLogMessageAndReset(&receiver_log);
+    BuildReceiverLog(&receiver_log, &packet);
   }
   if (packet.empty()) return;  // Sanity don't send empty packets.
 
@@ -246,7 +247,7 @@ void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block,
 
 void RtcpSender::BuildSdec(Packet* packet) const {
   size_t start_size = packet->size();
-  DCHECK_LT(start_size +  12 + c_name_.length(), kMaxIpPacketSize)
+  DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize)
       << "Not enough buffer space";
   if (start_size + 12 > kMaxIpPacketSize) return;
 
@@ -262,7 +263,7 @@ void RtcpSender::BuildSdec(Packet* packet) const {
   uint32 sdes_length_position = static_cast<uint32>(start_size) + 3;
   big_endian_writer.WriteU16(0);
   big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
-  big_endian_writer.WriteU8(1);  // CNAME = 1
+  big_endian_writer.WriteU8(1);       // CNAME = 1
   big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length()));
 
   size_t sdes_length = 10 + c_name_.length();
@@ -287,8 +288,7 @@ void RtcpSender::BuildSdec(Packet* packet) const {
   (*packet)[sdes_length_position] = buffer_length;
 }
 
-void RtcpSender::BuildPli(uint32 remote_ssrc,
-                          Packet* packet) const {
+void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const {
   size_t start_size = packet->size();
   DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space";
   if (start_size + 12 > kMaxIpPacketSize) return;
@@ -299,8 +299,8 @@ void RtcpSender::BuildPli(uint32 remote_ssrc,
   uint8 FMT = 1;  // Picture loss indicator.
   big_endian_writer.WriteU8(0x80 + FMT);
   big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific);
-  big_endian_writer.WriteU16(2);  // Used fixed length of 2.
-  big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
+  big_endian_writer.WriteU16(2);            // Used fixed length of 2.
+  big_endian_writer.WriteU32(ssrc_);        // Add our own SSRC.
   big_endian_writer.WriteU32(remote_ssrc);  // Add the remote SSRC.
 }
 
@@ -313,8 +313,7 @@ void RtcpSender::BuildPli(uint32 remote_ssrc,
    |   defined per codec          ...                | Padding (0) |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
-void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi,
-                           Packet* packet) const {
+void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const {
   size_t start_size = packet->size();
   DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space";
   if (start_size + 24 > kMaxIpPacketSize) return;
@@ -354,8 +353,8 @@ void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi,
 
   // Add picture ID.
   for (int i = bytes_required - 1; i > 0; i--) {
-    big_endian_writer.WriteU8(
-        0x80 | static_cast<uint8>(rpsi->picture_id >> (i * 7)));
+    big_endian_writer.WriteU8(0x80 |
+                              static_cast<uint8>(rpsi->picture_id >> (i * 7)));
   }
   // Add last byte of picture ID.
   big_endian_writer.WriteU8(static_cast<uint8>(rpsi->picture_id & 0x7f));
@@ -366,8 +365,7 @@ void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi,
   }
 }
 
-void RtcpSender::BuildRemb(const RtcpRembMessage* remb,
-                           Packet* packet) const {
+void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const {
   size_t start_size = packet->size();
   size_t remb_size = 20 + 4 * remb->remb_ssrcs.size();
   DCHECK_LT(start_size + remb_size, kMaxIpPacketSize)
@@ -385,19 +383,18 @@ void RtcpSender::BuildRemb(const RtcpRembMessage* remb,
   big_endian_writer.WriteU8(0);
   big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4));
   big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
-  big_endian_writer.WriteU32(0);  // Remote SSRC must be 0.
+  big_endian_writer.WriteU32(0);      // Remote SSRC must be 0.
   big_endian_writer.WriteU32(kRemb);
   big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size()));
 
   // 6 bit exponent and a 18 bit mantissa.
   uint8 bitrate_exponent;
   uint32 bitrate_mantissa;
-  BitrateToRembExponentBitrate(remb->remb_bitrate,
-                               &bitrate_exponent,
+  BitrateToRembExponentBitrate(remb->remb_bitrate, &bitrate_exponent,
                                &bitrate_mantissa);
 
-  big_endian_writer.WriteU8(static_cast<uint8>((bitrate_exponent << 2) +
-      ((bitrate_mantissa >> 16) & 0x03)));
+  big_endian_writer.WriteU8(static_cast<uint8>(
+      (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03)));
   big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8));
   big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa));
 
@@ -410,8 +407,7 @@ void RtcpSender::BuildRemb(const RtcpRembMessage* remb,
                                                    remb->remb_bitrate);
 }
 
-void RtcpSender::BuildNack(const RtcpNackMessage* nack,
-                           Packet* packet) const {
+void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const {
   size_t start_size = packet->size();
   DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space";
   if (start_size + 16 > kMaxIpPacketSize) return;
@@ -426,14 +422,14 @@ void RtcpSender::BuildNack(const RtcpNackMessage* nack,
   big_endian_writer.WriteU8(0);
   size_t nack_size_pos = start_size + 3;
   big_endian_writer.WriteU8(3);
-  big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
+  big_endian_writer.WriteU32(ssrc_);              // Add our own SSRC.
   big_endian_writer.WriteU32(nack->remote_ssrc);  // Add the remote SSRC.
 
   // Build NACK bitmasks and write them to the Rtcp message.
   // The nack list should be sorted and not contain duplicates.
   size_t number_of_nack_fields = 0;
-  size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields,
-      (kMaxIpPacketSize - packet->size()) / 4);
+  size_t max_number_of_nack_fields = std::min<size_t>(
+      kRtcpMaxNackFields, (kMaxIpPacketSize - packet->size()) / 4);
 
   std::list<uint16>::const_iterator it = nack->nack_list.begin();
   while (it != nack->nack_list.end() &&
@@ -475,7 +471,7 @@ void RtcpSender::BuildBye(Packet* packet) const {
   net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
   big_endian_writer.WriteU8(0x80 + 1);
   big_endian_writer.WriteU8(transport::kPacketTypeBye);
-  big_endian_writer.WriteU16(1);  // Length.
+  big_endian_writer.WriteU16(1);      // Length.
   big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
 }
 
@@ -491,19 +487,18 @@ void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr,
 
   big_endian_writer.WriteU8(0x80);
   big_endian_writer.WriteU8(transport::kPacketTypeXr);
-  big_endian_writer.WriteU16(4);  // Length.
+  big_endian_writer.WriteU16(4);      // Length.
   big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
-  big_endian_writer.WriteU8(4);  // Add block type.
-  big_endian_writer.WriteU8(0);  // Add reserved.
-  big_endian_writer.WriteU16(2);  // Block length.
+  big_endian_writer.WriteU8(4);       // Add block type.
+  big_endian_writer.WriteU8(0);       // Add reserved.
+  big_endian_writer.WriteU16(2);      // Block length.
 
   // Add the media (received RTP) SSRC.
   big_endian_writer.WriteU32(rrtr->ntp_seconds);
   big_endian_writer.WriteU32(rrtr->ntp_fraction);
 }
 
-void RtcpSender::BuildCast(const RtcpCastMessage* cast,
-                           Packet* packet) const {
+void RtcpSender::BuildCast(const RtcpCastMessage* cast, Packet* packet) const {
   size_t start_size = packet->size();
   DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space";
   if (start_size + 20 > kMaxIpPacketSize) return;
@@ -515,9 +510,9 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast,
   big_endian_writer.WriteU8(0x80 + FMT);
   big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific);
   big_endian_writer.WriteU8(0);
-  size_t cast_size_pos = start_size + 3; // Save length position.
+  size_t cast_size_pos = start_size + 3;  // Save length position.
   big_endian_writer.WriteU8(4);
-  big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
+  big_endian_writer.WriteU32(ssrc_);              // Add our own SSRC.
   big_endian_writer.WriteU32(cast->media_ssrc_);  // Remote SSRC.
   big_endian_writer.WriteU32(kCast);
   big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_));
@@ -527,14 +522,15 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast,
   big_endian_writer.WriteU8(0);  // Reserved.
 
   size_t number_of_loss_fields = 0;
-  size_t max_number_of_loss_fields = std::min<size_t>(kRtcpMaxCastLossFields,
-      (kMaxIpPacketSize - packet->size()) / 4);
+  size_t max_number_of_loss_fields = std::min<size_t>(
+      kRtcpMaxCastLossFields, (kMaxIpPacketSize - packet->size()) / 4);
 
   MissingFramesAndPacketsMap::const_iterator frame_it =
       cast->missing_frames_and_packets_.begin();
 
   for (; frame_it != cast->missing_frames_and_packets_.end() &&
-      number_of_loss_fields < max_number_of_loss_fields; ++frame_it) {
+             number_of_loss_fields < max_number_of_loss_fields;
+       ++frame_it) {
     // Iterate through all frames with missing packets.
     if (frame_it->second.empty()) {
       // Special case all packets in a frame is missing.
@@ -552,8 +548,8 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast,
 
         start_size = packet->size();
         packet->resize(start_size + 4);
-        net::BigEndianWriter big_endian_nack_writer(
-            &((*packet)[start_size]), 4);
+        net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]),
+                                                    4);
 
         // Write frame and packet id to buffer before calculating bitmask.
         big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first));
@@ -588,11 +584,9 @@ void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message,
   size_t total_number_of_messages_to_send = 0;
   size_t rtcp_log_size = 0;
 
-  if (!ScanRtcpReceiverLogMessage(*receiver_log_message,
-                                  packet_start_size,
-                                  &number_of_frames,
-                                  &total_number_of_messages_to_send,
-                                  &rtcp_log_size)) {
+  if (!ScanRtcpReceiverLogMessage(
+           *receiver_log_message, packet_start_size, &number_of_frames,
+           &total_number_of_messages_to_send, &rtcp_log_size)) {
     return;
   }
   packet->resize(packet_start_size + rtcp_log_size);
@@ -601,15 +595,16 @@ void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message,
                                          rtcp_log_size);
   big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype);
   big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined);
-  big_endian_writer.WriteU16(static_cast<uint16>(2 + 2 * number_of_frames +
-                             total_number_of_messages_to_send));
+  big_endian_writer.WriteU16(static_cast<uint16>(
+      2 + 2 * number_of_frames + total_number_of_messages_to_send));
   big_endian_writer.WriteU32(ssrc_);  // Add our own SSRC.
   big_endian_writer.WriteU32(kCast);
 
   while (!receiver_log_message->empty() &&
          total_number_of_messages_to_send > 0) {
-    RtcpReceiverFrameLogMessage& frame_log_messages =
-        receiver_log_message->front();
+    RtcpReceiverFrameLogMessage& frame_log_messages(
+        receiver_log_message->front());
+
     // Add our frame header.
     big_endian_writer.WriteU32(frame_log_messages.rtp_timestamp_);
     size_t messages_in_frame = frame_log_messages.event_log_messages_.size();
@@ -636,8 +631,9 @@ void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message,
       const RtcpReceiverEventLogMessage& event_message =
           frame_log_messages.event_log_messages_.front();
       uint16 event_type_and_timestamp_delta =
-          MergeEventTypeAndTimestampForWireFormat(event_message.type,
-          event_message.event_timestamp - event_timestamp_base);
+          MergeEventTypeAndTimestampForWireFormat(
+              event_message.type,
+              event_message.event_timestamp - event_timestamp_base);
       switch (event_message.type) {
         case kAudioAckSent:
         case kVideoAckSent:
@@ -645,13 +641,14 @@ void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message,
         case kAudioFrameDecoded:
         case kVideoFrameDecoded:
         case kVideoRenderDelay:
-          big_endian_writer.WriteU16(static_cast<uint16>(
-              event_message.delay_delta.InMilliseconds()));
+          big_endian_writer.WriteU16(
+              static_cast<uint16>(event_message.delay_delta.InMilliseconds()));
           big_endian_writer.WriteU16(event_type_and_timestamp_delta);
           break;
         case kAudioPacketReceived:
         case kVideoPacketReceived:
-        case kDuplicatePacketReceived:
+        case kDuplicateAudioPacketReceived:
+        case kDuplicateVideoPacketReceived:
           big_endian_writer.WriteU16(event_message.packet_id);
           big_endian_writer.WriteU16(event_type_and_timestamp_delta);
           break;