X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmedia%2Fcast%2Frtcp%2Frtcp_sender.cc;h=af9042f4f498293003983589fceae8b33a336508;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=c56dcb9607c889ee4b9c2bc6345dcef119beb7a7;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/media/cast/rtcp/rtcp_sender.cc b/src/media/cast/rtcp/rtcp_sender.cc index c56dcb9..af9042f 100644 --- a/src/media/cast/rtcp/rtcp_sender.cc +++ b/src/media/cast/rtcp/rtcp_sender.cc @@ -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 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(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(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(rpsi->picture_id >> (i * 7))); + big_endian_writer.WriteU8(0x80 | + static_cast(rpsi->picture_id >> (i * 7))); } // Add last byte of picture ID. big_endian_writer.WriteU8(static_cast(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(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(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((bitrate_exponent << 2) + - ((bitrate_mantissa >> 16) & 0x03))); + big_endian_writer.WriteU8(static_cast( + (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03))); big_endian_writer.WriteU8(static_cast(bitrate_mantissa >> 8)); big_endian_writer.WriteU8(static_cast(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(kRtcpMaxNackFields, - (kMaxIpPacketSize - packet->size()) / 4); + size_t max_number_of_nack_fields = std::min( + kRtcpMaxNackFields, (kMaxIpPacketSize - packet->size()) / 4); std::list::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(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(kRtcpMaxCastLossFields, - (kMaxIpPacketSize - packet->size()) / 4); + size_t max_number_of_loss_fields = std::min( + 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(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(2 + 2 * number_of_frames + - total_number_of_messages_to_send)); + big_endian_writer.WriteU16(static_cast( + 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( - event_message.delay_delta.InMilliseconds())); + big_endian_writer.WriteU16( + static_cast(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;