aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/rtp_rtcp
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/modules/rtp_rtcp')
-rw-r--r--webrtc/modules/rtp_rtcp/BUILD.gn48
-rw-r--r--webrtc/modules/rtp_rtcp/OWNERS17
-rw-r--r--webrtc/modules/rtp_rtcp/include/fec_receiver.h (renamed from webrtc/modules/rtp_rtcp/interface/fec_receiver.h)8
-rw-r--r--webrtc/modules/rtp_rtcp/include/receive_statistics.h (renamed from webrtc/modules/rtp_rtcp/interface/receive_statistics.h)10
-rw-r--r--webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h (renamed from webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h)6
-rw-r--r--webrtc/modules/rtp_rtcp/include/rtp_cvo.h (renamed from webrtc/modules/rtp_rtcp/interface/rtp_cvo.h)6
-rw-r--r--webrtc/modules/rtp_rtcp/include/rtp_header_parser.h (renamed from webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h)8
-rw-r--r--webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h (renamed from webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h)32
-rw-r--r--webrtc/modules/rtp_rtcp/include/rtp_receiver.h (renamed from webrtc/modules/rtp_rtcp/interface/rtp_receiver.h)10
-rw-r--r--webrtc/modules/rtp_rtcp/include/rtp_rtcp.h (renamed from webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h)36
-rw-r--r--webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h (renamed from webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h)106
-rw-r--r--webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h33
-rw-r--r--webrtc/modules/rtp_rtcp/rtp_rtcp.gypi48
-rw-r--r--webrtc/modules/rtp_rtcp/source/CPPLINT.cfg6
-rw-r--r--webrtc/modules/rtp_rtcp/source/byte_io.h15
-rw-r--r--webrtc/modules/rtp_rtcp/source/dtmf_queue.cc6
-rw-r--r--webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h6
-rw-r--r--webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h12
-rw-r--r--webrtc/modules/rtp_rtcp/source/fec_receiver_impl.h6
-rw-r--r--webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc4
-rw-r--r--webrtc/modules/rtp_rtcp/source/fec_test_helper.h4
-rw-r--r--webrtc/modules/rtp_rtcp/source/forward_error_correction.cc178
-rw-r--r--webrtc/modules/rtp_rtcp/source/forward_error_correction.h2
-rw-r--r--webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.cc106
-rw-r--r--webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h2
-rw-r--r--webrtc/modules/rtp_rtcp/source/h264_sps_parser_unittest.cc11
-rw-r--r--webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h12
-rw-r--r--webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc68
-rw-r--r--webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc49
-rw-r--r--webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc29
-rw-r--r--webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h11
-rw-r--r--webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc17
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet.cc647
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet.h692
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc79
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h66
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc81
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.cc133
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h63
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/bye_unittest.cc173
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc28
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h41
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc157
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.cc100
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.h63
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr_unittest.cc102
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc95
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h63
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report_unittest.cc98
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.cc163
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h63
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/nack_unittest.cc190
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.cc70
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h49
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/pli_unittest.cc66
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.cc45
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h48
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.cc89
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h66
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc145
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc89
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h67
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc86
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.cc49
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h49
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr_unittest.cc51
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.cc45
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h48
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.cc108
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h81
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/sli_unittest.cc91
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc119
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h60
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn_unittest.cc84
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc105
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h64
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr_unittest.cc43
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.cc107
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h53
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric_unittest.cc93
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc561
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc13
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver.h6
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc3
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h4
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc34
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_sender.cc787
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_sender.h484
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_utility.cc5
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_utility.h4
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc29
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format.h4
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_vp9.cc72
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc33
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_header_extension.h13
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_header_parser.cc4
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_packet_history.h12
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc8
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc30
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc141
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h20
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc32
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h8
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h6
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc4
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h2
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h39
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc28
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h14
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc32
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_sender.cc63
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_sender.h23
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc450
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h171
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc270
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc46
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_sender_video.h18
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_utility.cc151
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_utility.h114
-rw-r--r--webrtc/modules/rtp_rtcp/source/ssrc_database.cc111
-rw-r--r--webrtc/modules/rtp_rtcp/source/ssrc_database.h48
-rw-r--r--webrtc/modules/rtp_rtcp/source/time_util.h48
-rw-r--r--webrtc/modules/rtp_rtcp/source/time_util_unittest.cc62
-rw-r--r--webrtc/modules/rtp_rtcp/source/tmmbr_help.cc4
-rw-r--r--webrtc/modules/rtp_rtcp/source/video_codec_information.h13
-rw-r--r--webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc36
-rw-r--r--webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h4
-rw-r--r--webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator_unittest.cc2
-rw-r--r--webrtc/modules/rtp_rtcp/test/BWEStandAlone/BWEStandAlone.cc199
-rw-r--r--webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc1055
-rw-r--r--webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h170
-rw-r--r--webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.cc432
-rw-r--r--webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h149
-rw-r--r--webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.cc411
-rw-r--r--webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h153
-rw-r--r--webrtc/modules/rtp_rtcp/test/bwe_standalone.gypi85
-rw-r--r--webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc7
-rw-r--r--webrtc/modules/rtp_rtcp/test/testAPI/test_api.h15
-rw-r--r--webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc23
-rw-r--r--webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc29
-rw-r--r--webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc6
-rw-r--r--webrtc/modules/rtp_rtcp/test/testFec/average_residual_loss_xor_codes.h7
-rw-r--r--webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc120
-rw-r--r--webrtc/modules/rtp_rtcp/test/testFec/test_packet_masks_metrics.cc27
156 files changed, 6197 insertions, 6860 deletions
diff --git a/webrtc/modules/rtp_rtcp/BUILD.gn b/webrtc/modules/rtp_rtcp/BUILD.gn
index c651424611..a3d3403172 100644
--- a/webrtc/modules/rtp_rtcp/BUILD.gn
+++ b/webrtc/modules/rtp_rtcp/BUILD.gn
@@ -10,14 +10,14 @@ import("../../build/webrtc.gni")
source_set("rtp_rtcp") {
sources = [
- "interface/fec_receiver.h",
- "interface/receive_statistics.h",
- "interface/remote_ntp_time_estimator.h",
- "interface/rtp_header_parser.h",
- "interface/rtp_payload_registry.h",
- "interface/rtp_receiver.h",
- "interface/rtp_rtcp.h",
- "interface/rtp_rtcp_defines.h",
+ "include/fec_receiver.h",
+ "include/receive_statistics.h",
+ "include/remote_ntp_time_estimator.h",
+ "include/rtp_header_parser.h",
+ "include/rtp_payload_registry.h",
+ "include/rtp_receiver.h",
+ "include/rtp_rtcp.h",
+ "include/rtp_rtcp_defines.h",
"mocks/mock_rtp_rtcp.h",
"source/bitrate.cc",
"source/bitrate.h",
@@ -46,8 +46,40 @@ source_set("rtp_rtcp") {
"source/remote_ntp_time_estimator.cc",
"source/rtcp_packet.cc",
"source/rtcp_packet.h",
+ "source/rtcp_packet/app.cc",
+ "source/rtcp_packet/app.h",
+ "source/rtcp_packet/bye.cc",
+ "source/rtcp_packet/bye.h",
+ "source/rtcp_packet/compound_packet.cc",
+ "source/rtcp_packet/compound_packet.h",
+ "source/rtcp_packet/dlrr.cc",
+ "source/rtcp_packet/dlrr.h",
+ "source/rtcp_packet/extended_jitter_report.cc",
+ "source/rtcp_packet/extended_jitter_report.h",
+ "source/rtcp_packet/nack.cc",
+ "source/rtcp_packet/nack.h",
+ "source/rtcp_packet/pli.cc",
+ "source/rtcp_packet/pli.h",
+ "source/rtcp_packet/psfb.cc",
+ "source/rtcp_packet/psfb.h",
+ "source/rtcp_packet/receiver_report.cc",
+ "source/rtcp_packet/receiver_report.h",
+ "source/rtcp_packet/report_block.cc",
+ "source/rtcp_packet/report_block.h",
+ "source/rtcp_packet/rrtr.cc",
+ "source/rtcp_packet/rrtr.h",
+ "source/rtcp_packet/rtpfb.cc",
+ "source/rtcp_packet/rtpfb.h",
+ "source/rtcp_packet/sli.cc",
+ "source/rtcp_packet/sli.h",
+ "source/rtcp_packet/tmmbn.cc",
+ "source/rtcp_packet/tmmbn.h",
+ "source/rtcp_packet/tmmbr.cc",
+ "source/rtcp_packet/tmmbr.h",
"source/rtcp_packet/transport_feedback.cc",
"source/rtcp_packet/transport_feedback.h",
+ "source/rtcp_packet/voip_metric.cc",
+ "source/rtcp_packet/voip_metric.h",
"source/rtcp_receiver.cc",
"source/rtcp_receiver.h",
"source/rtcp_receiver_help.cc",
diff --git a/webrtc/modules/rtp_rtcp/OWNERS b/webrtc/modules/rtp_rtcp/OWNERS
index 2b08b6b2dc..fd12dcea0c 100644
--- a/webrtc/modules/rtp_rtcp/OWNERS
+++ b/webrtc/modules/rtp_rtcp/OWNERS
@@ -1,6 +1,11 @@
-stefan@webrtc.org
-henrik.lundin@webrtc.org
-mflodman@webrtc.org
-asapersson@webrtc.org
-
-per-file BUILD.gn=kjellander@webrtc.org
+stefan@webrtc.org
+henrik.lundin@webrtc.org
+mflodman@webrtc.org
+asapersson@webrtc.org
+
+# These are for the common case of adding or renaming files. If you're doing
+# structural changes, please get a review from a reviewer in this file.
+per-file *.gyp=*
+per-file *.gypi=*
+
+per-file BUILD.gn=kjellander@webrtc.org
diff --git a/webrtc/modules/rtp_rtcp/interface/fec_receiver.h b/webrtc/modules/rtp_rtcp/include/fec_receiver.h
index 3608165dab..65e85ad7a5 100644
--- a/webrtc/modules/rtp_rtcp/interface/fec_receiver.h
+++ b/webrtc/modules/rtp_rtcp/include/fec_receiver.h
@@ -8,10 +8,10 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_FEC_RECEIVER_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_FEC_RECEIVER_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_FEC_RECEIVER_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_FEC_RECEIVER_H_
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -43,4 +43,4 @@ class FecReceiver {
virtual FecPacketCounter GetPacketCounter() const = 0;
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_FEC_RECEIVER_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_FEC_RECEIVER_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/receive_statistics.h b/webrtc/modules/rtp_rtcp/include/receive_statistics.h
index 6bd5cd846e..b4a7cd0de2 100644
--- a/webrtc/modules/rtp_rtcp/interface/receive_statistics.h
+++ b/webrtc/modules/rtp_rtcp/include/receive_statistics.h
@@ -8,13 +8,13 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RECEIVE_STATISTICS_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RECEIVE_STATISTICS_H_
#include <map>
-#include "webrtc/modules/interface/module.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -99,4 +99,4 @@ class NullReceiveStatistics : public ReceiveStatistics {
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RECEIVE_STATISTICS_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h b/webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
index 0ffba212a6..56c6e48691 100644
--- a/webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h
+++ b/webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
@@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_REMOTE_NTP_TIME_ESTIMATOR_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_REMOTE_NTP_TIME_ESTIMATOR_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/system_wrappers/include/rtp_to_ntp.h"
@@ -48,4 +48,4 @@ class RemoteNtpTimeEstimator {
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_REMOTE_NTP_TIME_ESTIMATOR_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_cvo.h b/webrtc/modules/rtp_rtcp/include/rtp_cvo.h
index c7a0268ef0..2e30d898ec 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_cvo.h
+++ b/webrtc/modules/rtp_rtcp/include/rtp_cvo.h
@@ -7,8 +7,8 @@
* 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_INTERFACE_RTP_CVO__H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_CVO__H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_CVO_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_CVO_H_
#include "webrtc/common_video/rotation.h"
@@ -51,4 +51,4 @@ inline VideoRotation ConvertCVOByteToVideoRotation(uint8_t rotation) {
}
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_CVO__H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_CVO_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h b/webrtc/modules/rtp_rtcp/include/rtp_header_parser.h
index 2809996b25..329de32611 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h
+++ b/webrtc/modules/rtp_rtcp/include/rtp_header_parser.h
@@ -7,10 +7,10 @@
* 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_INTERFACE_RTP_HEADER_PARSER_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_HEADER_PARSER_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_PARSER_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_PARSER_H_
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -41,4 +41,4 @@ class RtpHeaderParser {
virtual bool DeregisterRtpHeaderExtension(RTPExtensionType type) = 0;
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_HEADER_PARSER_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_PARSER_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h b/webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h
index 313bef1112..fae864107f 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h
+++ b/webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h
@@ -8,8 +8,10 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_PAYLOAD_REGISTRY_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_PAYLOAD_REGISTRY_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_PAYLOAD_REGISTRY_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_PAYLOAD_REGISTRY_H_
+
+#include <map>
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
@@ -27,7 +29,7 @@ class RTPPayloadStrategy {
virtual bool PayloadIsCompatible(const RtpUtility::Payload& payload,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) const = 0;
virtual void UpdatePayloadRate(RtpUtility::Payload* payload,
@@ -37,7 +39,7 @@ class RTPPayloadStrategy {
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int8_t payloadType,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) const = 0;
virtual int GetPayloadTypeFrequency(
@@ -52,14 +54,14 @@ class RTPPayloadStrategy {
class RTPPayloadRegistry {
public:
// The registry takes ownership of the strategy.
- RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy);
+ explicit RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy);
~RTPPayloadRegistry();
int32_t RegisterReceivePayload(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const int8_t payload_type,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate,
bool* created_new_payload_type);
@@ -69,7 +71,7 @@ class RTPPayloadRegistry {
int32_t ReceivePayloadType(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate,
int8_t* payload_type) const;
@@ -108,8 +110,16 @@ class RTPPayloadRegistry {
int GetPayloadTypeFrequency(uint8_t payload_type) const;
+ // DEPRECATED. Use PayloadTypeToPayload below that returns const Payload*
+ // instead of taking output parameter.
+ // TODO(danilchap): Remove this when all callers have been updated.
bool PayloadTypeToPayload(const uint8_t payload_type,
- RtpUtility::Payload*& payload) const;
+ RtpUtility::Payload*& payload) const { // NOLINT
+ payload =
+ const_cast<RtpUtility::Payload*>(PayloadTypeToPayload(payload_type));
+ return payload != nullptr;
+ }
+ const RtpUtility::Payload* PayloadTypeToPayload(uint8_t payload_type) const;
void ResetLastReceivedPayloadTypes() {
CriticalSectionScoped cs(crit_sect_.get());
@@ -145,7 +155,7 @@ class RTPPayloadRegistry {
int8_t last_received_media_payload_type() const {
CriticalSectionScoped cs(crit_sect_.get());
return last_received_media_payload_type_;
- };
+ }
bool use_rtx_payload_mapping_on_restore() const {
CriticalSectionScoped cs(crit_sect_.get());
@@ -163,7 +173,7 @@ class RTPPayloadRegistry {
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const size_t payload_name_length,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate);
bool IsRtxInternal(const RTPHeader& header) const;
@@ -190,4 +200,4 @@ class RTPPayloadRegistry {
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_PAYLOAD_REGISTRY_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_PAYLOAD_REGISTRY_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_receiver.h b/webrtc/modules/rtp_rtcp/include/rtp_receiver.h
index 2fb8ac5d61..0640d5cc19 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_receiver.h
+++ b/webrtc/modules/rtp_rtcp/include/rtp_receiver.h
@@ -8,10 +8,10 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RECEIVER_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RECEIVER_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RECEIVER_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RECEIVER_H_
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -61,7 +61,7 @@ class RtpReceiver {
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const int8_t payload_type,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) = 0;
// De-registers |payload_type| from the payload registry.
@@ -100,4 +100,4 @@ class RtpReceiver {
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RECEIVER_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RECEIVER_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h b/webrtc/modules/rtp_rtcp/include/rtp_rtcp.h
index f907408573..6a7022a94c 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
+++ b/webrtc/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -8,14 +8,15 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_
#include <set>
+#include <utility>
#include <vector>
-#include "webrtc/modules/interface/module.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/include/module.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
namespace webrtc {
// Forward declarations.
@@ -580,9 +581,13 @@ class RtpRtcp : public Module {
*
* return -1 on failure else 0
*/
- virtual int32_t SendREDPayloadType(
- int8_t& payloadType) const = 0;
-
+ // DEPRECATED. Use SendREDPayloadType below that takes output parameter
+ // by pointer instead of by reference.
+ // TODO(danilchap): Remove this when all callers have been updated.
+ int32_t SendREDPayloadType(int8_t& payloadType) const { // NOLINT
+ return SendREDPayloadType(&payloadType);
+ }
+ virtual int32_t SendREDPayloadType(int8_t* payload_type) const = 0;
/*
* Store the audio level in dBov for header-extension-for-audio-level-
* indication.
@@ -614,10 +619,17 @@ class RtpRtcp : public Module {
/*
* Get generic FEC setting
*/
- virtual void GenericFECStatus(bool& enable,
- uint8_t& payloadTypeRED,
- uint8_t& payloadTypeFEC) = 0;
-
+ // DEPRECATED. Use GenericFECStatus below that takes output parameters
+ // by pointers instead of by references.
+ // TODO(danilchap): Remove this when all callers have been updated.
+ void GenericFECStatus(bool& enable, // NOLINT
+ uint8_t& payloadTypeRED, // NOLINT
+ uint8_t& payloadTypeFEC) { // NOLINT
+ GenericFECStatus(&enable, &payloadTypeRED, &payloadTypeFEC);
+ }
+ virtual void GenericFECStatus(bool* enable,
+ uint8_t* payload_type_red,
+ uint8_t* payload_type_fec) = 0;
virtual int32_t SetFecParameters(
const FecProtectionParams* delta_params,
@@ -638,4 +650,4 @@ class RtpRtcp : public Module {
virtual int32_t RequestKeyFrame() = 0;
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h
index 6936352aca..fad97f19cc 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
+++ b/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h
@@ -8,13 +8,13 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
-#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_DEFINES_H_
+#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_DEFINES_H_
#include <stddef.h>
#include <list>
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/typedefs.h"
@@ -33,31 +33,23 @@ const int kVideoPayloadTypeFrequency = 90000;
// Minimum RTP header size in bytes.
const uint8_t kRtpHeaderSize = 12;
-struct AudioPayload
-{
+struct AudioPayload {
uint32_t frequency;
- uint8_t channels;
+ size_t channels;
uint32_t rate;
};
-struct VideoPayload
-{
+struct VideoPayload {
RtpVideoCodecTypes videoCodecType;
uint32_t maxRate;
};
-union PayloadUnion
-{
+union PayloadUnion {
AudioPayload Audio;
VideoPayload Video;
};
-enum RTPAliveType
-{
- kRtpDead = 0,
- kRtpNoRtp = 1,
- kRtpAlive = 2
-};
+enum RTPAliveType { kRtpDead = 0, kRtpNoRtp = 1, kRtpAlive = 2 };
enum ProtectionType {
kUnprotectedPacket,
@@ -78,10 +70,7 @@ enum RTPExtensionType {
kRtpExtensionTransportSequenceNumber,
};
-enum RTCPAppSubTypes
-{
- kAppSubtypeBwe = 0x00
-};
+enum RTCPAppSubTypes { kAppSubtypeBwe = 0x00 };
// TODO(sprang): Make this an enum class once rtcp_receiver has been cleaned up.
enum RTCPPacketType : uint32_t {
@@ -109,17 +98,9 @@ enum RTCPPacketType : uint32_t {
enum KeyFrameRequestMethod { kKeyFrameReqPliRtcp, kKeyFrameReqFirRtcp };
-enum RtpRtcpPacketType
-{
- kPacketRtp = 0,
- kPacketKeepAlive = 1
-};
+enum RtpRtcpPacketType { kPacketRtp = 0, kPacketKeepAlive = 1 };
-enum NACKMethod
-{
- kNackOff = 0,
- kNackRtcp = 2
-};
+enum NACKMethod { kNackOff = 0, kNackRtcp = 2 };
enum RetransmissionMode : uint8_t {
kRetransmitOff = 0x0,
@@ -138,8 +119,7 @@ enum RtxMode {
const size_t kRtxHeaderSize = 2;
-struct RTCPSenderInfo
-{
+struct RTCPSenderInfo {
uint32_t NTPseconds;
uint32_t NTPfraction;
uint32_t RTPtimeStamp;
@@ -206,40 +186,36 @@ struct RtpState {
bool media_has_been_sent;
};
-class RtpData
-{
-public:
- virtual ~RtpData() {}
+class RtpData {
+ public:
+ virtual ~RtpData() {}
- virtual int32_t OnReceivedPayloadData(
- const uint8_t* payloadData,
- const size_t payloadSize,
- const WebRtcRTPHeader* rtpHeader) = 0;
+ virtual int32_t OnReceivedPayloadData(const uint8_t* payloadData,
+ const size_t payloadSize,
+ const WebRtcRTPHeader* rtpHeader) = 0;
- virtual bool OnRecoveredPacket(const uint8_t* packet,
- size_t packet_length) = 0;
+ virtual bool OnRecoveredPacket(const uint8_t* packet,
+ size_t packet_length) = 0;
};
-class RtpFeedback
-{
-public:
- virtual ~RtpFeedback() {}
-
- // Receiving payload change or SSRC change. (return success!)
- /*
- * channels - number of channels in codec (1 = mono, 2 = stereo)
- */
- virtual int32_t OnInitializeDecoder(
- const int8_t payloadType,
- const char payloadName[RTP_PAYLOAD_NAME_SIZE],
- const int frequency,
- const uint8_t channels,
- const uint32_t rate) = 0;
-
- virtual void OnIncomingSSRCChanged(const uint32_t ssrc) = 0;
-
- virtual void OnIncomingCSRCChanged(const uint32_t CSRC,
- const bool added) = 0;
+class RtpFeedback {
+ public:
+ virtual ~RtpFeedback() {}
+
+ // Receiving payload change or SSRC change. (return success!)
+ /*
+ * channels - number of channels in codec (1 = mono, 2 = stereo)
+ */
+ virtual int32_t OnInitializeDecoder(
+ const int8_t payloadType,
+ const char payloadName[RTP_PAYLOAD_NAME_SIZE],
+ const int frequency,
+ const size_t channels,
+ const uint32_t rate) = 0;
+
+ virtual void OnIncomingSSRCChanged(const uint32_t ssrc) = 0;
+
+ virtual void OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) = 0;
};
class RtpAudioFeedback {
@@ -346,7 +322,7 @@ class RtcpRttStats {
virtual int64_t LastProcessedRtt() const = 0;
- virtual ~RtcpRttStats() {};
+ virtual ~RtcpRttStats() {}
};
// Null object version of RtpFeedback.
@@ -357,7 +333,7 @@ class NullRtpFeedback : public RtpFeedback {
int32_t OnInitializeDecoder(const int8_t payloadType,
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) override {
return 0;
}
@@ -437,4 +413,4 @@ class TransportSequenceNumberAllocator {
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_DEFINES_H_
diff --git a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index bc4aec8967..796be1304c 100644
--- a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -11,11 +11,15 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_MOCKS_MOCK_RTP_RTCP_H_
#define WEBRTC_MODULES_RTP_RTCP_MOCKS_MOCK_RTP_RTCP_H_
+#include <set>
+#include <utility>
+#include <vector>
+
#include "testing/gmock/include/gmock/gmock.h"
-#include "webrtc/modules/interface/module.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/include/module.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
namespace webrtc {
@@ -108,7 +112,10 @@ class MockRtpRtcp : public RtpRtcp {
MOCK_CONST_METHOD0(SendingMedia,
bool());
MOCK_CONST_METHOD4(BitrateSent,
- void(uint32_t* totalRate, uint32_t* videoRate, uint32_t* fecRate, uint32_t* nackRate));
+ void(uint32_t* totalRate,
+ uint32_t* videoRate,
+ uint32_t* fecRate,
+ uint32_t* nackRate));
MOCK_METHOD1(RegisterVideoBitrateObserver, void(BitrateStatisticsObserver*));
MOCK_CONST_METHOD0(GetVideoBitrateObserver, BitrateStatisticsObserver*(void));
MOCK_CONST_METHOD1(EstimatedReceiveBandwidth,
@@ -172,7 +179,10 @@ class MockRtpRtcp : public RtpRtcp {
MOCK_CONST_METHOD1(RemoteRTCPStat,
int32_t(std::vector<RTCPReportBlock>* receiveBlocks));
MOCK_METHOD4(SetRTCPApplicationSpecificData,
- int32_t(const uint8_t subType, const uint32_t name, const uint8_t* data, const uint16_t length));
+ int32_t(const uint8_t subType,
+ const uint32_t name,
+ const uint8_t* data,
+ const uint16_t length));
MOCK_METHOD1(SetRTCPVoIPMetrics,
int32_t(const RTCPVoIPMetric* VoIPMetric));
MOCK_METHOD1(SetRtcpXrRrtrStatus,
@@ -214,12 +224,9 @@ class MockRtpRtcp : public RtpRtcp {
int32_t(const uint8_t key, const uint16_t time_ms, const uint8_t level));
MOCK_METHOD1(SetSendREDPayloadType,
int32_t(const int8_t payloadType));
- MOCK_CONST_METHOD1(SendREDPayloadType,
- int32_t(int8_t& payloadType));
+ MOCK_CONST_METHOD1(SendREDPayloadType, int32_t(int8_t* payloadType));
MOCK_METHOD2(SetRTPAudioLevelIndicationStatus,
int32_t(const bool enable, const uint8_t ID));
- MOCK_CONST_METHOD2(GetRTPAudioLevelIndicationStatus,
- int32_t(bool& enable, uint8_t& ID));
MOCK_METHOD1(SetAudioLevel,
int32_t(const uint8_t level_dBov));
MOCK_METHOD1(SetTargetSendBitrate,
@@ -229,9 +236,9 @@ class MockRtpRtcp : public RtpRtcp {
const uint8_t payload_type_red,
const uint8_t payload_type_fec));
MOCK_METHOD3(GenericFECStatus,
- void(bool& enable,
- uint8_t& payloadTypeRED,
- uint8_t& payloadTypeFEC));
+ void(bool* enable,
+ uint8_t* payloadTypeRED,
+ uint8_t* payloadTypeFEC));
MOCK_METHOD2(SetFecParameters,
int32_t(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params));
@@ -239,8 +246,6 @@ class MockRtpRtcp : public RtpRtcp {
int32_t(const KeyFrameRequestMethod method));
MOCK_METHOD0(RequestKeyFrame,
int32_t());
- MOCK_CONST_METHOD3(Version,
- int32_t(char* version, uint32_t& remaining_buffer_in_bytes, uint32_t& position));
MOCK_METHOD0(TimeUntilNextProcess,
int64_t());
MOCK_METHOD0(Process,
diff --git a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
index e35a75cd0f..d340f746be 100644
--- a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
+++ b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
@@ -17,14 +17,14 @@
],
'sources': [
# Common
- 'interface/fec_receiver.h',
- 'interface/receive_statistics.h',
- 'interface/remote_ntp_time_estimator.h',
- 'interface/rtp_header_parser.h',
- 'interface/rtp_payload_registry.h',
- 'interface/rtp_receiver.h',
- 'interface/rtp_rtcp.h',
- 'interface/rtp_rtcp_defines.h',
+ 'include/fec_receiver.h',
+ 'include/receive_statistics.h',
+ 'include/remote_ntp_time_estimator.h',
+ 'include/rtp_header_parser.h',
+ 'include/rtp_payload_registry.h',
+ 'include/rtp_receiver.h',
+ 'include/rtp_rtcp.h',
+ 'include/rtp_rtcp_defines.h',
'source/bitrate.cc',
'source/bitrate.h',
'source/byte_io.h',
@@ -41,8 +41,40 @@
'source/rtp_rtcp_impl.h',
'source/rtcp_packet.cc',
'source/rtcp_packet.h',
+ 'source/rtcp_packet/app.cc',
+ 'source/rtcp_packet/app.h',
+ 'source/rtcp_packet/bye.cc',
+ 'source/rtcp_packet/bye.h',
+ 'source/rtcp_packet/compound_packet.cc',
+ 'source/rtcp_packet/compound_packet.h',
+ 'source/rtcp_packet/dlrr.cc',
+ 'source/rtcp_packet/dlrr.h',
+ 'source/rtcp_packet/extended_jitter_report.cc',
+ 'source/rtcp_packet/extended_jitter_report.h',
+ 'source/rtcp_packet/nack.cc',
+ 'source/rtcp_packet/nack.h',
+ 'source/rtcp_packet/pli.cc',
+ 'source/rtcp_packet/pli.h',
+ 'source/rtcp_packet/psfb.cc',
+ 'source/rtcp_packet/psfb.h',
+ 'source/rtcp_packet/receiver_report.cc',
+ 'source/rtcp_packet/receiver_report.h',
+ 'source/rtcp_packet/report_block.cc',
+ 'source/rtcp_packet/report_block.h',
+ 'source/rtcp_packet/rrtr.cc',
+ 'source/rtcp_packet/rrtr.h',
+ 'source/rtcp_packet/rtpfb.cc',
+ 'source/rtcp_packet/rtpfb.h',
+ 'source/rtcp_packet/sli.cc',
+ 'source/rtcp_packet/sli.h',
+ 'source/rtcp_packet/tmmbn.cc',
+ 'source/rtcp_packet/tmmbn.h',
+ 'source/rtcp_packet/tmmbr.cc',
+ 'source/rtcp_packet/tmmbr.h',
'source/rtcp_packet/transport_feedback.cc',
'source/rtcp_packet/transport_feedback.h',
+ 'source/rtcp_packet/voip_metric.cc',
+ 'source/rtcp_packet/voip_metric.h',
'source/rtcp_receiver.cc',
'source/rtcp_receiver.h',
'source/rtcp_receiver_help.cc',
diff --git a/webrtc/modules/rtp_rtcp/source/CPPLINT.cfg b/webrtc/modules/rtp_rtcp/source/CPPLINT.cfg
new file mode 100644
index 0000000000..c318452482
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/CPPLINT.cfg
@@ -0,0 +1,6 @@
+#tmmbr_help is refactored in CL#1474693002
+exclude_files=tmmbr_help.*
+#rtcp_utility planned to be removed when webrtc:5260 will be finished.
+exclude_files=rtcp_utility.*
+#rtcp_receiver/rtcp_receiver_help will be refactored more deeply as part of webrtc:5260
+exclude_files=rtcp_receiver.*
diff --git a/webrtc/modules/rtp_rtcp/source/byte_io.h b/webrtc/modules/rtp_rtcp/source/byte_io.h
index d8903b8483..c69c178078 100644
--- a/webrtc/modules/rtp_rtcp/source/byte_io.h
+++ b/webrtc/modules/rtp_rtcp/source/byte_io.h
@@ -51,17 +51,14 @@ namespace webrtc {
// platform that doesn't use two's complement, implement conversion to/from
// wire format.
-namespace {
-inline void AssertTwosComplement() {
- // Assume the if any one signed integer type is two's complement, then all
- // other will be too.
- static_assert(
- (-1 & 0x03) == 0x03,
- "Only two's complement representation of signed integers supported.");
-}
+// Assume the if any one signed integer type is two's complement, then all
+// other will be too.
+static_assert(
+ (-1 & 0x03) == 0x03,
+ "Only two's complement representation of signed integers supported.");
+
// Plain const char* won't work for static_assert, use #define instead.
#define kSizeErrorMsg "Byte size must be less than or equal to data type size."
-}
// Utility class for getting the unsigned equivalent of a signed type.
template <typename T>
diff --git a/webrtc/modules/rtp_rtcp/source/dtmf_queue.cc b/webrtc/modules/rtp_rtcp/source/dtmf_queue.cc
index becea912ab..ab21b8704a 100644
--- a/webrtc/modules/rtp_rtcp/source/dtmf_queue.cc
+++ b/webrtc/modules/rtp_rtcp/source/dtmf_queue.cc
@@ -10,7 +10,7 @@
#include "webrtc/modules/rtp_rtcp/source/dtmf_queue.h"
-#include <string.h> //memset
+#include <string.h>
namespace webrtc {
DTMFqueue::DTMFqueue()
@@ -21,7 +21,9 @@ DTMFqueue::DTMFqueue()
memset(dtmf_level_, 0, sizeof(dtmf_level_));
}
-DTMFqueue::~DTMFqueue() { delete dtmf_critsect_; }
+DTMFqueue::~DTMFqueue() {
+ delete dtmf_critsect_;
+}
int32_t DTMFqueue::AddDTMF(uint8_t key, uint16_t len, uint8_t level) {
CriticalSectionScoped lock(dtmf_critsect_);
diff --git a/webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h b/webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h
index 6105ae1d24..0b39908bb1 100644
--- a/webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h
+++ b/webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h
@@ -27,7 +27,8 @@
#include "webrtc/typedefs.h"
-namespace {
+namespace webrtc {
+namespace fec_private_tables {
const uint8_t kMaskBursty1_1[2] = {
0x80, 0x00
@@ -756,5 +757,6 @@ const uint8_t** kPacketMaskBurstyTbl[12] = {
kPacketMaskBursty12
};
-} // namespace
+} // namespace fec_private_tables
+} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_PRIVATE_TABLES_BURSTY_H_
diff --git a/webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h b/webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h
index ff6de43b76..295d749873 100644
--- a/webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h
+++ b/webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h
@@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_PRIVATE_TABLES_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_PRIVATE_TABLES_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_PRIVATE_TABLES_RANDOM_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_PRIVATE_TABLES_RANDOM_H_
// This file contains a set of packets masks for the FEC code. The masks in
// this table are specifically designed to favor recovery to random loss.
@@ -17,7 +17,8 @@
#include "webrtc/typedefs.h"
-namespace {
+namespace webrtc {
+namespace fec_private_tables {
const uint8_t kMaskRandom10_1[2] = {
0xff, 0xc0
@@ -24518,5 +24519,6 @@ const uint8_t** kPacketMaskRandomTbl[48] = {
kPacketMaskRandom48
};
-} // namespace
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_PRIVATE_TABLES_H_
+} // namespace fec_private_tables
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_PRIVATE_TABLES_RANDOM_H_
diff --git a/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.h b/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.h
index 24db39b902..6a63813f40 100644
--- a/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.h
+++ b/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.h
@@ -14,8 +14,8 @@
// This header is included to get the nested declaration of Packet structure.
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/fec_receiver.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/typedefs.h"
@@ -25,7 +25,7 @@ class CriticalSectionWrapper;
class FecReceiverImpl : public FecReceiver {
public:
- FecReceiverImpl(RtpData* callback);
+ explicit FecReceiverImpl(RtpData* callback);
virtual ~FecReceiverImpl();
int32_t AddReceivedRedPacket(const RTPHeader& rtp_header,
diff --git a/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc
index f64b537a52..bb22e1d580 100644
--- a/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc
@@ -15,8 +15,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/include/fec_receiver.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
diff --git a/webrtc/modules/rtp_rtcp/source/fec_test_helper.h b/webrtc/modules/rtp_rtcp/source/fec_test_helper.h
index e1791adba3..aacc2d1ecc 100644
--- a/webrtc/modules/rtp_rtcp/source/fec_test_helper.h
+++ b/webrtc/modules/rtp_rtcp/source/fec_test_helper.h
@@ -11,7 +11,7 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_TEST_HELPER_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_TEST_HELPER_H_
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
namespace webrtc {
@@ -54,6 +54,6 @@ class FrameGenerator {
uint16_t seq_num_;
uint32_t timestamp_;
};
-}
+} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_TEST_HELPER_H_
diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc b/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc
index aad418f015..b85d813790 100644
--- a/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc
+++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc
@@ -10,15 +10,15 @@
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
-#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iterator>
+#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h"
@@ -36,11 +36,11 @@ const uint8_t kUlpHeaderSizeLBitClear = (2 + kMaskSizeLBitClear);
// Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum.
const uint8_t kTransportOverhead = 28;
-enum {
- kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets
-};
+enum { kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets };
-int32_t ForwardErrorCorrection::Packet::AddRef() { return ++ref_count_; }
+int32_t ForwardErrorCorrection::Packet::AddRef() {
+ return ++ref_count_;
+}
int32_t ForwardErrorCorrection::Packet::Release() {
int32_t ref_count;
@@ -72,7 +72,8 @@ class FecPacket : public ForwardErrorCorrection::SortablePacket {
};
bool ForwardErrorCorrection::SortablePacket::LessThan(
- const SortablePacket* first, const SortablePacket* second) {
+ const SortablePacket* first,
+ const SortablePacket* second) {
return IsNewerSequenceNumber(second->seq_num, first->seq_num);
}
@@ -83,8 +84,7 @@ ForwardErrorCorrection::RecoveredPacket::RecoveredPacket() {}
ForwardErrorCorrection::RecoveredPacket::~RecoveredPacket() {}
ForwardErrorCorrection::ForwardErrorCorrection()
- : generated_fec_packets_(kMaxMediaPackets),
- fec_packet_received_(false) {}
+ : generated_fec_packets_(kMaxMediaPackets), fec_packet_received_(false) {}
ForwardErrorCorrection::~ForwardErrorCorrection() {}
@@ -112,7 +112,6 @@ int32_t ForwardErrorCorrection::GenerateFEC(const PacketList& media_packet_list,
FecMaskType fec_mask_type,
PacketList* fec_packet_list) {
const uint16_t num_media_packets = media_packet_list.size();
-
// Sanity check arguments.
assert(num_media_packets > 0);
assert(num_important_packets >= 0 &&
@@ -126,12 +125,10 @@ int32_t ForwardErrorCorrection::GenerateFEC(const PacketList& media_packet_list,
}
bool l_bit = (num_media_packets > 8 * kMaskSizeLBitClear);
- int num_maskBytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
+ int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
// Do some error checking on the media packets.
- PacketList::const_iterator media_list_it = media_packet_list.begin();
- while (media_list_it != media_packet_list.end()) {
- Packet* media_packet = *media_list_it;
+ for (Packet* media_packet : media_packet_list) {
assert(media_packet);
if (media_packet->length < kRtpHeaderSize) {
@@ -146,7 +143,6 @@ int32_t ForwardErrorCorrection::GenerateFEC(const PacketList& media_packet_list,
LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes "
<< "with overhead is larger than " << IP_PACKET_SIZE;
}
- media_list_it++;
}
int num_fec_packets =
@@ -167,29 +163,29 @@ int32_t ForwardErrorCorrection::GenerateFEC(const PacketList& media_packet_list,
// -- Generate packet masks --
// Always allocate space for a large mask.
- uint8_t* packet_mask = new uint8_t[num_fec_packets * kMaskSizeLBitSet];
- memset(packet_mask, 0, num_fec_packets * num_maskBytes);
+ rtc::scoped_ptr<uint8_t[]> packet_mask(
+ new uint8_t[num_fec_packets * kMaskSizeLBitSet]);
+ memset(packet_mask.get(), 0, num_fec_packets * num_mask_bytes);
internal::GeneratePacketMasks(num_media_packets, num_fec_packets,
num_important_packets, use_unequal_protection,
- mask_table, packet_mask);
-
- int num_maskBits = InsertZerosInBitMasks(media_packet_list, packet_mask,
- num_maskBytes, num_fec_packets);
+ mask_table, packet_mask.get());
- l_bit = (num_maskBits > 8 * kMaskSizeLBitClear);
+ int num_mask_bits = InsertZerosInBitMasks(
+ media_packet_list, packet_mask.get(), num_mask_bytes, num_fec_packets);
- if (num_maskBits < 0) {
- delete[] packet_mask;
+ if (num_mask_bits < 0) {
return -1;
}
+ l_bit = (num_mask_bits > 8 * kMaskSizeLBitClear);
if (l_bit) {
- num_maskBytes = kMaskSizeLBitSet;
+ num_mask_bytes = kMaskSizeLBitSet;
}
- GenerateFecBitStrings(media_packet_list, packet_mask, num_fec_packets, l_bit);
- GenerateFecUlpHeaders(media_packet_list, packet_mask, l_bit, num_fec_packets);
+ GenerateFecBitStrings(media_packet_list, packet_mask.get(), num_fec_packets,
+ l_bit);
+ GenerateFecUlpHeaders(media_packet_list, packet_mask.get(), l_bit,
+ num_fec_packets);
- delete[] packet_mask;
return 0;
}
@@ -206,26 +202,30 @@ int ForwardErrorCorrection::GetNumberOfFecPackets(int num_media_packets,
}
void ForwardErrorCorrection::GenerateFecBitStrings(
- const PacketList& media_packet_list, uint8_t* packet_mask,
- int num_fec_packets, bool l_bit) {
+ const PacketList& media_packet_list,
+ uint8_t* packet_mask,
+ int num_fec_packets,
+ bool l_bit) {
if (media_packet_list.empty()) {
return;
}
uint8_t media_payload_length[2];
- const int num_maskBytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
+ const int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
const uint16_t ulp_header_size =
l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear;
const uint16_t fec_rtp_offset =
kFecHeaderSize + ulp_header_size - kRtpHeaderSize;
for (int i = 0; i < num_fec_packets; ++i) {
+ Packet* const fec_packet = &generated_fec_packets_[i];
PacketList::const_iterator media_list_it = media_packet_list.begin();
- uint32_t pkt_mask_idx = i * num_maskBytes;
+ uint32_t pkt_mask_idx = i * num_mask_bytes;
uint32_t media_pkt_idx = 0;
uint16_t fec_packet_length = 0;
uint16_t prev_seq_num = ParseSequenceNumber((*media_list_it)->data);
while (media_list_it != media_packet_list.end()) {
- // Each FEC packet has a multiple byte mask.
+ // Each FEC packet has a multiple byte mask. Determine if this media
+ // packet should be included in FEC packet i.
if (packet_mask[pkt_mask_idx] & (1 << (7 - media_pkt_idx))) {
Packet* media_packet = *media_list_it;
@@ -235,42 +235,40 @@ void ForwardErrorCorrection::GenerateFecBitStrings(
fec_packet_length = media_packet->length + fec_rtp_offset;
// On the first protected packet, we don't need to XOR.
- if (generated_fec_packets_[i].length == 0) {
+ if (fec_packet->length == 0) {
// Copy the first 2 bytes of the RTP header.
- memcpy(generated_fec_packets_[i].data, media_packet->data, 2);
+ memcpy(fec_packet->data, media_packet->data, 2);
// Copy the 5th to 8th bytes of the RTP header.
- memcpy(&generated_fec_packets_[i].data[4], &media_packet->data[4], 4);
+ memcpy(&fec_packet->data[4], &media_packet->data[4], 4);
// Copy network-ordered payload size.
- memcpy(&generated_fec_packets_[i].data[8], media_payload_length, 2);
+ memcpy(&fec_packet->data[8], media_payload_length, 2);
// Copy RTP payload, leaving room for the ULP header.
- memcpy(
- &generated_fec_packets_[i].data[kFecHeaderSize + ulp_header_size],
- &media_packet->data[kRtpHeaderSize],
- media_packet->length - kRtpHeaderSize);
+ memcpy(&fec_packet->data[kFecHeaderSize + ulp_header_size],
+ &media_packet->data[kRtpHeaderSize],
+ media_packet->length - kRtpHeaderSize);
} else {
// XOR with the first 2 bytes of the RTP header.
- generated_fec_packets_[i].data[0] ^= media_packet->data[0];
- generated_fec_packets_[i].data[1] ^= media_packet->data[1];
+ fec_packet->data[0] ^= media_packet->data[0];
+ fec_packet->data[1] ^= media_packet->data[1];
// XOR with the 5th to 8th bytes of the RTP header.
for (uint32_t j = 4; j < 8; ++j) {
- generated_fec_packets_[i].data[j] ^= media_packet->data[j];
+ fec_packet->data[j] ^= media_packet->data[j];
}
// XOR with the network-ordered payload size.
- generated_fec_packets_[i].data[8] ^= media_payload_length[0];
- generated_fec_packets_[i].data[9] ^= media_payload_length[1];
+ fec_packet->data[8] ^= media_payload_length[0];
+ fec_packet->data[9] ^= media_payload_length[1];
// XOR with RTP payload, leaving room for the ULP header.
for (int32_t j = kFecHeaderSize + ulp_header_size;
j < fec_packet_length; j++) {
- generated_fec_packets_[i].data[j] ^=
- media_packet->data[j - fec_rtp_offset];
+ fec_packet->data[j] ^= media_packet->data[j - fec_rtp_offset];
}
}
- if (fec_packet_length > generated_fec_packets_[i].length) {
- generated_fec_packets_[i].length = fec_packet_length;
+ if (fec_packet_length > fec_packet->length) {
+ fec_packet->length = fec_packet_length;
}
}
media_list_it++;
@@ -279,19 +277,18 @@ void ForwardErrorCorrection::GenerateFecBitStrings(
media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num);
prev_seq_num = seq_num;
}
- if (media_pkt_idx == 8) {
- // Switch to the next mask byte.
- media_pkt_idx = 0;
- pkt_mask_idx++;
- }
+ pkt_mask_idx += media_pkt_idx / 8;
+ media_pkt_idx %= 8;
}
- assert(generated_fec_packets_[i].length);
- //Note: This shouldn't happen: means packet mask is wrong or poorly designed
+ RTC_DCHECK_GT(fec_packet->length, 0u)
+ << "Packet mask is wrong or poorly designed.";
}
}
int ForwardErrorCorrection::InsertZerosInBitMasks(
- const PacketList& media_packets, uint8_t* packet_mask, int num_mask_bytes,
+ const PacketList& media_packets,
+ uint8_t* packet_mask,
+ int num_mask_bytes,
int num_fec_packets) {
uint8_t* new_mask = NULL;
if (media_packets.size() <= 1) {
@@ -307,6 +304,9 @@ int ForwardErrorCorrection::InsertZerosInBitMasks(
// required.
return media_packets.size();
}
+ // We can only protect 8 * kMaskSizeLBitSet packets.
+ if (total_missing_seq_nums + media_packets.size() > 8 * kMaskSizeLBitSet)
+ return -1;
// Allocate the new mask.
int new_mask_bytes = kMaskSizeLBitClear;
if (media_packets.size() + total_missing_seq_nums > 8 * kMaskSizeLBitClear) {
@@ -357,7 +357,8 @@ int ForwardErrorCorrection::InsertZerosInBitMasks(
return new_bit_index;
}
-void ForwardErrorCorrection::InsertZeroColumns(int num_zeros, uint8_t* new_mask,
+void ForwardErrorCorrection::InsertZeroColumns(int num_zeros,
+ uint8_t* new_mask,
int new_mask_bytes,
int num_fec_packets,
int new_bit_index) {
@@ -368,9 +369,12 @@ void ForwardErrorCorrection::InsertZeroColumns(int num_zeros, uint8_t* new_mask,
}
}
-void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask, int new_mask_bytes,
- uint8_t* old_mask, int old_mask_bytes,
- int num_fec_packets, int new_bit_index,
+void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask,
+ int new_mask_bytes,
+ uint8_t* old_mask,
+ int old_mask_bytes,
+ int num_fec_packets,
+ int new_bit_index,
int old_bit_index) {
// Copy column from the old mask to the beginning of the new mask and shift it
// out from the old mask.
@@ -386,7 +390,9 @@ void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask, int new_mask_bytes,
}
void ForwardErrorCorrection::GenerateFecUlpHeaders(
- const PacketList& media_packet_list, uint8_t* packet_mask, bool l_bit,
+ const PacketList& media_packet_list,
+ uint8_t* packet_mask,
+ bool l_bit,
int num_fec_packets) {
// -- Generate FEC and ULP headers --
//
@@ -412,33 +418,34 @@ void ForwardErrorCorrection::GenerateFecUlpHeaders(
PacketList::const_iterator media_list_it = media_packet_list.begin();
Packet* media_packet = *media_list_it;
assert(media_packet != NULL);
- int num_maskBytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
+ int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
const uint16_t ulp_header_size =
l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear;
for (int i = 0; i < num_fec_packets; ++i) {
+ Packet* const fec_packet = &generated_fec_packets_[i];
// -- FEC header --
- generated_fec_packets_[i].data[0] &= 0x7f; // Set E to zero.
+ fec_packet->data[0] &= 0x7f; // Set E to zero.
if (l_bit == 0) {
- generated_fec_packets_[i].data[0] &= 0xbf; // Clear the L bit.
+ fec_packet->data[0] &= 0xbf; // Clear the L bit.
} else {
- generated_fec_packets_[i].data[0] |= 0x40; // Set the L bit.
+ fec_packet->data[0] |= 0x40; // Set the L bit.
}
// Two byte sequence number from first RTP packet to SN base.
// We use the same sequence number base for every FEC packet,
// but that's not required in general.
- memcpy(&generated_fec_packets_[i].data[2], &media_packet->data[2], 2);
+ memcpy(&fec_packet->data[2], &media_packet->data[2], 2);
// -- ULP header --
// Copy the payload size to the protection length field.
// (We protect the entire packet.)
ByteWriter<uint16_t>::WriteBigEndian(
- &generated_fec_packets_[i].data[10],
- generated_fec_packets_[i].length - kFecHeaderSize - ulp_header_size);
+ &fec_packet->data[10],
+ fec_packet->length - kFecHeaderSize - ulp_header_size);
// Copy the packet mask.
- memcpy(&generated_fec_packets_[i].data[12], &packet_mask[i * num_maskBytes],
- num_maskBytes);
+ memcpy(&fec_packet->data[12], &packet_mask[i * num_mask_bytes],
+ num_mask_bytes);
}
}
@@ -460,7 +467,7 @@ void ForwardErrorCorrection::ResetState(
ProtectedPacketList::iterator protected_packet_list_it;
protected_packet_list_it = fec_packet->protected_pkt_list.begin();
while (protected_packet_list_it != fec_packet->protected_pkt_list.end()) {
- delete* protected_packet_list_it;
+ delete *protected_packet_list_it;
protected_packet_list_it =
fec_packet->protected_pkt_list.erase(protected_packet_list_it);
}
@@ -472,7 +479,8 @@ void ForwardErrorCorrection::ResetState(
}
void ForwardErrorCorrection::InsertMediaPacket(
- ReceivedPacket* rx_packet, RecoveredPacketList* recovered_packet_list) {
+ ReceivedPacket* rx_packet,
+ RecoveredPacketList* recovered_packet_list) {
RecoveredPacketList::iterator recovered_packet_list_it =
recovered_packet_list->begin();
@@ -538,9 +546,9 @@ void ForwardErrorCorrection::InsertFECPacket(
const uint16_t seq_num_base =
ByteReader<uint16_t>::ReadBigEndian(&fec_packet->pkt->data[2]);
- const uint16_t maskSizeBytes =
- (fec_packet->pkt->data[0] & 0x40) ? kMaskSizeLBitSet
- : kMaskSizeLBitClear; // L bit set?
+ const uint16_t maskSizeBytes = (fec_packet->pkt->data[0] & 0x40)
+ ? kMaskSizeLBitSet
+ : kMaskSizeLBitClear; // L bit set?
for (uint16_t byte_idx = 0; byte_idx < maskSizeBytes; ++byte_idx) {
uint8_t packet_mask = fec_packet->pkt->data[12 + byte_idx];
@@ -574,7 +582,8 @@ void ForwardErrorCorrection::InsertFECPacket(
}
void ForwardErrorCorrection::AssignRecoveredPackets(
- FecPacket* fec_packet, const RecoveredPacketList* recovered_packets) {
+ FecPacket* fec_packet,
+ const RecoveredPacketList* recovered_packets) {
// Search for missing packets which have arrived or have been recovered by
// another FEC packet.
ProtectedPacketList* not_recovered = &fec_packet->protected_pkt_list;
@@ -599,7 +608,6 @@ void ForwardErrorCorrection::AssignRecoveredPackets(
void ForwardErrorCorrection::InsertPackets(
ReceivedPacketList* received_packet_list,
RecoveredPacketList* recovered_packet_list) {
-
while (!received_packet_list->empty()) {
ReceivedPacket* rx_packet = received_packet_list->front();
@@ -611,9 +619,9 @@ void ForwardErrorCorrection::InsertPackets(
// old FEC packets based on timestamp information or better sequence number
// thresholding (e.g., to distinguish between wrap-around and reordering).
if (!fec_packet_list_.empty()) {
- uint16_t seq_num_diff = abs(
- static_cast<int>(rx_packet->seq_num) -
- static_cast<int>(fec_packet_list_.front()->seq_num));
+ uint16_t seq_num_diff =
+ abs(static_cast<int>(rx_packet->seq_num) -
+ static_cast<int>(fec_packet_list_.front()->seq_num));
if (seq_num_diff > 0x3fff) {
DiscardFECPacket(fec_packet_list_.front());
fec_packet_list_.pop_front();
@@ -637,9 +645,9 @@ void ForwardErrorCorrection::InsertPackets(
bool ForwardErrorCorrection::InitRecovery(const FecPacket* fec_packet,
RecoveredPacket* recovered) {
// This is the first packet which we try to recover with.
- const uint16_t ulp_header_size =
- fec_packet->pkt->data[0] & 0x40 ? kUlpHeaderSizeLBitSet
- : kUlpHeaderSizeLBitClear; // L bit set?
+ const uint16_t ulp_header_size = fec_packet->pkt->data[0] & 0x40
+ ? kUlpHeaderSizeLBitSet
+ : kUlpHeaderSizeLBitClear; // L bit set?
if (fec_packet->pkt->length <
static_cast<size_t>(kFecHeaderSize + ulp_header_size)) {
LOG(LS_WARNING)
diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h
index f92f014db3..9ba6ce0438 100644
--- a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h
+++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h
@@ -15,7 +15,7 @@
#include <vector>
#include "webrtc/base/scoped_ref_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/system_wrappers/include/ref_count.h"
#include "webrtc/typedefs.h"
diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.cc b/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.cc
index 6d9be90de1..fae59078b1 100644
--- a/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.cc
+++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.cc
@@ -17,6 +17,8 @@
#include "webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h"
namespace {
+using webrtc::fec_private_tables::kPacketMaskBurstyTbl;
+using webrtc::fec_private_tables::kPacketMaskRandomTbl;
// Allow for different modes of protection for packets in UEP case.
enum ProtectionMode {
@@ -37,8 +39,11 @@ enum ProtectionMode {
// [0, num_rows * num_sub_mask_bytes]
// \param[out] packet_mask A pointer to hold the output mask, of size
// [0, x * num_mask_bytes], where x >= num_rows.
-void FitSubMask(int num_mask_bytes, int num_sub_mask_bytes, int num_rows,
- const uint8_t* sub_mask, uint8_t* packet_mask) {
+void FitSubMask(int num_mask_bytes,
+ int num_sub_mask_bytes,
+ int num_rows,
+ const uint8_t* sub_mask,
+ uint8_t* packet_mask) {
if (num_mask_bytes == num_sub_mask_bytes) {
memcpy(packet_mask, sub_mask, num_rows * num_sub_mask_bytes);
} else {
@@ -70,13 +75,15 @@ void FitSubMask(int num_mask_bytes, int num_sub_mask_bytes, int num_rows,
// \param[out] packet_mask A pointer to hold the output mask, of size
// [0, x * num_mask_bytes],
// where x >= end_row_fec.
-// TODO (marpan): This function is doing three things at the same time:
+// TODO(marpan): This function is doing three things at the same time:
// shift within a byte, byte shift and resizing.
// Split up into subroutines.
-void ShiftFitSubMask(int num_mask_bytes, int res_mask_bytes,
- int num_column_shift, int end_row, const uint8_t* sub_mask,
+void ShiftFitSubMask(int num_mask_bytes,
+ int res_mask_bytes,
+ int num_column_shift,
+ int end_row,
+ const uint8_t* sub_mask,
uint8_t* packet_mask) {
-
// Number of bit shifts within a byte
const int num_bit_shifts = (num_column_shift % 8);
const int num_byte_shifts = num_column_shift >> 3;
@@ -128,7 +135,6 @@ void ShiftFitSubMask(int num_mask_bytes, int res_mask_bytes,
// For the first byte in the row (j=0 case).
shift_right_curr_byte = sub_mask[pkt_mask_idx2] >> num_bit_shifts;
packet_mask[pkt_mask_idx] = shift_right_curr_byte;
-
}
}
} // namespace
@@ -151,7 +157,9 @@ FecMaskType PacketMaskTable::InitMaskType(FecMaskType fec_mask_type,
assert(num_media_packets <= static_cast<int>(sizeof(kPacketMaskRandomTbl) /
sizeof(*kPacketMaskRandomTbl)));
switch (fec_mask_type) {
- case kFecMaskRandom: { return kFecMaskRandom; }
+ case kFecMaskRandom: {
+ return kFecMaskRandom;
+ }
case kFecMaskBursty: {
int max_media_packets = static_cast<int>(sizeof(kPacketMaskBurstyTbl) /
sizeof(*kPacketMaskBurstyTbl));
@@ -170,17 +178,24 @@ FecMaskType PacketMaskTable::InitMaskType(FecMaskType fec_mask_type,
// |fec_mask_type|.
const uint8_t*** PacketMaskTable::InitMaskTable(FecMaskType fec_mask_type) {
switch (fec_mask_type) {
- case kFecMaskRandom: { return kPacketMaskRandomTbl; }
- case kFecMaskBursty: { return kPacketMaskBurstyTbl; }
+ case kFecMaskRandom: {
+ return kPacketMaskRandomTbl;
+ }
+ case kFecMaskBursty: {
+ return kPacketMaskBurstyTbl;
+ }
}
assert(false);
return kPacketMaskRandomTbl;
}
// Remaining protection after important (first partition) packet protection
-void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
- int num_fec_for_imp_packets, int num_mask_bytes,
- ProtectionMode mode, uint8_t* packet_mask,
+void RemainingPacketProtection(int num_media_packets,
+ int num_fec_remaining,
+ int num_fec_for_imp_packets,
+ int num_mask_bytes,
+ ProtectionMode mode,
+ uint8_t* packet_mask,
const PacketMaskTable& mask_table) {
if (mode == kModeNoOverlap) {
// sub_mask21
@@ -191,8 +206,10 @@ void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
const int res_mask_bytes =
(l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear;
- const uint8_t* packet_mask_sub_21 = mask_table.fec_packet_mask_table()[
- num_media_packets - num_fec_for_imp_packets - 1][num_fec_remaining - 1];
+ const uint8_t* packet_mask_sub_21 =
+ mask_table.fec_packet_mask_table()[num_media_packets -
+ num_fec_for_imp_packets -
+ 1][num_fec_remaining - 1];
ShiftFitSubMask(num_mask_bytes, res_mask_bytes, num_fec_for_imp_packets,
(num_fec_for_imp_packets + num_fec_remaining),
@@ -201,8 +218,9 @@ void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
} else if (mode == kModeOverlap || mode == kModeBiasFirstPacket) {
// sub_mask22
- const uint8_t* packet_mask_sub_22 = mask_table
- .fec_packet_mask_table()[num_media_packets - 1][num_fec_remaining - 1];
+ const uint8_t* packet_mask_sub_22 =
+ mask_table.fec_packet_mask_table()[num_media_packets -
+ 1][num_fec_remaining - 1];
FitSubMask(num_mask_bytes, num_mask_bytes, num_fec_remaining,
packet_mask_sub_22,
@@ -217,41 +235,42 @@ void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
} else {
assert(false);
}
-
}
// Protection for important (first partition) packets
-void ImportantPacketProtection(int num_fec_for_imp_packets, int num_imp_packets,
- int num_mask_bytes, uint8_t* packet_mask,
+void ImportantPacketProtection(int num_fec_for_imp_packets,
+ int num_imp_packets,
+ int num_mask_bytes,
+ uint8_t* packet_mask,
const PacketMaskTable& mask_table) {
const int l_bit = num_imp_packets > 16 ? 1 : 0;
const int num_imp_mask_bytes =
(l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear;
// Get sub_mask1 from table
- const uint8_t* packet_mask_sub_1 = mask_table.fec_packet_mask_table()[
- num_imp_packets - 1][num_fec_for_imp_packets - 1];
+ const uint8_t* packet_mask_sub_1 =
+ mask_table.fec_packet_mask_table()[num_imp_packets -
+ 1][num_fec_for_imp_packets - 1];
FitSubMask(num_mask_bytes, num_imp_mask_bytes, num_fec_for_imp_packets,
packet_mask_sub_1, packet_mask);
-
}
// This function sets the protection allocation: i.e., how many FEC packets
// to use for num_imp (1st partition) packets, given the: number of media
// packets, number of FEC packets, and number of 1st partition packets.
-int SetProtectionAllocation(int num_media_packets, int num_fec_packets,
+int SetProtectionAllocation(int num_media_packets,
+ int num_fec_packets,
int num_imp_packets) {
-
- // TODO (marpan): test different cases for protection allocation:
+ // TODO(marpan): test different cases for protection allocation:
// Use at most (alloc_par * num_fec_packets) for important packets.
float alloc_par = 0.5;
int max_num_fec_for_imp = alloc_par * num_fec_packets;
- int num_fec_for_imp_packets =
- (num_imp_packets < max_num_fec_for_imp) ? num_imp_packets
- : max_num_fec_for_imp;
+ int num_fec_for_imp_packets = (num_imp_packets < max_num_fec_for_imp)
+ ? num_imp_packets
+ : max_num_fec_for_imp;
// Fall back to equal protection in this case
if (num_fec_packets == 1 && (num_media_packets > 2 * num_imp_packets)) {
@@ -268,7 +287,7 @@ int SetProtectionAllocation(int num_media_packets, int num_fec_packets,
// Current version has 3 modes (options) to build UEP mask from existing ones.
// Various other combinations may be added in future versions.
// Longer-term, we may add another set of tables specifically for UEP cases.
-// TODO (marpan): also consider modification of masks for bursty loss cases.
+// TODO(marpan): also consider modification of masks for bursty loss cases.
// Mask is characterized as (#packets_to_protect, #fec_for_protection).
// Protection factor defined as: (#fec_for_protection / #packets_to_protect).
@@ -306,13 +325,14 @@ int SetProtectionAllocation(int num_media_packets, int num_fec_packets,
// Protection Mode 2 may be extended for a sort of sliding protection
// (i.e., vary the number/density of "1s" across columns) across packets.
-void UnequalProtectionMask(int num_media_packets, int num_fec_packets,
- int num_imp_packets, int num_mask_bytes,
+void UnequalProtectionMask(int num_media_packets,
+ int num_fec_packets,
+ int num_imp_packets,
+ int num_mask_bytes,
uint8_t* packet_mask,
const PacketMaskTable& mask_table) {
-
// Set Protection type and allocation
- // TODO (marpan): test/update for best mode and some combinations thereof.
+ // TODO(marpan): test/update for best mode and some combinations thereof.
ProtectionMode mode = kModeOverlap;
int num_fec_for_imp_packets = 0;
@@ -341,11 +361,12 @@ void UnequalProtectionMask(int num_media_packets, int num_fec_packets,
num_fec_for_imp_packets, num_mask_bytes, mode,
packet_mask, mask_table);
}
-
}
-void GeneratePacketMasks(int num_media_packets, int num_fec_packets,
- int num_imp_packets, bool use_unequal_protection,
+void GeneratePacketMasks(int num_media_packets,
+ int num_fec_packets,
+ int num_imp_packets,
+ bool use_unequal_protection,
const PacketMaskTable& mask_table,
uint8_t* packet_mask) {
assert(num_media_packets > 0);
@@ -361,16 +382,15 @@ void GeneratePacketMasks(int num_media_packets, int num_fec_packets,
// Retrieve corresponding mask table directly:for equal-protection case.
// Mask = (k,n-k), with protection factor = (n-k)/k,
// where k = num_media_packets, n=total#packets, (n-k)=num_fec_packets.
- memcpy(packet_mask, mask_table.fec_packet_mask_table()[
- num_media_packets - 1][num_fec_packets - 1],
+ memcpy(packet_mask,
+ mask_table.fec_packet_mask_table()[num_media_packets -
+ 1][num_fec_packets - 1],
num_fec_packets * num_mask_bytes);
- } else //UEP case
- {
+ } else { // UEP case
UnequalProtectionMask(num_media_packets, num_fec_packets, num_imp_packets,
num_mask_bytes, packet_mask, mask_table);
-
} // End of UEP modification
-} //End of GetPacketMasks
+} // End of GetPacketMasks
} // namespace internal
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h b/webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h
index 53ef2a61f4..28276afb72 100644
--- a/webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h
+++ b/webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h
@@ -11,8 +11,8 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_PARSER_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_PARSER_H_
-#include <stdint.h>
#include <stddef.h>
+#include <stdint.h>
namespace rtc {
class BitBuffer;
diff --git a/webrtc/modules/rtp_rtcp/source/h264_sps_parser_unittest.cc b/webrtc/modules/rtp_rtcp/source/h264_sps_parser_unittest.cc
index ceadf4cb6b..7a7e3ed293 100644
--- a/webrtc/modules/rtp_rtcp/source/h264_sps_parser_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/h264_sps_parser_unittest.cc
@@ -12,6 +12,7 @@
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/arraysize.h"
#include "webrtc/base/bitbuffer.h"
namespace webrtc {
@@ -121,7 +122,7 @@ TEST(H264SpsParserTest, TestSampleSPSHdLandscape) {
const uint8_t buffer[] = {0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50, 0x05,
0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00,
0x00, 0x2A, 0xE0, 0xF1, 0x83, 0x19, 0x60};
- H264SpsParser parser = H264SpsParser(buffer, ARRAY_SIZE(buffer));
+ H264SpsParser parser = H264SpsParser(buffer, arraysize(buffer));
EXPECT_TRUE(parser.Parse());
EXPECT_EQ(1280u, parser.width());
EXPECT_EQ(720u, parser.height());
@@ -133,7 +134,7 @@ TEST(H264SpsParserTest, TestSampleSPSVgaLandscape) {
const uint8_t buffer[] = {0x7A, 0x00, 0x1E, 0xBC, 0xD9, 0x40, 0xA0, 0x2F,
0xF8, 0x98, 0x40, 0x00, 0x00, 0x03, 0x01, 0x80,
0x00, 0x00, 0x56, 0x83, 0xC5, 0x8B, 0x65, 0x80};
- H264SpsParser parser = H264SpsParser(buffer, ARRAY_SIZE(buffer));
+ H264SpsParser parser = H264SpsParser(buffer, arraysize(buffer));
EXPECT_TRUE(parser.Parse());
EXPECT_EQ(640u, parser.width());
EXPECT_EQ(360u, parser.height());
@@ -145,7 +146,7 @@ TEST(H264SpsParserTest, TestSampleSPSWeirdResolution) {
const uint8_t buffer[] = {0x7A, 0x00, 0x0D, 0xBC, 0xD9, 0x43, 0x43, 0x3E,
0x5E, 0x10, 0x00, 0x00, 0x03, 0x00, 0x60, 0x00,
0x00, 0x15, 0xA0, 0xF1, 0x42, 0x99, 0x60};
- H264SpsParser parser = H264SpsParser(buffer, ARRAY_SIZE(buffer));
+ H264SpsParser parser = H264SpsParser(buffer, arraysize(buffer));
EXPECT_TRUE(parser.Parse());
EXPECT_EQ(200u, parser.width());
EXPECT_EQ(400u, parser.height());
@@ -154,7 +155,7 @@ TEST(H264SpsParserTest, TestSampleSPSWeirdResolution) {
TEST(H264SpsParserTest, TestSyntheticSPSQvgaLandscape) {
uint8_t buffer[kSpsBufferMaxSize] = {0};
GenerateFakeSps(320u, 180u, buffer);
- H264SpsParser parser = H264SpsParser(buffer, ARRAY_SIZE(buffer));
+ H264SpsParser parser = H264SpsParser(buffer, arraysize(buffer));
EXPECT_TRUE(parser.Parse());
EXPECT_EQ(320u, parser.width());
EXPECT_EQ(180u, parser.height());
@@ -163,7 +164,7 @@ TEST(H264SpsParserTest, TestSyntheticSPSQvgaLandscape) {
TEST(H264SpsParserTest, TestSyntheticSPSWeirdResolution) {
uint8_t buffer[kSpsBufferMaxSize] = {0};
GenerateFakeSps(156u, 122u, buffer);
- H264SpsParser parser = H264SpsParser(buffer, ARRAY_SIZE(buffer));
+ H264SpsParser parser = H264SpsParser(buffer, arraysize(buffer));
EXPECT_TRUE(parser.Parse());
EXPECT_EQ(156u, parser.width());
EXPECT_EQ(122u, parser.height());
diff --git a/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h b/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h
index f577cbaad1..011829cc6c 100644
--- a/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h
+++ b/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h
@@ -8,11 +8,11 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_PAYLOAD_REGISTRY_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_PAYLOAD_REGISTRY_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_PAYLOAD_STRATEGY_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_PAYLOAD_STRATEGY_H_
#include "testing/gmock/include/gmock/gmock.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
namespace webrtc {
@@ -23,7 +23,7 @@ class MockRTPPayloadStrategy : public RTPPayloadStrategy {
MOCK_CONST_METHOD4(PayloadIsCompatible,
bool(const RtpUtility::Payload& payload,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate));
MOCK_CONST_METHOD2(UpdatePayloadRate,
void(RtpUtility::Payload* payload, const uint32_t rate));
@@ -34,10 +34,10 @@ class MockRTPPayloadStrategy : public RTPPayloadStrategy {
RtpUtility::Payload*(const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int8_t payloadType,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate));
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_PAYLOAD_REGISTRY_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_PAYLOAD_STRATEGY_H_
diff --git a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
index 07a3693507..e19c31bfec 100644
--- a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc
@@ -16,15 +16,15 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.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/include/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/transport.h"
-using namespace webrtc;
+namespace webrtc {
const int kVideoNackListSize = 30;
const uint32_t kTestSsrc = 3456;
@@ -35,8 +35,7 @@ const int kNumFrames = 30;
const int kPayloadType = 123;
const int kRtxPayloadType = 98;
-class VerifyingRtxReceiver : public NullRtpData
-{
+class VerifyingRtxReceiver : public NullRtpData {
public:
VerifyingRtxReceiver() {}
@@ -54,7 +53,7 @@ class VerifyingRtxReceiver : public NullRtpData
class TestRtpFeedback : public NullRtpFeedback {
public:
- TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
+ explicit TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
virtual ~TestRtpFeedback() {}
void OnIncomingSSRCChanged(const uint32_t ssrc) override {
@@ -86,9 +85,7 @@ class RtxLoopBackTransport : public webrtc::Transport {
rtp_receiver_ = receiver;
}
- void DropEveryNthPacket(int n) {
- packet_loss_ = n;
- }
+ void DropEveryNthPacket(int n) { packet_loss_ = n; }
void DropConsecutivePackets(int start, int total) {
consecutive_drop_start_ = start;
@@ -100,15 +97,13 @@ class RtxLoopBackTransport : public webrtc::Transport {
size_t len,
const PacketOptions& options) override {
count_++;
- const unsigned char* ptr = static_cast<const unsigned char*>(data);
+ const unsigned char* ptr = static_cast<const unsigned char*>(data);
uint32_t ssrc = (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11];
- if (ssrc == rtx_ssrc_) count_rtx_ssrc_++;
+ if (ssrc == rtx_ssrc_)
+ count_rtx_ssrc_++;
uint16_t sequence_number = (ptr[2] << 8) + ptr[3];
size_t packet_length = len;
- // TODO(pbos): Figure out why this needs to be initialized. Likely this
- // is hiding a bug either in test setup or other code.
- // https://code.google.com/p/webrtc/issues/detail?id=3183
- uint8_t restored_packet[1500] = {0};
+ uint8_t restored_packet[1500];
RTPHeader header;
rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
if (!parser->Parse(ptr, len, &header)) {
@@ -136,21 +131,19 @@ class RtxLoopBackTransport : public webrtc::Transport {
if (!parser->Parse(restored_packet, packet_length, &header)) {
return false;
}
+ ptr = restored_packet;
} else {
rtp_payload_registry_->SetIncomingPayloadType(header);
}
- const uint8_t* restored_packet_payload =
- restored_packet + header.headerLength;
- packet_length -= header.headerLength;
PayloadUnion payload_specific;
if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
&payload_specific)) {
return false;
}
- if (!rtp_receiver_->IncomingRtpPacket(header, restored_packet_payload,
- packet_length, payload_specific,
- true)) {
+ if (!rtp_receiver_->IncomingRtpPacket(header, ptr + header.headerLength,
+ packet_length - header.headerLength,
+ payload_specific, true)) {
return false;
}
return true;
@@ -194,8 +187,7 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_));
rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
- &fake_clock, &receiver_, rtp_feedback_.get(),
- &rtp_payload_registry_));
+ &fake_clock, &receiver_, rtp_feedback_.get(), &rtp_payload_registry_));
rtp_rtcp_module_->SetSSRC(kTestSsrc);
rtp_rtcp_module_->SetRTCPStatus(RtcpMode::kCompound);
@@ -215,11 +207,9 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
EXPECT_EQ(0, rtp_rtcp_module_->RegisterSendPayload(video_codec));
rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType);
- EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName,
- video_codec.plType,
- 90000,
- 0,
- video_codec.maxBitrate));
+ EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(
+ video_codec.plName, video_codec.plType, 90000, 0,
+ video_codec.maxBitrate));
rtp_payload_registry_.SetRtxPayloadType(kRtxPayloadType, kPayloadType);
for (size_t n = 0; n < payload_data_length; n++) {
@@ -230,8 +220,7 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
int BuildNackList(uint16_t* nack_list) {
receiver_.sequence_numbers_.sort();
std::list<uint16_t> missing_sequence_numbers;
- std::list<uint16_t>::iterator it =
- receiver_.sequence_numbers_.begin();
+ std::list<uint16_t>::iterator it = receiver_.sequence_numbers_.begin();
while (it != receiver_.sequence_numbers_.end()) {
uint16_t sequence_number_1 = *it;
@@ -239,15 +228,14 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
if (it != receiver_.sequence_numbers_.end()) {
uint16_t sequence_number_2 = *it;
// Add all missing sequence numbers to list
- for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2;
- ++i) {
+ for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2; ++i) {
missing_sequence_numbers.push_back(i);
}
}
}
int n = 0;
for (it = missing_sequence_numbers.begin();
- it != missing_sequence_numbers.end(); ++it) {
+ it != missing_sequence_numbers.end(); ++it) {
nack_list[n++] = (*it);
}
return n;
@@ -298,7 +286,7 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
rtc::scoped_ptr<TestRtpFeedback> rtp_feedback_;
RtxLoopBackTransport transport_;
VerifyingRtxReceiver receiver_;
- uint8_t payload_data[65000];
+ uint8_t payload_data[65000];
size_t payload_data_length;
SimulatedClock fake_clock;
};
@@ -345,8 +333,10 @@ TEST_F(RtpRtcpRtxNackTest, RtxNack) {
RunRtxTest(kRtxRetransmitted, 10);
EXPECT_EQ(kTestSequenceNumber, *(receiver_.sequence_numbers_.begin()));
EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1,
- *(receiver_.sequence_numbers_.rbegin()));
+ *(receiver_.sequence_numbers_.rbegin()));
EXPECT_EQ(kTestNumberOfPackets, receiver_.sequence_numbers_.size());
EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_);
EXPECT_TRUE(ExpectedPacketsReceived());
}
+
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc b/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc
index 683b951f1e..be4b453454 100644
--- a/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc
@@ -9,8 +9,10 @@
*/
#include <list>
+#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/modules/rtp_rtcp/source/producer_fec.h"
@@ -54,6 +56,53 @@ class ProducerFecTest : public ::testing::Test {
FrameGenerator* generator_;
};
+// Verifies bug found via fuzzing, where a gap in the packet sequence caused us
+// to move past the end of the current FEC packet mask byte without moving to
+// the next byte. That likely caused us to repeatedly read from the same byte,
+// and if that byte didn't protect packets we would generate empty FEC.
+TEST_F(ProducerFecTest, NoEmptyFecWithSeqNumGaps) {
+ struct Packet {
+ size_t header_size;
+ size_t payload_size;
+ uint16_t seq_num;
+ bool marker_bit;
+ };
+ std::vector<Packet> protected_packets;
+ protected_packets.push_back({15, 3, 41, 0});
+ protected_packets.push_back({14, 1, 43, 0});
+ protected_packets.push_back({19, 0, 48, 0});
+ protected_packets.push_back({19, 0, 50, 0});
+ protected_packets.push_back({14, 3, 51, 0});
+ protected_packets.push_back({13, 8, 52, 0});
+ protected_packets.push_back({19, 2, 53, 0});
+ protected_packets.push_back({12, 3, 54, 0});
+ protected_packets.push_back({21, 0, 55, 0});
+ protected_packets.push_back({13, 3, 57, 1});
+ FecProtectionParams params = {117, 0, 3, kFecMaskBursty};
+ producer_->SetFecParameters(&params, 0);
+ uint8_t packet[28] = {0};
+ for (Packet p : protected_packets) {
+ if (p.marker_bit) {
+ packet[1] |= 0x80;
+ } else {
+ packet[1] &= ~0x80;
+ }
+ ByteWriter<uint16_t>::WriteBigEndian(&packet[2], p.seq_num);
+ producer_->AddRtpPacketAndGenerateFec(packet, p.payload_size,
+ p.header_size);
+ uint16_t num_fec_packets = producer_->NumAvailableFecPackets();
+ std::vector<RedPacket*> fec_packets;
+ if (num_fec_packets > 0) {
+ fec_packets =
+ producer_->GetFecPackets(kRedPayloadType, 99, 100, p.header_size);
+ EXPECT_EQ(num_fec_packets, fec_packets.size());
+ }
+ for (RedPacket* fec_packet : fec_packets) {
+ delete fec_packet;
+ }
+ }
+}
+
TEST_F(ProducerFecTest, OneFrameFec) {
// The number of media packets (|kNumPackets|), number of frames (one for
// this test), and the protection factor (|params->fec_rate|) are set to make
diff --git a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc
index 8ac7e0a383..24f1e2c96e 100644
--- a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -14,7 +14,7 @@
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/modules/rtp_rtcp/source/time_util.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
namespace webrtc {
@@ -37,8 +37,6 @@ StreamStatisticianImpl::StreamStatisticianImpl(
cumulative_loss_(0),
jitter_q4_transmission_time_offset_(0),
last_receive_time_ms_(0),
- last_receive_time_secs_(0),
- last_receive_time_frac_(0),
last_received_timestamp_(0),
last_received_transmission_time_offset_(0),
received_seq_first_(0),
@@ -79,9 +77,7 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
// are received, 4 will be ignored.
if (in_order) {
// Current time in samples.
- uint32_t receive_time_secs;
- uint32_t receive_time_frac;
- clock_->CurrentNtp(receive_time_secs, receive_time_frac);
+ NtpTime receive_time(*clock_);
// Wrong if we use RetransmitOfOldPacket.
if (receive_counters_.transmitted.packets > 1 &&
@@ -97,11 +93,10 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
if (header.timestamp != last_received_timestamp_ &&
(receive_counters_.transmitted.packets -
receive_counters_.retransmitted.packets) > 1) {
- UpdateJitter(header, receive_time_secs, receive_time_frac);
+ UpdateJitter(header, receive_time);
}
last_received_timestamp_ = header.timestamp;
- last_receive_time_secs_ = receive_time_secs;
- last_receive_time_frac_ = receive_time_frac;
+ last_receive_time_ntp_ = receive_time;
last_receive_time_ms_ = clock_->TimeInMilliseconds();
}
@@ -113,14 +108,11 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
}
void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
- uint32_t receive_time_secs,
- uint32_t receive_time_frac) {
- uint32_t receive_time_rtp = RtpUtility::ConvertNTPTimeToRTP(
- receive_time_secs, receive_time_frac, header.payload_type_frequency);
+ NtpTime receive_time) {
+ uint32_t receive_time_rtp =
+ NtpToRtp(receive_time, header.payload_type_frequency);
uint32_t last_receive_time_rtp =
- RtpUtility::ConvertNTPTimeToRTP(last_receive_time_secs_,
- last_receive_time_frac_,
- header.payload_type_frequency);
+ NtpToRtp(last_receive_time_ntp_, header.payload_type_frequency);
int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) -
(header.timestamp - last_received_timestamp_);
@@ -267,6 +259,7 @@ RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
stats.fraction_lost = local_fraction_lost;
// We need a counter for cumulative loss too.
+ // TODO(danilchap): Ensure cumulative loss is below maximum value of 2^24.
cumulative_loss_ += missing;
stats.cumulative_lost = cumulative_loss_;
stats.extended_max_sequence_number =
@@ -319,8 +312,8 @@ void StreamStatisticianImpl::ProcessBitrate() {
void StreamStatisticianImpl::LastReceiveTimeNtp(uint32_t* secs,
uint32_t* frac) const {
CriticalSectionScoped cs(stream_lock_.get());
- *secs = last_receive_time_secs_;
- *frac = last_receive_time_frac_;
+ *secs = last_receive_time_ntp_.seconds();
+ *frac = last_receive_time_ntp_.fractions();
}
bool StreamStatisticianImpl::IsRetransmitOfOldPacket(
diff --git a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h
index fe42990fe9..025dcd42c7 100644
--- a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h
+++ b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h
@@ -11,13 +11,15 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
#include <algorithm>
+#include <map>
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/include/ntp_time.h"
namespace webrtc {
@@ -51,9 +53,7 @@ class StreamStatisticianImpl : public StreamStatistician {
private:
bool InOrderPacketInternal(uint16_t sequence_number) const;
RtcpStatistics CalculateRtcpStatistics();
- void UpdateJitter(const RTPHeader& header,
- uint32_t receive_time_secs,
- uint32_t receive_time_frac);
+ void UpdateJitter(const RTPHeader& header, NtpTime receive_time);
void UpdateCounters(const RTPHeader& rtp_header,
size_t packet_length,
bool retransmitted);
@@ -72,8 +72,7 @@ class StreamStatisticianImpl : public StreamStatistician {
uint32_t jitter_q4_transmission_time_offset_;
int64_t last_receive_time_ms_;
- uint32_t last_receive_time_secs_;
- uint32_t last_receive_time_frac_;
+ NtpTime last_receive_time_ntp_;
uint32_t last_received_timestamp_;
int32_t last_received_transmission_time_offset_;
uint16_t received_seq_first_;
diff --git a/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc
index 5b522281df..c265c17c04 100644
--- a/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc
@@ -11,7 +11,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
#include "webrtc/system_wrappers/include/clock.h"
namespace webrtc {
diff --git a/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc b/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
index 74fc9cdc56..ccc15ec417 100644
--- a/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
+++ b/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h"
+#include "webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
#include "webrtc/base/logging.h"
#include "webrtc/system_wrappers/include/clock.h"
diff --git a/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc b/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc
index bc9cf2ee39..797c7883a9 100644
--- a/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc
@@ -11,7 +11,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h"
+#include "webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
#include "webrtc/system_wrappers/include/clock.h"
using ::testing::_;
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
index 7a7645fd1b..87c0259b3e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
@@ -21,16 +21,13 @@
#include "webrtc/test/null_transport.h"
#include "webrtc/typedefs.h"
+namespace webrtc {
namespace {
-using namespace webrtc;
-
-
class TestTransport : public Transport {
public:
- TestTransport(RTCPReceiver* rtcp_receiver) :
- rtcp_receiver_(rtcp_receiver) {
- }
+ explicit TestTransport(RTCPReceiver* rtcp_receiver)
+ : rtcp_receiver_(rtcp_receiver) {}
bool SendRtp(const uint8_t* /*data*/,
size_t /*len*/,
@@ -38,9 +35,8 @@ class TestTransport : public Transport {
return false;
}
bool SendRtcp(const uint8_t* packet, size_t packetLength) override {
- RTCPUtility::RTCPParserV2 rtcpParser((uint8_t*)packet,
- packetLength,
- true); // Allow non-compound RTCP
+ RTCPUtility::RTCPParserV2 rtcpParser(packet, packetLength,
+ true); // Allow non-compound RTCP
EXPECT_TRUE(rtcpParser.IsValid());
RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
@@ -53,11 +49,11 @@ class TestTransport : public Transport {
rtcpPacketInformation.receiverEstimatedMaxBitrate);
return true;
}
+
private:
RTCPReceiver* rtcp_receiver_;
};
-
class RtcpFormatRembTest : public ::testing::Test {
protected:
RtcpFormatRembTest()
@@ -134,3 +130,4 @@ TEST_F(RtcpFormatRembTest, TestCompund) {
EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRemb));
}
} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
index 792caa7b8b..eef2978371 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
@@ -10,6 +10,8 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include <algorithm>
+
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
@@ -19,38 +21,25 @@ using webrtc::RTCPUtility::kBtReceiverReferenceTime;
using webrtc::RTCPUtility::kBtVoipMetric;
using webrtc::RTCPUtility::PT_APP;
-using webrtc::RTCPUtility::PT_BYE;
using webrtc::RTCPUtility::PT_IJ;
using webrtc::RTCPUtility::PT_PSFB;
-using webrtc::RTCPUtility::PT_RR;
using webrtc::RTCPUtility::PT_RTPFB;
using webrtc::RTCPUtility::PT_SDES;
using webrtc::RTCPUtility::PT_SR;
using webrtc::RTCPUtility::PT_XR;
using webrtc::RTCPUtility::RTCPPacketAPP;
-using webrtc::RTCPUtility::RTCPPacketBYE;
using webrtc::RTCPUtility::RTCPPacketPSFBAPP;
using webrtc::RTCPUtility::RTCPPacketPSFBFIR;
using webrtc::RTCPUtility::RTCPPacketPSFBFIRItem;
-using webrtc::RTCPUtility::RTCPPacketPSFBPLI;
using webrtc::RTCPUtility::RTCPPacketPSFBREMBItem;
using webrtc::RTCPUtility::RTCPPacketPSFBRPSI;
-using webrtc::RTCPUtility::RTCPPacketPSFBSLI;
-using webrtc::RTCPUtility::RTCPPacketPSFBSLIItem;
using webrtc::RTCPUtility::RTCPPacketReportBlockItem;
-using webrtc::RTCPUtility::RTCPPacketRR;
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;
using webrtc::RTCPUtility::RTCPPacketXRDLRRReportBlockItem;
-using webrtc::RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem;
using webrtc::RTCPUtility::RTCPPacketXR;
-using webrtc::RTCPUtility::RTCPPacketXRVOIPMetricItem;
namespace webrtc {
namespace rtcp {
@@ -122,21 +111,6 @@ void CreateSenderReport(const RTCPPacketSR& sr,
AssignUWord32(buffer, pos, sr.SenderOctetCount);
}
-// Receiver report (RR), header (RFC 3550).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| RC | PT=RR=201 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of packet sender |
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-
-void CreateReceiverReport(const RTCPPacketRR& rr,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, rr.SenderSSRC);
-}
-
// Report block (RFC 3550).
//
// 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
@@ -154,43 +128,15 @@ void CreateReceiverReport(const RTCPPacketRR& rr,
// | delay since last SR (DLSR) |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-void CreateReportBlocks(const std::vector<RTCPPacketReportBlockItem>& blocks,
+void CreateReportBlocks(const std::vector<ReportBlock>& blocks,
uint8_t* buffer,
size_t* pos) {
- for (std::vector<RTCPPacketReportBlockItem>::const_iterator
- it = blocks.begin(); it != blocks.end(); ++it) {
- AssignUWord32(buffer, pos, (*it).SSRC);
- AssignUWord8(buffer, pos, (*it).FractionLost);
- AssignUWord24(buffer, pos, (*it).CumulativeNumOfPacketsLost);
- AssignUWord32(buffer, pos, (*it).ExtendedHighestSequenceNumber);
- AssignUWord32(buffer, pos, (*it).Jitter);
- AssignUWord32(buffer, pos, (*it).LastSR);
- AssignUWord32(buffer, pos, (*it).DelayLastSR);
+ for (const ReportBlock& block : blocks) {
+ block.Create(buffer + *pos);
+ *pos += ReportBlock::kLength;
}
}
-// Transmission Time Offsets in RTP Streams (RFC 5450).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// hdr |V=2|P| RC | PT=IJ=195 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | inter-arrival jitter |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// . .
-// . .
-// . .
-// | inter-arrival jitter |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateIj(const std::vector<uint32_t>& ij_items,
- uint8_t* buffer,
- size_t* pos) {
- for (uint32_t item : ij_items)
- AssignUWord32(buffer, pos, item);
-}
-
// Source Description (SDES) (RFC 3550).
//
// 0 1 2 3
@@ -233,129 +179,6 @@ void CreateSdes(const std::vector<Sdes::Chunk>& chunks,
}
}
-// Bye packet (BYE) (RFC 3550).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| SC | PT=BYE=203 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC/CSRC |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// : ... :
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-// (opt) | length | reason for leaving ...
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateBye(const RTCPPacketBYE& bye,
- const std::vector<uint32_t>& csrcs,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, bye.SenderSSRC);
- for (uint32_t csrc : csrcs)
- AssignUWord32(buffer, pos, csrc);
-}
-
-// Application-Defined packet (APP) (RFC 3550).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| subtype | PT=APP=204 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC/CSRC |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | name (ASCII) |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | application-dependent data ...
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateApp(const RTCPPacketAPP& app,
- uint32_t ssrc,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, ssrc);
- AssignUWord32(buffer, pos, app.Name);
- memcpy(buffer + *pos, app.Data, app.Size);
- *pos += app.Size;
-}
-
-// RFC 4585: Feedback format.
-//
-// Common packet format:
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| FMT | PT | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of packet sender |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of media source |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// : Feedback Control Information (FCI) :
-// :
-//
-
-// Picture loss indication (PLI) (RFC 4585).
-//
-// FCI: no feedback control information.
-
-void CreatePli(const RTCPPacketPSFBPLI& pli,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, pli.SenderSSRC);
- AssignUWord32(buffer, pos, pli.MediaSSRC);
-}
-
-// Slice loss indication (SLI) (RFC 4585).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | First | Number | PictureID |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateSli(const RTCPPacketPSFBSLI& sli,
- const RTCPPacketPSFBSLIItem& sli_item,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, sli.SenderSSRC);
- AssignUWord32(buffer, pos, sli.MediaSSRC);
-
- AssignUWord8(buffer, pos, sli_item.FirstMB >> 5);
- AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) +
- ((sli_item.NumberOfMB >> 10) & 0x07));
- AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2);
- AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId);
-}
-
-// Generic NACK (RFC 4585).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | PID | BLP |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateNack(const RTCPPacketRTPFBNACK& nack,
- const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields,
- size_t start_index,
- size_t end_index,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, nack.SenderSSRC);
- AssignUWord32(buffer, pos, nack.MediaSSRC);
- for (size_t i = start_index; i < end_index; ++i) {
- const RTCPPacketRTPFBNACKItem& nack_item = nack_fields[i];
- AssignUWord16(buffer, pos, nack_item.PacketID);
- AssignUWord16(buffer, pos, nack_item.BitMask);
- }
-}
-
// Reference picture selection indication (RPSI) (RFC 4585).
//
// FCI:
@@ -407,66 +230,6 @@ void CreateFir(const RTCPPacketPSFBFIR& fir,
AssignUWord24(buffer, pos, 0);
}
-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 Request (TMMBR) (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 CreateTmmbr(const RTCPPacketRTPFBTMMBR& tmmbr,
- const RTCPPacketRTPFBTMMBRItem& tmmbr_item,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, tmmbr.SenderSSRC);
- AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0);
- 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
@@ -529,130 +292,6 @@ void CreateXrHeader(const RTCPPacketXR& header,
AssignUWord32(buffer, pos, header.OriginatorSSRC);
}
-void CreateXrBlockHeader(uint8_t block_type,
- uint16_t block_length,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord8(buffer, pos, block_type);
- AssignUWord8(buffer, pos, 0);
- AssignUWord16(buffer, pos, block_length);
-}
-
-// Receiver Reference Time Report Block (RFC 3611).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | BT=4 | reserved | block length = 2 |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | NTP timestamp, most significant word |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | NTP timestamp, least significant word |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateRrtr(const std::vector<RTCPPacketXRReceiverReferenceTimeItem>& rrtrs,
- uint8_t* buffer,
- size_t* pos) {
- const uint16_t kBlockLength = 2;
- for (std::vector<RTCPPacketXRReceiverReferenceTimeItem>::const_iterator it =
- rrtrs.begin(); it != rrtrs.end(); ++it) {
- CreateXrBlockHeader(kBtReceiverReferenceTime, kBlockLength, buffer, pos);
- AssignUWord32(buffer, pos, (*it).NTPMostSignificant);
- AssignUWord32(buffer, pos, (*it).NTPLeastSignificant);
- }
-}
-
-// DLRR Report Block (RFC 3611).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | BT=5 | reserved | block length |
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-// | SSRC_1 (SSRC of first receiver) | sub-
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
-// | last RR (LRR) | 1
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | delay since last RR (DLRR) |
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-// | SSRC_2 (SSRC of second receiver) | sub-
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
-// : ... : 2
-
-void CreateDlrr(const std::vector<Xr::DlrrBlock>& dlrrs,
- uint8_t* buffer,
- size_t* pos) {
- for (std::vector<Xr::DlrrBlock>::const_iterator it = dlrrs.begin();
- it != dlrrs.end(); ++it) {
- if ((*it).empty()) {
- continue;
- }
- uint16_t block_length = 3 * (*it).size();
- CreateXrBlockHeader(kBtDlrr, block_length, buffer, pos);
- for (Xr::DlrrBlock::const_iterator it_block = (*it).begin();
- it_block != (*it).end(); ++it_block) {
- AssignUWord32(buffer, pos, (*it_block).SSRC);
- AssignUWord32(buffer, pos, (*it_block).LastRR);
- AssignUWord32(buffer, pos, (*it_block).DelayLastRR);
- }
- }
-}
-
-// VoIP Metrics Report Block (RFC 3611).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | BT=7 | reserved | block length = 8 |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of source |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | loss rate | discard rate | burst density | gap density |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | burst duration | gap duration |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | round trip delay | end system delay |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | signal level | noise level | RERL | Gmin |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | R factor | ext. R factor | MOS-LQ | MOS-CQ |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | RX config | reserved | JB nominal |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | JB maximum | JB abs max |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-void CreateVoipMetric(const std::vector<RTCPPacketXRVOIPMetricItem>& metrics,
- uint8_t* buffer,
- size_t* pos) {
- const uint16_t kBlockLength = 8;
- for (std::vector<RTCPPacketXRVOIPMetricItem>::const_iterator it =
- metrics.begin(); it != metrics.end(); ++it) {
- CreateXrBlockHeader(kBtVoipMetric, kBlockLength, buffer, pos);
- AssignUWord32(buffer, pos, (*it).SSRC);
- AssignUWord8(buffer, pos, (*it).lossRate);
- AssignUWord8(buffer, pos, (*it).discardRate);
- AssignUWord8(buffer, pos, (*it).burstDensity);
- AssignUWord8(buffer, pos, (*it).gapDensity);
- AssignUWord16(buffer, pos, (*it).burstDuration);
- AssignUWord16(buffer, pos, (*it).gapDuration);
- AssignUWord16(buffer, pos, (*it).roundTripDelay);
- AssignUWord16(buffer, pos, (*it).endSystemDelay);
- AssignUWord8(buffer, pos, (*it).signalLevel);
- AssignUWord8(buffer, pos, (*it).noiseLevel);
- AssignUWord8(buffer, pos, (*it).RERL);
- AssignUWord8(buffer, pos, (*it).Gmin);
- AssignUWord8(buffer, pos, (*it).Rfactor);
- AssignUWord8(buffer, pos, (*it).extRfactor);
- AssignUWord8(buffer, pos, (*it).MOSLQ);
- AssignUWord8(buffer, pos, (*it).MOSCQ);
- AssignUWord8(buffer, pos, (*it).RXconfig);
- AssignUWord8(buffer, pos, 0);
- AssignUWord16(buffer, pos, (*it).JBnominal);
- AssignUWord16(buffer, pos, (*it).JBmax);
- AssignUWord16(buffer, pos, (*it).JBabsMax);
- }
-}
} // namespace
void RtcpPacket::Append(RtcpPacket* packet) {
@@ -751,17 +390,6 @@ void RtcpPacket::CreateHeader(
AssignUWord16(buffer, pos, length);
}
-bool Empty::Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const {
- return true;
-}
-
-size_t Empty::BlockLength() const {
- return 0;
-}
-
bool SenderReport::Create(uint8_t* packet,
size_t* index,
size_t max_length,
@@ -781,58 +409,11 @@ bool SenderReport::WithReportBlock(const ReportBlock& block) {
LOG(LS_WARNING) << "Max report blocks reached.";
return false;
}
- report_blocks_.push_back(block.report_block_);
+ report_blocks_.push_back(block);
sr_.NumberOfReportBlocks = report_blocks_.size();
return true;
}
-bool ReceiverReport::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;
- }
- CreateHeader(rr_.NumberOfReportBlocks, PT_RR, HeaderLength(), packet, index);
- CreateReceiverReport(rr_, packet, index);
- CreateReportBlocks(report_blocks_, packet, index);
- return true;
-}
-
-bool ReceiverReport::WithReportBlock(const ReportBlock& block) {
- if (report_blocks_.size() >= kMaxNumberOfReportBlocks) {
- LOG(LS_WARNING) << "Max report blocks reached.";
- return false;
- }
- report_blocks_.push_back(block.report_block_);
- rr_.NumberOfReportBlocks = report_blocks_.size();
- return true;
-}
-
-bool Ij::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;
- }
- size_t length = ij_items_.size();
- CreateHeader(length, PT_IJ, length, packet, index);
- CreateIj(ij_items_, packet, index);
- return true;
-}
-
-bool Ij::WithJitterItem(uint32_t jitter) {
- if (ij_items_.size() >= kMaxNumberOfIjItems) {
- LOG(LS_WARNING) << "Max inter-arrival jitter items reached.";
- return false;
- }
- ij_items_.push_back(jitter);
- return true;
-}
-
bool Sdes::Create(uint8_t* packet,
size_t* index,
size_t max_length,
@@ -876,129 +457,6 @@ size_t Sdes::BlockLength() const {
return length;
}
-bool Bye::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;
- }
- size_t length = HeaderLength();
- CreateHeader(length, PT_BYE, length, packet, index);
- CreateBye(bye_, csrcs_, packet, index);
- return true;
-}
-
-bool Bye::WithCsrc(uint32_t csrc) {
- if (csrcs_.size() >= kMaxNumberOfCsrcs) {
- LOG(LS_WARNING) << "Max CSRC size reached.";
- return false;
- }
- csrcs_.push_back(csrc);
- return true;
-}
-
-bool App::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;
- }
- CreateHeader(app_.SubType, PT_APP, HeaderLength(), packet, index);
- CreateApp(app_, ssrc_, packet, index);
- return true;
-}
-
-bool Pli::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 = 1;
- CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index);
- CreatePli(pli_, packet, index);
- return true;
-}
-
-bool Sli::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 = 2;
- CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index);
- CreateSli(sli_, sli_item_, packet, index);
- return true;
-}
-
-bool Nack::Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const {
- assert(!nack_fields_.empty());
- // If nack list can't fit in packet, try to fragment.
- size_t nack_index = 0;
- do {
- size_t bytes_left_in_buffer = max_length - *index;
- if (bytes_left_in_buffer < kCommonFbFmtLength + 4) {
- if (!OnBufferFull(packet, index, callback))
- return false;
- continue;
- }
- int64_t num_nack_fields =
- std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4,
- nack_fields_.size() - nack_index);
-
- const uint8_t kFmt = 1;
- size_t size_bytes = (num_nack_fields * 4) + kCommonFbFmtLength;
- size_t header_length = ((size_bytes + 3) / 4) - 1; // As 32bit words - 1
- CreateHeader(kFmt, PT_RTPFB, header_length, packet, index);
- CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields,
- packet, index);
-
- nack_index += num_nack_fields;
- } while (nack_index < nack_fields_.size());
-
- return true;
-}
-
-size_t Nack::BlockLength() const {
- return (nack_fields_.size() * 4) + kCommonFbFmtLength;
-}
-
-void Nack::WithList(const uint16_t* nack_list, int length) {
- assert(nack_list);
- assert(nack_fields_.empty());
- int i = 0;
- while (i < length) {
- uint16_t pid = nack_list[i++];
- // Bitmask specifies losses in any of the 16 packets following the pid.
- uint16_t bitmask = 0;
- while (i < length) {
- int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1;
- if (shift >= 0 && shift <= 15) {
- bitmask |= (1 << shift);
- ++i;
- } else {
- break;
- }
- }
- RTCPUtility::RTCPPacketRTPFBNACKItem item;
- item.PacketID = pid;
- item.BitMask = bitmask;
- nack_fields_.push_back(item);
- }
-}
-
bool Rpsi::Create(uint8_t* packet,
size_t* index,
size_t max_length,
@@ -1077,48 +535,6 @@ void Remb::AppliesTo(uint32_t ssrc) {
remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc;
}
-bool Tmmbr::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 = 3;
- CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index);
- CreateTmmbr(tmmbr_, tmmbr_item_, packet, index);
- 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,
@@ -1129,29 +545,38 @@ bool Xr::Create(uint8_t* packet,
}
CreateHeader(0U, PT_XR, HeaderLength(), packet, index);
CreateXrHeader(xr_header_, packet, index);
- CreateRrtr(rrtr_blocks_, packet, index);
- CreateDlrr(dlrr_blocks_, packet, index);
- CreateVoipMetric(voip_metric_blocks_, packet, index);
+ for (const Rrtr& block : rrtr_blocks_) {
+ block.Create(packet + *index);
+ *index += Rrtr::kLength;
+ }
+ for (const Dlrr& block : dlrr_blocks_) {
+ block.Create(packet + *index);
+ *index += block.BlockLength();
+ }
+ for (const VoipMetric& block : voip_metric_blocks_) {
+ block.Create(packet + *index);
+ *index += VoipMetric::kLength;
+ }
return true;
}
bool Xr::WithRrtr(Rrtr* rrtr) {
- assert(rrtr);
+ RTC_DCHECK(rrtr);
if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) {
LOG(LS_WARNING) << "Max RRTR blocks reached.";
return false;
}
- rrtr_blocks_.push_back(rrtr->rrtr_block_);
+ rrtr_blocks_.push_back(*rrtr);
return true;
}
bool Xr::WithDlrr(Dlrr* dlrr) {
- assert(dlrr);
+ RTC_DCHECK(dlrr);
if (dlrr_blocks_.size() >= kMaxNumberOfDlrrBlocks) {
LOG(LS_WARNING) << "Max DLRR blocks reached.";
return false;
}
- dlrr_blocks_.push_back(dlrr->dlrr_block_);
+ dlrr_blocks_.push_back(*dlrr);
return true;
}
@@ -1161,38 +586,18 @@ bool Xr::WithVoipMetric(VoipMetric* voip_metric) {
LOG(LS_WARNING) << "Max Voip Metric blocks reached.";
return false;
}
- voip_metric_blocks_.push_back(voip_metric->metric_);
+ voip_metric_blocks_.push_back(*voip_metric);
return true;
}
size_t Xr::DlrrLength() const {
- const size_t kBlockHeaderLen = 4;
- const size_t kSubBlockLen = 12;
size_t length = 0;
- for (std::vector<DlrrBlock>::const_iterator it = dlrr_blocks_.begin();
- it != dlrr_blocks_.end(); ++it) {
- if (!(*it).empty()) {
- length += kBlockHeaderLen + kSubBlockLen * (*it).size();
- }
+ for (const Dlrr& block : dlrr_blocks_) {
+ length += block.BlockLength();
}
return length;
}
-bool Dlrr::WithDlrrItem(uint32_t ssrc,
- uint32_t last_rr,
- uint32_t delay_last_rr) {
- if (dlrr_block_.size() >= kMaxNumberOfDlrrItems) {
- LOG(LS_WARNING) << "Max DLRR items reached.";
- return false;
- }
- RTCPPacketXRDLRRReportBlockItem dlrr;
- dlrr.SSRC = ssrc;
- dlrr.LastRR = last_rr;
- dlrr.DelayLastRR = delay_last_rr;
- dlrr_block_.push_back(dlrr);
- return true;
-}
-
RawPacket::RawPacket(size_t buffer_length)
: buffer_length_(buffer_length), length_(0) {
buffer_.reset(new uint8_t[buffer_length]);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
index 3c34957c36..01c97c38ba 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
@@ -9,16 +9,20 @@
*
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
-#define WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
#include <map>
#include <string>
#include <vector>
#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -27,10 +31,7 @@ namespace rtcp {
static const int kCommonFbFmtLength = 12;
static const int kReportBlockLength = 24;
-class Dlrr;
class RawPacket;
-class Rrtr;
-class VoipMetric;
// Class for building RTCP packets.
//
@@ -115,93 +116,17 @@ class RtcpPacket {
size_t HeaderLength() const;
static const size_t kHeaderLength = 4;
+ std::vector<RtcpPacket*> appended_packets_;
private:
bool CreateAndAddAppended(uint8_t* packet,
size_t* index,
size_t max_length,
PacketReadyCallback* callback) const;
-
- std::vector<RtcpPacket*> appended_packets_;
};
// TODO(sprang): Move RtcpPacket subclasses out to separate files.
-class Empty : public RtcpPacket {
- public:
- Empty() : RtcpPacket() {}
-
- virtual ~Empty() {}
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- size_t BlockLength() const override;
-
- private:
- RTC_DISALLOW_COPY_AND_ASSIGN(Empty);
-};
-
-// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
-//
-// RTCP report block (RFC 3550).
-//
-// 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_1 (SSRC of first source) |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | fraction lost | cumulative number of packets lost |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | extended highest sequence number received |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | interarrival jitter |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | last SR (LSR) |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | delay since last SR (DLSR) |
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-
-class ReportBlock {
- public:
- ReportBlock() {
- // TODO(asapersson): Consider adding a constructor to struct.
- memset(&report_block_, 0, sizeof(report_block_));
- }
-
- ~ReportBlock() {}
-
- void To(uint32_t ssrc) {
- report_block_.SSRC = ssrc;
- }
- void WithFractionLost(uint8_t fraction_lost) {
- report_block_.FractionLost = fraction_lost;
- }
- void WithCumulativeLost(uint32_t cumulative_lost) {
- report_block_.CumulativeNumOfPacketsLost = cumulative_lost;
- }
- void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
- report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
- }
- void WithJitter(uint32_t jitter) {
- report_block_.Jitter = jitter;
- }
- void WithLastSr(uint32_t last_sr) {
- report_block_.LastSR = last_sr;
- }
- void WithDelayLastSr(uint32_t delay_last_sr) {
- report_block_.DelayLastSR = delay_last_sr;
- }
-
- private:
- friend class SenderReport;
- friend class ReceiverReport;
- RTCPUtility::RTCPPacketReportBlockItem report_block_;
-};
-
// RTCP sender report (RFC 3550).
//
// 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
@@ -268,102 +193,11 @@ class SenderReport : public RtcpPacket {
}
RTCPUtility::RTCPPacketSR sr_;
- std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
+ std::vector<ReportBlock> report_blocks_;
RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
};
-//
-// RTCP receiver report (RFC 3550).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| RC | PT=RR=201 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of packet sender |
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-// | report block(s) |
-// | .... |
-
-class ReceiverReport : public RtcpPacket {
- public:
- ReceiverReport() : RtcpPacket() {
- memset(&rr_, 0, sizeof(rr_));
- }
-
- virtual ~ReceiverReport() {}
-
- void From(uint32_t ssrc) {
- rr_.SenderSSRC = ssrc;
- }
- bool WithReportBlock(const ReportBlock& block);
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
- static const int kMaxNumberOfReportBlocks = 0x1F;
-
- size_t BlockLength() const {
- const size_t kRrHeaderLength = 8;
- return kRrHeaderLength + report_blocks_.size() * kReportBlockLength;
- }
-
- RTCPUtility::RTCPPacketRR rr_;
- std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(ReceiverReport);
-};
-
-// Transmission Time Offsets in RTP Streams (RFC 5450).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// hdr |V=2|P| RC | PT=IJ=195 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | inter-arrival jitter |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// . .
-// . .
-// . .
-// | inter-arrival jitter |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-// If present, this RTCP packet must be placed after a receiver report
-// (inside a compound RTCP packet), and MUST have the same value for RC
-// (reception report count) as the receiver report.
-
-class Ij : public RtcpPacket {
- public:
- Ij() : RtcpPacket() {}
-
- virtual ~Ij() {}
-
- bool WithJitterItem(uint32_t jitter);
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
- static const int kMaxNumberOfIjItems = 0x1f;
-
- size_t BlockLength() const {
- return kHeaderLength + 4 * ij_items_.size();
- }
-
- std::vector<uint32_t> ij_items_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(Ij);
-};
-
// Source Description (SDES) (RFC 3550).
//
// 0 1 2 3
@@ -420,262 +254,6 @@ class Sdes : public RtcpPacket {
RTC_DISALLOW_COPY_AND_ASSIGN(Sdes);
};
-//
-// Bye packet (BYE) (RFC 3550).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| SC | PT=BYE=203 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC/CSRC |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// : ... :
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-// (opt) | length | reason for leaving ...
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-class Bye : public RtcpPacket {
- public:
- Bye() : RtcpPacket() {
- memset(&bye_, 0, sizeof(bye_));
- }
-
- virtual ~Bye() {}
-
- void From(uint32_t ssrc) {
- bye_.SenderSSRC = ssrc;
- }
-
- bool WithCsrc(uint32_t csrc);
-
- // TODO(sprang): Add support for reason field?
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
- static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC.
-
- size_t BlockLength() const {
- size_t source_count = 1 + csrcs_.size();
- return kHeaderLength + 4 * source_count;
- }
-
- RTCPUtility::RTCPPacketBYE bye_;
- std::vector<uint32_t> csrcs_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(Bye);
-};
-
-// Application-Defined packet (APP) (RFC 3550).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| subtype | PT=APP=204 | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC/CSRC |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | name (ASCII) |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | application-dependent data ...
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-class App : public RtcpPacket {
- public:
- App()
- : RtcpPacket(),
- ssrc_(0) {
- memset(&app_, 0, sizeof(app_));
- }
-
- virtual ~App() {}
-
- void From(uint32_t ssrc) {
- ssrc_ = ssrc;
- }
- void WithSubType(uint8_t subtype) {
- assert(subtype <= 0x1f);
- app_.SubType = subtype;
- }
- void WithName(uint32_t name) {
- app_.Name = name;
- }
- void WithData(const uint8_t* data, uint16_t data_length) {
- assert(data);
- assert(data_length <= kRtcpAppCode_DATA_SIZE);
- assert(data_length % 4 == 0);
- memcpy(app_.Data, data, data_length);
- app_.Size = data_length;
- }
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
- size_t BlockLength() const {
- return 12 + app_.Size;
- }
-
- uint32_t ssrc_;
- RTCPUtility::RTCPPacketAPP app_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(App);
-};
-
-// RFC 4585: Feedback format.
-//
-// Common packet format:
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |V=2|P| FMT | PT | length |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of packet sender |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of media source |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// : Feedback Control Information (FCI) :
-// :
-
-// Picture loss indication (PLI) (RFC 4585).
-//
-// FCI: no feedback control information.
-
-class Pli : public RtcpPacket {
- public:
- Pli() : RtcpPacket() {
- memset(&pli_, 0, sizeof(pli_));
- }
-
- virtual ~Pli() {}
-
- void From(uint32_t ssrc) {
- pli_.SenderSSRC = ssrc;
- }
- void To(uint32_t ssrc) {
- pli_.MediaSSRC = ssrc;
- }
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
- size_t BlockLength() const {
- return kCommonFbFmtLength;
- }
-
- RTCPUtility::RTCPPacketPSFBPLI pli_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(Pli);
-};
-
-// Slice loss indication (SLI) (RFC 4585).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | First | Number | PictureID |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-class Sli : public RtcpPacket {
- public:
- Sli() : RtcpPacket() {
- memset(&sli_, 0, sizeof(sli_));
- memset(&sli_item_, 0, sizeof(sli_item_));
- }
-
- virtual ~Sli() {}
-
- void From(uint32_t ssrc) {
- sli_.SenderSSRC = ssrc;
- }
- void To(uint32_t ssrc) {
- sli_.MediaSSRC = ssrc;
- }
- void WithFirstMb(uint16_t first_mb) {
- assert(first_mb <= 0x1fff);
- sli_item_.FirstMB = first_mb;
- }
- void WithNumberOfMb(uint16_t number_mb) {
- assert(number_mb <= 0x1fff);
- sli_item_.NumberOfMB = number_mb;
- }
- void WithPictureId(uint8_t picture_id) {
- assert(picture_id <= 0x3f);
- sli_item_.PictureId = picture_id;
- }
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
- size_t BlockLength() const {
- const size_t kFciLength = 4;
- return kCommonFbFmtLength + kFciLength;
- }
-
- RTCPUtility::RTCPPacketPSFBSLI sli_;
- RTCPUtility::RTCPPacketPSFBSLIItem sli_item_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(Sli);
-};
-
-// Generic NACK (RFC 4585).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | PID | BLP |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-class Nack : public RtcpPacket {
- public:
- Nack() : RtcpPacket() {
- memset(&nack_, 0, sizeof(nack_));
- }
-
- virtual ~Nack() {}
-
- void From(uint32_t ssrc) {
- nack_.SenderSSRC = ssrc;
- }
- void To(uint32_t ssrc) {
- nack_.MediaSSRC = ssrc;
- }
- void WithList(const uint16_t* nack_list, int length);
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- size_t BlockLength() const override;
-
- private:
-
- RTCPUtility::RTCPPacketRTPFBNACK nack_;
- std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(Nack);
-};
-
// Reference picture selection indication (RPSI) (RFC 4585).
//
// FCI:
@@ -775,105 +353,6 @@ class Fir : public RtcpPacket {
RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
};
-// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (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 Tmmbr : public RtcpPacket {
- public:
- Tmmbr() : RtcpPacket() {
- memset(&tmmbr_, 0, sizeof(tmmbr_));
- memset(&tmmbr_item_, 0, sizeof(tmmbr_item_));
- }
-
- virtual ~Tmmbr() {}
-
- void From(uint32_t ssrc) {
- tmmbr_.SenderSSRC = ssrc;
- }
- void To(uint32_t ssrc) {
- tmmbr_item_.SSRC = ssrc;
- }
- void WithBitrateKbps(uint32_t bitrate_kbps) {
- tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps;
- }
- void WithOverhead(uint16_t overhead) {
- assert(overhead <= 0x1ff);
- tmmbr_item_.MeasuredOverhead = overhead;
- }
-
- protected:
- bool Create(uint8_t* packet,
- size_t* index,
- size_t max_length,
- RtcpPacket::PacketReadyCallback* callback) const override;
-
- private:
- size_t BlockLength() const {
- const size_t kFciLen = 8;
- return kCommonFbFmtLength + kFciLen;
- }
-
- RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_;
- RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_;
-
- 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
@@ -978,163 +457,22 @@ class Xr : public RtcpPacket {
return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength();
}
- size_t RrtrLength() const {
- const size_t kRrtrBlockLength = 12;
- return kRrtrBlockLength * rrtr_blocks_.size();
- }
+ size_t RrtrLength() const { return Rrtr::kLength * rrtr_blocks_.size(); }
size_t DlrrLength() const;
size_t VoipMetricLength() const {
- const size_t kVoipMetricBlockLength = 36;
- return kVoipMetricBlockLength * voip_metric_blocks_.size();
+ return VoipMetric::kLength * voip_metric_blocks_.size();
}
RTCPUtility::RTCPPacketXR xr_header_;
- std::vector<RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem> rrtr_blocks_;
- std::vector<DlrrBlock> dlrr_blocks_;
- std::vector<RTCPUtility::RTCPPacketXRVOIPMetricItem> voip_metric_blocks_;
+ std::vector<Rrtr> rrtr_blocks_;
+ std::vector<Dlrr> dlrr_blocks_;
+ std::vector<VoipMetric> voip_metric_blocks_;
RTC_DISALLOW_COPY_AND_ASSIGN(Xr);
};
-// Receiver Reference Time Report Block (RFC 3611).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | BT=4 | reserved | block length = 2 |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | NTP timestamp, most significant word |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | NTP timestamp, least significant word |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-class Rrtr {
- public:
- Rrtr() {
- memset(&rrtr_block_, 0, sizeof(rrtr_block_));
- }
- ~Rrtr() {}
-
- void WithNtpSec(uint32_t sec) {
- rrtr_block_.NTPMostSignificant = sec;
- }
- void WithNtpFrac(uint32_t frac) {
- rrtr_block_.NTPLeastSignificant = frac;
- }
-
- private:
- friend class Xr;
- RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem rrtr_block_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(Rrtr);
-};
-
-// DLRR Report Block (RFC 3611).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | BT=5 | reserved | block length |
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-// | SSRC_1 (SSRC of first receiver) | sub-
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
-// | last RR (LRR) | 1
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | delay since last RR (DLRR) |
-// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-// | SSRC_2 (SSRC of second receiver) | sub-
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
-// : ... : 2
-
-class Dlrr {
- public:
- Dlrr() {}
- ~Dlrr() {}
-
- // Max 100 DLRR Items can be added per DLRR report block.
- bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr);
-
- private:
- friend class Xr;
- static const int kMaxNumberOfDlrrItems = 100;
-
- std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(Dlrr);
-};
-
-// VoIP Metrics Report Block (RFC 3611).
-//
-// 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
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | BT=7 | reserved | block length = 8 |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | SSRC of source |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | loss rate | discard rate | burst density | gap density |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | burst duration | gap duration |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | round trip delay | end system delay |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | signal level | noise level | RERL | Gmin |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | R factor | ext. R factor | MOS-LQ | MOS-CQ |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | RX config | reserved | JB nominal |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | JB maximum | JB abs max |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-class VoipMetric {
- public:
- VoipMetric() {
- memset(&metric_, 0, sizeof(metric_));
- }
- ~VoipMetric() {}
-
- void To(uint32_t ssrc) { metric_.SSRC = ssrc; }
- void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; }
- void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; }
- void BurstDensity(uint8_t burst_density) {
- metric_.burstDensity = burst_density;
- }
- void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; }
- void BurstDuration(uint16_t burst_duration) {
- metric_.burstDuration = burst_duration;
- }
- void GapDuration(uint16_t gap_duration) {
- metric_.gapDuration = gap_duration;
- }
- void RoundTripDelay(uint16_t round_trip_delay) {
- metric_.roundTripDelay = round_trip_delay;
- }
- void EndSystemDelay(uint16_t end_system_delay) {
- metric_.endSystemDelay = end_system_delay;
- }
- void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; }
- void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; }
- void Rerl(uint8_t rerl) { metric_.RERL = rerl; }
- void Gmin(uint8_t gmin) { metric_.Gmin = gmin; }
- void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; }
- void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; }
- void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; }
- void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; }
- void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; }
- void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; }
- void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; }
- void JbAbsMax(uint16_t jbabsmax) { metric_.JBabsMax = jbabsmax; }
-
- private:
- friend class Xr;
- RTCPUtility::RTCPPacketXRVOIPMetricItem metric_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(VoipMetric);
-};
-
// Class holding a RTCP packet.
//
// Takes a built rtcp packet.
@@ -1163,4 +501,4 @@ class RawPacket {
} // namespace rtcp
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc
new file mode 100644
index 0000000000..a1ad8d6427
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 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/app.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::RTCPUtility::RtcpCommonHeader;
+
+namespace webrtc {
+namespace rtcp {
+
+// Application-Defined packet (APP) (RFC 3550).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| subtype | PT=APP=204 | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 0 | SSRC/CSRC |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 4 | name (ASCII) |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 8 | application-dependent data ...
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+bool App::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
+ RTC_DCHECK(header.packet_type == kPacketType);
+
+ sub_type_ = header.count_or_format;
+ ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[0]);
+ name_ = ByteReader<uint32_t>::ReadBigEndian(&payload[4]);
+ data_.SetData(&payload[8], header.payload_size_bytes - 8);
+ return true;
+}
+
+void App::WithSubType(uint8_t subtype) {
+ RTC_DCHECK_LE(subtype, 0x1f);
+ sub_type_ = subtype;
+}
+
+void App::WithData(const uint8_t* data, size_t data_length) {
+ RTC_DCHECK(data);
+ RTC_DCHECK_EQ(0u, data_length % 4) << "Data must be 32 bits aligned.";
+ RTC_DCHECK(data_length <= kMaxDataSize) << "App data size << " << data_length
+ << "exceed maximum of "
+ << kMaxDataSize << " bytes.";
+ data_.SetData(data, data_length);
+}
+
+bool App::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 size_t index_end = *index + BlockLength();
+ CreateHeader(sub_type_, kPacketType, HeaderLength(), packet, index);
+
+ ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 0], ssrc_);
+ ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 4], name_);
+ memcpy(&packet[*index + 8], data_.data(), data_.size());
+ *index += (8 + data_.size());
+ RTC_DCHECK_EQ(index_end, *index);
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h
new file mode 100644
index 0000000000..16bd3fc2a2
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 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_APP_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_APP_H_
+
+#include "webrtc/base/buffer.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class App : public RtcpPacket {
+ public:
+ static const uint8_t kPacketType = 204;
+ // 28 bytes for UDP header
+ // 12 bytes for RTCP app header
+ static const size_t kMaxDataSize = IP_PACKET_SIZE - 12 - 28;
+ App() : sub_type_(0), ssrc_(0), name_(0) {}
+
+ virtual ~App() {}
+
+ // Parse assumes header is already parsed and validated.
+ bool Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload); // Size of the payload is in the header.
+
+ void From(uint32_t ssrc) { ssrc_ = ssrc; }
+ void WithSubType(uint8_t subtype);
+ void WithName(uint32_t name) { name_ = name; }
+ void WithData(const uint8_t* data, size_t data_length);
+
+ uint8_t sub_type() const { return sub_type_; }
+ uint32_t ssrc() const { return ssrc_; }
+ uint32_t name() const { return name_; }
+ size_t data_size() const { return data_.size(); }
+ const uint8_t* data() const { return data_.data(); }
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+ size_t BlockLength() const override { return 12 + data_.size(); }
+
+ uint8_t sub_type_;
+ uint32_t ssrc_;
+ uint32_t name_;
+ rtc::Buffer data_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(App);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_APP_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc
new file mode 100644
index 0000000000..4451fe8fb5
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015 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/app.h"
+
+#include <limits>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+using webrtc::rtcp::App;
+using webrtc::rtcp::RawPacket;
+using webrtc::RTCPUtility::RtcpCommonHeader;
+using webrtc::RTCPUtility::RtcpParseCommonHeader;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kName = ((uint32_t)'n' << 24) | ((uint32_t)'a' << 16) |
+ ((uint32_t)'m' << 8) | (uint32_t)'e';
+const uint32_t kSenderSsrc = 0x12345678;
+
+class RtcpPacketAppTest : public ::testing::Test {
+ protected:
+ void BuildPacket() { packet = app.Build(); }
+ void ParsePacket() {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header));
+ // Check there is exactly one RTCP packet in the buffer.
+ EXPECT_EQ(header.BlockSize(), packet->Length());
+ EXPECT_TRUE(parsed_.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+ }
+
+ App app;
+ rtc::scoped_ptr<RawPacket> packet;
+ const App& parsed() { return parsed_; }
+
+ private:
+ App parsed_;
+};
+
+TEST_F(RtcpPacketAppTest, WithNoData) {
+ app.WithSubType(30);
+ app.WithName(kName);
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(30U, parsed().sub_type());
+ EXPECT_EQ(kName, parsed().name());
+ EXPECT_EQ(0u, parsed().data_size());
+}
+
+TEST_F(RtcpPacketAppTest, WithData) {
+ app.From(kSenderSsrc);
+ app.WithSubType(30);
+ app.WithName(kName);
+ const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
+ const size_t kDataLength = sizeof(kData) / sizeof(kData[0]);
+ app.WithData(kData, kDataLength);
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(30U, parsed().sub_type());
+ EXPECT_EQ(kName, parsed().name());
+ EXPECT_EQ(kDataLength, parsed().data_size());
+ EXPECT_EQ(0, memcmp(kData, parsed().data(), kDataLength));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.cc
new file mode 100644
index 0000000000..4cfc921ce5
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.cc
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015 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/bye.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::RTCPUtility::RtcpCommonHeader;
+
+namespace webrtc {
+namespace rtcp {
+
+// Bye packet (BYE) (RFC 3550).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| SC | PT=BYE=203 | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | SSRC/CSRC |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// : ... :
+// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+// (opt) | length | reason for leaving ...
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+Bye::Bye() : sender_ssrc_(0) {}
+
+bool Bye::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
+ RTC_DCHECK(header.packet_type == kPacketType);
+
+ const uint8_t src_count = header.count_or_format;
+ // Validate packet.
+ if (header.payload_size_bytes < 4u * src_count) {
+ LOG(LS_WARNING)
+ << "Packet is too small to contain CSRCs it promise to have.";
+ return false;
+ }
+ bool has_reason = (header.payload_size_bytes > 4u * src_count);
+ uint8_t reason_length = 0;
+ if (has_reason) {
+ reason_length = payload[4u * src_count];
+ if (header.payload_size_bytes - 4u * src_count < 1u + reason_length) {
+ LOG(LS_WARNING) << "Invalid reason length: " << reason_length;
+ return false;
+ }
+ }
+ // Once sure packet is valid, copy values.
+ if (src_count == 0) { // A count value of zero is valid, but useless.
+ sender_ssrc_ = 0;
+ csrcs_.clear();
+ } else {
+ sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(payload);
+ csrcs_.resize(src_count - 1);
+ for (size_t i = 1; i < src_count; ++i)
+ csrcs_[i - 1] = ByteReader<uint32_t>::ReadBigEndian(&payload[4 * i]);
+ }
+
+ if (has_reason) {
+ reason_.assign(reinterpret_cast<const char*>(&payload[4u * src_count + 1]),
+ reason_length);
+ } else {
+ reason_.clear();
+ }
+
+ return true;
+}
+
+bool Bye::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 size_t index_end = *index + BlockLength();
+
+ CreateHeader(1 + csrcs_.size(), kPacketType, HeaderLength(), packet, index);
+ // Store srcs of the leaving clients.
+ ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], sender_ssrc_);
+ *index += sizeof(uint32_t);
+ for (uint32_t csrc : csrcs_) {
+ ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], csrc);
+ *index += sizeof(uint32_t);
+ }
+ // Store the reason to leave.
+ if (!reason_.empty()) {
+ uint8_t reason_length = reason_.size();
+ packet[(*index)++] = reason_length;
+ memcpy(&packet[*index], reason_.data(), reason_length);
+ *index += reason_length;
+ // Add padding bytes if needed.
+ size_t bytes_to_pad = index_end - *index;
+ RTC_DCHECK_LE(bytes_to_pad, 3u);
+ if (bytes_to_pad > 0) {
+ memset(&packet[*index], 0, bytes_to_pad);
+ *index += bytes_to_pad;
+ }
+ }
+ RTC_DCHECK_EQ(index_end, *index);
+ return true;
+}
+
+bool Bye::WithCsrc(uint32_t csrc) {
+ if (csrcs_.size() >= kMaxNumberOfCsrcs) {
+ LOG(LS_WARNING) << "Max CSRC size reached.";
+ return false;
+ }
+ csrcs_.push_back(csrc);
+ return true;
+}
+
+void Bye::WithReason(const std::string& reason) {
+ RTC_DCHECK_LE(reason.size(), 0xffu);
+ reason_ = reason;
+}
+
+size_t Bye::BlockLength() const {
+ size_t src_count = (1 + csrcs_.size());
+ size_t reason_size_in_32bits = reason_.empty() ? 0 : (reason_.size() / 4 + 1);
+ return kHeaderLength + 4 * (src_count + reason_size_in_32bits);
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h
new file mode 100644
index 0000000000..6b4a181330
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 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_BYE_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_BYE_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class Bye : public RtcpPacket {
+ public:
+ static const uint8_t kPacketType = 203;
+
+ Bye();
+ virtual ~Bye() {}
+
+ // Parse assumes header is already parsed and validated.
+ bool Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload); // Size of the payload is in the header.
+
+ void From(uint32_t ssrc) { sender_ssrc_ = ssrc; }
+ bool WithCsrc(uint32_t csrc);
+ void WithReason(const std::string& reason);
+
+ uint32_t sender_ssrc() const { return sender_ssrc_; }
+ const std::vector<uint32_t>& csrcs() const { return csrcs_; }
+ const std::string& reason() const { return reason_; }
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+ static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC.
+
+ size_t BlockLength() const override;
+
+ uint32_t sender_ssrc_;
+ std::vector<uint32_t> csrcs_;
+ std::string reason_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(Bye);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_BYE_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye_unittest.cc
new file mode 100644
index 0000000000..d2ae8ed782
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/bye_unittest.cc
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2015 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/bye.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+using ::testing::ElementsAre;
+
+using webrtc::rtcp::Bye;
+using webrtc::rtcp::RawPacket;
+using webrtc::RTCPUtility::RtcpCommonHeader;
+using webrtc::RTCPUtility::RtcpParseCommonHeader;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kSenderSsrc = 0x12345678;
+const uint32_t kCsrc1 = 0x22232425;
+const uint32_t kCsrc2 = 0x33343536;
+
+class RtcpPacketByeTest : public ::testing::Test {
+ protected:
+ void BuildPacket() { packet = bye.Build(); }
+ void ParsePacket() {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header));
+ // Check that there is exactly one RTCP packet in the buffer.
+ EXPECT_EQ(header.BlockSize(), packet->Length());
+ EXPECT_TRUE(parsed_bye.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+ }
+
+ Bye bye;
+ rtc::scoped_ptr<RawPacket> packet;
+ Bye parsed_bye;
+};
+
+TEST_F(RtcpPacketByeTest, Bye) {
+ bye.From(kSenderSsrc);
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(kSenderSsrc, parsed_bye.sender_ssrc());
+ EXPECT_TRUE(parsed_bye.csrcs().empty());
+ EXPECT_TRUE(parsed_bye.reason().empty());
+}
+
+TEST_F(RtcpPacketByeTest, WithCsrcs) {
+ bye.From(kSenderSsrc);
+ EXPECT_TRUE(bye.WithCsrc(kCsrc1));
+ EXPECT_TRUE(bye.WithCsrc(kCsrc2));
+ EXPECT_TRUE(bye.reason().empty());
+
+ BuildPacket();
+ EXPECT_EQ(16u, packet->Length()); // Header: 4, 3xSRCs: 12, Reason: 0.
+
+ ParsePacket();
+
+ EXPECT_EQ(kSenderSsrc, parsed_bye.sender_ssrc());
+ EXPECT_THAT(parsed_bye.csrcs(), ElementsAre(kCsrc1, kCsrc2));
+ EXPECT_TRUE(parsed_bye.reason().empty());
+}
+
+TEST_F(RtcpPacketByeTest, WithCsrcsAndReason) {
+ const std::string kReason = "Some Reason";
+
+ bye.From(kSenderSsrc);
+ EXPECT_TRUE(bye.WithCsrc(kCsrc1));
+ EXPECT_TRUE(bye.WithCsrc(kCsrc2));
+ bye.WithReason(kReason);
+
+ BuildPacket();
+ EXPECT_EQ(28u, packet->Length()); // Header: 4, 3xSRCs: 12, Reason: 12.
+
+ ParsePacket();
+
+ EXPECT_EQ(kSenderSsrc, parsed_bye.sender_ssrc());
+ EXPECT_THAT(parsed_bye.csrcs(), ElementsAre(kCsrc1, kCsrc2));
+ EXPECT_EQ(kReason, parsed_bye.reason());
+}
+
+TEST_F(RtcpPacketByeTest, WithTooManyCsrcs) {
+ bye.From(kSenderSsrc);
+ const int kMaxCsrcs = (1 << 5) - 2; // 5 bit len, first item is sender SSRC.
+ for (int i = 0; i < kMaxCsrcs; ++i) {
+ EXPECT_TRUE(bye.WithCsrc(i));
+ }
+ EXPECT_FALSE(bye.WithCsrc(kMaxCsrcs));
+}
+
+TEST_F(RtcpPacketByeTest, WithAReason) {
+ const std::string kReason = "Some Random Reason";
+
+ bye.From(kSenderSsrc);
+ bye.WithReason(kReason);
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(kSenderSsrc, parsed_bye.sender_ssrc());
+ EXPECT_TRUE(parsed_bye.csrcs().empty());
+ EXPECT_EQ(kReason, parsed_bye.reason());
+}
+
+TEST_F(RtcpPacketByeTest, WithReasons) {
+ // Test that packet creation/parsing behave with reasons of different length
+ // both when it require padding and when it does not.
+ for (size_t reminder = 0; reminder < 4; ++reminder) {
+ const std::string kReason(4 + reminder, 'a' + reminder);
+ bye.From(kSenderSsrc);
+ bye.WithReason(kReason);
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(kReason, parsed_bye.reason());
+ }
+}
+
+TEST_F(RtcpPacketByeTest, ParseEmptyPacket) {
+ RtcpCommonHeader header;
+ header.packet_type = Bye::kPacketType;
+ header.count_or_format = 0;
+ header.payload_size_bytes = 0;
+ uint8_t empty_payload[1];
+
+ EXPECT_TRUE(parsed_bye.Parse(header, empty_payload + 1));
+ EXPECT_EQ(0u, parsed_bye.sender_ssrc());
+ EXPECT_TRUE(parsed_bye.csrcs().empty());
+ EXPECT_TRUE(parsed_bye.reason().empty());
+}
+
+TEST_F(RtcpPacketByeTest, ParseFailOnInvalidSrcCount) {
+ bye.From(kSenderSsrc);
+
+ BuildPacket();
+
+ RtcpCommonHeader header;
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header);
+ header.count_or_format = 2; // Lie there are 2 ssrcs, not one.
+
+ EXPECT_FALSE(parsed_bye.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+}
+
+TEST_F(RtcpPacketByeTest, ParseFailOnInvalidReasonLength) {
+ bye.From(kSenderSsrc);
+ bye.WithReason("18 characters long");
+
+ BuildPacket();
+
+ RtcpCommonHeader header;
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header);
+ header.payload_size_bytes -= 4; // Payload is usually 32bit aligned.
+
+ EXPECT_FALSE(parsed_bye.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc
new file mode 100644
index 0000000000..8f5afd5dd1
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc
@@ -0,0 +1,28 @@
+/*
+ * 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/compound_packet.h"
+
+namespace webrtc {
+namespace rtcp {
+
+bool CompoundPacket::Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const {
+ return true;
+}
+
+size_t CompoundPacket::BlockLength() const {
+ return 0;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h
new file mode 100644
index 0000000000..f2f49a8ffb
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h
@@ -0,0 +1,41 @@
+/*
+ * 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_COMPOUND_PACKET_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_COMPOUND_PACKET_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class CompoundPacket : public RtcpPacket {
+ public:
+ CompoundPacket() : RtcpPacket() {}
+
+ virtual ~CompoundPacket() {}
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ size_t BlockLength() const override;
+
+ private:
+ RTC_DISALLOW_COPY_AND_ASSIGN(CompoundPacket);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_COMPOUND_PACKET_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc
new file mode 100644
index 0000000000..83dc5f6ed3
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc
@@ -0,0 +1,157 @@
+/*
+ * 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/compound_packet.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
+#include "webrtc/test/rtcp_packet_parser.h"
+
+using webrtc::rtcp::Bye;
+using webrtc::rtcp::CompoundPacket;
+using webrtc::rtcp::Fir;
+using webrtc::rtcp::RawPacket;
+using webrtc::rtcp::ReceiverReport;
+using webrtc::rtcp::ReportBlock;
+using webrtc::rtcp::SenderReport;
+using webrtc::test::RtcpPacketParser;
+
+namespace webrtc {
+
+const uint32_t kSenderSsrc = 0x12345678;
+
+TEST(RtcpCompoundPacketTest, AppendPacket) {
+ Fir fir;
+ ReportBlock rb;
+ ReceiverReport rr;
+ rr.From(kSenderSsrc);
+ EXPECT_TRUE(rr.WithReportBlock(rb));
+ rr.Append(&fir);
+
+ rtc::scoped_ptr<RawPacket> packet(rr.Build());
+ RtcpPacketParser parser;
+ parser.Parse(packet->Buffer(), packet->Length());
+ EXPECT_EQ(1, parser.receiver_report()->num_packets());
+ EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc());
+ EXPECT_EQ(1, parser.report_block()->num_packets());
+ EXPECT_EQ(1, parser.fir()->num_packets());
+}
+
+TEST(RtcpCompoundPacketTest, AppendPacketOnEmpty) {
+ CompoundPacket empty;
+ ReceiverReport rr;
+ rr.From(kSenderSsrc);
+ empty.Append(&rr);
+
+ rtc::scoped_ptr<RawPacket> packet(empty.Build());
+ RtcpPacketParser parser;
+ parser.Parse(packet->Buffer(), packet->Length());
+ EXPECT_EQ(1, parser.receiver_report()->num_packets());
+ EXPECT_EQ(0, parser.report_block()->num_packets());
+}
+
+TEST(RtcpCompoundPacketTest, AppendPacketWithOwnAppendedPacket) {
+ Fir fir;
+ Bye bye;
+ ReportBlock rb;
+
+ ReceiverReport rr;
+ EXPECT_TRUE(rr.WithReportBlock(rb));
+ rr.Append(&fir);
+
+ SenderReport sr;
+ sr.Append(&bye);
+ sr.Append(&rr);
+
+ rtc::scoped_ptr<RawPacket> packet(sr.Build());
+ RtcpPacketParser parser;
+ parser.Parse(packet->Buffer(), packet->Length());
+ EXPECT_EQ(1, parser.sender_report()->num_packets());
+ EXPECT_EQ(1, parser.receiver_report()->num_packets());
+ EXPECT_EQ(1, parser.report_block()->num_packets());
+ EXPECT_EQ(1, parser.bye()->num_packets());
+ EXPECT_EQ(1, parser.fir()->num_packets());
+}
+
+TEST(RtcpCompoundPacketTest, BuildWithInputBuffer) {
+ Fir fir;
+ ReportBlock rb;
+ ReceiverReport rr;
+ rr.From(kSenderSsrc);
+ EXPECT_TRUE(rr.WithReportBlock(rb));
+ rr.Append(&fir);
+
+ const size_t kRrLength = 8;
+ const size_t kReportBlockLength = 24;
+ const size_t kFirLength = 20;
+
+ class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
+ public:
+ void OnPacketReady(uint8_t* data, size_t length) override {
+ RtcpPacketParser parser;
+ parser.Parse(data, length);
+ EXPECT_EQ(1, parser.receiver_report()->num_packets());
+ EXPECT_EQ(1, parser.report_block()->num_packets());
+ EXPECT_EQ(1, parser.fir()->num_packets());
+ ++packets_created_;
+ }
+
+ int packets_created_ = 0;
+ } verifier;
+ const size_t kBufferSize = kRrLength + kReportBlockLength + kFirLength;
+ uint8_t buffer[kBufferSize];
+ EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
+ EXPECT_EQ(1, verifier.packets_created_);
+}
+
+TEST(RtcpCompoundPacketTest, BuildWithTooSmallBuffer_FragmentedSend) {
+ Fir fir;
+ ReportBlock rb;
+ ReceiverReport rr;
+ rr.From(kSenderSsrc);
+ EXPECT_TRUE(rr.WithReportBlock(rb));
+ rr.Append(&fir);
+
+ const size_t kRrLength = 8;
+ const size_t kReportBlockLength = 24;
+
+ class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
+ public:
+ void OnPacketReady(uint8_t* data, size_t length) override {
+ RtcpPacketParser parser;
+ parser.Parse(data, length);
+ switch (packets_created_++) {
+ case 0:
+ EXPECT_EQ(1, parser.receiver_report()->num_packets());
+ EXPECT_EQ(1, parser.report_block()->num_packets());
+ EXPECT_EQ(0, parser.fir()->num_packets());
+ break;
+ case 1:
+ EXPECT_EQ(0, parser.receiver_report()->num_packets());
+ EXPECT_EQ(0, parser.report_block()->num_packets());
+ EXPECT_EQ(1, parser.fir()->num_packets());
+ break;
+ default:
+ ADD_FAILURE() << "OnPacketReady not expected to be called "
+ << packets_created_ << " times.";
+ }
+ }
+
+ int packets_created_ = 0;
+ } verifier;
+ const size_t kBufferSize = kRrLength + kReportBlockLength;
+ uint8_t buffer[kBufferSize];
+ EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
+ EXPECT_EQ(2, verifier.packets_created_);
+}
+
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.cc
new file mode 100644
index 0000000000..6d6c48fada
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015 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/dlrr.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+namespace webrtc {
+namespace rtcp {
+// DLRR Report Block (RFC 3611).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | BT=5 | reserved | block length |
+// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+// | SSRC_1 (SSRC of first receiver) | sub-
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
+// | last RR (LRR) | 1
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | delay since last RR (DLRR) |
+// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+// | SSRC_2 (SSRC of second receiver) | sub-
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
+// : ... : 2
+bool Dlrr::Parse(const uint8_t* buffer, uint16_t block_length_32bits) {
+ RTC_DCHECK(buffer[0] == kBlockType);
+ // kReserved = buffer[1];
+ RTC_DCHECK_EQ(block_length_32bits,
+ ByteReader<uint16_t>::ReadBigEndian(&buffer[2]));
+ if (block_length_32bits % 3 != 0) {
+ LOG(LS_WARNING) << "Invalid size for dlrr block.";
+ return false;
+ }
+
+ size_t blocks_count = block_length_32bits / 3;
+ const uint8_t* read_at = buffer + kBlockHeaderLength;
+ sub_blocks_.resize(blocks_count);
+ for (SubBlock& sub_block : sub_blocks_) {
+ sub_block.ssrc = ByteReader<uint32_t>::ReadBigEndian(&read_at[0]);
+ sub_block.last_rr = ByteReader<uint32_t>::ReadBigEndian(&read_at[4]);
+ sub_block.delay_since_last_rr =
+ ByteReader<uint32_t>::ReadBigEndian(&read_at[8]);
+ read_at += kSubBlockLength;
+ }
+ return true;
+}
+
+size_t Dlrr::BlockLength() const {
+ if (sub_blocks_.empty())
+ return 0;
+ return kBlockHeaderLength + kSubBlockLength * sub_blocks_.size();
+}
+
+void Dlrr::Create(uint8_t* buffer) const {
+ if (sub_blocks_.empty()) // No subblocks, no need to write header either.
+ return;
+ // Create block header.
+ const uint8_t kReserved = 0;
+ buffer[0] = kBlockType;
+ buffer[1] = kReserved;
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], 3 * sub_blocks_.size());
+ // Create sub blocks.
+ uint8_t* write_at = buffer + kBlockHeaderLength;
+ for (const SubBlock& sub_block : sub_blocks_) {
+ ByteWriter<uint32_t>::WriteBigEndian(&write_at[0], sub_block.ssrc);
+ ByteWriter<uint32_t>::WriteBigEndian(&write_at[4], sub_block.last_rr);
+ ByteWriter<uint32_t>::WriteBigEndian(&write_at[8],
+ sub_block.delay_since_last_rr);
+ write_at += kSubBlockLength;
+ }
+ RTC_DCHECK_EQ(buffer + BlockLength(), write_at);
+}
+
+bool Dlrr::WithDlrrItem(uint32_t ssrc,
+ uint32_t last_rr,
+ uint32_t delay_last_rr) {
+ if (sub_blocks_.size() >= kMaxNumberOfDlrrItems) {
+ LOG(LS_WARNING) << "Max DLRR items reached.";
+ return false;
+ }
+ SubBlock block;
+ block.ssrc = ssrc;
+ block.last_rr = last_rr;
+ block.delay_since_last_rr = delay_last_rr;
+ sub_blocks_.push_back(block);
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.h
new file mode 100644
index 0000000000..9af2dedf3f
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 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_DLRR_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_DLRR_H_
+
+#include <vector>
+
+#include "webrtc/base/basictypes.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// DLRR Report Block: Delay since the Last Receiver Report (RFC 3611).
+class Dlrr {
+ public:
+ struct SubBlock {
+ // RFC 3611 4.5
+ uint32_t ssrc;
+ uint32_t last_rr;
+ uint32_t delay_since_last_rr;
+ };
+
+ static const uint8_t kBlockType = 5;
+ static const size_t kMaxNumberOfDlrrItems = 100;
+
+ Dlrr() {}
+ Dlrr(const Dlrr& other) = default;
+ ~Dlrr() {}
+
+ Dlrr& operator=(const Dlrr& other) = default;
+
+ // Second parameter is value read from block header,
+ // i.e. size of block in 32bits excluding block header itself.
+ bool Parse(const uint8_t* buffer, uint16_t block_length_32bits);
+
+ size_t BlockLength() const;
+ // Fills buffer with the Dlrr.
+ // Consumes BlockLength() bytes.
+ void Create(uint8_t* buffer) const;
+
+ // Max 100 DLRR Items can be added per DLRR report block.
+ bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr);
+
+ const std::vector<SubBlock>& sub_blocks() const { return sub_blocks_; }
+
+ private:
+ static const size_t kBlockHeaderLength = 4;
+ static const size_t kSubBlockLength = 12;
+
+ std::vector<SubBlock> sub_blocks_;
+};
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_DLRR_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr_unittest.cc
new file mode 100644
index 0000000000..c7c139c560
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr_unittest.cc
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2015 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/dlrr.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::rtcp::Dlrr;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kSsrc = 0x12345678;
+const uint32_t kLastRR = 0x23344556;
+const uint32_t kDelay = 0x33343536;
+const uint8_t kBlock[] = {0x05, 0x00, 0x00, 0x03, 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x34, 0x45, 0x56, 0x33, 0x34, 0x35, 0x36};
+const size_t kBlockSizeBytes = sizeof(kBlock);
+
+TEST(RtcpPacketDlrrTest, Empty) {
+ Dlrr dlrr;
+
+ EXPECT_EQ(0u, dlrr.BlockLength());
+}
+
+TEST(RtcpPacketDlrrTest, Create) {
+ Dlrr dlrr;
+ EXPECT_TRUE(dlrr.WithDlrrItem(kSsrc, kLastRR, kDelay));
+
+ ASSERT_EQ(kBlockSizeBytes, dlrr.BlockLength());
+ uint8_t buffer[kBlockSizeBytes];
+
+ dlrr.Create(buffer);
+ EXPECT_EQ(0, memcmp(buffer, kBlock, kBlockSizeBytes));
+}
+
+TEST(RtcpPacketDlrrTest, Parse) {
+ Dlrr dlrr;
+ uint16_t block_length = ByteReader<uint16_t>::ReadBigEndian(&kBlock[2]);
+ EXPECT_TRUE(dlrr.Parse(kBlock, block_length));
+
+ EXPECT_EQ(1u, dlrr.sub_blocks().size());
+ const Dlrr::SubBlock& block = dlrr.sub_blocks().front();
+ EXPECT_EQ(kSsrc, block.ssrc);
+ EXPECT_EQ(kLastRR, block.last_rr);
+ EXPECT_EQ(kDelay, block.delay_since_last_rr);
+}
+
+TEST(RtcpPacketDlrrTest, ParseFailsOnBadSize) {
+ const size_t kBigBufferSize = 0x100; // More than enough.
+ uint8_t buffer[kBigBufferSize];
+ buffer[0] = Dlrr::kBlockType;
+ buffer[1] = 0; // Reserved.
+ buffer[2] = 0; // Most significant size byte.
+ for (uint8_t size = 3; size < 6; ++size) {
+ buffer[3] = size;
+ Dlrr dlrr;
+ // Parse should be successful only when size is multiple of 3.
+ EXPECT_EQ(size % 3 == 0, dlrr.Parse(buffer, static_cast<uint16_t>(size)));
+ }
+}
+
+TEST(RtcpPacketDlrrTest, FailsOnTooManySubBlocks) {
+ Dlrr dlrr;
+ for (size_t i = 1; i <= Dlrr::kMaxNumberOfDlrrItems; ++i) {
+ EXPECT_TRUE(dlrr.WithDlrrItem(kSsrc + i, kLastRR + i, kDelay + i));
+ }
+ EXPECT_FALSE(dlrr.WithDlrrItem(kSsrc, kLastRR, kDelay));
+}
+
+TEST(RtcpPacketDlrrTest, CreateAndParseMaxSubBlocks) {
+ const size_t kBufferSize = 0x1000; // More than enough.
+ uint8_t buffer[kBufferSize];
+
+ // Create.
+ Dlrr dlrr;
+ for (size_t i = 1; i <= Dlrr::kMaxNumberOfDlrrItems; ++i) {
+ EXPECT_TRUE(dlrr.WithDlrrItem(kSsrc + i, kLastRR + i, kDelay + i));
+ }
+ size_t used_buffer_size = dlrr.BlockLength();
+ ASSERT_LE(used_buffer_size, kBufferSize);
+ dlrr.Create(buffer);
+
+ // Parse.
+ Dlrr parsed;
+ uint16_t block_length = ByteReader<uint16_t>::ReadBigEndian(&buffer[2]);
+ EXPECT_EQ(used_buffer_size, (block_length + 1) * 4u);
+ EXPECT_TRUE(parsed.Parse(buffer, block_length));
+ EXPECT_TRUE(parsed.sub_blocks().size() == Dlrr::kMaxNumberOfDlrrItems);
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc
new file mode 100644
index 0000000000..030f9f81fa
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015 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/extended_jitter_report.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+
+using webrtc::RTCPUtility::RtcpCommonHeader;
+
+namespace webrtc {
+namespace rtcp {
+
+// Transmission Time Offsets in RTP Streams (RFC 5450).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// hdr |V=2|P| RC | PT=IJ=195 | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | inter-arrival jitter |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// . .
+// . .
+// . .
+// | inter-arrival jitter |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// If present, this RTCP packet must be placed after a receiver report
+// (inside a compound RTCP packet), and MUST have the same value for RC
+// (reception report count) as the receiver report.
+
+bool ExtendedJitterReport::Parse(const RtcpCommonHeader& header,
+ const uint8_t* payload) {
+ RTC_DCHECK(header.packet_type == kPacketType);
+
+ const uint8_t jitters_count = header.count_or_format;
+ const size_t kJitterSizeBytes = 4u;
+
+ if (header.payload_size_bytes < jitters_count * kJitterSizeBytes) {
+ LOG(LS_WARNING) << "Packet is too small to contain all the jitter.";
+ return false;
+ }
+
+ inter_arrival_jitters_.resize(jitters_count);
+ for (size_t index = 0; index < jitters_count; ++index) {
+ inter_arrival_jitters_[index] =
+ ByteReader<uint32_t>::ReadBigEndian(&payload[index * kJitterSizeBytes]);
+ }
+
+ return true;
+}
+
+bool ExtendedJitterReport::WithJitter(uint32_t jitter) {
+ if (inter_arrival_jitters_.size() >= kMaxNumberOfJitters) {
+ LOG(LS_WARNING) << "Max inter-arrival jitter items reached.";
+ return false;
+ }
+ inter_arrival_jitters_.push_back(jitter);
+ return true;
+}
+
+bool ExtendedJitterReport::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 size_t index_end = *index + BlockLength();
+ size_t length = inter_arrival_jitters_.size();
+ CreateHeader(length, kPacketType, length, packet, index);
+
+ for (uint32_t jitter : inter_arrival_jitters_) {
+ ByteWriter<uint32_t>::WriteBigEndian(packet + *index, jitter);
+ *index += sizeof(uint32_t);
+ }
+ // Sanity check.
+ RTC_DCHECK_EQ(index_end, *index);
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h
new file mode 100644
index 0000000000..49de7be1a8
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 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_EXTENDED_JITTER_REPORT_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_EXTENDED_JITTER_REPORT_H_
+
+#include <vector>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class ExtendedJitterReport : public RtcpPacket {
+ public:
+ static const uint8_t kPacketType = 195;
+
+ ExtendedJitterReport() : RtcpPacket() {}
+
+ virtual ~ExtendedJitterReport() {}
+
+ // Parse assumes header is already parsed and validated.
+ bool Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload); // Size of the payload is in the header.
+
+ bool WithJitter(uint32_t jitter);
+
+ size_t jitters_count() const { return inter_arrival_jitters_.size(); }
+ uint32_t jitter(size_t index) const {
+ RTC_DCHECK_LT(index, jitters_count());
+ return inter_arrival_jitters_[index];
+ }
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+ static const int kMaxNumberOfJitters = 0x1f;
+
+ size_t BlockLength() const override {
+ return kHeaderLength + 4 * inter_arrival_jitters_.size();
+ }
+
+ std::vector<uint32_t> inter_arrival_jitters_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(ExtendedJitterReport);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_EXTENDED_JITTER_REPORT_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report_unittest.cc
new file mode 100644
index 0000000000..09d7b6305f
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report_unittest.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015 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/extended_jitter_report.h"
+
+#include <limits>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+using webrtc::rtcp::RawPacket;
+using webrtc::rtcp::ExtendedJitterReport;
+using webrtc::RTCPUtility::RtcpCommonHeader;
+using webrtc::RTCPUtility::RtcpParseCommonHeader;
+
+namespace webrtc {
+namespace {
+
+class RtcpPacketExtendedJitterReportTest : public ::testing::Test {
+ protected:
+ void BuildPacket() { packet = ij.Build(); }
+ void ParsePacket() {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header));
+ EXPECT_EQ(header.BlockSize(), packet->Length());
+ EXPECT_TRUE(parsed_.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+ }
+
+ ExtendedJitterReport ij;
+ rtc::scoped_ptr<RawPacket> packet;
+ const ExtendedJitterReport& parsed() { return parsed_; }
+
+ private:
+ ExtendedJitterReport parsed_;
+};
+
+TEST_F(RtcpPacketExtendedJitterReportTest, NoItem) {
+ // No initialization because packet is empty.
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(0u, parsed().jitters_count());
+}
+
+TEST_F(RtcpPacketExtendedJitterReportTest, OneItem) {
+ EXPECT_TRUE(ij.WithJitter(0x11121314));
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(1u, parsed().jitters_count());
+ EXPECT_EQ(0x11121314U, parsed().jitter(0));
+}
+
+TEST_F(RtcpPacketExtendedJitterReportTest, TwoItems) {
+ EXPECT_TRUE(ij.WithJitter(0x11121418));
+ EXPECT_TRUE(ij.WithJitter(0x22242628));
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(2u, parsed().jitters_count());
+ EXPECT_EQ(0x11121418U, parsed().jitter(0));
+ EXPECT_EQ(0x22242628U, parsed().jitter(1));
+}
+
+TEST_F(RtcpPacketExtendedJitterReportTest, TooManyItems) {
+ const int kMaxIjItems = (1 << 5) - 1;
+ for (int i = 0; i < kMaxIjItems; ++i) {
+ EXPECT_TRUE(ij.WithJitter(i));
+ }
+ EXPECT_FALSE(ij.WithJitter(kMaxIjItems));
+}
+
+TEST_F(RtcpPacketExtendedJitterReportTest, ParseFailWithTooManyItems) {
+ ij.WithJitter(0x11121418);
+ BuildPacket();
+ RtcpCommonHeader header;
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header);
+ header.count_or_format++; // Damage package.
+
+ ExtendedJitterReport parsed;
+
+ EXPECT_FALSE(parsed.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.cc
new file mode 100644
index 0000000000..8b9b354a06
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.cc
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2015 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/nack.h"
+
+#include <algorithm>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::RTCPUtility::RtcpCommonHeader;
+
+namespace webrtc {
+namespace rtcp {
+
+// RFC 4585: Feedback format.
+//
+// Common packet format:
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| FMT | PT | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 0 | SSRC of packet sender |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 4 | SSRC of media source |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// : Feedback Control Information (FCI) :
+// : :
+//
+// Generic NACK (RFC 4585).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | PID | BLP |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+bool Nack::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
+ RTC_DCHECK(header.packet_type == kPacketType);
+ RTC_DCHECK(header.count_or_format == kFeedbackMessageType);
+
+ if (header.payload_size_bytes < kCommonFeedbackLength + kNackItemLength) {
+ LOG(LS_WARNING) << "Payload length " << header.payload_size_bytes
+ << " is too small for a Nack.";
+ return false;
+ }
+ size_t nack_items =
+ (header.payload_size_bytes - kCommonFeedbackLength) / kNackItemLength;
+
+ ParseCommonFeedback(payload);
+ const uint8_t* next_nack = payload + kCommonFeedbackLength;
+
+ packet_ids_.clear();
+ packed_.resize(nack_items);
+ for (size_t index = 0; index < nack_items; ++index) {
+ packed_[index].first_pid = ByteReader<uint16_t>::ReadBigEndian(next_nack);
+ packed_[index].bitmask = ByteReader<uint16_t>::ReadBigEndian(next_nack + 2);
+ next_nack += kNackItemLength;
+ }
+ Unpack();
+
+ return true;
+}
+
+bool Nack::Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const {
+ RTC_DCHECK(!packed_.empty());
+ // If nack list can't fit in packet, try to fragment.
+ size_t nack_index = 0;
+ const size_t kCommonFbFmtLength = kHeaderLength + kCommonFeedbackLength;
+ do {
+ size_t bytes_left_in_buffer = max_length - *index;
+ if (bytes_left_in_buffer < kCommonFbFmtLength + kNackItemLength) {
+ if (!OnBufferFull(packet, index, callback))
+ return false;
+ continue;
+ }
+ size_t num_nack_fields =
+ std::min((bytes_left_in_buffer - kCommonFbFmtLength) / kNackItemLength,
+ packed_.size() - nack_index);
+
+ size_t size_bytes =
+ (num_nack_fields * kNackItemLength) + kCommonFbFmtLength;
+ size_t header_length = ((size_bytes + 3) / 4) - 1; // As 32bit words - 1
+ CreateHeader(kFeedbackMessageType, kPacketType, header_length, packet,
+ index);
+ CreateCommonFeedback(packet + *index);
+ *index += kCommonFeedbackLength;
+ size_t end_index = nack_index + num_nack_fields;
+ for (; nack_index < end_index; ++nack_index) {
+ const auto& item = packed_[nack_index];
+ ByteWriter<uint16_t>::WriteBigEndian(packet + *index + 0, item.first_pid);
+ ByteWriter<uint16_t>::WriteBigEndian(packet + *index + 2, item.bitmask);
+ *index += kNackItemLength;
+ }
+ RTC_DCHECK_LE(*index, max_length);
+ } while (nack_index < packed_.size());
+
+ return true;
+}
+
+size_t Nack::BlockLength() const {
+ return (packed_.size() * kNackItemLength) + kCommonFeedbackLength +
+ kHeaderLength;
+}
+
+void Nack::WithList(const uint16_t* nack_list, size_t length) {
+ RTC_DCHECK(nack_list);
+ RTC_DCHECK(packet_ids_.empty());
+ RTC_DCHECK(packed_.empty());
+ packet_ids_.assign(nack_list, nack_list + length);
+ Pack();
+}
+
+void Nack::Pack() {
+ RTC_DCHECK(!packet_ids_.empty());
+ RTC_DCHECK(packed_.empty());
+ auto it = packet_ids_.begin();
+ const auto end = packet_ids_.end();
+ while (it != end) {
+ PackedNack item;
+ item.first_pid = *it++;
+ // Bitmask specifies losses in any of the 16 packets following the pid.
+ item.bitmask = 0;
+ while (it != end) {
+ uint16_t shift = static_cast<uint16_t>(*it - item.first_pid - 1);
+ if (shift <= 15) {
+ item.bitmask |= (1 << shift);
+ ++it;
+ } else {
+ break;
+ }
+ }
+ packed_.push_back(item);
+ }
+}
+
+void Nack::Unpack() {
+ RTC_DCHECK(packet_ids_.empty());
+ RTC_DCHECK(!packed_.empty());
+ for (const PackedNack& item : packed_) {
+ packet_ids_.push_back(item.first_pid);
+ uint16_t pid = item.first_pid + 1;
+ for (uint16_t bitmask = item.bitmask; bitmask != 0; bitmask >>= 1, ++pid)
+ if (bitmask & 1)
+ packet_ids_.push_back(pid);
+ }
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h
new file mode 100644
index 0000000000..fb2be113a2
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 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_NACK_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_NACK_H_
+
+#include <vector>
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class Nack : public Rtpfb {
+ public:
+ const uint8_t kFeedbackMessageType = 1;
+ Nack() {}
+
+ virtual ~Nack() {}
+
+ // Parse assumes header is already parsed and validated.
+ bool Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload); // Size of the payload is in the header.
+
+ void WithList(const uint16_t* nack_list, size_t length);
+ const std::vector<uint16_t>& packet_ids() const { return packet_ids_; }
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ size_t BlockLength() const override;
+
+ private:
+ const size_t kNackItemLength = 4;
+ struct PackedNack {
+ uint16_t first_pid;
+ uint16_t bitmask;
+ };
+
+ void Pack(); // Fills packed_ using packed_ids_. (used in WithList).
+ void Unpack(); // Fills packet_ids_ using packed_. (used in Parse).
+
+ std::vector<PackedNack> packed_;
+ std::vector<uint16_t> packet_ids_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(Nack);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_NACK_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack_unittest.cc
new file mode 100644
index 0000000000..01e30f5644
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/nack_unittest.cc
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2015 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/nack.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::ElementsAreArray;
+using ::testing::Invoke;
+using ::testing::UnorderedElementsAreArray;
+
+using webrtc::rtcp::Nack;
+using webrtc::rtcp::RawPacket;
+using webrtc::RTCPUtility::RtcpCommonHeader;
+using webrtc::RTCPUtility::RtcpParseCommonHeader;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kSenderSsrc = 0x12345678;
+const uint32_t kRemoteSsrc = 0x23456789;
+
+const uint16_t kList[] = {0, 1, 3, 8, 16};
+const size_t kListLength = sizeof(kList) / sizeof(kList[0]);
+const uint8_t kPacket[] = {0x81, 205, 0x00, 0x03, 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x45, 0x67, 0x89, 0x00, 0x00, 0x80, 0x85};
+const size_t kPacketLength = sizeof(kPacket);
+
+const uint16_t kWrapList[] = {0xffdc, 0xffec, 0xfffe, 0xffff, 0x0000,
+ 0x0001, 0x0003, 0x0014, 0x0064};
+const size_t kWrapListLength = sizeof(kWrapList) / sizeof(kWrapList[0]);
+const uint8_t kWrapPacket[] = {0x81, 205, 0x00, 0x06, 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x45, 0x67, 0x89, 0xff, 0xdc, 0x80, 0x00,
+ 0xff, 0xfe, 0x00, 0x17, 0x00, 0x14, 0x00, 0x00,
+ 0x00, 0x64, 0x00, 0x00};
+const size_t kWrapPacketLength = sizeof(kWrapPacket);
+
+TEST(RtcpPacketNackTest, Create) {
+ Nack nack;
+ nack.From(kSenderSsrc);
+ nack.To(kRemoteSsrc);
+ nack.WithList(kList, kListLength);
+
+ rtc::scoped_ptr<RawPacket> packet = nack.Build();
+
+ EXPECT_EQ(kPacketLength, packet->Length());
+ EXPECT_EQ(0, memcmp(kPacket, packet->Buffer(), kPacketLength));
+}
+
+TEST(RtcpPacketNackTest, Parse) {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(RtcpParseCommonHeader(kPacket, kPacketLength, &header));
+ EXPECT_EQ(kPacketLength, header.BlockSize());
+ Nack parsed;
+
+ EXPECT_TRUE(
+ parsed.Parse(header, kPacket + RtcpCommonHeader::kHeaderSizeBytes));
+ const Nack& const_parsed = parsed;
+
+ EXPECT_EQ(kSenderSsrc, const_parsed.sender_ssrc());
+ EXPECT_EQ(kRemoteSsrc, const_parsed.media_ssrc());
+ EXPECT_THAT(const_parsed.packet_ids(), ElementsAreArray(kList));
+}
+
+TEST(RtcpPacketNackTest, CreateWrap) {
+ Nack nack;
+ nack.From(kSenderSsrc);
+ nack.To(kRemoteSsrc);
+ nack.WithList(kWrapList, kWrapListLength);
+
+ rtc::scoped_ptr<RawPacket> packet = nack.Build();
+
+ EXPECT_EQ(kWrapPacketLength, packet->Length());
+ EXPECT_EQ(0, memcmp(kWrapPacket, packet->Buffer(), kWrapPacketLength));
+}
+
+TEST(RtcpPacketNackTest, ParseWrap) {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(RtcpParseCommonHeader(kWrapPacket, kWrapPacketLength, &header));
+ EXPECT_EQ(kWrapPacketLength, header.BlockSize());
+
+ Nack parsed;
+ EXPECT_TRUE(
+ parsed.Parse(header, kWrapPacket + RtcpCommonHeader::kHeaderSizeBytes));
+
+ EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
+ EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc());
+ EXPECT_THAT(parsed.packet_ids(), ElementsAreArray(kWrapList));
+}
+
+TEST(RtcpPacketNackTest, BadOrder) {
+ // Does not guarantee optimal packing, but should guarantee correctness.
+ const uint16_t kUnorderedList[] = {1, 25, 13, 12, 9, 27, 29};
+ const size_t kUnorderedListLength =
+ sizeof(kUnorderedList) / sizeof(kUnorderedList[0]);
+ Nack nack;
+ nack.From(kSenderSsrc);
+ nack.To(kRemoteSsrc);
+ nack.WithList(kUnorderedList, kUnorderedListLength);
+
+ rtc::scoped_ptr<RawPacket> packet = nack.Build();
+
+ Nack parsed;
+ RtcpCommonHeader header;
+ EXPECT_TRUE(
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header));
+ EXPECT_TRUE(parsed.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+
+ EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
+ EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc());
+ EXPECT_THAT(parsed.packet_ids(), UnorderedElementsAreArray(kUnorderedList));
+}
+
+TEST(RtcpPacketNackTest, CreateFragmented) {
+ Nack nack;
+ const uint16_t kList[] = {1, 100, 200, 300, 400};
+ const uint16_t kListLength = sizeof(kList) / sizeof(kList[0]);
+ nack.From(kSenderSsrc);
+ nack.To(kRemoteSsrc);
+ nack.WithList(kList, kListLength);
+
+ class MockPacketReadyCallback : public rtcp::RtcpPacket::PacketReadyCallback {
+ public:
+ MOCK_METHOD2(OnPacketReady, void(uint8_t*, size_t));
+ } verifier;
+
+ class NackVerifier {
+ public:
+ explicit NackVerifier(std::vector<uint16_t> ids) : ids_(ids) {}
+ void operator()(uint8_t* data, size_t length) {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(RtcpParseCommonHeader(data, length, &header));
+ EXPECT_EQ(length, header.BlockSize());
+ Nack nack;
+ EXPECT_TRUE(
+ nack.Parse(header, data + RtcpCommonHeader::kHeaderSizeBytes));
+ EXPECT_EQ(kSenderSsrc, nack.sender_ssrc());
+ EXPECT_EQ(kRemoteSsrc, nack.media_ssrc());
+ EXPECT_THAT(nack.packet_ids(), ElementsAreArray(ids_));
+ }
+ std::vector<uint16_t> ids_;
+ } packet1({1, 100, 200}), packet2({300, 400});
+
+ EXPECT_CALL(verifier, OnPacketReady(_, _))
+ .WillOnce(Invoke(packet1))
+ .WillOnce(Invoke(packet2));
+ const size_t kBufferSize = 12 + (3 * 4); // Fits common header + 3 nack items
+ uint8_t buffer[kBufferSize];
+ EXPECT_TRUE(nack.BuildExternalBuffer(buffer, kBufferSize, &verifier));
+}
+
+TEST(RtcpPacketNackTest, CreateFailsWithTooSmallBuffer) {
+ const uint16_t kList[] = {1};
+ const size_t kMinNackBlockSize = 16;
+ Nack nack;
+ nack.From(kSenderSsrc);
+ nack.To(kRemoteSsrc);
+ nack.WithList(kList, 1);
+ class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
+ public:
+ void OnPacketReady(uint8_t* data, size_t length) override {
+ ADD_FAILURE() << "Buffer should be too small.";
+ }
+ } verifier;
+ uint8_t buffer[kMinNackBlockSize - 1];
+ EXPECT_FALSE(
+ nack.BuildExternalBuffer(buffer, kMinNackBlockSize - 1, &verifier));
+}
+
+TEST(RtcpPacketNackTest, ParseFailsWithTooSmallBuffer) {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(RtcpParseCommonHeader(kPacket, kPacketLength, &header));
+ header.payload_size_bytes--; // Damage the packet
+ Nack parsed;
+ EXPECT_FALSE(
+ parsed.Parse(header, kPacket + RtcpCommonHeader::kHeaderSizeBytes));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.cc
new file mode 100644
index 0000000000..3673491058
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015 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/pli.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+
+using webrtc::RTCPUtility::RtcpCommonHeader;
+
+namespace webrtc {
+namespace rtcp {
+
+// RFC 4585: Feedback format.
+//
+// Common packet format:
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| FMT | PT | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | SSRC of packet sender |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | SSRC of media source |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// : Feedback Control Information (FCI) :
+// : :
+
+//
+// Picture loss indication (PLI) (RFC 4585).
+// FCI: no feedback control information.
+bool Pli::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
+ RTC_DCHECK(header.packet_type == kPacketType);
+ RTC_DCHECK(header.count_or_format == kFeedbackMessageType);
+
+ if (header.payload_size_bytes < kCommonFeedbackLength) {
+ LOG(LS_WARNING) << "Packet is too small to be a valid PLI packet";
+ return false;
+ }
+
+ ParseCommonFeedback(payload);
+ return true;
+}
+
+bool Pli::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;
+ }
+
+ CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
+ index);
+ CreateCommonFeedback(packet + *index);
+ *index += kCommonFeedbackLength;
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h
new file mode 100644
index 0000000000..5567825830
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 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_PLI_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_PLI_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// Picture loss indication (PLI) (RFC 4585).
+class Pli : public Psfb {
+ public:
+ static const uint8_t kFeedbackMessageType = 1;
+
+ Pli() {}
+ virtual ~Pli() {}
+
+ // Parse assumes header is already parsed and validated.
+ bool Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload); // Size of the payload is in the header.
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+ size_t BlockLength() const override {
+ return kHeaderLength + kCommonFeedbackLength;
+ }
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(Pli);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_PLI_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli_unittest.cc
new file mode 100644
index 0000000000..1c47c3ffb1
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/pli_unittest.cc
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 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/pli.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+using webrtc::rtcp::Pli;
+using webrtc::rtcp::RawPacket;
+using webrtc::RTCPUtility::RtcpCommonHeader;
+using webrtc::RTCPUtility::RtcpParseCommonHeader;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kSenderSsrc = 0x12345678;
+const uint32_t kRemoteSsrc = 0x23456789;
+// Manually created Pli packet matching constants above.
+const uint8_t kPacket[] = {0x81, 206, 0x00, 0x02,
+ 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x45, 0x67, 0x89};
+const size_t kPacketLength = sizeof(kPacket);
+
+TEST(RtcpPacketPliTest, Parse) {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(RtcpParseCommonHeader(kPacket, kPacketLength, &header));
+ Pli mutable_parsed;
+ EXPECT_TRUE(mutable_parsed.Parse(
+ header, kPacket + RtcpCommonHeader::kHeaderSizeBytes));
+ const Pli& parsed = mutable_parsed; // Read values from constant object.
+
+ EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
+ EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc());
+}
+
+TEST(RtcpPacketPliTest, Create) {
+ Pli pli;
+ pli.From(kSenderSsrc);
+ pli.To(kRemoteSsrc);
+
+ rtc::scoped_ptr<RawPacket> packet(pli.Build());
+
+ ASSERT_EQ(kPacketLength, packet->Length());
+ EXPECT_EQ(0, memcmp(kPacket, packet->Buffer(), kPacketLength));
+}
+
+TEST(RtcpPacketPliTest, ParseFailsOnTooSmallPacket) {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(RtcpParseCommonHeader(kPacket, kPacketLength, &header));
+ header.payload_size_bytes--;
+
+ Pli parsed;
+ EXPECT_FALSE(
+ parsed.Parse(header, kPacket + RtcpCommonHeader::kHeaderSizeBytes));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.cc
new file mode 100644
index 0000000000..d1ee401dab
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 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/psfb.h"
+
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// RFC 4585: Feedback format.
+//
+// Common packet format:
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| FMT | PT | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 0 | SSRC of packet sender |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 4 | SSRC of media source |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// : Feedback Control Information (FCI) :
+// : :
+
+void Psfb::ParseCommonFeedback(const uint8_t* payload) {
+ sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[0]);
+ media_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[4]);
+}
+
+void Psfb::CreateCommonFeedback(uint8_t* payload) const {
+ ByteWriter<uint32_t>::WriteBigEndian(&payload[0], sender_ssrc_);
+ ByteWriter<uint32_t>::WriteBigEndian(&payload[4], media_ssrc_);
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h
new file mode 100644
index 0000000000..dddcdecba6
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 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_PSFB_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_PSFB_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// PSFB: Payload-specific feedback message.
+// RFC 4585, Section 6.3.
+class Psfb : public RtcpPacket {
+ public:
+ static const uint8_t kPacketType = 206;
+
+ Psfb() : sender_ssrc_(0), media_ssrc_(0) {}
+ virtual ~Psfb() {}
+
+ void From(uint32_t ssrc) { sender_ssrc_ = ssrc; }
+ void To(uint32_t ssrc) { media_ssrc_ = ssrc; }
+
+ uint32_t sender_ssrc() const { return sender_ssrc_; }
+ uint32_t media_ssrc() const { return media_ssrc_; }
+
+ protected:
+ static const size_t kCommonFeedbackLength = 8;
+ void ParseCommonFeedback(const uint8_t* payload);
+ void CreateCommonFeedback(uint8_t* payload) const;
+
+ private:
+ uint32_t sender_ssrc_;
+ uint32_t media_ssrc_;
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_PSFB_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.cc
new file mode 100644
index 0000000000..ef64b4f51b
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.cc
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015 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/receiver_report.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::RTCPUtility::RtcpCommonHeader;
+
+namespace webrtc {
+namespace rtcp {
+
+//
+// RTCP receiver report (RFC 3550).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| RC | PT=RR=201 | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | SSRC of packet sender |
+// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+// | report block(s) |
+// | .... |
+bool ReceiverReport::Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload) {
+ RTC_DCHECK(header.packet_type == kPacketType);
+
+ const uint8_t report_blocks_count = header.count_or_format;
+
+ if (header.payload_size_bytes <
+ kRrBaseLength + report_blocks_count * ReportBlock::kLength) {
+ LOG(LS_WARNING) << "Packet is too small to contain all the data.";
+ return false;
+ }
+
+ sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(payload);
+
+ const uint8_t* next_report_block = payload + kRrBaseLength;
+
+ report_blocks_.resize(report_blocks_count);
+ for (ReportBlock& block : report_blocks_) {
+ block.Parse(next_report_block, ReportBlock::kLength);
+ next_report_block += ReportBlock::kLength;
+ }
+
+ RTC_DCHECK_LE(next_report_block, payload + header.payload_size_bytes);
+ return true;
+}
+
+bool ReceiverReport::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;
+ }
+ CreateHeader(report_blocks_.size(), kPacketType, HeaderLength(), packet,
+ index);
+ ByteWriter<uint32_t>::WriteBigEndian(packet + *index, sender_ssrc_);
+ *index += kRrBaseLength;
+ for (const ReportBlock& block : report_blocks_) {
+ block.Create(packet + *index);
+ *index += ReportBlock::kLength;
+ }
+ return true;
+}
+
+bool ReceiverReport::WithReportBlock(const ReportBlock& block) {
+ if (report_blocks_.size() >= kMaxNumberOfReportBlocks) {
+ LOG(LS_WARNING) << "Max report blocks reached.";
+ return false;
+ }
+ report_blocks_.push_back(block);
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h
new file mode 100644
index 0000000000..172a84ea2f
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 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_RECEIVER_REPORT_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RECEIVER_REPORT_H_
+
+#include <vector>
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class ReceiverReport : public RtcpPacket {
+ public:
+ static const uint8_t kPacketType = 201;
+ ReceiverReport() : sender_ssrc_(0) {}
+
+ virtual ~ReceiverReport() {}
+
+ // Parse assumes header is already parsed and validated.
+ bool Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload); // Size of the payload is in the header.
+
+ void From(uint32_t ssrc) { sender_ssrc_ = ssrc; }
+ bool WithReportBlock(const ReportBlock& block);
+
+ uint32_t sender_ssrc() const { return sender_ssrc_; }
+ const std::vector<ReportBlock>& report_blocks() const {
+ return report_blocks_;
+ }
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+ static const size_t kRrBaseLength = 4;
+ static const size_t kMaxNumberOfReportBlocks = 0x1F;
+
+ size_t BlockLength() const {
+ return kHeaderLength + kRrBaseLength +
+ report_blocks_.size() * ReportBlock::kLength;
+ }
+
+ uint32_t sender_ssrc_;
+ std::vector<ReportBlock> report_blocks_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(ReceiverReport);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RECEIVER_REPORT_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc
new file mode 100644
index 0000000000..ff3da600a5
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015 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/receiver_report.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+using webrtc::rtcp::RawPacket;
+using webrtc::rtcp::ReceiverReport;
+using webrtc::rtcp::ReportBlock;
+using webrtc::RTCPUtility::RtcpCommonHeader;
+using webrtc::RTCPUtility::RtcpParseCommonHeader;
+
+namespace webrtc {
+namespace {
+const uint32_t kSenderSsrc = 0x12345678;
+const uint32_t kRemoteSsrc = 0x23456789;
+const uint8_t kFractionLost = 55;
+const uint32_t kCumulativeLost = 0x111213;
+const uint32_t kExtHighestSeqNum = 0x22232425;
+const uint32_t kJitter = 0x33343536;
+const uint32_t kLastSr = 0x44454647;
+const uint32_t kDelayLastSr = 0x55565758;
+// Manually created ReceiverReport with one ReportBlock matching constants
+// above.
+// Having this block allows to test Create and Parse separately.
+const uint8_t kPacket[] = {0x81, 201, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x45, 0x67, 0x89, 55, 0x11, 0x12, 0x13,
+ 0x22, 0x23, 0x24, 0x25, 0x33, 0x34, 0x35, 0x36,
+ 0x44, 0x45, 0x46, 0x47, 0x55, 0x56, 0x57, 0x58};
+const size_t kPacketLength = sizeof(kPacket);
+
+class RtcpPacketReceiverReportTest : public ::testing::Test {
+ protected:
+ void BuildPacket() { packet = rr.Build(); }
+ void ParsePacket() {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(
+ RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header));
+ EXPECT_EQ(header.BlockSize(), packet->Length());
+ EXPECT_TRUE(parsed_.Parse(
+ header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
+ }
+
+ ReceiverReport rr;
+ rtc::scoped_ptr<RawPacket> packet;
+ const ReceiverReport& parsed() { return parsed_; }
+
+ private:
+ ReceiverReport parsed_;
+};
+
+TEST_F(RtcpPacketReceiverReportTest, Parse) {
+ RtcpCommonHeader header;
+ RtcpParseCommonHeader(kPacket, kPacketLength, &header);
+ EXPECT_TRUE(rr.Parse(header, kPacket + RtcpCommonHeader::kHeaderSizeBytes));
+ const ReceiverReport& parsed = rr;
+
+ EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
+ EXPECT_EQ(1u, parsed.report_blocks().size());
+ const ReportBlock& rb = parsed.report_blocks().front();
+ EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
+ EXPECT_EQ(kFractionLost, rb.fraction_lost());
+ EXPECT_EQ(kCumulativeLost, rb.cumulative_lost());
+ EXPECT_EQ(kExtHighestSeqNum, rb.extended_high_seq_num());
+ EXPECT_EQ(kJitter, rb.jitter());
+ EXPECT_EQ(kLastSr, rb.last_sr());
+ EXPECT_EQ(kDelayLastSr, rb.delay_since_last_sr());
+}
+
+TEST_F(RtcpPacketReceiverReportTest, ParseFailsOnIncorrectSize) {
+ RtcpCommonHeader header;
+ RtcpParseCommonHeader(kPacket, kPacketLength, &header);
+ header.count_or_format++; // Damage the packet.
+ EXPECT_FALSE(rr.Parse(header, kPacket + RtcpCommonHeader::kHeaderSizeBytes));
+}
+
+TEST_F(RtcpPacketReceiverReportTest, Create) {
+ rr.From(kSenderSsrc);
+ ReportBlock rb;
+ rb.To(kRemoteSsrc);
+ rb.WithFractionLost(kFractionLost);
+ rb.WithCumulativeLost(kCumulativeLost);
+ rb.WithExtHighestSeqNum(kExtHighestSeqNum);
+ rb.WithJitter(kJitter);
+ rb.WithLastSr(kLastSr);
+ rb.WithDelayLastSr(kDelayLastSr);
+ rr.WithReportBlock(rb);
+
+ BuildPacket();
+
+ ASSERT_EQ(kPacketLength, packet->Length());
+ EXPECT_EQ(0, memcmp(kPacket, packet->Buffer(), kPacketLength));
+}
+
+TEST_F(RtcpPacketReceiverReportTest, WithoutReportBlocks) {
+ rr.From(kSenderSsrc);
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(kSenderSsrc, parsed().sender_ssrc());
+ EXPECT_EQ(0u, parsed().report_blocks().size());
+}
+
+TEST_F(RtcpPacketReceiverReportTest, WithTwoReportBlocks) {
+ ReportBlock rb1;
+ rb1.To(kRemoteSsrc);
+ ReportBlock rb2;
+ rb2.To(kRemoteSsrc + 1);
+
+ rr.From(kSenderSsrc);
+ EXPECT_TRUE(rr.WithReportBlock(rb1));
+ EXPECT_TRUE(rr.WithReportBlock(rb2));
+
+ BuildPacket();
+ ParsePacket();
+
+ EXPECT_EQ(kSenderSsrc, parsed().sender_ssrc());
+ EXPECT_EQ(2u, parsed().report_blocks().size());
+ EXPECT_EQ(kRemoteSsrc, parsed().report_blocks()[0].source_ssrc());
+ EXPECT_EQ(kRemoteSsrc + 1, parsed().report_blocks()[1].source_ssrc());
+}
+
+TEST_F(RtcpPacketReceiverReportTest, WithTooManyReportBlocks) {
+ rr.From(kSenderSsrc);
+ const size_t kMaxReportBlocks = (1 << 5) - 1;
+ ReportBlock rb;
+ for (size_t i = 0; i < kMaxReportBlocks; ++i) {
+ rb.To(kRemoteSsrc + i);
+ EXPECT_TRUE(rr.WithReportBlock(rb));
+ }
+ rb.To(kRemoteSsrc + kMaxReportBlocks);
+ EXPECT_FALSE(rr.WithReportBlock(rb));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc
new file mode 100644
index 0000000000..4911dbf5b7
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015 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/report_block.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
+//
+// RTCP report block (RFC 3550).
+//
+// 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
+// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+// 0 | SSRC_1 (SSRC of first source) |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 4 | fraction lost | cumulative number of packets lost |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 8 | extended highest sequence number received |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 12 | interarrival jitter |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 16 | last SR (LSR) |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 20 | delay since last SR (DLSR) |
+// 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+ReportBlock::ReportBlock()
+ : source_ssrc_(0),
+ fraction_lost_(0),
+ cumulative_lost_(0),
+ extended_high_seq_num_(0),
+ jitter_(0),
+ last_sr_(0),
+ delay_since_last_sr_(0) {}
+
+bool ReportBlock::Parse(const uint8_t* buffer, size_t length) {
+ RTC_DCHECK(buffer != nullptr);
+ if (length < ReportBlock::kLength) {
+ LOG(LS_ERROR) << "Report Block should be 24 bytes long";
+ return false;
+ }
+
+ source_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[0]);
+ fraction_lost_ = buffer[4];
+ cumulative_lost_ = ByteReader<uint32_t, 3>::ReadBigEndian(&buffer[5]);
+ extended_high_seq_num_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[8]);
+ jitter_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[12]);
+ last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[16]);
+ delay_since_last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[20]);
+
+ return true;
+}
+
+void ReportBlock::Create(uint8_t* buffer) const {
+ // Runtime check should be done while setting cumulative_lost.
+ RTC_DCHECK_LT(cumulative_lost(), (1u << 24)); // Have only 3 bytes for it.
+
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[0], source_ssrc());
+ ByteWriter<uint8_t>::WriteBigEndian(&buffer[4], fraction_lost());
+ ByteWriter<uint32_t, 3>::WriteBigEndian(&buffer[5], cumulative_lost());
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[8], extended_high_seq_num());
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[12], jitter());
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[16], last_sr());
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[20], delay_since_last_sr());
+}
+
+bool ReportBlock::WithCumulativeLost(uint32_t cumulative_lost) {
+ if (cumulative_lost >= (1u << 24)) { // Have only 3 bytes to store it.
+ LOG(LS_WARNING) << "Cumulative lost is too big to fit into Report Block";
+ return false;
+ }
+ cumulative_lost_ = cumulative_lost;
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h
new file mode 100644
index 0000000000..ef99e17297
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 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_REPORT_BLOCK_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_REPORT_BLOCK_H_
+
+#include "webrtc/base/basictypes.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class ReportBlock {
+ public:
+ static const size_t kLength = 24;
+
+ ReportBlock();
+ ~ReportBlock() {}
+
+ bool Parse(const uint8_t* buffer, size_t length);
+
+ // Fills buffer with the ReportBlock.
+ // Consumes ReportBlock::kLength bytes.
+ void Create(uint8_t* buffer) const;
+
+ void To(uint32_t ssrc) { source_ssrc_ = ssrc; }
+ void WithFractionLost(uint8_t fraction_lost) {
+ fraction_lost_ = fraction_lost;
+ }
+ bool WithCumulativeLost(uint32_t cumulative_lost);
+ void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
+ extended_high_seq_num_ = ext_highest_seq_num;
+ }
+ void WithJitter(uint32_t jitter) { jitter_ = jitter; }
+ void WithLastSr(uint32_t last_sr) { last_sr_ = last_sr; }
+ void WithDelayLastSr(uint32_t delay_last_sr) {
+ delay_since_last_sr_ = delay_last_sr;
+ }
+
+ uint32_t source_ssrc() const { return source_ssrc_; }
+ uint8_t fraction_lost() const { return fraction_lost_; }
+ uint32_t cumulative_lost() const { return cumulative_lost_; }
+ uint32_t extended_high_seq_num() const { return extended_high_seq_num_; }
+ uint32_t jitter() const { return jitter_; }
+ uint32_t last_sr() const { return last_sr_; }
+ uint32_t delay_since_last_sr() const { return delay_since_last_sr_; }
+
+ private:
+ uint32_t source_ssrc_;
+ uint8_t fraction_lost_;
+ uint32_t cumulative_lost_;
+ uint32_t extended_high_seq_num_;
+ uint32_t jitter_;
+ uint32_t last_sr_;
+ uint32_t delay_since_last_sr_;
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_REPORT_BLOCK_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc
new file mode 100644
index 0000000000..85bbb404a4
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015 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/report_block.h"
+
+#include <limits>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/random.h"
+
+using webrtc::rtcp::ReportBlock;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kRemoteSsrc = 0x23456789;
+const uint8_t kFractionLost = 55;
+// Use values that are streamed differently LE and BE.
+const uint32_t kCumulativeLost = 0x111213;
+const uint32_t kExtHighestSeqNum = 0x22232425;
+const uint32_t kJitter = 0x33343536;
+const uint32_t kLastSr = 0x44454647;
+const uint32_t kDelayLastSr = 0x55565758;
+const size_t kBufferLength = ReportBlock::kLength;
+
+TEST(RtcpPacketReportBlockTest, ParseChecksLength) {
+ uint8_t buffer[kBufferLength];
+ memset(buffer, 0, sizeof(buffer));
+
+ ReportBlock rb;
+ EXPECT_FALSE(rb.Parse(buffer, kBufferLength - 1));
+ EXPECT_TRUE(rb.Parse(buffer, kBufferLength));
+}
+
+TEST(RtcpPacketReportBlockTest, ParseAnyData) {
+ uint8_t buffer[kBufferLength];
+ // Fill buffer with semi-random data.
+ Random generator(0x256F8A285EC829ull);
+ for (size_t i = 0; i < kBufferLength; ++i)
+ buffer[i] = static_cast<uint8_t>(generator.Rand(0, 0xff));
+
+ ReportBlock rb;
+ EXPECT_TRUE(rb.Parse(buffer, kBufferLength));
+}
+
+TEST(RtcpPacketReportBlockTest, ParseMatchCreate) {
+ ReportBlock rb;
+ rb.To(kRemoteSsrc);
+ rb.WithFractionLost(kFractionLost);
+ rb.WithCumulativeLost(kCumulativeLost);
+ rb.WithExtHighestSeqNum(kExtHighestSeqNum);
+ rb.WithJitter(kJitter);
+ rb.WithLastSr(kLastSr);
+ rb.WithDelayLastSr(kDelayLastSr);
+
+ uint8_t buffer[kBufferLength];
+ rb.Create(buffer);
+
+ ReportBlock parsed;
+ EXPECT_TRUE(parsed.Parse(buffer, kBufferLength));
+
+ EXPECT_EQ(kRemoteSsrc, parsed.source_ssrc());
+ EXPECT_EQ(kFractionLost, parsed.fraction_lost());
+ EXPECT_EQ(kCumulativeLost, parsed.cumulative_lost());
+ EXPECT_EQ(kExtHighestSeqNum, parsed.extended_high_seq_num());
+ EXPECT_EQ(kJitter, parsed.jitter());
+ EXPECT_EQ(kLastSr, parsed.last_sr());
+ EXPECT_EQ(kDelayLastSr, parsed.delay_since_last_sr());
+}
+
+TEST(RtcpPacketReportBlockTest, ValidateCumulativeLost) {
+ const uint32_t kMaxCumulativeLost = 0xffffff;
+ ReportBlock rb;
+ EXPECT_FALSE(rb.WithCumulativeLost(kMaxCumulativeLost + 1));
+ EXPECT_TRUE(rb.WithCumulativeLost(kMaxCumulativeLost));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.cc
new file mode 100644
index 0000000000..db4ae67326
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 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/rrtr.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+namespace webrtc {
+namespace rtcp {
+// Receiver Reference Time Report Block (RFC 3611).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | BT=4 | reserved | block length = 2 |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | NTP timestamp, most significant word |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | NTP timestamp, least significant word |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+void Rrtr::Parse(const uint8_t* buffer) {
+ RTC_DCHECK(buffer[0] == kBlockType);
+ // reserved = buffer[1];
+ RTC_DCHECK(ByteReader<uint16_t>::ReadBigEndian(&buffer[2]) == kBlockLength);
+ uint32_t seconds = ByteReader<uint32_t>::ReadBigEndian(&buffer[4]);
+ uint32_t fraction = ByteReader<uint32_t>::ReadBigEndian(&buffer[8]);
+ ntp_.Set(seconds, fraction);
+}
+
+void Rrtr::Create(uint8_t* buffer) const {
+ const uint8_t kReserved = 0;
+ buffer[0] = kBlockType;
+ buffer[1] = kReserved;
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], kBlockLength);
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[4], ntp_.seconds());
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[8], ntp_.fractions());
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h
new file mode 100644
index 0000000000..3354f61df6
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 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_RRTR_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RRTR_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/system_wrappers/include/ntp_time.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class Rrtr {
+ public:
+ static const uint8_t kBlockType = 4;
+ static const uint16_t kBlockLength = 2;
+ static const size_t kLength = 4 * (kBlockLength + 1); // 12
+
+ Rrtr() {}
+ Rrtr(const Rrtr&) = default;
+ ~Rrtr() {}
+
+ Rrtr& operator=(const Rrtr&) = default;
+
+ void Parse(const uint8_t* buffer);
+
+ // Fills buffer with the Rrtr.
+ // Consumes Rrtr::kLength bytes.
+ void Create(uint8_t* buffer) const;
+
+ void WithNtp(const NtpTime& ntp) { ntp_ = ntp; }
+
+ NtpTime ntp() const { return ntp_; }
+
+ private:
+ NtpTime ntp_;
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RRTR_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr_unittest.cc
new file mode 100644
index 0000000000..6536e06186
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr_unittest.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 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/rrtr.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+using webrtc::rtcp::Rrtr;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kNtpSec = 0x12345678;
+const uint32_t kNtpFrac = 0x23456789;
+const uint8_t kBlock[] = {0x04, 0x00, 0x00, 0x02,
+ 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x45, 0x67, 0x89};
+const size_t kBlockSizeBytes = sizeof(kBlock);
+static_assert(
+ kBlockSizeBytes == Rrtr::kLength,
+ "Size of manually created Rrtr block should match class constant");
+
+TEST(RtcpPacketRrtrTest, Create) {
+ uint8_t buffer[Rrtr::kLength];
+ Rrtr rrtr;
+ rrtr.WithNtp(NtpTime(kNtpSec, kNtpFrac));
+
+ rrtr.Create(buffer);
+ EXPECT_EQ(0, memcmp(buffer, kBlock, kBlockSizeBytes));
+}
+
+TEST(RtcpPacketRrtrTest, Parse) {
+ Rrtr read_rrtr;
+ read_rrtr.Parse(kBlock);
+
+ // Run checks on const object to ensure all accessors have const modifier.
+ const Rrtr& parsed = read_rrtr;
+
+ EXPECT_EQ(kNtpSec, parsed.ntp().seconds());
+ EXPECT_EQ(kNtpFrac, parsed.ntp().fractions());
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.cc
new file mode 100644
index 0000000000..b5571d45a3
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 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/rtpfb.h"
+
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// RFC 4585, Section 6.1: Feedback format.
+//
+// Common packet format:
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| FMT | PT | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 0 | SSRC of packet sender |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 4 | SSRC of media source |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// : Feedback Control Information (FCI) :
+// : :
+
+void Rtpfb::ParseCommonFeedback(const uint8_t* payload) {
+ sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[0]);
+ media_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[4]);
+}
+
+void Rtpfb::CreateCommonFeedback(uint8_t* payload) const {
+ ByteWriter<uint32_t>::WriteBigEndian(&payload[0], sender_ssrc_);
+ ByteWriter<uint32_t>::WriteBigEndian(&payload[4], media_ssrc_);
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h
new file mode 100644
index 0000000000..801aa085c4
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 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_RTPFB_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RTPFB_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// RTPFB: Transport layer feedback message.
+// RFC4585, Section 6.2
+class Rtpfb : public RtcpPacket {
+ public:
+ static const uint8_t kPacketType = 205;
+
+ Rtpfb() : sender_ssrc_(0), media_ssrc_(0) {}
+ virtual ~Rtpfb() {}
+
+ void From(uint32_t ssrc) { sender_ssrc_ = ssrc; }
+ void To(uint32_t ssrc) { media_ssrc_ = ssrc; }
+
+ uint32_t sender_ssrc() const { return sender_ssrc_; }
+ uint32_t media_ssrc() const { return media_ssrc_; }
+
+ protected:
+ static const size_t kCommonFeedbackLength = 8;
+ void ParseCommonFeedback(const uint8_t* payload);
+ void CreateCommonFeedback(uint8_t* payload) const;
+
+ private:
+ uint32_t sender_ssrc_;
+ uint32_t media_ssrc_;
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RTPFB_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.cc
new file mode 100644
index 0000000000..829f3a9db9
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.cc
@@ -0,0 +1,108 @@
+/*
+ * 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/sli.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::RTCPUtility::RtcpCommonHeader;
+
+namespace webrtc {
+namespace rtcp {
+// RFC 4585: Feedback format.
+//
+// Common packet format:
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |V=2|P| FMT | PT | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | SSRC of packet sender |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | SSRC of media source |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// : Feedback Control Information (FCI) :
+// : :
+//
+// Slice loss indication (SLI) (RFC 4585).
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | First | Number | PictureID |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+Sli::Macroblocks::Macroblocks(uint8_t picture_id,
+ uint16_t first,
+ uint16_t number) {
+ RTC_DCHECK_LE(first, 0x1fff);
+ RTC_DCHECK_LE(number, 0x1fff);
+ RTC_DCHECK_LE(picture_id, 0x3f);
+ item_ = (first << 19) | (number << 6) | picture_id;
+}
+
+void Sli::Macroblocks::Parse(const uint8_t* buffer) {
+ item_ = ByteReader<uint32_t>::ReadBigEndian(buffer);
+}
+
+void Sli::Macroblocks::Create(uint8_t* buffer) const {
+ ByteWriter<uint32_t>::WriteBigEndian(buffer, item_);
+}
+
+bool Sli::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
+ RTC_DCHECK(header.packet_type == kPacketType);
+ RTC_DCHECK(header.count_or_format == kFeedbackMessageType);
+
+ if (header.payload_size_bytes <
+ kCommonFeedbackLength + Macroblocks::kLength) {
+ LOG(LS_WARNING) << "Packet is too small to be a valid SLI packet";
+ return false;
+ }
+
+ size_t number_of_items =
+ (header.payload_size_bytes - kCommonFeedbackLength) /
+ Macroblocks::kLength;
+
+ ParseCommonFeedback(payload);
+ items_.resize(number_of_items);
+
+ const uint8_t* next_item = payload + kCommonFeedbackLength;
+ for (Macroblocks& item : items_) {
+ item.Parse(next_item);
+ next_item += Macroblocks::kLength;
+ }
+
+ return true;
+}
+
+bool Sli::Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const {
+ RTC_DCHECK(!items_.empty());
+ while (*index + BlockLength() > max_length) {
+ if (!OnBufferFull(packet, index, callback))
+ return false;
+ }
+ CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
+ index);
+ CreateCommonFeedback(packet + *index);
+ *index += kCommonFeedbackLength;
+ for (const Macroblocks& item : items_) {
+ item.Create(packet + *index);
+ *index += Macroblocks::kLength;
+ }
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h
new file mode 100644
index 0000000000..5d9e6c93e9
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h
@@ -0,0 +1,81 @@
+/*
+ * 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_SLI_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SLI_H_
+
+#include <vector>
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+namespace rtcp {
+
+// Slice loss indication (SLI) (RFC 4585).
+class Sli : public Psfb {
+ public:
+ static const uint8_t kFeedbackMessageType = 2;
+ class Macroblocks {
+ public:
+ static const size_t kLength = 4;
+ Macroblocks() : item_(0) {}
+ Macroblocks(uint8_t picture_id, uint16_t first, uint16_t number);
+ ~Macroblocks() {}
+
+ void Parse(const uint8_t* buffer);
+ void Create(uint8_t* buffer) const;
+
+ uint16_t first() const { return item_ >> 19; }
+ uint16_t number() const { return (item_ >> 6) & 0x1fff; }
+ uint8_t picture_id() const { return (item_ & 0x3f); }
+
+ private:
+ uint32_t item_;
+ };
+
+ Sli() {}
+ virtual ~Sli() {}
+
+ // Parse assumes header is already parsed and validated.
+ bool Parse(const RTCPUtility::RtcpCommonHeader& header,
+ const uint8_t* payload); // Size of the payload is in the header.
+
+ void WithPictureId(uint8_t picture_id,
+ uint16_t first_macroblock = 0,
+ uint16_t number_macroblocks = 0x1fff) {
+ items_.push_back(
+ Macroblocks(picture_id, first_macroblock, number_macroblocks));
+ }
+
+ const std::vector<Macroblocks>& macroblocks() const { return items_; }
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+ size_t BlockLength() const override {
+ return RtcpPacket::kHeaderLength + Psfb::kCommonFeedbackLength +
+ items_.size() * Macroblocks::kLength;
+ }
+
+ std::vector<Macroblocks> items_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(Sli);
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SLI_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli_unittest.cc
new file mode 100644
index 0000000000..c2be16846b
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sli_unittest.cc
@@ -0,0 +1,91 @@
+/*
+ * 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/sli.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAreArray;
+using testing::make_tuple;
+using webrtc::rtcp::RawPacket;
+using webrtc::rtcp::Sli;
+using webrtc::RTCPUtility::RtcpCommonHeader;
+using webrtc::RTCPUtility::RtcpParseCommonHeader;
+
+namespace webrtc {
+namespace {
+
+const uint32_t kSenderSsrc = 0x12345678;
+const uint32_t kRemoteSsrc = 0x23456789;
+
+const uint8_t kPictureId = 0x3f;
+const uint16_t kFirstMb = 0x1e61;
+const uint16_t kNumberOfMb = 0x1a0a;
+const uint32_t kSliItem = (static_cast<uint32_t>(kFirstMb) << 19) |
+ (static_cast<uint32_t>(kNumberOfMb) << 6) |
+ static_cast<uint32_t>(kPictureId);
+
+// Manually created Sli packet matching constants above.
+const uint8_t kPacket[] = {0x82, 206, 0x00, 0x03,
+ 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x45, 0x67, 0x89,
+ (kSliItem >> 24) & 0xff,
+ (kSliItem >> 16) & 0xff,
+ (kSliItem >> 8) & 0xff,
+ kSliItem & 0xff};
+const size_t kPacketLength = sizeof(kPacket);
+
+bool ParseSli(const uint8_t* buffer, size_t length, Sli* sli) {
+ RtcpCommonHeader header;
+ EXPECT_TRUE(RtcpParseCommonHeader(buffer, length, &header));
+ EXPECT_EQ(length, header.BlockSize());
+ return sli->Parse(header, buffer + RtcpCommonHeader::kHeaderSizeBytes);
+}
+
+TEST(RtcpPacketSliTest, Create) {
+ Sli sli;
+ sli.From(kSenderSsrc);
+ sli.To(kRemoteSsrc);
+ sli.WithPictureId(kPictureId, kFirstMb, kNumberOfMb);
+
+ rtc::scoped_ptr<RawPacket> packet(sli.Build());
+
+ EXPECT_THAT(make_tuple(packet->Buffer(), packet->Length()),
+ ElementsAreArray(kPacket));
+}
+
+TEST(RtcpPacketSliTest, Parse) {
+ Sli mutable_parsed;
+ EXPECT_TRUE(ParseSli(kPacket, kPacketLength, &mutable_parsed));
+ const Sli& parsed = mutable_parsed; // Read values from constant object.
+
+ EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
+ EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc());
+ EXPECT_EQ(1u, parsed.macroblocks().size());
+ EXPECT_EQ(kFirstMb, parsed.macroblocks()[0].first());
+ EXPECT_EQ(kNumberOfMb, parsed.macroblocks()[0].number());
+ EXPECT_EQ(kPictureId, parsed.macroblocks()[0].picture_id());
+}
+
+TEST(RtcpPacketSliTest, ParseFailsOnTooSmallPacket) {
+ Sli sli;
+ sli.From(kSenderSsrc);
+ sli.To(kRemoteSsrc);
+ sli.WithPictureId(kPictureId, kFirstMb, kNumberOfMb);
+
+ rtc::scoped_ptr<RawPacket> packet(sli.Build());
+ packet->MutableBuffer()[3]--; // Decrease size by 1 word (4 bytes).
+
+ EXPECT_FALSE(ParseSli(packet->Buffer(), packet->Length() - 4, &sli));
+}
+
+} // namespace
+} // namespace webrtc
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 0000000000..fd0219cf82
--- /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 0000000000..82bf9dd9e9
--- /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 0000000000..32d64a97b4
--- /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/tmmbr.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc
new file mode 100644
index 0000000000..4df167de79
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc
@@ -0,0 +1,105 @@
+/*
+ * 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/tmmbr.h"
+
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+using webrtc::RTCPUtility::PT_RTPFB;
+using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR;
+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 Request (TMMBR) (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 CreateTmmbr(const RTCPPacketRTPFBTMMBR& tmmbr,
+ const RTCPPacketRTPFBTMMBRItem& tmmbr_item,
+ uint8_t* buffer,
+ size_t* pos) {
+ AssignUWord32(buffer, pos, tmmbr.SenderSSRC);
+ AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0);
+ CreateTmmbrItem(tmmbr_item, buffer, pos);
+}
+} // namespace
+
+bool Tmmbr::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 = 3;
+ CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index);
+ CreateTmmbr(tmmbr_, tmmbr_item_, packet, index);
+ return true;
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h
new file mode 100644
index 0000000000..84a4180ad3
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h
@@ -0,0 +1,64 @@
+/*
+ * 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_TMMBR_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TMMBR_H_
+
+#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 Request (TMMBR) (RFC 5104).
+class Tmmbr : public RtcpPacket {
+ public:
+ Tmmbr() : RtcpPacket() {
+ memset(&tmmbr_, 0, sizeof(tmmbr_));
+ memset(&tmmbr_item_, 0, sizeof(tmmbr_item_));
+ }
+
+ virtual ~Tmmbr() {}
+
+ void From(uint32_t ssrc) {
+ tmmbr_.SenderSSRC = ssrc;
+ }
+ void To(uint32_t ssrc) {
+ tmmbr_item_.SSRC = ssrc;
+ }
+ void WithBitrateKbps(uint32_t bitrate_kbps) {
+ tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps;
+ }
+ void WithOverhead(uint16_t overhead) {
+ assert(overhead <= 0x1ff);
+ tmmbr_item_.MeasuredOverhead = overhead;
+ }
+
+ protected:
+ bool Create(uint8_t* packet,
+ size_t* index,
+ size_t max_length,
+ RtcpPacket::PacketReadyCallback* callback) const override;
+
+ private:
+ size_t BlockLength() const {
+ const size_t kFciLen = 8;
+ return kCommonFbFmtLength + kFciLen;
+ }
+
+ RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_;
+ RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr);
+};
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TMMBR_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr_unittest.cc
new file mode 100644
index 0000000000..6d71caa251
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr_unittest.cc
@@ -0,0 +1,43 @@
+/*
+ * 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/tmmbr.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::Tmmbr;
+using webrtc::test::RtcpPacketParser;
+
+namespace webrtc {
+const uint32_t kSenderSsrc = 0x12345678;
+const uint32_t kRemoteSsrc = 0x23456789;
+
+TEST(RtcpPacketTest, Tmmbr) {
+ Tmmbr tmmbr;
+ tmmbr.From(kSenderSsrc);
+ tmmbr.To(kRemoteSsrc);
+ tmmbr.WithBitrateKbps(312);
+ tmmbr.WithOverhead(60);
+
+ rtc::scoped_ptr<RawPacket> packet(tmmbr.Build());
+ RtcpPacketParser parser;
+ parser.Parse(packet->Buffer(), packet->Length());
+ EXPECT_EQ(1, parser.tmmbr()->num_packets());
+ EXPECT_EQ(kSenderSsrc, parser.tmmbr()->Ssrc());
+ EXPECT_EQ(1, parser.tmmbr_item()->num_packets());
+ EXPECT_EQ(312U, parser.tmmbr_item()->BitrateKbps());
+ EXPECT_EQ(60U, parser.tmmbr_item()->Overhead());
+}
+
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h
index 4cc1f38479..ad6fd166f2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h
@@ -15,7 +15,7 @@
#include <vector>
#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
namespace webrtc {
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.cc
new file mode 100644
index 0000000000..a79d48e1ca
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 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/voip_metric.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
+namespace webrtc {
+namespace rtcp {
+// VoIP Metrics Report Block (RFC 3611).
+//
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 0 | BT=7 | reserved | block length = 8 |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 4 | SSRC of source |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 8 | loss rate | discard rate | burst density | gap density |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 12 | burst duration | gap duration |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 16 | round trip delay | end system delay |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 20 | signal level | noise level | RERL | Gmin |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 24 | R factor | ext. R factor | MOS-LQ | MOS-CQ |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 28 | RX config | reserved | JB nominal |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 32 | JB maximum | JB abs max |
+// 36 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+VoipMetric::VoipMetric() : ssrc_(0) {
+ memset(&voip_metric_, 0, sizeof(voip_metric_));
+}
+
+void VoipMetric::Parse(const uint8_t* buffer) {
+ RTC_DCHECK(buffer[0] == kBlockType);
+ // reserved = buffer[1];
+ RTC_DCHECK(ByteReader<uint16_t>::ReadBigEndian(&buffer[2]) == kBlockLength);
+ ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[4]);
+ voip_metric_.lossRate = buffer[8];
+ voip_metric_.discardRate = buffer[9];
+ voip_metric_.burstDensity = buffer[10];
+ voip_metric_.gapDensity = buffer[11];
+ voip_metric_.burstDuration = ByteReader<uint16_t>::ReadBigEndian(&buffer[12]);
+ voip_metric_.gapDuration = ByteReader<uint16_t>::ReadBigEndian(&buffer[14]);
+ voip_metric_.roundTripDelay =
+ ByteReader<uint16_t>::ReadBigEndian(&buffer[16]);
+ voip_metric_.endSystemDelay =
+ ByteReader<uint16_t>::ReadBigEndian(&buffer[18]);
+ voip_metric_.signalLevel = buffer[20];
+ voip_metric_.noiseLevel = buffer[21];
+ voip_metric_.RERL = buffer[22];
+ voip_metric_.Gmin = buffer[23];
+ voip_metric_.Rfactor = buffer[24];
+ voip_metric_.extRfactor = buffer[25];
+ voip_metric_.MOSLQ = buffer[26];
+ voip_metric_.MOSCQ = buffer[27];
+ voip_metric_.RXconfig = buffer[28];
+ // reserved = buffer[29];
+ voip_metric_.JBnominal = ByteReader<uint16_t>::ReadBigEndian(&buffer[30]);
+ voip_metric_.JBmax = ByteReader<uint16_t>::ReadBigEndian(&buffer[32]);
+ voip_metric_.JBabsMax = ByteReader<uint16_t>::ReadBigEndian(&buffer[34]);
+}
+
+void VoipMetric::Create(uint8_t* buffer) const {
+ const uint8_t kReserved = 0;
+ buffer[0] = kBlockType;
+ buffer[1] = kReserved;
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], kBlockLength);
+ ByteWriter<uint32_t>::WriteBigEndian(&buffer[4], ssrc_);
+ buffer[8] = voip_metric_.lossRate;
+ buffer[9] = voip_metric_.discardRate;
+ buffer[10] = voip_metric_.burstDensity;
+ buffer[11] = voip_metric_.gapDensity;
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[12], voip_metric_.burstDuration);
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[14], voip_metric_.gapDuration);
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[16],
+ voip_metric_.roundTripDelay);
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[18],
+ voip_metric_.endSystemDelay);
+ buffer[20] = voip_metric_.signalLevel;
+ buffer[21] = voip_metric_.noiseLevel;
+ buffer[22] = voip_metric_.RERL;
+ buffer[23] = voip_metric_.Gmin;
+ buffer[24] = voip_metric_.Rfactor;
+ buffer[25] = voip_metric_.extRfactor;
+ buffer[26] = voip_metric_.MOSLQ;
+ buffer[27] = voip_metric_.MOSCQ;
+ buffer[28] = voip_metric_.RXconfig;
+ buffer[29] = kReserved;
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[30], voip_metric_.JBnominal);
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[32], voip_metric_.JBmax);
+ ByteWriter<uint16_t>::WriteBigEndian(&buffer[34], voip_metric_.JBabsMax);
+}
+
+} // namespace rtcp
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h
new file mode 100644
index 0000000000..9e3e41995a
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015 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_VOIP_METRIC_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_VOIP_METRIC_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/modules/include/module_common_types.h"
+
+namespace webrtc {
+namespace rtcp {
+
+class VoipMetric {
+ public:
+ static const uint8_t kBlockType = 7;
+ static const uint16_t kBlockLength = 8;
+ static const size_t kLength = 4 * (kBlockLength + 1); // 36
+ VoipMetric();
+ VoipMetric(const VoipMetric&) = default;
+ ~VoipMetric() {}
+
+ VoipMetric& operator=(const VoipMetric&) = default;
+
+ void Parse(const uint8_t* buffer);
+
+ // Fills buffer with the VoipMetric.
+ // Consumes VoipMetric::kLength bytes.
+ void Create(uint8_t* buffer) const;
+
+ void To(uint32_t ssrc) { ssrc_ = ssrc; }
+ void WithVoipMetric(const RTCPVoIPMetric& voip_metric) {
+ voip_metric_ = voip_metric;
+ }
+
+ uint32_t ssrc() const { return ssrc_; }
+ const RTCPVoIPMetric& voip_metric() const { return voip_metric_; }
+
+ private:
+ uint32_t ssrc_;
+ RTCPVoIPMetric voip_metric_;
+};
+
+} // namespace rtcp
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_VOIP_METRIC_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric_unittest.cc
new file mode 100644
index 0000000000..44c82d67a9
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric_unittest.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015 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/voip_metric.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace webrtc {
+namespace rtcp {
+namespace {
+
+const uint32_t kRemoteSsrc = 0x23456789;
+const uint8_t kBlock[] = {0x07, 0x00, 0x00, 0x08, 0x23, 0x45, 0x67, 0x89,
+ 0x01, 0x02, 0x03, 0x04, 0x11, 0x12, 0x22, 0x23,
+ 0x33, 0x34, 0x44, 0x45, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x55, 0x56,
+ 0x66, 0x67, 0x77, 0x78};
+const size_t kBlockSizeBytes = sizeof(kBlock);
+static_assert(
+ kBlockSizeBytes == VoipMetric::kLength,
+ "Size of manually created Voip Metric block should match class constant");
+
+TEST(RtcpPacketVoipMetricTest, Create) {
+ uint8_t buffer[VoipMetric::kLength];
+ RTCPVoIPMetric metric;
+ metric.lossRate = 1;
+ metric.discardRate = 2;
+ metric.burstDensity = 3;
+ metric.gapDensity = 4;
+ metric.burstDuration = 0x1112;
+ metric.gapDuration = 0x2223;
+ metric.roundTripDelay = 0x3334;
+ metric.endSystemDelay = 0x4445;
+ metric.signalLevel = 5;
+ metric.noiseLevel = 6;
+ metric.RERL = 7;
+ metric.Gmin = 8;
+ metric.Rfactor = 9;
+ metric.extRfactor = 10;
+ metric.MOSLQ = 11;
+ metric.MOSCQ = 12;
+ metric.RXconfig = 13;
+ metric.JBnominal = 0x5556;
+ metric.JBmax = 0x6667;
+ metric.JBabsMax = 0x7778;
+ VoipMetric metric_block;
+ metric_block.To(kRemoteSsrc);
+ metric_block.WithVoipMetric(metric);
+
+ metric_block.Create(buffer);
+ EXPECT_EQ(0, memcmp(buffer, kBlock, kBlockSizeBytes));
+}
+
+TEST(RtcpPacketVoipMetricTest, Parse) {
+ VoipMetric read_metric;
+ read_metric.Parse(kBlock);
+
+ // Run checks on const object to ensure all accessors have const modifier.
+ const VoipMetric& parsed = read_metric;
+
+ EXPECT_EQ(kRemoteSsrc, parsed.ssrc());
+ EXPECT_EQ(1, parsed.voip_metric().lossRate);
+ EXPECT_EQ(2, parsed.voip_metric().discardRate);
+ EXPECT_EQ(3, parsed.voip_metric().burstDensity);
+ EXPECT_EQ(4, parsed.voip_metric().gapDensity);
+ EXPECT_EQ(0x1112, parsed.voip_metric().burstDuration);
+ EXPECT_EQ(0x2223, parsed.voip_metric().gapDuration);
+ EXPECT_EQ(0x3334, parsed.voip_metric().roundTripDelay);
+ EXPECT_EQ(0x4445, parsed.voip_metric().endSystemDelay);
+ EXPECT_EQ(5, parsed.voip_metric().signalLevel);
+ EXPECT_EQ(6, parsed.voip_metric().noiseLevel);
+ EXPECT_EQ(7, parsed.voip_metric().RERL);
+ EXPECT_EQ(8, parsed.voip_metric().Gmin);
+ EXPECT_EQ(9, parsed.voip_metric().Rfactor);
+ EXPECT_EQ(10, parsed.voip_metric().extRfactor);
+ EXPECT_EQ(11, parsed.voip_metric().MOSLQ);
+ EXPECT_EQ(12, parsed.voip_metric().MOSCQ);
+ EXPECT_EQ(13, parsed.voip_metric().RXconfig);
+ EXPECT_EQ(0x5556, parsed.voip_metric().JBnominal);
+ EXPECT_EQ(0x6667, parsed.voip_metric().JBmax);
+ EXPECT_EQ(0x7778, parsed.voip_metric().JBabsMax);
+}
+
+} // namespace
+} // namespace rtcp
+} // 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 77520b633b..22f61f5cab 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
@@ -14,6 +14,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "webrtc/test/rtcp_packet_parser.h"
using ::testing::ElementsAre;
@@ -21,23 +24,15 @@ using ::testing::ElementsAre;
using webrtc::rtcp::App;
using webrtc::rtcp::Bye;
using webrtc::rtcp::Dlrr;
-using webrtc::rtcp::Empty;
using webrtc::rtcp::Fir;
-using webrtc::rtcp::Ij;
-using webrtc::rtcp::Nack;
-using webrtc::rtcp::Pli;
-using webrtc::rtcp::Sdes;
-using webrtc::rtcp::SenderReport;
-using webrtc::rtcp::Sli;
using webrtc::rtcp::RawPacket;
using webrtc::rtcp::ReceiverReport;
using webrtc::rtcp::Remb;
using webrtc::rtcp::ReportBlock;
using webrtc::rtcp::Rpsi;
using webrtc::rtcp::Rrtr;
+using webrtc::rtcp::Sdes;
using webrtc::rtcp::SenderReport;
-using webrtc::rtcp::Tmmbn;
-using webrtc::rtcp::Tmmbr;
using webrtc::rtcp::VoipMetric;
using webrtc::rtcp::Xr;
using webrtc::test::RtcpPacketParser;
@@ -47,81 +42,6 @@ namespace webrtc {
const uint32_t kSenderSsrc = 0x12345678;
const uint32_t kRemoteSsrc = 0x23456789;
-TEST(RtcpPacketTest, Rr) {
- ReceiverReport rr;
- rr.From(kSenderSsrc);
-
- rtc::scoped_ptr<RawPacket> packet(rr.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc());
- EXPECT_EQ(0, parser.report_block()->num_packets());
-}
-
-TEST(RtcpPacketTest, RrWithOneReportBlock) {
- ReportBlock rb;
- rb.To(kRemoteSsrc);
- rb.WithFractionLost(55);
- rb.WithCumulativeLost(0x111111);
- rb.WithExtHighestSeqNum(0x22222222);
- rb.WithJitter(0x33333333);
- rb.WithLastSr(0x44444444);
- rb.WithDelayLastSr(0x55555555);
-
- ReceiverReport rr;
- rr.From(kSenderSsrc);
- EXPECT_TRUE(rr.WithReportBlock(rb));
-
- rtc::scoped_ptr<RawPacket> packet(rr.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc());
- EXPECT_EQ(1, parser.report_block()->num_packets());
- EXPECT_EQ(kRemoteSsrc, parser.report_block()->Ssrc());
- EXPECT_EQ(55U, parser.report_block()->FractionLost());
- EXPECT_EQ(0x111111U, parser.report_block()->CumPacketLost());
- EXPECT_EQ(0x22222222U, parser.report_block()->ExtHighestSeqNum());
- EXPECT_EQ(0x33333333U, parser.report_block()->Jitter());
- EXPECT_EQ(0x44444444U, parser.report_block()->LastSr());
- EXPECT_EQ(0x55555555U, parser.report_block()->DelayLastSr());
-}
-
-TEST(RtcpPacketTest, RrWithTwoReportBlocks) {
- ReportBlock rb1;
- rb1.To(kRemoteSsrc);
- ReportBlock rb2;
- rb2.To(kRemoteSsrc + 1);
-
- ReceiverReport rr;
- rr.From(kSenderSsrc);
- EXPECT_TRUE(rr.WithReportBlock(rb1));
- EXPECT_TRUE(rr.WithReportBlock(rb2));
-
- rtc::scoped_ptr<RawPacket> packet(rr.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc());
- EXPECT_EQ(2, parser.report_block()->num_packets());
- EXPECT_EQ(1, parser.report_blocks_per_ssrc(kRemoteSsrc));
- EXPECT_EQ(1, parser.report_blocks_per_ssrc(kRemoteSsrc + 1));
-}
-
-TEST(RtcpPacketTest, RrWithTooManyReportBlocks) {
- ReceiverReport rr;
- rr.From(kSenderSsrc);
- const int kMaxReportBlocks = (1 << 5) - 1;
- ReportBlock rb;
- for (int i = 0; i < kMaxReportBlocks; ++i) {
- rb.To(kRemoteSsrc + i);
- EXPECT_TRUE(rr.WithReportBlock(rb));
- }
- rb.To(kRemoteSsrc + kMaxReportBlocks);
- EXPECT_FALSE(rr.WithReportBlock(rb));
-}
-
TEST(RtcpPacketTest, Sr) {
SenderReport sr;
sr.From(kSenderSsrc);
@@ -196,50 +116,6 @@ TEST(RtcpPacketTest, SrWithTooManyReportBlocks) {
EXPECT_FALSE(sr.WithReportBlock(rb));
}
-TEST(RtcpPacketTest, IjNoItem) {
- Ij ij;
-
- rtc::scoped_ptr<RawPacket> packet(ij.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.ij()->num_packets());
- EXPECT_EQ(0, parser.ij_item()->num_packets());
-}
-
-TEST(RtcpPacketTest, IjOneItem) {
- Ij ij;
- EXPECT_TRUE(ij.WithJitterItem(0x11111111));
-
- rtc::scoped_ptr<RawPacket> packet(ij.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.ij()->num_packets());
- EXPECT_EQ(1, parser.ij_item()->num_packets());
- EXPECT_EQ(0x11111111U, parser.ij_item()->Jitter());
-}
-
-TEST(RtcpPacketTest, IjTwoItems) {
- Ij ij;
- EXPECT_TRUE(ij.WithJitterItem(0x11111111));
- EXPECT_TRUE(ij.WithJitterItem(0x22222222));
-
- rtc::scoped_ptr<RawPacket> packet(ij.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.ij()->num_packets());
- EXPECT_EQ(2, parser.ij_item()->num_packets());
- EXPECT_EQ(0x22222222U, parser.ij_item()->Jitter());
-}
-
-TEST(RtcpPacketTest, IjTooManyItems) {
- Ij ij;
- const int kMaxIjItems = (1 << 5) - 1;
- for (int i = 0; i < kMaxIjItems; ++i) {
- EXPECT_TRUE(ij.WithJitterItem(i));
- }
- EXPECT_FALSE(ij.WithJitterItem(kMaxIjItems));
-}
-
TEST(RtcpPacketTest, AppWithNoData) {
App app;
app.WithSubType(30);
@@ -339,140 +215,6 @@ TEST(RtcpPacketTest, CnameItemWithEmptyString) {
EXPECT_EQ("", parser.sdes_chunk()->Cname());
}
-TEST(RtcpPacketTest, Pli) {
- Pli pli;
- pli.From(kSenderSsrc);
- pli.To(kRemoteSsrc);
-
- rtc::scoped_ptr<RawPacket> packet(pli.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.pli()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.pli()->Ssrc());
- EXPECT_EQ(kRemoteSsrc, parser.pli()->MediaSsrc());
-}
-
-TEST(RtcpPacketTest, Sli) {
- const uint16_t kFirstMb = 7777;
- const uint16_t kNumberOfMb = 6666;
- const uint8_t kPictureId = 60;
- Sli sli;
- sli.From(kSenderSsrc);
- sli.To(kRemoteSsrc);
- sli.WithFirstMb(kFirstMb);
- sli.WithNumberOfMb(kNumberOfMb);
- sli.WithPictureId(kPictureId);
-
- rtc::scoped_ptr<RawPacket> packet(sli.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.sli()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.sli()->Ssrc());
- EXPECT_EQ(kRemoteSsrc, parser.sli()->MediaSsrc());
- EXPECT_EQ(1, parser.sli_item()->num_packets());
- EXPECT_EQ(kFirstMb, parser.sli_item()->FirstMb());
- EXPECT_EQ(kNumberOfMb, parser.sli_item()->NumberOfMb());
- EXPECT_EQ(kPictureId, parser.sli_item()->PictureId());
-}
-
-TEST(RtcpPacketTest, Nack) {
- Nack nack;
- const uint16_t kList[] = {0, 1, 3, 8, 16};
- const uint16_t kListLength = sizeof(kList) / sizeof(kList[0]);
- nack.From(kSenderSsrc);
- nack.To(kRemoteSsrc);
- nack.WithList(kList, kListLength);
- rtc::scoped_ptr<RawPacket> packet(nack.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.nack()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.nack()->Ssrc());
- EXPECT_EQ(kRemoteSsrc, parser.nack()->MediaSsrc());
- EXPECT_EQ(1, parser.nack_item()->num_packets());
- std::vector<uint16_t> seqs = parser.nack_item()->last_nack_list();
- EXPECT_EQ(kListLength, seqs.size());
- for (size_t i = 0; i < kListLength; ++i) {
- EXPECT_EQ(kList[i], seqs[i]);
- }
-}
-
-TEST(RtcpPacketTest, NackWithWrap) {
- Nack nack;
- const uint16_t kList[] = {65500, 65516, 65534, 65535, 0, 1, 3, 20, 100};
- const uint16_t kListLength = sizeof(kList) / sizeof(kList[0]);
- nack.From(kSenderSsrc);
- nack.To(kRemoteSsrc);
- nack.WithList(kList, kListLength);
- rtc::scoped_ptr<RawPacket> packet(nack.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.nack()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.nack()->Ssrc());
- EXPECT_EQ(kRemoteSsrc, parser.nack()->MediaSsrc());
- EXPECT_EQ(4, parser.nack_item()->num_packets());
- std::vector<uint16_t> seqs = parser.nack_item()->last_nack_list();
- EXPECT_EQ(kListLength, seqs.size());
- for (size_t i = 0; i < kListLength; ++i) {
- EXPECT_EQ(kList[i], seqs[i]);
- }
-}
-
-TEST(RtcpPacketTest, NackFragmented) {
- Nack nack;
- const uint16_t kList[] = {1, 100, 200, 300, 400};
- const uint16_t kListLength = sizeof(kList) / sizeof(kList[0]);
- nack.From(kSenderSsrc);
- nack.To(kRemoteSsrc);
- nack.WithList(kList, kListLength);
-
- class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
- public:
- void OnPacketReady(uint8_t* data, size_t length) override {
- ++packets_created_;
- RtcpPacketParser parser;
- parser.Parse(data, length);
- EXPECT_EQ(1, parser.nack()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.nack()->Ssrc());
- EXPECT_EQ(kRemoteSsrc, parser.nack()->MediaSsrc());
- switch (packets_created_) {
- case 1:
- EXPECT_THAT(parser.nack_item()->last_nack_list(),
- ElementsAre(1, 100, 200));
- break;
- case 2:
- EXPECT_THAT(parser.nack_item()->last_nack_list(),
- ElementsAre(300, 400));
- break;
- default:
- ADD_FAILURE() << "Unexpected packet count: " << packets_created_;
- }
- }
- int packets_created_ = 0;
- } verifier;
- const size_t kBufferSize = 12 + (3 * 4); // Fits common header + 3 nack items
- uint8_t buffer[kBufferSize];
- EXPECT_TRUE(nack.BuildExternalBuffer(buffer, kBufferSize, &verifier));
- EXPECT_EQ(2, verifier.packets_created_);
-}
-
-TEST(RtcpPacketTest, NackWithTooSmallBuffer) {
- const uint16_t kList[] = {1};
- const size_t kMinNackBlockSize = 16;
- Nack nack;
- nack.From(kSenderSsrc);
- nack.To(kRemoteSsrc);
- nack.WithList(kList, 1);
- class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
- public:
- void OnPacketReady(uint8_t* data, size_t length) override {
- ADD_FAILURE() << "Buffer should be too small.";
- }
- } verifier;
- uint8_t buffer[kMinNackBlockSize - 1];
- EXPECT_FALSE(
- nack.BuildExternalBuffer(buffer, kMinNackBlockSize - 1, &verifier));
-}
-
TEST(RtcpPacketTest, Rpsi) {
Rpsi rpsi;
// 1000001 (7 bits = 1 byte in native string).
@@ -562,127 +304,6 @@ TEST(RtcpPacketTest, Fir) {
EXPECT_EQ(123U, parser.fir_item()->SeqNum());
}
-TEST(RtcpPacketTest, AppendPacket) {
- Fir fir;
- ReportBlock rb;
- ReceiverReport rr;
- rr.From(kSenderSsrc);
- EXPECT_TRUE(rr.WithReportBlock(rb));
- rr.Append(&fir);
-
- rtc::scoped_ptr<RawPacket> packet(rr.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc());
- EXPECT_EQ(1, parser.report_block()->num_packets());
- EXPECT_EQ(1, parser.fir()->num_packets());
-}
-
-TEST(RtcpPacketTest, AppendPacketOnEmpty) {
- Empty empty;
- ReceiverReport rr;
- rr.From(kSenderSsrc);
- empty.Append(&rr);
-
- rtc::scoped_ptr<RawPacket> packet(empty.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(0, parser.report_block()->num_packets());
-}
-
-TEST(RtcpPacketTest, AppendPacketWithOwnAppendedPacket) {
- Fir fir;
- Bye bye;
- ReportBlock rb;
-
- ReceiverReport rr;
- EXPECT_TRUE(rr.WithReportBlock(rb));
- rr.Append(&fir);
-
- SenderReport sr;
- sr.Append(&bye);
- sr.Append(&rr);
-
- rtc::scoped_ptr<RawPacket> packet(sr.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.sender_report()->num_packets());
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(1, parser.report_block()->num_packets());
- EXPECT_EQ(1, parser.bye()->num_packets());
- EXPECT_EQ(1, parser.fir()->num_packets());
-}
-
-TEST(RtcpPacketTest, Bye) {
- Bye bye;
- bye.From(kSenderSsrc);
-
- rtc::scoped_ptr<RawPacket> packet(bye.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.bye()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.bye()->Ssrc());
-}
-
-TEST(RtcpPacketTest, ByeWithCsrcs) {
- Fir fir;
- Bye bye;
- bye.From(kSenderSsrc);
- EXPECT_TRUE(bye.WithCsrc(0x22222222));
- EXPECT_TRUE(bye.WithCsrc(0x33333333));
- bye.Append(&fir);
-
- rtc::scoped_ptr<RawPacket> packet(bye.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.bye()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.bye()->Ssrc());
- EXPECT_EQ(1, parser.fir()->num_packets());
-}
-
-TEST(RtcpPacketTest, ByeWithTooManyCsrcs) {
- Bye bye;
- bye.From(kSenderSsrc);
- const int kMaxCsrcs = (1 << 5) - 2; // 5 bit len, first item is sender SSRC.
- for (int i = 0; i < kMaxCsrcs; ++i) {
- EXPECT_TRUE(bye.WithCsrc(i));
- }
- EXPECT_FALSE(bye.WithCsrc(kMaxCsrcs));
-}
-
-TEST(RtcpPacketTest, BuildWithInputBuffer) {
- Fir fir;
- ReportBlock rb;
- ReceiverReport rr;
- rr.From(kSenderSsrc);
- EXPECT_TRUE(rr.WithReportBlock(rb));
- rr.Append(&fir);
-
- const size_t kRrLength = 8;
- const size_t kReportBlockLength = 24;
- const size_t kFirLength = 20;
-
- class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
- public:
- void OnPacketReady(uint8_t* data, size_t length) override {
- RtcpPacketParser parser;
- parser.Parse(data, length);
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(1, parser.report_block()->num_packets());
- EXPECT_EQ(1, parser.fir()->num_packets());
- ++packets_created_;
- }
-
- int packets_created_ = 0;
- } verifier;
- const size_t kBufferSize = kRrLength + kReportBlockLength + kFirLength;
- uint8_t buffer[kBufferSize];
- EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
- EXPECT_EQ(1, verifier.packets_created_);
-}
-
TEST(RtcpPacketTest, BuildWithTooSmallBuffer) {
ReportBlock rb;
ReceiverReport rr;
@@ -703,47 +324,6 @@ TEST(RtcpPacketTest, BuildWithTooSmallBuffer) {
EXPECT_FALSE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
}
-TEST(RtcpPacketTest, BuildWithTooSmallBuffer_FragmentedSend) {
- Fir fir;
- ReportBlock rb;
- ReceiverReport rr;
- rr.From(kSenderSsrc);
- EXPECT_TRUE(rr.WithReportBlock(rb));
- rr.Append(&fir);
-
- const size_t kRrLength = 8;
- const size_t kReportBlockLength = 24;
-
- class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
- public:
- void OnPacketReady(uint8_t* data, size_t length) override {
- RtcpPacketParser parser;
- parser.Parse(data, length);
- switch (packets_created_++) {
- case 0:
- EXPECT_EQ(1, parser.receiver_report()->num_packets());
- EXPECT_EQ(1, parser.report_block()->num_packets());
- EXPECT_EQ(0, parser.fir()->num_packets());
- break;
- case 1:
- EXPECT_EQ(0, parser.receiver_report()->num_packets());
- EXPECT_EQ(0, parser.report_block()->num_packets());
- EXPECT_EQ(1, parser.fir()->num_packets());
- break;
- default:
- ADD_FAILURE() << "OnPacketReady not expected to be called "
- << packets_created_ << " times.";
- }
- }
-
- int packets_created_ = 0;
- } verifier;
- const size_t kBufferSize = kRrLength + kReportBlockLength;
- uint8_t buffer[kBufferSize];
- EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
- EXPECT_EQ(2, verifier.packets_created_);
-}
-
TEST(RtcpPacketTest, Remb) {
Remb remb;
remb.From(kSenderSsrc);
@@ -765,81 +345,6 @@ TEST(RtcpPacketTest, Remb) {
EXPECT_EQ(kRemoteSsrc + 2, ssrcs[2]);
}
-TEST(RtcpPacketTest, Tmmbr) {
- Tmmbr tmmbr;
- tmmbr.From(kSenderSsrc);
- tmmbr.To(kRemoteSsrc);
- tmmbr.WithBitrateKbps(312);
- tmmbr.WithOverhead(60);
-
- rtc::scoped_ptr<RawPacket> packet(tmmbr.Build());
- RtcpPacketParser parser;
- parser.Parse(packet->Buffer(), packet->Length());
- EXPECT_EQ(1, parser.tmmbr()->num_packets());
- EXPECT_EQ(kSenderSsrc, parser.tmmbr()->Ssrc());
- EXPECT_EQ(1, parser.tmmbr_item()->num_packets());
- EXPECT_EQ(312U, parser.tmmbr_item()->BitrateKbps());
- 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);
@@ -853,8 +358,7 @@ TEST(RtcpPacketTest, XrWithNoReportBlocks) {
TEST(RtcpPacketTest, XrWithRrtr) {
Rrtr rrtr;
- rrtr.WithNtpSec(0x11111111);
- rrtr.WithNtpFrac(0x22222222);
+ rrtr.WithNtp(NtpTime(0x11111111, 0x22222222));
Xr xr;
xr.From(kSenderSsrc);
EXPECT_TRUE(xr.WithRrtr(&rrtr));
@@ -871,11 +375,9 @@ TEST(RtcpPacketTest, XrWithRrtr) {
TEST(RtcpPacketTest, XrWithTwoRrtrBlocks) {
Rrtr rrtr1;
- rrtr1.WithNtpSec(0x11111111);
- rrtr1.WithNtpFrac(0x22222222);
+ rrtr1.WithNtp(NtpTime(0x11111111, 0x22222222));
Rrtr rrtr2;
- rrtr2.WithNtpSec(0x33333333);
- rrtr2.WithNtpFrac(0x44444444);
+ rrtr2.WithNtp(NtpTime(0x33333333, 0x44444444));
Xr xr;
xr.From(kSenderSsrc);
EXPECT_TRUE(xr.WithRrtr(&rrtr1));
@@ -967,32 +469,33 @@ TEST(RtcpPacketTest, XrWithTwoDlrrBlocks) {
}
TEST(RtcpPacketTest, XrWithVoipMetric) {
- VoipMetric metric;
- metric.To(kRemoteSsrc);
- metric.LossRate(1);
- metric.DiscardRate(2);
- metric.BurstDensity(3);
- metric.GapDensity(4);
- metric.BurstDuration(0x1111);
- metric.GapDuration(0x2222);
- metric.RoundTripDelay(0x3333);
- metric.EndSystemDelay(0x4444);
- metric.SignalLevel(5);
- metric.NoiseLevel(6);
- metric.Rerl(7);
- metric.Gmin(8);
- metric.Rfactor(9);
- metric.ExtRfactor(10);
- metric.MosLq(11);
- metric.MosCq(12);
- metric.RxConfig(13);
- metric.JbNominal(0x5555);
- metric.JbMax(0x6666);
- metric.JbAbsMax(0x7777);
-
+ RTCPVoIPMetric metric;
+ metric.lossRate = 1;
+ metric.discardRate = 2;
+ metric.burstDensity = 3;
+ metric.gapDensity = 4;
+ metric.burstDuration = 0x1111;
+ metric.gapDuration = 0x2222;
+ metric.roundTripDelay = 0x3333;
+ metric.endSystemDelay = 0x4444;
+ metric.signalLevel = 5;
+ metric.noiseLevel = 6;
+ metric.RERL = 7;
+ metric.Gmin = 8;
+ metric.Rfactor = 9;
+ metric.extRfactor = 10;
+ metric.MOSLQ = 11;
+ metric.MOSCQ = 12;
+ metric.RXconfig = 13;
+ metric.JBnominal = 0x5555;
+ metric.JBmax = 0x6666;
+ metric.JBabsMax = 0x7777;
+ VoipMetric metric_block;
+ metric_block.To(kRemoteSsrc);
+ metric_block.WithVoipMetric(metric);
Xr xr;
xr.From(kSenderSsrc);
- EXPECT_TRUE(xr.WithVoipMetric(&metric));
+ EXPECT_TRUE(xr.WithVoipMetric(&metric_block));
rtc::scoped_ptr<RawPacket> packet(xr.Build());
RtcpPacketParser parser;
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
index b914838109..d65b04c8ab 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -23,8 +23,13 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
namespace webrtc {
-using namespace RTCPUtility;
-using namespace RTCPHelp;
+using RTCPHelp::RTCPPacketInformation;
+using RTCPHelp::RTCPReceiveInformation;
+using RTCPHelp::RTCPReportBlockInformation;
+using RTCPUtility::kBtVoipMetric;
+using RTCPUtility::RTCPCnameInformation;
+using RTCPUtility::RTCPPacketReportBlockItem;
+using RTCPUtility::RTCPPacketTypes;
// The number of RTCP time intervals needed to trigger a timeout.
const int kRrTimeoutIntervals = 3;
@@ -741,7 +746,7 @@ bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
return updateBoundingSet;
}
-int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
+int32_t RTCPReceiver::BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec) {
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
@@ -761,7 +766,7 @@ int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
i++) {
if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
// owner of bounding set
- tmmbrOwner = true;
+ *tmmbrOwner = true;
}
boundingSetRec->SetEntry(i,
receiveInfo->TmmbnBoundingSet.Tmmbr(i),
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
index 272397675b..24861bd49e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -12,11 +12,11 @@
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_H_
#include <map>
-#include <vector>
#include <set>
+#include <vector>
#include "webrtc/base/thread_annotations.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
@@ -103,7 +103,7 @@ public:
bool UpdateRTCPReceiveInformationTimers();
- int32_t BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec);
+ int32_t BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec);
int32_t UpdateTMMBR();
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc
index 718990d10b..a5c0e28282 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc
@@ -17,7 +17,7 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
namespace webrtc {
-using namespace RTCPHelp;
+namespace RTCPHelp {
RTCPPacketInformation::RTCPPacketInformation()
: rtcpPacketTypeFlags(0),
@@ -190,4 +190,5 @@ void RTCPReceiveInformation::VerifyAndAllocateBoundingSet(
const uint32_t minimumSize) {
TmmbnBoundingSet.VerifyAndAllocateSet(minimumSize);
}
+} // namespace RTCPHelp
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h
index 37b7b88370..a792841962 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h
@@ -11,10 +11,12 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_HELP_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_HELP_H_
+#include <list>
+#include <vector>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" // RTCPReportBlock
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" // RTCPReportBlock
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
#include "webrtc/typedefs.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 1581845476..5d2fda347e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -15,17 +15,23 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-// Note: This file has no directory. Lint warning must be ignored.
#include "webrtc/common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.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/sli.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
-#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
namespace webrtc {
@@ -384,20 +390,20 @@ TEST_F(RtcpReceiverTest, GetRtt) {
}
TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
- rtcp::Ij ij;
+ rtcp::ExtendedJitterReport ij;
rtc::scoped_ptr<rtcp::RawPacket> packet(ij.Build());
EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
}
TEST_F(RtcpReceiverTest, InjectIjWithOneItem) {
- rtcp::Ij ij;
- ij.WithJitterItem(0x11111111);
+ rtcp::ExtendedJitterReport ij;
+ ij.WithJitter(0x11213141);
rtc::scoped_ptr<rtcp::RawPacket> packet(ij.Build());
EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
EXPECT_EQ(kRtcpTransmissionTimeOffset, rtcp_packet_info_.rtcpPacketTypeFlags);
- EXPECT_EQ(0x11111111U, rtcp_packet_info_.interArrivalJitter);
+ EXPECT_EQ(0x11213141U, rtcp_packet_info_.interArrivalJitter);
}
TEST_F(RtcpReceiverTest, InjectAppWithNoData) {
@@ -586,7 +592,9 @@ TEST_F(RtcpReceiverTest, InjectXrVoipPacket) {
const uint8_t kLossRate = 123;
rtcp::VoipMetric voip_metric;
voip_metric.To(kSourceSsrc);
- voip_metric.LossRate(kLossRate);
+ RTCPVoIPMetric metric;
+ metric.lossRate = kLossRate;
+ voip_metric.WithVoipMetric(metric);
rtcp::Xr xr;
xr.From(0x2345);
xr.WithVoipMetric(&voip_metric);
@@ -615,8 +623,7 @@ TEST_F(RtcpReceiverTest, XrVoipPacketNotToUsIgnored) {
TEST_F(RtcpReceiverTest, InjectXrReceiverReferenceTimePacket) {
rtcp::Rrtr rrtr;
- rrtr.WithNtpSec(0x10203);
- rrtr.WithNtpFrac(0x40506);
+ rrtr.WithNtp(NtpTime(0x10203, 0x40506));
rtcp::Xr xr;
xr.From(0x2345);
xr.WithRrtr(&rrtr);
@@ -751,13 +758,12 @@ TEST_F(RtcpReceiverTest, LastReceivedXrReferenceTimeInfoInitiallyFalse) {
TEST_F(RtcpReceiverTest, GetLastReceivedXrReferenceTimeInfo) {
const uint32_t kSenderSsrc = 0x123456;
- const uint32_t kNtpSec = 0x10203;
- const uint32_t kNtpFrac = 0x40506;
- const uint32_t kNtpMid = RTCPUtility::MidNtp(kNtpSec, kNtpFrac);
+ const NtpTime kNtp(0x10203, 0x40506);
+ const uint32_t kNtpMid =
+ RTCPUtility::MidNtp(kNtp.seconds(), kNtp.fractions());
rtcp::Rrtr rrtr;
- rrtr.WithNtpSec(kNtpSec);
- rrtr.WithNtpFrac(kNtpFrac);
+ rrtr.WithNtp(kNtp);
rtcp::Xr xr;
xr.From(kSenderSsrc);
xr.WithRrtr(&rrtr);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
index 22b9477e05..848d73b2c4 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -11,17 +11,26 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
#include <assert.h> // assert
-#include <stdlib.h> // rand
#include <string.h> // memcpy
#include <algorithm> // min
#include <limits> // max
+#include <utility>
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/trace_event.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
+#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/sli.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.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"
@@ -31,13 +40,11 @@ namespace webrtc {
using RTCPUtility::RTCPCnameInformation;
NACKStringBuilder::NACKStringBuilder()
- : stream_(""), count_(0), prevNack_(0), consecutive_(false) {
-}
+ : stream_(""), count_(0), prevNack_(0), consecutive_(false) {}
NACKStringBuilder::~NACKStringBuilder() {}
-void NACKStringBuilder::PushNACK(uint16_t nack)
-{
+void NACKStringBuilder::PushNACK(uint16_t nack) {
if (count_ == 0) {
stream_ << nack;
} else if (nack == prevNack_ + 1) {
@@ -71,64 +78,63 @@ RTCPSender::FeedbackState::FeedbackState()
last_rr_ntp_frac(0),
remote_sr(0),
has_last_xr_rr(false),
- module(nullptr) {
-}
+ module(nullptr) {}
-struct RTCPSender::RtcpContext {
- RtcpContext(const FeedbackState& feedback_state,
- int32_t nack_size,
- const uint16_t* nack_list,
- bool repeat,
- uint64_t picture_id,
- uint8_t* buffer,
- uint32_t buffer_size)
- : feedback_state(feedback_state),
- nack_size(nack_size),
- nack_list(nack_list),
- repeat(repeat),
- picture_id(picture_id),
- buffer(buffer),
- buffer_size(buffer_size),
- ntp_sec(0),
- ntp_frac(0),
- position(0) {}
-
- uint8_t* AllocateData(uint32_t bytes) {
- RTC_DCHECK_LE(position + bytes, buffer_size);
- uint8_t* ptr = &buffer[position];
- position += bytes;
- return ptr;
+class PacketContainer : public rtcp::CompoundPacket,
+ public rtcp::RtcpPacket::PacketReadyCallback {
+ public:
+ explicit PacketContainer(Transport* transport)
+ : transport_(transport), bytes_sent_(0) {}
+ virtual ~PacketContainer() {
+ for (RtcpPacket* packet : appended_packets_)
+ delete packet;
}
- const FeedbackState& feedback_state;
- int32_t nack_size;
- const uint16_t* nack_list;
- bool repeat;
- uint64_t picture_id;
- uint8_t* buffer;
- uint32_t buffer_size;
- uint32_t ntp_sec;
- uint32_t ntp_frac;
- uint32_t position;
-};
-
-// TODO(sprang): Once all builders use RtcpPacket, call SendToNetwork() here.
-class RTCPSender::PacketBuiltCallback
- : public rtcp::RtcpPacket::PacketReadyCallback {
- public:
- PacketBuiltCallback(RtcpContext* context) : context_(context) {}
- virtual ~PacketBuiltCallback() {}
void OnPacketReady(uint8_t* data, size_t length) override {
- context_->position += length;
+ if (transport_->SendRtcp(data, length))
+ bytes_sent_ += length;
}
- bool BuildPacket(const rtcp::RtcpPacket& packet) {
- return packet.BuildExternalBuffer(
- &context_->buffer[context_->position],
- context_->buffer_size - context_->position, this);
+
+ size_t SendPackets() {
+ rtcp::CompoundPacket::Build(this);
+ return bytes_sent_;
}
private:
- RtcpContext* const context_;
+ Transport* transport_;
+ size_t bytes_sent_;
+};
+
+class RTCPSender::RtcpContext {
+ public:
+ RtcpContext(const FeedbackState& feedback_state,
+ int32_t nack_size,
+ const uint16_t* nack_list,
+ bool repeat,
+ uint64_t picture_id,
+ uint32_t ntp_sec,
+ uint32_t ntp_frac,
+ PacketContainer* container)
+ : feedback_state_(feedback_state),
+ nack_size_(nack_size),
+ nack_list_(nack_list),
+ repeat_(repeat),
+ picture_id_(picture_id),
+ ntp_sec_(ntp_sec),
+ ntp_frac_(ntp_frac),
+ container_(container) {}
+
+ virtual ~RtcpContext() {}
+
+ const FeedbackState& feedback_state_;
+ const int32_t nack_size_;
+ const uint16_t* nack_list_;
+ const bool repeat_;
+ const uint64_t picture_id_;
+ const uint32_t ntp_sec_;
+ const uint32_t ntp_frac_;
+
+ PacketContainer* const container_;
};
RTCPSender::RTCPSender(
@@ -139,6 +145,7 @@ RTCPSender::RTCPSender(
Transport* outgoing_transport)
: audio_(audio),
clock_(clock),
+ random_(clock_->TimeInMicroseconds()),
method_(RtcpMode::kOff),
transport_(outgoing_transport),
@@ -193,8 +200,7 @@ RTCPSender::RTCPSender(
builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr;
}
-RTCPSender::~RTCPSender() {
-}
+RTCPSender::~RTCPSender() {}
RtcpMode RTCPSender::Status() const {
CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
@@ -340,63 +346,63 @@ int32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) {
}
bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const {
-/*
- For audio we use a fix 5 sec interval
+ /*
+ For audio we use a fix 5 sec interval
- For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
- technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
- that should be extremely rare
+ For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
+ technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
+ that should be extremely rare
-From RFC 3550
+ From RFC 3550
- MAX RTCP BW is 5% if the session BW
- A send report is approximately 65 bytes inc CNAME
- A receiver report is approximately 28 bytes
+ MAX RTCP BW is 5% if the session BW
+ A send report is approximately 65 bytes inc CNAME
+ A receiver report is approximately 28 bytes
- The RECOMMENDED value for the reduced minimum in seconds is 360
- divided by the session bandwidth in kilobits/second. This minimum
- is smaller than 5 seconds for bandwidths greater than 72 kb/s.
+ The RECOMMENDED value for the reduced minimum in seconds is 360
+ divided by the session bandwidth in kilobits/second. This minimum
+ is smaller than 5 seconds for bandwidths greater than 72 kb/s.
- If the participant has not yet sent an RTCP packet (the variable
- initial is true), the constant Tmin is set to 2.5 seconds, else it
- is set to 5 seconds.
+ If the participant has not yet sent an RTCP packet (the variable
+ initial is true), the constant Tmin is set to 2.5 seconds, else it
+ is set to 5 seconds.
- The interval between RTCP packets is varied randomly over the
- range [0.5,1.5] times the calculated interval to avoid unintended
- synchronization of all participants
+ The interval between RTCP packets is varied randomly over the
+ range [0.5,1.5] times the calculated interval to avoid unintended
+ synchronization of all participants
- if we send
- If the participant is a sender (we_sent true), the constant C is
- set to the average RTCP packet size (avg_rtcp_size) divided by 25%
- of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
- number of senders.
+ if we send
+ If the participant is a sender (we_sent true), the constant C is
+ set to the average RTCP packet size (avg_rtcp_size) divided by 25%
+ of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
+ number of senders.
- if we receive only
- If we_sent is not true, the constant C is set
- to the average RTCP packet size divided by 75% of the RTCP
- bandwidth. The constant n is set to the number of receivers
- (members - senders). If the number of senders is greater than
- 25%, senders and receivers are treated together.
+ if we receive only
+ If we_sent is not true, the constant C is set
+ to the average RTCP packet size divided by 75% of the RTCP
+ bandwidth. The constant n is set to the number of receivers
+ (members - senders). If the number of senders is greater than
+ 25%, senders and receivers are treated together.
- reconsideration NOT required for peer-to-peer
- "timer reconsideration" is
- employed. This algorithm implements a simple back-off mechanism
- which causes users to hold back RTCP packet transmission if the
- group sizes are increasing.
+ reconsideration NOT required for peer-to-peer
+ "timer reconsideration" is
+ employed. This algorithm implements a simple back-off mechanism
+ which causes users to hold back RTCP packet transmission if the
+ group sizes are increasing.
- n = number of members
- C = avg_size/(rtcpBW/4)
+ n = number of members
+ C = avg_size/(rtcpBW/4)
- 3. The deterministic calculated interval Td is set to max(Tmin, n*C).
+ 3. The deterministic calculated interval Td is set to max(Tmin, n*C).
- 4. The calculated interval T is set to a number uniformly distributed
- between 0.5 and 1.5 times the deterministic calculated interval.
+ 4. The calculated interval T is set to a number uniformly distributed
+ between 0.5 and 1.5 times the deterministic calculated interval.
- 5. The resulting value of T is divided by e-3/2=1.21828 to compensate
- for the fact that the timer reconsideration algorithm converges to
- a value of the RTCP bandwidth below the intended average
-*/
+ 5. The resulting value of T is divided by e-3/2=1.21828 to compensate
+ for the fact that the timer reconsideration algorithm converges to
+ a value of the RTCP bandwidth below the intended average
+ */
int64_t now = clock_->TimeInMilliseconds();
@@ -451,32 +457,15 @@ bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp,
return true;
}
-int32_t RTCPSender::AddReportBlock(const RTCPReportBlock& report_block) {
- if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) {
- LOG(LS_WARNING) << "Too many report blocks.";
- return -1;
- }
- rtcp::ReportBlock* block = &report_blocks_[report_block.remoteSSRC];
- block->To(report_block.remoteSSRC);
- block->WithFractionLost(report_block.fractionLost);
- block->WithCumulativeLost(report_block.cumulativeLost);
- block->WithExtHighestSeqNum(report_block.extendedHighSeqNum);
- block->WithJitter(report_block.jitter);
- block->WithLastSr(report_block.lastSR);
- block->WithDelayLastSr(report_block.delaySinceLastSR);
-
- return 0;
-}
-
-RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) {
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) {
for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) {
// shift old
last_send_report_[i + 1] = last_send_report_[i];
last_rtcp_time_[i + 1] = last_rtcp_time_[i];
}
- last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac);
- last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 16);
+ last_rtcp_time_[0] = Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_);
+ last_send_report_[0] = (ctx.ntp_sec_ << 16) + (ctx.ntp_frac_ >> 16);
// The timestamp of this RTCP packet should be estimated as the timestamp of
// the frame being captured at this moment. We are calculating that
@@ -485,67 +474,52 @@ RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) {
uint32_t rtp_timestamp =
start_timestamp_ + last_rtp_timestamp_ +
(clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) *
- (ctx->feedback_state.frequency_hz / 1000);
+ (ctx.feedback_state_.frequency_hz / 1000);
- rtcp::SenderReport report;
- report.From(ssrc_);
- report.WithNtpSec(ctx->ntp_sec);
- report.WithNtpFrac(ctx->ntp_frac);
- report.WithRtpTimestamp(rtp_timestamp);
- report.WithPacketCount(ctx->feedback_state.packets_sent);
- report.WithOctetCount(ctx->feedback_state.media_bytes_sent);
+ rtcp::SenderReport* report = new rtcp::SenderReport();
+ report->From(ssrc_);
+ report->WithNtpSec(ctx.ntp_sec_);
+ report->WithNtpFrac(ctx.ntp_frac_);
+ report->WithRtpTimestamp(rtp_timestamp);
+ report->WithPacketCount(ctx.feedback_state_.packets_sent);
+ report->WithOctetCount(ctx.feedback_state_.media_bytes_sent);
for (auto it : report_blocks_)
- report.WithReportBlock(it.second);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(report))
- return BuildResult::kTruncated;
+ report->WithReportBlock(it.second);
report_blocks_.clear();
- return BuildResult::kSuccess;
+
+ return rtc::scoped_ptr<rtcp::SenderReport>(report);
}
-RTCPSender::BuildResult RTCPSender::BuildSDES(RtcpContext* ctx) {
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSDES(
+ const RtcpContext& ctx) {
size_t length_cname = cname_.length();
RTC_CHECK_LT(length_cname, static_cast<size_t>(RTCP_CNAME_SIZE));
- rtcp::Sdes sdes;
- sdes.WithCName(ssrc_, cname_);
+ rtcp::Sdes* sdes = new rtcp::Sdes();
+ sdes->WithCName(ssrc_, cname_);
for (const auto it : csrc_cnames_)
- sdes.WithCName(it.first, it.second);
+ sdes->WithCName(it.first, it.second);
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(sdes))
- return BuildResult::kTruncated;
-
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Sdes>(sdes);
}
-RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) {
- rtcp::ReceiverReport report;
- report.From(ssrc_);
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildRR(const RtcpContext& ctx) {
+ rtcp::ReceiverReport* report = new rtcp::ReceiverReport();
+ report->From(ssrc_);
for (auto it : report_blocks_)
- report.WithReportBlock(it.second);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(report))
- return BuildResult::kTruncated;
+ report->WithReportBlock(it.second);
report_blocks_.clear();
-
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::ReceiverReport>(report);
}
-RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) {
- rtcp::Pli pli;
- pli.From(ssrc_);
- pli.To(remote_ssrc_);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(pli))
- return BuildResult::kTruncated;
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildPLI(const RtcpContext& ctx) {
+ rtcp::Pli* pli = new rtcp::Pli();
+ pli->From(ssrc_);
+ pli->To(remote_ssrc_);
TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"RTCPSender::PLI");
@@ -553,21 +527,17 @@ RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) {
TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount",
ssrc_, packet_type_counter_.pli_packets);
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Pli>(pli);
}
-RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) {
- if (!ctx->repeat)
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildFIR(const RtcpContext& ctx) {
+ if (!ctx.repeat_)
++sequence_number_fir_; // Do not increase if repetition.
- rtcp::Fir fir;
- fir.From(ssrc_);
- fir.To(remote_ssrc_);
- fir.WithCommandSeqNum(sequence_number_fir_);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(fir))
- return BuildResult::kTruncated;
+ rtcp::Fir* fir = new rtcp::Fir();
+ fir->From(ssrc_);
+ fir->To(remote_ssrc_);
+ fir->WithCommandSeqNum(sequence_number_fir_);
TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"RTCPSender::FIR");
@@ -575,7 +545,7 @@ RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) {
TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount",
ssrc_, packet_type_counter_.fir_packets);
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Fir>(fir);
}
/*
@@ -585,20 +555,14 @@ RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) {
| First | Number | PictureID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-RTCPSender::BuildResult RTCPSender::BuildSLI(RtcpContext* ctx) {
- rtcp::Sli sli;
- sli.From(ssrc_);
- sli.To(remote_ssrc_);
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSLI(const RtcpContext& ctx) {
+ rtcp::Sli* sli = new rtcp::Sli();
+ sli->From(ssrc_);
+ sli->To(remote_ssrc_);
// Crop picture id to 6 least significant bits.
- sli.WithPictureId(ctx->picture_id & 0x3F);
- sli.WithFirstMb(0);
- sli.WithNumberOfMb(0x1FFF); // 13 bits, only ones for now.
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(sli))
- return BuildResult::kTruncated;
+ sli->WithPictureId(ctx.picture_id_ & 0x3F);
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Sli>(sli);
}
/*
@@ -613,38 +577,32 @@ RTCPSender::BuildResult RTCPSender::BuildSLI(RtcpContext* ctx) {
/*
* Note: not generic made for VP8
*/
-RTCPSender::BuildResult RTCPSender::BuildRPSI(RtcpContext* ctx) {
- if (ctx->feedback_state.send_payload_type == 0xFF)
- return BuildResult::kError;
-
- rtcp::Rpsi rpsi;
- rpsi.From(ssrc_);
- rpsi.To(remote_ssrc_);
- rpsi.WithPayloadType(ctx->feedback_state.send_payload_type);
- rpsi.WithPictureId(ctx->picture_id);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(rpsi))
- return BuildResult::kTruncated;
-
- return BuildResult::kSuccess;
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildRPSI(
+ const RtcpContext& ctx) {
+ if (ctx.feedback_state_.send_payload_type == 0xFF)
+ return nullptr;
+
+ rtcp::Rpsi* rpsi = new rtcp::Rpsi();
+ rpsi->From(ssrc_);
+ rpsi->To(remote_ssrc_);
+ rpsi->WithPayloadType(ctx.feedback_state_.send_payload_type);
+ rpsi->WithPictureId(ctx.picture_id_);
+
+ return rtc::scoped_ptr<rtcp::Rpsi>(rpsi);
}
-RTCPSender::BuildResult RTCPSender::BuildREMB(RtcpContext* ctx) {
- rtcp::Remb remb;
- remb.From(ssrc_);
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildREMB(
+ const RtcpContext& ctx) {
+ rtcp::Remb* remb = new rtcp::Remb();
+ remb->From(ssrc_);
for (uint32_t ssrc : remb_ssrcs_)
- remb.AppliesTo(ssrc);
- remb.WithBitrateBps(remb_bitrate_);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(remb))
- return BuildResult::kTruncated;
+ remb->AppliesTo(ssrc);
+ remb->WithBitrateBps(remb_bitrate_);
TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"RTCPSender::REMB");
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Remb>(remb);
}
void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) {
@@ -652,9 +610,10 @@ void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) {
tmmbr_send_ = target_bitrate / 1000;
}
-RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) {
- if (ctx->feedback_state.module == NULL)
- return BuildResult::kError;
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBR(
+ const RtcpContext& ctx) {
+ if (ctx.feedback_state_.module == nullptr)
+ return nullptr;
// Before sending the TMMBR check the received TMMBN, only an owner is
// allowed to raise the bitrate:
// * If the sender is an owner of the TMMBN -> send TMMBR
@@ -669,14 +628,14 @@ RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) {
// will accuire criticalSectionRTCPReceiver_ is a potental deadlock but
// since RTCPreceiver is not doing the reverse we should be fine
int32_t lengthOfBoundingSet =
- ctx->feedback_state.module->BoundingSet(tmmbrOwner, candidateSet);
+ ctx.feedback_state_.module->BoundingSet(&tmmbrOwner, candidateSet);
if (lengthOfBoundingSet > 0) {
for (int32_t i = 0; i < lengthOfBoundingSet; i++) {
if (candidateSet->Tmmbr(i) == tmmbr_send_ &&
candidateSet->PacketOH(i) == packet_oh_send_) {
- // do not send the same tuple
- return BuildResult::kAborted;
+ // Do not send the same tuple.
+ return nullptr;
}
}
if (!tmmbrOwner) {
@@ -687,124 +646,69 @@ RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) {
int numCandidates = lengthOfBoundingSet + 1;
// find bounding set
- TMMBRSet* boundingSet = NULL;
+ TMMBRSet* boundingSet = nullptr;
int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet);
if (numBoundingSet > 0 || numBoundingSet <= numCandidates)
tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet);
if (!tmmbrOwner) {
- // did not enter bounding set, no meaning to send this request
- return BuildResult::kAborted;
+ // Did not enter bounding set, no meaning to send this request.
+ return nullptr;
}
}
}
- if (tmmbr_send_) {
- rtcp::Tmmbr tmmbr;
- tmmbr.From(ssrc_);
- tmmbr.To(remote_ssrc_);
- tmmbr.WithBitrateKbps(tmmbr_send_);
- tmmbr.WithOverhead(packet_oh_send_);
+ if (!tmmbr_send_)
+ return nullptr;
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(tmmbr))
- return BuildResult::kTruncated;
- }
- return BuildResult::kSuccess;
+ rtcp::Tmmbr* tmmbr = new rtcp::Tmmbr();
+ tmmbr->From(ssrc_);
+ tmmbr->To(remote_ssrc_);
+ tmmbr->WithBitrateKbps(tmmbr_send_);
+ tmmbr->WithOverhead(packet_oh_send_);
+
+ return rtc::scoped_ptr<rtcp::Tmmbr>(tmmbr);
}
-RTCPSender::BuildResult RTCPSender::BuildTMMBN(RtcpContext* ctx) {
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBN(
+ const RtcpContext& ctx) {
TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend();
- if (boundingSet == NULL)
- return BuildResult::kError;
+ if (boundingSet == nullptr)
+ return nullptr;
- rtcp::Tmmbn tmmbn;
- tmmbn.From(ssrc_);
+ rtcp::Tmmbn* tmmbn = new rtcp::Tmmbn();
+ tmmbn->From(ssrc_);
for (uint32_t i = 0; i < boundingSet->lengthOfSet(); i++) {
if (boundingSet->Tmmbr(i) > 0) {
- tmmbn.WithTmmbr(boundingSet->Ssrc(i), boundingSet->Tmmbr(i),
- boundingSet->PacketOH(i));
+ tmmbn->WithTmmbr(boundingSet->Ssrc(i), boundingSet->Tmmbr(i),
+ boundingSet->PacketOH(i));
}
}
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(tmmbn))
- return BuildResult::kTruncated;
-
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Tmmbn>(tmmbn);
}
-RTCPSender::BuildResult RTCPSender::BuildAPP(RtcpContext* ctx) {
- rtcp::App app;
- app.From(ssrc_);
- app.WithSubType(app_sub_type_);
- app.WithName(app_name_);
- app.WithData(app_data_.get(), app_length_);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(app))
- return BuildResult::kTruncated;
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildAPP(const RtcpContext& ctx) {
+ rtcp::App* app = new rtcp::App();
+ app->From(ssrc_);
+ app->WithSubType(app_sub_type_);
+ app->WithName(app_name_);
+ app->WithData(app_data_.get(), app_length_);
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::App>(app);
}
-RTCPSender::BuildResult RTCPSender::BuildNACK(RtcpContext* ctx) {
- // sanity
- if (ctx->position + 16 >= IP_PACKET_SIZE) {
- LOG(LS_WARNING) << "Failed to build NACK.";
- return BuildResult::kTruncated;
- }
-
- // int size, uint16_t* nack_list
- // add nack list
- uint8_t FMT = 1;
- *ctx->AllocateData(1) = 0x80 + FMT;
- *ctx->AllocateData(1) = 205;
-
- *ctx->AllocateData(1) = 0;
- int nack_size_pos_ = ctx->position;
- *ctx->AllocateData(1) = 3; // setting it to one kNACK signal as default
-
- // Add our own SSRC
- ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_);
-
- // Add the remote SSRC
- ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_);
-
- // Build NACK bitmasks and write them to the RTCP message.
- // The nack list should be sorted and not contain duplicates if one
- // wants to build the smallest rtcp nack packet.
- int numOfNackFields = 0;
- int maxNackFields =
- std::min<int>(kRtcpMaxNackFields, (IP_PACKET_SIZE - ctx->position) / 4);
- int i = 0;
- while (i < ctx->nack_size && numOfNackFields < maxNackFields) {
- uint16_t nack = ctx->nack_list[i++];
- uint16_t bitmask = 0;
- while (i < ctx->nack_size) {
- int shift = static_cast<uint16_t>(ctx->nack_list[i] - nack) - 1;
- if (shift >= 0 && shift <= 15) {
- bitmask |= (1 << shift);
- ++i;
- } else {
- break;
- }
- }
- // Write the sequence number and the bitmask to the packet.
- assert(ctx->position + 4 < IP_PACKET_SIZE);
- ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), nack);
- ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), bitmask);
- numOfNackFields++;
- }
- ctx->buffer[nack_size_pos_] = static_cast<uint8_t>(2 + numOfNackFields);
-
- if (i != ctx->nack_size)
- LOG(LS_WARNING) << "Nack list too large for one packet.";
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildNACK(
+ const RtcpContext& ctx) {
+ rtcp::Nack* nack = new rtcp::Nack();
+ nack->From(ssrc_);
+ nack->To(remote_ssrc_);
+ nack->WithList(ctx.nack_list_, ctx.nack_size_);
// Report stats.
NACKStringBuilder stringBuilder;
- for (int idx = 0; idx < i; ++idx) {
- stringBuilder.PushNACK(ctx->nack_list[idx]);
- nack_stats_.ReportRequest(ctx->nack_list[idx]);
+ for (int idx = 0; idx < ctx.nack_size_; ++idx) {
+ stringBuilder.PushNACK(ctx.nack_list_[idx]);
+ nack_stats_.ReportRequest(ctx.nack_list_[idx]);
}
packet_type_counter_.nack_requests = nack_stats_.requests();
packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
@@ -816,101 +720,66 @@ RTCPSender::BuildResult RTCPSender::BuildNACK(RtcpContext* ctx) {
TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount",
ssrc_, packet_type_counter_.nack_packets);
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Nack>(nack);
}
-RTCPSender::BuildResult RTCPSender::BuildBYE(RtcpContext* ctx) {
- rtcp::Bye bye;
- bye.From(ssrc_);
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildBYE(const RtcpContext& ctx) {
+ rtcp::Bye* bye = new rtcp::Bye();
+ bye->From(ssrc_);
for (uint32_t csrc : csrcs_)
- bye.WithCsrc(csrc);
+ bye->WithCsrc(csrc);
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(bye))
- return BuildResult::kTruncated;
-
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Bye>(bye);
}
-RTCPSender::BuildResult RTCPSender::BuildReceiverReferenceTime(
- RtcpContext* ctx) {
-
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildReceiverReferenceTime(
+ const RtcpContext& ctx) {
if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR)
last_xr_rr_.erase(last_xr_rr_.begin());
last_xr_rr_.insert(std::pair<uint32_t, int64_t>(
- RTCPUtility::MidNtp(ctx->ntp_sec, ctx->ntp_frac),
- Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac)));
+ RTCPUtility::MidNtp(ctx.ntp_sec_, ctx.ntp_frac_),
+ Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_)));
- rtcp::Xr xr;
- xr.From(ssrc_);
+ rtcp::Xr* xr = new rtcp::Xr();
+ xr->From(ssrc_);
rtcp::Rrtr rrtr;
- rrtr.WithNtpSec(ctx->ntp_sec);
- rrtr.WithNtpFrac(ctx->ntp_frac);
+ rrtr.WithNtp(NtpTime(ctx.ntp_sec_, ctx.ntp_frac_));
- xr.WithRrtr(&rrtr);
+ xr->WithRrtr(&rrtr);
// TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP?
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(xr))
- return BuildResult::kTruncated;
-
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Xr>(xr);
}
-RTCPSender::BuildResult RTCPSender::BuildDlrr(RtcpContext* ctx) {
- rtcp::Xr xr;
- xr.From(ssrc_);
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildDlrr(
+ const RtcpContext& ctx) {
+ rtcp::Xr* xr = new rtcp::Xr();
+ xr->From(ssrc_);
rtcp::Dlrr dlrr;
- const RtcpReceiveTimeInfo& info = ctx->feedback_state.last_xr_rr;
+ const RtcpReceiveTimeInfo& info = ctx.feedback_state_.last_xr_rr;
dlrr.WithDlrrItem(info.sourceSSRC, info.lastRR, info.delaySinceLastRR);
- xr.WithDlrr(&dlrr);
+ xr->WithDlrr(&dlrr);
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(xr))
- return BuildResult::kTruncated;
-
- return BuildResult::kSuccess;
+ return rtc::scoped_ptr<rtcp::Xr>(xr);
}
// TODO(sprang): Add a unit test for this, or remove if the code isn't used.
-RTCPSender::BuildResult RTCPSender::BuildVoIPMetric(RtcpContext* ctx) {
- rtcp::Xr xr;
- xr.From(ssrc_);
+rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildVoIPMetric(
+ const RtcpContext& context) {
+ rtcp::Xr* xr = new rtcp::Xr();
+ xr->From(ssrc_);
rtcp::VoipMetric voip;
voip.To(remote_ssrc_);
- voip.LossRate(xr_voip_metric_.lossRate);
- voip.DiscardRate(xr_voip_metric_.discardRate);
- voip.BurstDensity(xr_voip_metric_.burstDensity);
- voip.GapDensity(xr_voip_metric_.gapDensity);
- voip.BurstDuration(xr_voip_metric_.burstDuration);
- voip.GapDuration(xr_voip_metric_.gapDuration);
- voip.RoundTripDelay(xr_voip_metric_.roundTripDelay);
- voip.EndSystemDelay(xr_voip_metric_.endSystemDelay);
- voip.SignalLevel(xr_voip_metric_.signalLevel);
- voip.NoiseLevel(xr_voip_metric_.noiseLevel);
- voip.Rerl(xr_voip_metric_.RERL);
- voip.Gmin(xr_voip_metric_.Gmin);
- voip.Rfactor(xr_voip_metric_.Rfactor);
- voip.ExtRfactor(xr_voip_metric_.extRfactor);
- voip.MosLq(xr_voip_metric_.MOSLQ);
- voip.MosCq(xr_voip_metric_.MOSCQ);
- voip.RxConfig(xr_voip_metric_.RXconfig);
- voip.JbNominal(xr_voip_metric_.JBnominal);
- voip.JbMax(xr_voip_metric_.JBmax);
- voip.JbAbsMax(xr_voip_metric_.JBabsMax);
-
- xr.WithVoipMetric(&voip);
-
- PacketBuiltCallback callback(ctx);
- if (!callback.BuildPacket(xr))
- return BuildResult::kTruncated;
-
- return BuildResult::kSuccess;
+ voip.WithVoipMetric(xr_voip_metric_);
+
+ xr->WithVoipMetric(&voip);
+
+ return rtc::scoped_ptr<rtcp::Xr>(xr);
}
int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
@@ -926,43 +795,59 @@ int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
int32_t RTCPSender::SendCompoundRTCP(
const FeedbackState& feedback_state,
- const std::set<RTCPPacketType>& packetTypes,
+ const std::set<RTCPPacketType>& packet_types,
int32_t nack_size,
const uint16_t* nack_list,
bool repeat,
uint64_t pictureID) {
+ PacketContainer container(transport_);
{
CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
if (method_ == RtcpMode::kOff) {
LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
return -1;
}
- }
- uint8_t rtcp_buffer[IP_PACKET_SIZE];
- int rtcp_length =
- PrepareRTCP(feedback_state, packetTypes, nack_size, nack_list, repeat,
- pictureID, rtcp_buffer, IP_PACKET_SIZE);
- // Sanity don't send empty packets.
- if (rtcp_length <= 0)
- return -1;
+ // We need to send our NTP even if we haven't received any reports.
+ uint32_t ntp_sec;
+ uint32_t ntp_frac;
+ clock_->CurrentNtp(ntp_sec, ntp_frac);
+ RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID,
+ ntp_sec, ntp_frac, &container);
+
+ PrepareReport(packet_types, feedback_state);
+
+ auto it = report_flags_.begin();
+ while (it != report_flags_.end()) {
+ auto builder_it = builders_.find(it->type);
+ RTC_DCHECK(builder_it != builders_.end());
+ if (it->is_volatile) {
+ report_flags_.erase(it++);
+ } else {
+ ++it;
+ }
- return SendToNetwork(rtcp_buffer, static_cast<size_t>(rtcp_length));
-}
+ BuilderFunc func = builder_it->second;
+ rtc::scoped_ptr<rtcp::RtcpPacket> packet = (this->*func)(context);
+ if (packet.get() == nullptr)
+ return -1;
+ container.Append(packet.release());
+ }
-int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state,
- const std::set<RTCPPacketType>& packetTypes,
- int32_t nack_size,
- const uint16_t* nack_list,
- bool repeat,
- uint64_t pictureID,
- uint8_t* rtcp_buffer,
- int buffer_size) {
- CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
+ if (packet_type_counter_observer_ != nullptr) {
+ packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
+ remote_ssrc_, packet_type_counter_);
+ }
- RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID,
- rtcp_buffer, buffer_size);
+ RTC_DCHECK(AllVolatileFlagsConsumed());
+ }
+
+ size_t bytes_sent = container.SendPackets();
+ return bytes_sent == 0 ? -1 : 0;
+}
+void RTCPSender::PrepareReport(const std::set<RTCPPacketType>& packetTypes,
+ const FeedbackState& feedback_state) {
// Add all flags as volatile. Non volatile entries will not be overwritten
// and all new volatile flags added will be consumed by the end of this call.
SetFlags(packetTypes, true);
@@ -986,9 +871,6 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state,
if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty()))
SetFlag(kRtcpSdes, true);
- // We need to send our NTP even if we haven't received any reports.
- clock_->CurrentNtp(context.ntp_sec, context.ntp_frac);
-
if (generate_report) {
if (!sending_ && xr_send_receiver_reference_time_enabled_)
SetFlag(kRtcpXrReceiverReferenceTime, true);
@@ -996,15 +878,9 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state,
SetFlag(kRtcpXrDlrrReportBlock, true);
// generate next time to send an RTCP report
- // seeded from RTP constructor
- int32_t random = rand() % 1000;
- int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS;
-
- if (audio_) {
- timeToNext = (RTCP_INTERVAL_AUDIO_MS / 2) +
- (RTCP_INTERVAL_AUDIO_MS * random / 1000);
- } else {
- uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS;
+ uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS;
+
+ if (!audio_) {
if (sending_) {
// Calculate bandwidth for video; 360 / send bandwidth in kbit/s.
uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000;
@@ -1013,74 +889,46 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state,
}
if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS)
minIntervalMs = RTCP_INTERVAL_VIDEO_MS;
- timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000);
}
+ // The interval between RTCP packets is varied randomly over the
+ // range [1/2,3/2] times the calculated interval.
+ uint32_t timeToNext =
+ random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2);
next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext;
StatisticianMap statisticians =
receive_statistics_->GetActiveStatisticians();
- if (!statisticians.empty()) {
- for (auto it = statisticians.begin(); it != statisticians.end(); ++it) {
- RTCPReportBlock report_block;
- if (PrepareReport(feedback_state, it->first, it->second,
- &report_block)) {
- AddReportBlock(report_block);
- }
- }
- }
- }
-
- auto it = report_flags_.begin();
- while (it != report_flags_.end()) {
- auto builder = builders_.find(it->type);
- RTC_DCHECK(builder != builders_.end());
- if (it->is_volatile) {
- report_flags_.erase(it++);
- } else {
- ++it;
- }
-
- uint32_t start_position = context.position;
- BuildResult result = (this->*(builder->second))(&context);
- switch (result) {
- case BuildResult::kError:
- return -1;
- case BuildResult::kTruncated:
- return context.position;
- case BuildResult::kAborted:
- context.position = start_position;
- FALLTHROUGH();
- case BuildResult::kSuccess:
- continue;
- default:
- abort();
+ RTC_DCHECK(report_blocks_.empty());
+ for (auto& it : statisticians) {
+ AddReportBlock(feedback_state, it.first, it.second);
}
}
-
- if (packet_type_counter_observer_ != NULL) {
- packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
- remote_ssrc_, packet_type_counter_);
- }
-
- RTC_DCHECK(AllVolatileFlagsConsumed());
-
- return context.position;
}
-bool RTCPSender::PrepareReport(const FeedbackState& feedback_state,
- uint32_t ssrc,
- StreamStatistician* statistician,
- RTCPReportBlock* report_block) {
+bool RTCPSender::AddReportBlock(const FeedbackState& feedback_state,
+ uint32_t ssrc,
+ StreamStatistician* statistician) {
// Do we have receive statistics to send?
RtcpStatistics stats;
if (!statistician->GetStatistics(&stats, true))
return false;
- report_block->fractionLost = stats.fraction_lost;
- report_block->cumulativeLost = stats.cumulative_lost;
- report_block->extendedHighSeqNum =
- stats.extended_max_sequence_number;
- report_block->jitter = stats.jitter;
- report_block->remoteSSRC = ssrc;
+
+ if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) {
+ LOG(LS_WARNING) << "Too many report blocks.";
+ return false;
+ }
+ RTC_DCHECK(report_blocks_.find(ssrc) == report_blocks_.end());
+ rtcp::ReportBlock* block = &report_blocks_[ssrc];
+ block->To(ssrc);
+ block->WithFractionLost(stats.fraction_lost);
+ if (!block->WithCumulativeLost(stats.cumulative_lost)) {
+ report_blocks_.erase(ssrc);
+ LOG(LS_WARNING) << "Cumulative lost is oversized.";
+ return false;
+ }
+ block->WithExtHighestSeqNum(stats.extended_max_sequence_number);
+ block->WithJitter(stats.jitter);
+ block->WithLastSr(feedback_state.remote_sr);
// TODO(sprang): Do we really need separate time stamps for each report?
// Get our NTP as late as possible to avoid a race.
@@ -1089,7 +937,6 @@ bool RTCPSender::PrepareReport(const FeedbackState& feedback_state,
clock_->CurrentNtp(ntp_secs, ntp_frac);
// Delay since last received report.
- uint32_t delaySinceLastReceivedSR = 0;
if ((feedback_state.last_rr_ntp_secs != 0) ||
(feedback_state.last_rr_ntp_frac != 0)) {
// Get the 16 lowest bits of seconds and the 16 highest bits of fractions.
@@ -1101,19 +948,11 @@ bool RTCPSender::PrepareReport(const FeedbackState& feedback_state,
receiveTime <<= 16;
receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
- delaySinceLastReceivedSR = now-receiveTime;
+ block->WithDelayLastSr(now - receiveTime);
}
- report_block->delaySinceLastSR = delaySinceLastReceivedSR;
- report_block->lastSR = feedback_state.remote_sr;
return true;
}
-int32_t RTCPSender::SendToNetwork(const uint8_t* dataBuffer, size_t length) {
- if (transport_->SendRtcp(dataBuffer, length))
- return 0;
- return -1;
-}
-
void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
assert(csrcs.size() <= kRtpCsrcSize);
CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
@@ -1203,7 +1042,7 @@ bool RTCPSender::AllVolatileFlagsConsumed() const {
bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) {
class Sender : public rtcp::RtcpPacket::PacketReadyCallback {
public:
- Sender(Transport* transport)
+ explicit Sender(Transport* transport)
: transport_(transport), send_failure_(false) {}
void OnPacketReady(uint8_t* data, size_t length) override {
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
index 9ec928363b..dd3aec4c9f 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
@@ -15,13 +15,15 @@
#include <set>
#include <sstream>
#include <string>
+#include <vector>
+#include "webrtc/base/random.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
@@ -50,277 +52,251 @@ class NACKStringBuilder {
};
class RTCPSender {
-public:
- struct FeedbackState {
- FeedbackState();
+ public:
+ struct FeedbackState {
+ FeedbackState();
+
+ uint8_t send_payload_type;
+ uint32_t frequency_hz;
+ uint32_t packets_sent;
+ size_t media_bytes_sent;
+ uint32_t send_bitrate;
+
+ uint32_t last_rr_ntp_secs;
+ uint32_t last_rr_ntp_frac;
+ uint32_t remote_sr;
+
+ bool has_last_xr_rr;
+ RtcpReceiveTimeInfo last_xr_rr;
+
+ // Used when generating TMMBR.
+ ModuleRtpRtcpImpl* module;
+ };
+
+ RTCPSender(bool audio,
+ Clock* clock,
+ ReceiveStatistics* receive_statistics,
+ RtcpPacketTypeCounterObserver* packet_type_counter_observer,
+ Transport* outgoing_transport);
+ virtual ~RTCPSender();
+
+ RtcpMode Status() const;
+ void SetRTCPStatus(RtcpMode method);
+
+ bool Sending() const;
+ int32_t SetSendingStatus(const FeedbackState& feedback_state,
+ bool enabled); // combine the functions
+
+ int32_t SetNackStatus(bool enable);
- uint8_t send_payload_type;
- uint32_t frequency_hz;
- uint32_t packets_sent;
- size_t media_bytes_sent;
- uint32_t send_bitrate;
+ void SetStartTimestamp(uint32_t start_timestamp);
- uint32_t last_rr_ntp_secs;
- uint32_t last_rr_ntp_frac;
- uint32_t remote_sr;
+ void SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms);
- bool has_last_xr_rr;
- RtcpReceiveTimeInfo last_xr_rr;
+ void SetSSRC(uint32_t ssrc);
- // Used when generating TMMBR.
- ModuleRtpRtcpImpl* module;
- };
+ void SetRemoteSSRC(uint32_t ssrc);
- RTCPSender(bool audio,
- Clock* clock,
- ReceiveStatistics* receive_statistics,
- RtcpPacketTypeCounterObserver* packet_type_counter_observer,
- Transport* outgoing_transport);
- virtual ~RTCPSender();
+ int32_t SetCNAME(const char* cName);
- RtcpMode Status() const;
- void SetRTCPStatus(RtcpMode method);
+ int32_t AddMixedCNAME(uint32_t SSRC, const char* c_name);
- bool Sending() const;
- int32_t SetSendingStatus(const FeedbackState& feedback_state,
- bool enabled); // combine the functions
+ int32_t RemoveMixedCNAME(uint32_t SSRC);
- int32_t SetNackStatus(bool enable);
+ int64_t SendTimeOfSendReport(uint32_t sendReport);
- void SetStartTimestamp(uint32_t start_timestamp);
+ bool SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const;
- void SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms);
+ bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const;
- void SetSSRC(uint32_t ssrc);
+ int32_t SendRTCP(const FeedbackState& feedback_state,
+ RTCPPacketType packetType,
+ int32_t nackSize = 0,
+ const uint16_t* nackList = 0,
+ bool repeat = false,
+ uint64_t pictureID = 0);
- void SetRemoteSSRC(uint32_t ssrc);
+ int32_t SendCompoundRTCP(const FeedbackState& feedback_state,
+ const std::set<RTCPPacketType>& packetTypes,
+ int32_t nackSize = 0,
+ const uint16_t* nackList = 0,
+ bool repeat = false,
+ uint64_t pictureID = 0);
- int32_t SetCNAME(const char* cName);
+ bool REMB() const;
- int32_t AddMixedCNAME(uint32_t SSRC, const char* c_name);
+ void SetREMBStatus(bool enable);
- int32_t RemoveMixedCNAME(uint32_t SSRC);
+ void SetREMBData(uint32_t bitrate, const std::vector<uint32_t>& ssrcs);
- int64_t SendTimeOfSendReport(uint32_t sendReport);
+ bool TMMBR() const;
- bool SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const;
+ void SetTMMBRStatus(bool enable);
- bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const;
+ int32_t SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit);
- int32_t SendRTCP(const FeedbackState& feedback_state,
- RTCPPacketType packetType,
- int32_t nackSize = 0,
- const uint16_t* nackList = 0,
- bool repeat = false,
- uint64_t pictureID = 0);
-
- int32_t SendCompoundRTCP(const FeedbackState& feedback_state,
- const std::set<RTCPPacketType>& packetTypes,
- int32_t nackSize = 0,
- const uint16_t* nackList = 0,
- bool repeat = false,
- uint64_t pictureID = 0);
-
- bool REMB() const;
-
- void SetREMBStatus(bool enable);
-
- void SetREMBData(uint32_t bitrate, const std::vector<uint32_t>& ssrcs);
-
- bool TMMBR() const;
-
- void SetTMMBRStatus(bool enable);
-
- int32_t SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit);
-
- int32_t SetApplicationSpecificData(uint8_t subType,
- uint32_t name,
- const uint8_t* data,
- uint16_t length);
- int32_t SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric);
-
- void SendRtcpXrReceiverReferenceTime(bool enable);
-
- bool RtcpXrReceiverReferenceTime() const;
-
- void SetCsrcs(const std::vector<uint32_t>& csrcs);
-
- void SetTargetBitrate(unsigned int target_bitrate);
- bool SendFeedbackPacket(const rtcp::TransportFeedback& packet);
-
-private:
- struct RtcpContext;
-
- // The BuildResult indicates the outcome of a call to a builder method,
- // constructing a part of an RTCP packet:
- //
- // kError
- // Building RTCP packet failed, propagate error out to caller.
- // kAbort
- // The (partial) block being build should not be included. Reset current
- // buffer position to the state before the method call and proceed to the
- // next packet type.
- // kTruncated
- // There is not enough room in the buffer to fit the data being constructed.
- // (IP packet is full). Proceed to the next packet type, and call this
- // method again when a new buffer has been allocated.
- // TODO(sprang): Actually allocate multiple packets if needed.
- // kSuccess
- // Data has been successfully placed in the buffer.
-
- enum class BuildResult { kError, kAborted, kTruncated, kSuccess };
-
- int32_t SendToNetwork(const uint8_t* dataBuffer, size_t length);
-
- int32_t AddReportBlock(const RTCPReportBlock& report_block)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
-
- bool PrepareReport(const FeedbackState& feedback_state,
- uint32_t ssrc,
- StreamStatistician* statistician,
- RTCPReportBlock* report_block);
-
- int PrepareRTCP(const FeedbackState& feedback_state,
- const std::set<RTCPPacketType>& packetTypes,
- int32_t nackSize,
- const uint16_t* nackList,
- bool repeat,
- uint64_t pictureID,
- uint8_t* rtcp_buffer,
- int buffer_size);
-
- BuildResult BuildSR(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildRR(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildSDES(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildPLI(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildREMB(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildTMMBR(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildTMMBN(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildAPP(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildVoIPMetric(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildBYE(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildFIR(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildSLI(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildRPSI(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildNACK(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildReceiverReferenceTime(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- BuildResult BuildDlrr(RtcpContext* context)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
-
-private:
- const bool audio_;
- Clock* const clock_;
- RtcpMode method_ GUARDED_BY(critical_section_rtcp_sender_);
-
- Transport* const transport_;
-
- rtc::scoped_ptr<CriticalSectionWrapper> critical_section_rtcp_sender_;
- bool using_nack_ GUARDED_BY(critical_section_rtcp_sender_);
- bool sending_ GUARDED_BY(critical_section_rtcp_sender_);
- bool remb_enabled_ GUARDED_BY(critical_section_rtcp_sender_);
-
- int64_t next_time_to_send_rtcp_ GUARDED_BY(critical_section_rtcp_sender_);
-
- uint32_t start_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
- uint32_t last_rtp_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
- int64_t last_frame_capture_time_ms_ GUARDED_BY(critical_section_rtcp_sender_);
- uint32_t ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
- // SSRC that we receive on our RTP channel
- uint32_t remote_ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
- std::string cname_ GUARDED_BY(critical_section_rtcp_sender_);
-
- ReceiveStatistics* receive_statistics_
- GUARDED_BY(critical_section_rtcp_sender_);
- std::map<uint32_t, rtcp::ReportBlock> report_blocks_
- GUARDED_BY(critical_section_rtcp_sender_);
- std::map<uint32_t, std::string> csrc_cnames_
- GUARDED_BY(critical_section_rtcp_sender_);
-
- // Sent
- uint32_t last_send_report_[RTCP_NUMBER_OF_SR] GUARDED_BY(
- critical_section_rtcp_sender_); // allow packet loss and RTT above 1 sec
- int64_t last_rtcp_time_[RTCP_NUMBER_OF_SR] GUARDED_BY(
- critical_section_rtcp_sender_);
-
- // Sent XR receiver reference time report.
- // <mid ntp (mid 32 bits of the 64 bits NTP timestamp), send time in ms>.
- std::map<uint32_t, int64_t> last_xr_rr_
- GUARDED_BY(critical_section_rtcp_sender_);
-
- // send CSRCs
- std::vector<uint32_t> csrcs_ GUARDED_BY(critical_section_rtcp_sender_);
-
- // Full intra request
- uint8_t sequence_number_fir_ GUARDED_BY(critical_section_rtcp_sender_);
-
- // REMB
- uint32_t remb_bitrate_ GUARDED_BY(critical_section_rtcp_sender_);
- std::vector<uint32_t> remb_ssrcs_ GUARDED_BY(critical_section_rtcp_sender_);
-
- TMMBRHelp tmmbr_help_ GUARDED_BY(critical_section_rtcp_sender_);
- uint32_t tmmbr_send_ GUARDED_BY(critical_section_rtcp_sender_);
- uint32_t packet_oh_send_ GUARDED_BY(critical_section_rtcp_sender_);
-
- // APP
- uint8_t app_sub_type_ GUARDED_BY(critical_section_rtcp_sender_);
- uint32_t app_name_ GUARDED_BY(critical_section_rtcp_sender_);
- rtc::scoped_ptr<uint8_t[]> app_data_ GUARDED_BY(critical_section_rtcp_sender_);
- uint16_t app_length_ GUARDED_BY(critical_section_rtcp_sender_);
-
- // True if sending of XR Receiver reference time report is enabled.
- bool xr_send_receiver_reference_time_enabled_
- GUARDED_BY(critical_section_rtcp_sender_);
-
- // XR VoIP metric
- RTCPVoIPMetric xr_voip_metric_ GUARDED_BY(critical_section_rtcp_sender_);
-
- RtcpPacketTypeCounterObserver* const packet_type_counter_observer_;
- RtcpPacketTypeCounter packet_type_counter_
- GUARDED_BY(critical_section_rtcp_sender_);
-
- RTCPUtility::NackStats nack_stats_ GUARDED_BY(critical_section_rtcp_sender_);
-
- void SetFlag(RTCPPacketType type, bool is_volatile)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- void SetFlags(const std::set<RTCPPacketType>& types, bool is_volatile)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- bool IsFlagPresent(RTCPPacketType type) const
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- bool ConsumeFlag(RTCPPacketType type, bool forced = false)
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- bool AllVolatileFlagsConsumed() const
- EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
- struct ReportFlag {
- ReportFlag(RTCPPacketType type, bool is_volatile)
- : type(type), is_volatile(is_volatile) {}
- bool operator<(const ReportFlag& flag) const { return type < flag.type; }
- bool operator==(const ReportFlag& flag) const { return type == flag.type; }
- const RTCPPacketType type;
- const bool is_volatile;
- };
-
- std::set<ReportFlag> report_flags_ GUARDED_BY(critical_section_rtcp_sender_);
-
- typedef BuildResult (RTCPSender::*Builder)(RtcpContext*);
- std::map<RTCPPacketType, Builder> builders_;
-
- class PacketBuiltCallback;
+ int32_t SetApplicationSpecificData(uint8_t subType,
+ uint32_t name,
+ const uint8_t* data,
+ uint16_t length);
+ int32_t SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric);
+
+ void SendRtcpXrReceiverReferenceTime(bool enable);
+
+ bool RtcpXrReceiverReferenceTime() const;
+
+ void SetCsrcs(const std::vector<uint32_t>& csrcs);
+
+ void SetTargetBitrate(unsigned int target_bitrate);
+ bool SendFeedbackPacket(const rtcp::TransportFeedback& packet);
+
+ private:
+ class RtcpContext;
+
+ // Determine which RTCP messages should be sent and setup flags.
+ void PrepareReport(const std::set<RTCPPacketType>& packetTypes,
+ const FeedbackState& feedback_state)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+
+ bool AddReportBlock(const FeedbackState& feedback_state,
+ uint32_t ssrc,
+ StreamStatistician* statistician)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildSR(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildRR(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildSDES(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildPLI(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildREMB(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildTMMBR(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildTMMBN(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildAPP(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildVoIPMetric(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildBYE(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildFIR(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildSLI(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildRPSI(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildNACK(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildReceiverReferenceTime(
+ const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<rtcp::RtcpPacket> BuildDlrr(const RtcpContext& context)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+
+ private:
+ const bool audio_;
+ Clock* const clock_;
+ Random random_ GUARDED_BY(critical_section_rtcp_sender_);
+ RtcpMode method_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ Transport* const transport_;
+
+ rtc::scoped_ptr<CriticalSectionWrapper> critical_section_rtcp_sender_;
+ bool using_nack_ GUARDED_BY(critical_section_rtcp_sender_);
+ bool sending_ GUARDED_BY(critical_section_rtcp_sender_);
+ bool remb_enabled_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ int64_t next_time_to_send_rtcp_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ uint32_t start_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
+ uint32_t last_rtp_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
+ int64_t last_frame_capture_time_ms_ GUARDED_BY(critical_section_rtcp_sender_);
+ uint32_t ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
+ // SSRC that we receive on our RTP channel
+ uint32_t remote_ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
+ std::string cname_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ ReceiveStatistics* receive_statistics_
+ GUARDED_BY(critical_section_rtcp_sender_);
+ std::map<uint32_t, rtcp::ReportBlock> report_blocks_
+ GUARDED_BY(critical_section_rtcp_sender_);
+ std::map<uint32_t, std::string> csrc_cnames_
+ GUARDED_BY(critical_section_rtcp_sender_);
+
+ // Sent
+ uint32_t last_send_report_[RTCP_NUMBER_OF_SR] GUARDED_BY(
+ critical_section_rtcp_sender_); // allow packet loss and RTT above 1 sec
+ int64_t last_rtcp_time_[RTCP_NUMBER_OF_SR] GUARDED_BY(
+ critical_section_rtcp_sender_);
+
+ // Sent XR receiver reference time report.
+ // <mid ntp (mid 32 bits of the 64 bits NTP timestamp), send time in ms>.
+ std::map<uint32_t, int64_t> last_xr_rr_
+ GUARDED_BY(critical_section_rtcp_sender_);
+
+ // send CSRCs
+ std::vector<uint32_t> csrcs_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ // Full intra request
+ uint8_t sequence_number_fir_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ // REMB
+ uint32_t remb_bitrate_ GUARDED_BY(critical_section_rtcp_sender_);
+ std::vector<uint32_t> remb_ssrcs_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ TMMBRHelp tmmbr_help_ GUARDED_BY(critical_section_rtcp_sender_);
+ uint32_t tmmbr_send_ GUARDED_BY(critical_section_rtcp_sender_);
+ uint32_t packet_oh_send_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ // APP
+ uint8_t app_sub_type_ GUARDED_BY(critical_section_rtcp_sender_);
+ uint32_t app_name_ GUARDED_BY(critical_section_rtcp_sender_);
+ rtc::scoped_ptr<uint8_t[]> app_data_
+ GUARDED_BY(critical_section_rtcp_sender_);
+ uint16_t app_length_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ // True if sending of XR Receiver reference time report is enabled.
+ bool xr_send_receiver_reference_time_enabled_
+ GUARDED_BY(critical_section_rtcp_sender_);
+
+ // XR VoIP metric
+ RTCPVoIPMetric xr_voip_metric_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ RtcpPacketTypeCounterObserver* const packet_type_counter_observer_;
+ RtcpPacketTypeCounter packet_type_counter_
+ GUARDED_BY(critical_section_rtcp_sender_);
+
+ RTCPUtility::NackStats nack_stats_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ void SetFlag(RTCPPacketType type, bool is_volatile)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ void SetFlags(const std::set<RTCPPacketType>& types, bool is_volatile)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ bool IsFlagPresent(RTCPPacketType type) const
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ bool ConsumeFlag(RTCPPacketType type, bool forced = false)
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ bool AllVolatileFlagsConsumed() const
+ EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
+ struct ReportFlag {
+ ReportFlag(RTCPPacketType type, bool is_volatile)
+ : type(type), is_volatile(is_volatile) {}
+ bool operator<(const ReportFlag& flag) const { return type < flag.type; }
+ bool operator==(const ReportFlag& flag) const { return type == flag.type; }
+ const RTCPPacketType type;
+ const bool is_volatile;
+ };
+
+ std::set<ReportFlag> report_flags_ GUARDED_BY(critical_section_rtcp_sender_);
+
+ typedef rtc::scoped_ptr<rtcp::RtcpPacket> (RTCPSender::*BuilderFunc)(
+ const RtcpContext&);
+ std::map<RTCPPacketType, BuilderFunc> builders_;
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
index d2b80438cc..e19499612d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
@@ -8,9 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/base/checks.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
-#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include <assert.h>
#include <math.h> // ceil
@@ -19,6 +17,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
namespace webrtc {
@@ -42,8 +41,8 @@ void NackStats::ReportRequest(uint16_t sequence_number) {
uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac) {
return (ntp_sec << 16) + (ntp_frac >> 16);
-} // end RTCPUtility
}
+} // namespace RTCPUtility
// RTCPParserV2 : currently read only
RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData,
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.h b/webrtc/modules/rtp_rtcp/source/rtcp_utility.h
index f05d512919..0b03ceb56e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.h
@@ -14,7 +14,7 @@
#include <stddef.h> // size_t, ptrdiff_t
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
#include "webrtc/typedefs.h"
@@ -487,6 +487,6 @@ class RTCPPacketIterator {
RtcpCommonHeader _header;
};
-} // RTCPUtility
+} // namespace RTCPUtility
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc
index 541f522f8d..80f961bd1e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc
@@ -11,6 +11,7 @@
#include <list>
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/random.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
@@ -41,8 +42,12 @@ template <typename T> void ClearList(std::list<T*>* my_list) {
class RtpFecTest : public ::testing::Test {
protected:
RtpFecTest()
- : fec_(new ForwardErrorCorrection()), ssrc_(rand()), fec_seq_num_(0) {}
+ : random_(0xfec133700742),
+ fec_(new ForwardErrorCorrection()),
+ ssrc_(random_.Rand<uint32_t>()),
+ fec_seq_num_(0) {}
+ webrtc::Random random_;
ForwardErrorCorrection* fec_;
int ssrc_;
uint16_t fec_seq_num_;
@@ -891,22 +896,20 @@ int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets,
assert(num_media_packets > 0);
ForwardErrorCorrection::Packet* media_packet = NULL;
int sequence_number = start_seq_num;
- int time_stamp = rand();
+ int time_stamp = random_.Rand<int>();
for (int i = 0; i < num_media_packets; ++i) {
media_packet = new ForwardErrorCorrection::Packet;
media_packet_list_.push_back(media_packet);
- media_packet->length = static_cast<size_t>(
- (static_cast<float>(rand()) / RAND_MAX) *
- (IP_PACKET_SIZE - kRtpHeaderSize - kTransportOverhead -
- ForwardErrorCorrection::PacketOverhead()));
+ const uint32_t kMinPacketSize = kRtpHeaderSize;
+ const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize -
+ kTransportOverhead -
+ ForwardErrorCorrection::PacketOverhead();
+ media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize);
- if (media_packet->length < kRtpHeaderSize) {
- media_packet->length = kRtpHeaderSize;
- }
// Generate random values for the first 2 bytes
- media_packet->data[0] = static_cast<uint8_t>(rand() % 256);
- media_packet->data[1] = static_cast<uint8_t>(rand() % 256);
+ media_packet->data[0] = random_.Rand<uint8_t>();
+ media_packet->data[1] = random_.Rand<uint8_t>();
// The first two bits are assumed to be 10 by the FEC encoder.
// In fact the FEC decoder will set the two first bits to 10 regardless of
@@ -929,7 +932,7 @@ int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets,
// Generate random values for payload.
for (size_t j = 12; j < media_packet->length; ++j) {
- media_packet->data[j] = static_cast<uint8_t>(rand() % 256);
+ media_packet->data[j] = random_.Rand<uint8_t>();
}
sequence_number++;
}
@@ -940,5 +943,5 @@ int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets,
}
int RtpFecTest::ConstructMediaPackets(int num_media_packets) {
- return ConstructMediaPacketsSeqNum(num_media_packets, rand());
+ return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>());
}
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format.h b/webrtc/modules/rtp_rtcp/source/rtp_format.h
index 18225f9bb4..3519499248 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format.h
@@ -14,8 +14,8 @@
#include <string>
#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/interface/module_common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/include/module_common_types.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
namespace webrtc {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc
index aeef44364a..c422577c81 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc
@@ -11,7 +11,7 @@
#include <string.h>
#include "webrtc/base/logging.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/h264_sps_parser.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_h264.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
index 1a14b5554a..d29e3d4f21 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
@@ -13,7 +13,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc
index 39b64c6ffa..b47e9b9359 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc
@@ -11,7 +11,7 @@
#include <string>
#include "webrtc/base/logging.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
namespace webrtc {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h b/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h
index 63db349c74..d62ecba85f 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h
@@ -30,7 +30,7 @@
#include <vector>
#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
#include "webrtc/typedefs.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h b/webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h
index 2fe963251f..668476833d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h
@@ -19,7 +19,7 @@
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_TEST_HELPER_H_
#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h"
#include "webrtc/typedefs.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.cc
index 0e76a8eae8..d2f22d5044 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.cc
@@ -47,10 +47,6 @@ int16_t Tl0PicIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) {
return (hdr.tl0_pic_idx == kNoTl0PicIdx) ? def : hdr.tl0_pic_idx;
}
-uint8_t GofIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) {
- return (hdr.gof_idx == kNoGofIdx) ? def : hdr.gof_idx;
-}
-
// Picture ID:
//
// +-+-+-+-+-+-+-+-+
@@ -74,19 +70,17 @@ bool PictureIdPresent(const RTPVideoHeaderVP9& hdr) {
// Flexible mode (F=1): Non-flexible mode (F=0):
//
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
-// L: | T |U| S |D| |GOF_IDX| S |D|
+// L: | T |U| S |D| | T |U| S |D|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// | TL0PICIDX |
// +-+-+-+-+-+-+-+-+
//
size_t LayerInfoLength(const RTPVideoHeaderVP9& hdr) {
- if (hdr.flexible_mode) {
- return (hdr.temporal_idx == kNoTemporalIdx &&
- hdr.spatial_idx == kNoSpatialIdx) ? 0 : 1;
- } else {
- return (hdr.gof_idx == kNoGofIdx &&
- hdr.spatial_idx == kNoSpatialIdx) ? 0 : 2;
+ if (hdr.temporal_idx == kNoTemporalIdx &&
+ hdr.spatial_idx == kNoSpatialIdx) {
+ return 0;
}
+ return hdr.flexible_mode ? 1 : 2;
}
bool LayerInfoPresent(const RTPVideoHeaderVP9& hdr) {
@@ -198,8 +192,8 @@ bool WritePictureId(const RTPVideoHeaderVP9& vp9,
// L: | T |U| S |D|
// +-+-+-+-+-+-+-+-+
//
-bool WriteLayerInfoFlexibleMode(const RTPVideoHeaderVP9& vp9,
- rtc::BitBufferWriter* writer) {
+bool WriteLayerInfoCommon(const RTPVideoHeaderVP9& vp9,
+ rtc::BitBufferWriter* writer) {
RETURN_FALSE_ON_ERROR(writer->WriteBits(TemporalIdxField(vp9, 0), 3));
RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.temporal_up_switch ? 1 : 0, 1));
RETURN_FALSE_ON_ERROR(writer->WriteBits(SpatialIdxField(vp9, 0), 3));
@@ -210,27 +204,26 @@ bool WriteLayerInfoFlexibleMode(const RTPVideoHeaderVP9& vp9,
// Non-flexible mode (F=0):
//
// +-+-+-+-+-+-+-+-+
-// L: |GOF_IDX| S |D|
+// L: | T |U| S |D|
// +-+-+-+-+-+-+-+-+
// | TL0PICIDX |
// +-+-+-+-+-+-+-+-+
//
bool WriteLayerInfoNonFlexibleMode(const RTPVideoHeaderVP9& vp9,
rtc::BitBufferWriter* writer) {
- RETURN_FALSE_ON_ERROR(writer->WriteBits(GofIdxField(vp9, 0), 4));
- RETURN_FALSE_ON_ERROR(writer->WriteBits(SpatialIdxField(vp9, 0), 3));
- RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.inter_layer_predicted ? 1: 0, 1));
RETURN_FALSE_ON_ERROR(writer->WriteUInt8(Tl0PicIdxField(vp9, 0)));
return true;
}
bool WriteLayerInfo(const RTPVideoHeaderVP9& vp9,
rtc::BitBufferWriter* writer) {
- if (vp9.flexible_mode) {
- return WriteLayerInfoFlexibleMode(vp9, writer);
- } else {
- return WriteLayerInfoNonFlexibleMode(vp9, writer);
- }
+ if (!WriteLayerInfoCommon(vp9, writer))
+ return false;
+
+ if (vp9.flexible_mode)
+ return true;
+
+ return WriteLayerInfoNonFlexibleMode(vp9, writer);
}
// Reference indices:
@@ -246,7 +239,7 @@ bool WriteRefIndices(const RTPVideoHeaderVP9& vp9,
vp9.num_ref_pics == 0 || vp9.num_ref_pics > kMaxVp9RefPics) {
return false;
}
- for (size_t i = 0; i < vp9.num_ref_pics; ++i) {
+ for (uint8_t i = 0; i < vp9.num_ref_pics; ++i) {
bool n_bit = !(i == vp9.num_ref_pics - 1);
RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.pid_diff[i], 7));
RETURN_FALSE_ON_ERROR(writer->WriteBits(n_bit ? 1 : 0, 1));
@@ -301,7 +294,7 @@ bool WriteSsData(const RTPVideoHeaderVP9& vp9, rtc::BitBufferWriter* writer) {
writer->WriteBits(vp9.gof.temporal_up_switch[i] ? 1 : 0, 1));
RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.gof.num_ref_pics[i], 2));
RETURN_FALSE_ON_ERROR(writer->WriteBits(kReservedBitValue0, 2));
- for (size_t r = 0; r < vp9.gof.num_ref_pics[i]; ++r) {
+ for (uint8_t r = 0; r < vp9.gof.num_ref_pics[i]; ++r) {
RETURN_FALSE_ON_ERROR(writer->WriteUInt8(vp9.gof.pid_diff[i][r]));
}
}
@@ -337,8 +330,7 @@ bool ParsePictureId(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
// L: | T |U| S |D|
// +-+-+-+-+-+-+-+-+
//
-bool ParseLayerInfoFlexibleMode(rtc::BitBuffer* parser,
- RTPVideoHeaderVP9* vp9) {
+bool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
uint32_t t, u_bit, s, d_bit;
RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1));
@@ -354,32 +346,27 @@ bool ParseLayerInfoFlexibleMode(rtc::BitBuffer* parser,
// Layer indices (non-flexible mode):
//
// +-+-+-+-+-+-+-+-+
-// L: |GOF_IDX| S |D|
+// L: | T |U| S |D|
// +-+-+-+-+-+-+-+-+
// | TL0PICIDX |
// +-+-+-+-+-+-+-+-+
//
bool ParseLayerInfoNonFlexibleMode(rtc::BitBuffer* parser,
RTPVideoHeaderVP9* vp9) {
- uint32_t gof_idx, s, d_bit;
uint8_t tl0picidx;
- RETURN_FALSE_ON_ERROR(parser->ReadBits(&gof_idx, 4));
- RETURN_FALSE_ON_ERROR(parser->ReadBits(&s, 3));
- RETURN_FALSE_ON_ERROR(parser->ReadBits(&d_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&tl0picidx));
- vp9->gof_idx = gof_idx;
- vp9->spatial_idx = s;
- vp9->inter_layer_predicted = d_bit ? true : false;
vp9->tl0_pic_idx = tl0picidx;
return true;
}
bool ParseLayerInfo(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
- if (vp9->flexible_mode) {
- return ParseLayerInfoFlexibleMode(parser, vp9);
- } else {
- return ParseLayerInfoNonFlexibleMode(parser, vp9);
- }
+ if (!ParseLayerInfoCommon(parser, vp9))
+ return false;
+
+ if (vp9->flexible_mode)
+ return true;
+
+ return ParseLayerInfoNonFlexibleMode(parser, vp9);
}
// Reference indices:
@@ -466,7 +453,7 @@ bool ParseSsData(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
vp9->gof.temporal_up_switch[i] = u_bit ? true : false;
vp9->gof.num_ref_pics[i] = r;
- for (size_t p = 0; p < vp9->gof.num_ref_pics[i]; ++p) {
+ for (uint8_t p = 0; p < vp9->gof.num_ref_pics[i]; ++p) {
uint8_t p_diff;
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&p_diff));
vp9->gof.pid_diff[i][p] = p_diff;
@@ -604,7 +591,7 @@ bool RtpPacketizerVp9::NextPacket(uint8_t* buffer,
// +-+-+-+-+-+-+-+-+
// M: | EXTENDED PID | (RECOMMENDED)
// +-+-+-+-+-+-+-+-+
-// L: |GOF_IDX| S |D| (CONDITIONALLY RECOMMENDED)
+// L: | T |U| S |D| (CONDITIONALLY RECOMMENDED)
// +-+-+-+-+-+-+-+-+
// | TL0PICIDX | (CONDITIONALLY REQUIRED)
// +-+-+-+-+-+-+-+-+
@@ -738,7 +725,8 @@ bool RtpDepacketizerVp9::Parse(ParsedPayload* parsed_payload,
parsed_payload->type.Video.height = vp9->height[0];
}
}
- parsed_payload->type.Video.isFirstPacket = b_bit && (vp9->spatial_idx == 0);
+ parsed_payload->type.Video.isFirstPacket =
+ b_bit && (!l_bit || !vp9->inter_layer_predicted);
uint64_t rem_bits = parser.RemainingBitCount();
assert(rem_bits % 8 == 0);
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h b/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h
index abce7e7791..3feca4392a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h
@@ -25,7 +25,7 @@
#include <string>
#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
#include "webrtc/typedefs.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc
index 66ab5cdb71..5bbafe459d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc
@@ -55,7 +55,7 @@ void VerifyHeader(const RTPVideoHeaderVP9& expected,
actual.gof.temporal_up_switch[i]);
EXPECT_EQ(expected.gof.temporal_idx[i], actual.gof.temporal_idx[i]);
EXPECT_EQ(expected.gof.num_ref_pics[i], actual.gof.num_ref_pics[i]);
- for (size_t j = 0; j < expected.gof.num_ref_pics[i]; j++) {
+ for (uint8_t j = 0; j < expected.gof.num_ref_pics[i]; j++) {
EXPECT_EQ(expected.gof.pid_diff[i][j], actual.gof.pid_diff[i][j]);
}
}
@@ -112,7 +112,7 @@ void ParseAndCheckPacket(const uint8_t* packet,
// +-+-+-+-+-+-+-+-+
// M: | EXTENDED PID | (RECOMMENDED)
// +-+-+-+-+-+-+-+-+
-// L: |GOF_IDX| S |D| (CONDITIONALLY RECOMMENDED)
+// L: | T |U| S |D| (CONDITIONALLY RECOMMENDED)
// +-+-+-+-+-+-+-+-+
// | TL0PICIDX | (CONDITIONALLY REQUIRED)
// +-+-+-+-+-+-+-+-+
@@ -255,7 +255,8 @@ TEST_F(RtpPacketizerVp9Test, TestLayerInfoWithNonFlexibleMode) {
const size_t kFrameSize = 30;
const size_t kPacketSize = 25;
- expected_.gof_idx = 3;
+ expected_.temporal_idx = 3;
+ expected_.temporal_up_switch = true; // U
expected_.num_spatial_layers = 3;
expected_.spatial_idx = 2;
expected_.inter_layer_predicted = true; // D
@@ -264,9 +265,9 @@ TEST_F(RtpPacketizerVp9Test, TestLayerInfoWithNonFlexibleMode) {
// Two packets:
// | I:0, P:0, L:1, F:0, B:1, E:0, V:0 | (3hdr + 15 payload)
- // L: | GOF_IDX:3, S:2, D:1 | TL0PICIDX:117 |
+ // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 |
// | I:0, P:0, L:1, F:0, B:0, E:1, V:0 | (3hdr + 15 payload)
- // L: | GOF_IDX:3, S:2, D:1 | TL0PICIDX:117 |
+ // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 |
const size_t kExpectedHdrSizes[] = {3, 3};
const size_t kExpectedSizes[] = {18, 18};
const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes);
@@ -505,16 +506,20 @@ TEST_F(RtpDepacketizerVp9Test, ParseTwoBytePictureId) {
TEST_F(RtpDepacketizerVp9Test, ParseLayerInfoWithNonFlexibleMode) {
const uint8_t kHeaderLength = 3;
- const uint8_t kGofIdx = 7;
+ const uint8_t kTemporalIdx = 2;
+ const uint8_t kUbit = 1;
const uint8_t kSpatialIdx = 1;
const uint8_t kDbit = 1;
const uint8_t kTl0PicIdx = 17;
uint8_t packet[13] = {0};
packet[0] = 0x20; // I:0 P:0 L:1 F:0 B:0 E:0 V:0 R:0
- packet[1] = (kGofIdx << 4) | (kSpatialIdx << 1) | kDbit; // GOF_IDX:7 S:1 D:1
- packet[2] = kTl0PicIdx; // TL0PICIDX:17
+ packet[1] = (kTemporalIdx << 5) | (kUbit << 4) | (kSpatialIdx << 1) | kDbit;
+ packet[2] = kTl0PicIdx;
- expected_.gof_idx = kGofIdx;
+ // T:2 U:1 S:1 D:1
+ // TL0PICIDX:17
+ expected_.temporal_idx = kTemporalIdx;
+ expected_.temporal_up_switch = kUbit ? true : false;
expected_.spatial_idx = kSpatialIdx;
expected_.inter_layer_predicted = kDbit ? true : false;
expected_.tl0_pic_idx = kTl0PicIdx;
@@ -545,9 +550,9 @@ TEST_F(RtpDepacketizerVp9Test, ParseLayerInfoWithFlexibleMode) {
TEST_F(RtpDepacketizerVp9Test, ParseRefIdx) {
const uint8_t kHeaderLength = 6;
const int16_t kPictureId = 17;
- const int16_t kPdiff1 = 17;
- const int16_t kPdiff2 = 18;
- const int16_t kPdiff3 = 127;
+ const uint8_t kPdiff1 = 17;
+ const uint8_t kPdiff2 = 18;
+ const uint8_t kPdiff3 = 127;
uint8_t packet[13] = {0};
packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 R:0
packet[1] = 0x80 | ((kPictureId >> 8) & 0x7F); // Two byte pictureID.
@@ -577,7 +582,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseRefIdx) {
}
TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithNoPictureId) {
- const int16_t kPdiff = 3;
+ const uint8_t kPdiff = 3;
uint8_t packet[13] = {0};
packet[0] = 0x58; // I:0 P:1 L:0 F:1 B:1 E:0 V:0 R:0
packet[1] = (kPdiff << 1); // P,F: P_DIFF:3 N:0
@@ -587,7 +592,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithNoPictureId) {
}
TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithTooManyRefPics) {
- const int16_t kPdiff = 3;
+ const uint8_t kPdiff = 3;
uint8_t packet[13] = {0};
packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 R:0
packet[1] = kMaxOneBytePictureId; // I: PICTURE ID:127
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_extension.h b/webrtc/modules/rtp_rtcp/source/rtp_header_extension.h
index 7be3c2e5c4..342e38a1f2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extension.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extension.h
@@ -8,12 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_RTP_HEADER_EXTENSION_H_
-#define WEBRTC_MODULES_RTP_RTCP_RTP_HEADER_EXTENSION_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSION_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSION_H_
#include <map>
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -28,7 +28,7 @@ const size_t kVideoRotationLength = 2;
const size_t kTransportSequenceNumberLength = 3;
struct HeaderExtension {
- HeaderExtension(RTPExtensionType extension_type)
+ explicit HeaderExtension(RTPExtensionType extension_type)
: type(extension_type), length(0), active(true) {
Init();
}
@@ -112,6 +112,7 @@ class RtpHeaderExtensionMap {
int32_t Register(const RTPExtensionType type, const uint8_t id, bool active);
std::map<uint8_t, HeaderExtension*> extensionMap_;
};
-}
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSION_H_
-#endif // WEBRTC_MODULES_RTP_RTCP_RTP_HEADER_EXTENSION_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc
index 520cf7a962..ca37750621 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc
@@ -15,7 +15,7 @@
#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
#include "webrtc/typedefs.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_parser.cc b/webrtc/modules/rtp_rtcp/source/rtp_header_parser.cc
index 266bad8858..d4cbe544cc 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_parser.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_parser.cc
@@ -7,7 +7,7 @@
* 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/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
@@ -58,7 +58,7 @@ bool RtpHeaderParserImpl::Parse(const uint8_t* packet,
rtp_header_extension_map_.GetCopy(&map);
}
- const bool valid_rtpheader = rtp_parser.Parse(*header, &map);
+ const bool valid_rtpheader = rtp_parser.Parse(header, &map);
if (!valid_rtpheader) {
return false;
}
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc b/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc
index aa941d63ff..49f9d8530a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc
@@ -13,6 +13,8 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h> // memset
+
+#include <algorithm>
#include <limits>
#include <set>
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h b/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h
index e97d11eeaa..8e1a732b19 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h
@@ -10,14 +10,14 @@
* Class for storing RTP packets.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_RTP_PACKET_HISTORY_H_
-#define WEBRTC_MODULES_RTP_RTCP_RTP_PACKET_HISTORY_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
#include <vector>
#include "webrtc/base/thread_annotations.h"
-#include "webrtc/modules/interface/module_common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/include/module_common_types.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -29,7 +29,7 @@ static const size_t kMaxHistoryCapacity = 9600;
class RTPPacketHistory {
public:
- RTPPacketHistory(Clock* clock);
+ explicit RTPPacketHistory(Clock* clock);
~RTPPacketHistory();
void SetStorePacketsStatus(bool enable, uint16_t number_to_store);
@@ -101,4 +101,4 @@ class RTPPacketHistory {
std::vector<StoredPacket> stored_packets_ GUARDED_BY(critsect_);
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_RTP_PACKET_HISTORY_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
index 00a6ac7ed2..a406d8bc9b 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
@@ -12,10 +12,9 @@
#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h"
#include "webrtc/system_wrappers/include/clock.h"
-#include "webrtc/video_engine/vie_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -29,7 +28,7 @@ class RtpPacketHistoryTest : public ::testing::Test {
~RtpPacketHistoryTest() {
delete hist_;
}
-
+
SimulatedClock fake_clock_;
RTPPacketHistory* hist_;
enum {kPayload = 127};
@@ -54,7 +53,7 @@ class RtpPacketHistoryTest : public ::testing::Test {
array[(*cur_pos)++] = ssrc >> 16;
array[(*cur_pos)++] = ssrc >> 8;
array[(*cur_pos)++] = ssrc;
- }
+ }
};
TEST_F(RtpPacketHistoryTest, SetStoreStatus) {
@@ -268,6 +267,7 @@ TEST_F(RtpPacketHistoryTest, DynamicExpansion) {
}
TEST_F(RtpPacketHistoryTest, FullExpansion) {
+ static const int kSendSidePacketHistorySize = 600;
hist_->SetStorePacketsStatus(true, kSendSidePacketHistorySize);
size_t len;
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc b/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc
index 38d1450c23..ce0bcd7fed 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
@@ -40,7 +40,7 @@ int32_t RTPPayloadRegistry::RegisterReceivePayload(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const int8_t payload_type,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate,
bool* created_new_payload) {
assert(payload_type >= 0);
@@ -139,7 +139,7 @@ void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const size_t payload_name_length,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) {
RtpUtility::PayloadTypeMap::iterator iterator = payload_type_map_.begin();
for (; iterator != payload_type_map_.end(); ++iterator) {
@@ -171,7 +171,7 @@ void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
int32_t RTPPayloadRegistry::ReceivePayloadType(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate,
int8_t* payload_type) const {
assert(payload_type);
@@ -343,17 +343,16 @@ bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type,
int RTPPayloadRegistry::GetPayloadTypeFrequency(
uint8_t payload_type) const {
- RtpUtility::Payload* payload;
- if (!PayloadTypeToPayload(payload_type, payload)) {
+ const RtpUtility::Payload* payload = PayloadTypeToPayload(payload_type);
+ if (!payload) {
return -1;
}
CriticalSectionScoped cs(crit_sect_.get());
return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload);
}
-bool RTPPayloadRegistry::PayloadTypeToPayload(
- const uint8_t payload_type,
- RtpUtility::Payload*& payload) const {
+const RtpUtility::Payload* RTPPayloadRegistry::PayloadTypeToPayload(
+ uint8_t payload_type) const {
CriticalSectionScoped cs(crit_sect_.get());
RtpUtility::PayloadTypeMap::const_iterator it =
@@ -361,11 +360,10 @@ bool RTPPayloadRegistry::PayloadTypeToPayload(
// Check that this is a registered payload type.
if (it == payload_type_map_.end()) {
- return false;
+ return nullptr;
}
- payload = it->second;
- return true;
+ return it->second;
}
void RTPPayloadRegistry::SetIncomingPayloadType(const RTPHeader& header) {
@@ -390,7 +388,7 @@ class RTPPayloadAudioStrategy : public RTPPayloadStrategy {
bool PayloadIsCompatible(const RtpUtility::Payload& payload,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) const override {
return
payload.audio &&
@@ -409,7 +407,7 @@ class RTPPayloadAudioStrategy : public RTPPayloadStrategy {
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int8_t payloadType,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) const override {
RtpUtility::Payload* payload = new RtpUtility::Payload;
payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
@@ -433,7 +431,7 @@ class RTPPayloadVideoStrategy : public RTPPayloadStrategy {
bool PayloadIsCompatible(const RtpUtility::Payload& payload,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) const override {
return !payload.audio;
}
@@ -447,7 +445,7 @@ class RTPPayloadVideoStrategy : public RTPPayloadStrategy {
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int8_t payloadType,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) const override {
RtpVideoCodecTypes videoType = kRtpVideoGeneric;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
index 0b9bf2751e..b73666d1af 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
@@ -8,12 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
@@ -25,7 +25,7 @@ using ::testing::Return;
using ::testing::_;
static const char* kTypicalPayloadName = "name";
-static const uint8_t kTypicalChannels = 1;
+static const size_t kTypicalChannels = 1;
static const int kTypicalFrequency = 44000;
static const int kTypicalRate = 32 * 1024;
@@ -52,10 +52,9 @@ class RtpPayloadRegistryTest : public ::testing::Test {
RtpUtility::Payload* returned_payload_on_heap =
new RtpUtility::Payload(returned_payload);
EXPECT_CALL(*mock_payload_strategy_,
- CreatePayloadType(kTypicalPayloadName, payload_type,
- kTypicalFrequency,
- kTypicalChannels,
- rate)).WillOnce(Return(returned_payload_on_heap));
+ CreatePayloadType(kTypicalPayloadName, payload_type,
+ kTypicalFrequency, kTypicalChannels, rate))
+ .WillOnce(Return(returned_payload_on_heap));
return returned_payload_on_heap;
}
@@ -70,14 +69,14 @@ TEST_F(RtpPayloadRegistryTest, RegistersAndRemembersPayloadsUntilDeregistered) {
bool new_payload_created = false;
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
- kTypicalRate, &new_payload_created));
+ kTypicalPayloadName, payload_type, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &new_payload_created));
EXPECT_TRUE(new_payload_created) << "A new payload WAS created.";
- RtpUtility::Payload* retrieved_payload = NULL;
- EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
- retrieved_payload));
+ const RtpUtility::Payload* retrieved_payload =
+ rtp_payload_registry_->PayloadTypeToPayload(payload_type);
+ EXPECT_TRUE(retrieved_payload);
// We should get back the exact pointer to the payload returned by the
// payload strategy.
@@ -85,32 +84,30 @@ TEST_F(RtpPayloadRegistryTest, RegistersAndRemembersPayloadsUntilDeregistered) {
// Now forget about it and verify it's gone.
EXPECT_EQ(0, rtp_payload_registry_->DeRegisterReceivePayload(payload_type));
- EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
- payload_type, retrieved_payload));
+ EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(payload_type));
}
TEST_F(RtpPayloadRegistryTest, AudioRedWorkProperly) {
const uint8_t kRedPayloadType = 127;
const int kRedSampleRate = 8000;
- const int kRedChannels = 1;
+ const size_t kRedChannels = 1;
const int kRedBitRate = 0;
// This creates an audio RTP payload strategy.
- rtp_payload_registry_.reset(new RTPPayloadRegistry(
- RTPPayloadStrategy::CreateStrategy(true)));
+ rtp_payload_registry_.reset(
+ new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(true)));
bool new_payload_created = false;
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- "red", kRedPayloadType, kRedSampleRate, kRedChannels, kRedBitRate,
- &new_payload_created));
+ "red", kRedPayloadType, kRedSampleRate, kRedChannels,
+ kRedBitRate, &new_payload_created));
EXPECT_TRUE(new_payload_created);
EXPECT_EQ(kRedPayloadType, rtp_payload_registry_->red_payload_type());
- RtpUtility::Payload* retrieved_payload = NULL;
- EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(kRedPayloadType,
- retrieved_payload));
- ASSERT_TRUE(retrieved_payload);
+ const RtpUtility::Payload* retrieved_payload =
+ rtp_payload_registry_->PayloadTypeToPayload(kRedPayloadType);
+ EXPECT_TRUE(retrieved_payload);
EXPECT_TRUE(retrieved_payload->audio);
EXPECT_STRCASEEQ("red", retrieved_payload->name);
@@ -127,27 +124,29 @@ TEST_F(RtpPayloadRegistryTest,
RtpUtility::Payload* first_payload_on_heap =
ExpectReturnOfTypicalAudioPayload(payload_type, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
- kTypicalRate, &ignored));
+ kTypicalPayloadName, payload_type, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &ignored));
EXPECT_EQ(-1, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
- kTypicalRate, &ignored)) << "Adding same codec twice = bad.";
+ kTypicalPayloadName, payload_type, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &ignored))
+ << "Adding same codec twice = bad.";
RtpUtility::Payload* second_payload_on_heap =
ExpectReturnOfTypicalAudioPayload(payload_type - 1, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
- kTypicalChannels, kTypicalRate, &ignored)) <<
- "With a different payload type is fine though.";
+ kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &ignored))
+ << "With a different payload type is fine though.";
// Ensure both payloads are preserved.
- RtpUtility::Payload* retrieved_payload = NULL;
- EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
- retrieved_payload));
+ const RtpUtility::Payload* retrieved_payload =
+ rtp_payload_registry_->PayloadTypeToPayload(payload_type);
+ EXPECT_TRUE(retrieved_payload);
EXPECT_EQ(first_payload_on_heap, retrieved_payload);
- EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1,
- retrieved_payload));
+ retrieved_payload =
+ rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1);
+ EXPECT_TRUE(retrieved_payload);
EXPECT_EQ(second_payload_on_heap, retrieved_payload);
// Ok, update the rate for one of the codecs. If either the incoming rate or
@@ -158,8 +157,8 @@ TEST_F(RtpPayloadRegistryTest,
EXPECT_CALL(*mock_payload_strategy_,
UpdatePayloadRate(first_payload_on_heap, kTypicalRate));
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
- kTypicalRate, &ignored));
+ kTypicalPayloadName, payload_type, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &ignored));
}
TEST_F(RtpPayloadRegistryTest,
@@ -174,35 +173,31 @@ TEST_F(RtpPayloadRegistryTest,
bool ignored = false;
ExpectReturnOfTypicalAudioPayload(payload_type, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
- kTypicalRate, &ignored));
+ kTypicalPayloadName, payload_type, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &ignored));
ExpectReturnOfTypicalAudioPayload(payload_type - 1, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
- kTypicalChannels, kTypicalRate, &ignored));
+ kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &ignored));
- RtpUtility::Payload* retrieved_payload = NULL;
- EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
- payload_type, retrieved_payload)) << "The first payload should be "
- "deregistered because the only thing that differs is payload type.";
- EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
- payload_type - 1, retrieved_payload)) <<
- "The second payload should still be registered though.";
+ EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(payload_type))
+ << "The first payload should be "
+ "deregistered because the only thing that differs is payload type.";
+ EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1))
+ << "The second payload should still be registered though.";
// Now ensure non-compatible codecs aren't removed.
ON_CALL(*mock_payload_strategy_, PayloadIsCompatible(_, _, _, _))
.WillByDefault(Return(false));
ExpectReturnOfTypicalAudioPayload(payload_type + 1, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, payload_type + 1, kTypicalFrequency,
- kTypicalChannels, kTypicalRate, &ignored));
-
- EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
- payload_type - 1, retrieved_payload)) <<
- "Not compatible; both payloads should be kept.";
- EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
- payload_type + 1, retrieved_payload)) <<
- "Not compatible; both payloads should be kept.";
+ kTypicalPayloadName, payload_type + 1, kTypicalFrequency,
+ kTypicalChannels, kTypicalRate, &ignored));
+
+ EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1))
+ << "Not compatible; both payloads should be kept.";
+ EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type + 1))
+ << "Not compatible; both payloads should be kept.";
}
TEST_F(RtpPayloadRegistryTest,
@@ -218,18 +213,17 @@ TEST_F(RtpPayloadRegistryTest,
bool ignored;
ExpectReturnOfTypicalAudioPayload(34, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
- kTypicalPayloadName, 34, kTypicalFrequency, kTypicalChannels,
- kTypicalRate, &ignored));
+ kTypicalPayloadName, 34, kTypicalFrequency, kTypicalChannels,
+ kTypicalRate, &ignored));
EXPECT_EQ(-1, rtp_payload_registry_->last_received_payload_type());
media_type_unchanged = rtp_payload_registry_->ReportMediaPayloadType(18);
EXPECT_FALSE(media_type_unchanged);
}
-class ParameterizedRtpPayloadRegistryTest :
- public RtpPayloadRegistryTest,
- public ::testing::WithParamInterface<int> {
-};
+class ParameterizedRtpPayloadRegistryTest
+ : public RtpPayloadRegistryTest,
+ public ::testing::WithParamInterface<int> {};
TEST_P(ParameterizedRtpPayloadRegistryTest,
FailsToRegisterKnownPayloadsWeAreNotInterestedIn) {
@@ -237,26 +231,26 @@ TEST_P(ParameterizedRtpPayloadRegistryTest,
bool ignored;
EXPECT_EQ(-1, rtp_payload_registry_->RegisterReceivePayload(
- "whatever", static_cast<uint8_t>(payload_type), 19, 1, 17, &ignored));
+ "whatever", static_cast<uint8_t>(payload_type), 19, 1, 17,
+ &ignored));
}
INSTANTIATE_TEST_CASE_P(TestKnownBadPayloadTypes,
ParameterizedRtpPayloadRegistryTest,
testing::Values(64, 72, 73, 74, 75, 76, 77, 78, 79));
-class RtpPayloadRegistryGenericTest :
- public RtpPayloadRegistryTest,
- public ::testing::WithParamInterface<int> {
-};
+class RtpPayloadRegistryGenericTest
+ : public RtpPayloadRegistryTest,
+ public ::testing::WithParamInterface<int> {};
TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) {
int payload_type = GetParam();
bool ignored;
- EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload("generic-codec",
- static_cast<int8_t>(payload_type),
- 19, 1, 17, &ignored)); // dummy values, except for payload_type
+ EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
+ "generic-codec", static_cast<int8_t>(payload_type), 19, 1,
+ 17, &ignored)); // dummy values, except for payload_type
}
// Generates an RTX packet for the given length and original sequence number.
@@ -395,7 +389,8 @@ TEST_F(RtpPayloadRegistryTest, InvalidRtxConfiguration) {
TestRtxPacket(rtp_payload_registry_.get(), 106, 0, false);
}
-INSTANTIATE_TEST_CASE_P(TestDynamicRange, RtpPayloadRegistryGenericTest,
- testing::Range(96, 127+1));
+INSTANTIATE_TEST_CASE_P(TestDynamicRange,
+ RtpPayloadRegistryGenericTest,
+ testing::Range(96, 127 + 1));
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h
index 176852e01e..1dd07d1cc9 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h
@@ -14,8 +14,8 @@
#include <set>
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/typedefs.h"
@@ -42,9 +42,7 @@ class RTPReceiverAudio : public RTPReceiverStrategy,
// Is TelephoneEvent configured with payload type payload_type
bool TelephoneEventPayloadType(const int8_t payload_type) const;
- TelephoneEventHandler* GetTelephoneEventHandler() {
- return this;
- }
+ TelephoneEventHandler* GetTelephoneEventHandler() { return this; }
// Returns true if CNG is configured with payload type payload_type. If so,
// the frequency and cng_payload_type_has_changed are filled in.
@@ -96,13 +94,11 @@ class RTPReceiverAudio : public RTPReceiverStrategy,
int Energy(uint8_t array_of_energy[kRtpCsrcSize]) const override;
private:
-
- int32_t ParseAudioCodecSpecific(
- WebRtcRTPHeader* rtp_header,
- const uint8_t* payload_data,
- size_t payload_length,
- const AudioPayload& audio_specific,
- bool is_red);
+ int32_t ParseAudioCodecSpecific(WebRtcRTPHeader* rtp_header,
+ const uint8_t* payload_data,
+ size_t payload_length,
+ const AudioPayload& audio_specific,
+ bool is_red);
uint32_t last_received_frequency_;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc
index e1ebd0c8bb..2e21f230d3 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc
@@ -16,13 +16,12 @@
#include <string.h>
#include "webrtc/base/logging.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
namespace webrtc {
-using RtpUtility::GetCurrentRTP;
using RtpUtility::Payload;
using RtpUtility::StringCompare;
@@ -97,7 +96,7 @@ int32_t RtpReceiverImpl::RegisterReceivePayload(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const int8_t payload_type,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) {
CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
@@ -170,7 +169,7 @@ bool RtpReceiverImpl::IncomingRtpPacket(
int8_t first_payload_byte = payload_length > 0 ? payload[0] : 0;
bool is_red = false;
- if (CheckPayloadChanged(rtp_header, first_payload_byte, is_red,
+ if (CheckPayloadChanged(rtp_header, first_payload_byte, &is_red,
&payload_specific) == -1) {
if (payload_length == 0) {
// OK, keep-alive packet.
@@ -253,7 +252,7 @@ void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
bool new_ssrc = false;
bool re_initialize_decoder = false;
char payload_name[RTP_PAYLOAD_NAME_SIZE];
- uint8_t channels = 1;
+ size_t channels = 1;
uint32_t rate = 0;
{
@@ -276,12 +275,11 @@ void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
if (rtp_header.payloadType == last_received_payload_type) {
re_initialize_decoder = true;
- Payload* payload;
- if (!rtp_payload_registry_->PayloadTypeToPayload(
- rtp_header.payloadType, payload)) {
+ const Payload* payload = rtp_payload_registry_->PayloadTypeToPayload(
+ rtp_header.payloadType);
+ if (!payload) {
return;
}
- assert(payload);
payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
if (payload->audio) {
@@ -321,7 +319,7 @@ void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
// last known payload).
int32_t RtpReceiverImpl::CheckPayloadChanged(const RTPHeader& rtp_header,
const int8_t first_payload_byte,
- bool& is_red,
+ bool* is_red,
PayloadUnion* specific_payload) {
bool re_initialize_decoder = false;
@@ -339,7 +337,7 @@ int32_t RtpReceiverImpl::CheckPayloadChanged(const RTPHeader& rtp_header,
if (rtp_payload_registry_->red_payload_type() == payload_type) {
// Get the real codec payload type.
payload_type = first_payload_byte & 0x7f;
- is_red = true;
+ *is_red = true;
if (rtp_payload_registry_->red_payload_type() == payload_type) {
// Invalid payload type, traced by caller. If we proceeded here,
@@ -361,16 +359,16 @@ int32_t RtpReceiverImpl::CheckPayloadChanged(const RTPHeader& rtp_header,
&should_discard_changes);
if (should_discard_changes) {
- is_red = false;
+ *is_red = false;
return 0;
}
- Payload* payload;
- if (!rtp_payload_registry_->PayloadTypeToPayload(payload_type, payload)) {
+ const Payload* payload =
+ rtp_payload_registry_->PayloadTypeToPayload(payload_type);
+ if (!payload) {
// Not a registered payload type.
return -1;
}
- assert(payload);
payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
@@ -391,7 +389,7 @@ int32_t RtpReceiverImpl::CheckPayloadChanged(const RTPHeader& rtp_header,
}
} else {
rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
- is_red = false;
+ *is_red = false;
}
} // End critsect.
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h
index 46741d59b4..5cf94c2859 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h
@@ -12,8 +12,8 @@
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/typedefs.h"
@@ -36,7 +36,7 @@ class RtpReceiverImpl : public RtpReceiver {
int32_t RegisterReceivePayload(const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const int8_t payload_type,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) override;
int32_t DeRegisterReceivePayload(const int8_t payload_type) override;
@@ -71,7 +71,7 @@ class RtpReceiverImpl : public RtpReceiver {
void CheckCSRC(const WebRtcRTPHeader& rtp_header);
int32_t CheckPayloadChanged(const RTPHeader& rtp_header,
const int8_t first_payload_byte,
- bool& is_red,
+ bool* is_red,
PayloadUnion* payload);
Clock* clock_;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
index 37c3e6e49a..0f7ad30e87 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
@@ -12,8 +12,8 @@
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_STRATEGY_H_
#include "webrtc/base/scoped_ptr.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/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/typedefs.h"
@@ -95,7 +95,7 @@ class RTPReceiverStrategy {
// Note: Implementations may call the callback for other reasons than calls
// to ParseRtpPacket, for instance if the implementation somehow recovers a
// packet.
- RTPReceiverStrategy(RtpData* data_callback);
+ explicit RTPReceiverStrategy(RtpData* data_callback);
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
PayloadUnion last_payload_;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
index 1af2d4857e..53051dd321 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
@@ -16,8 +16,8 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/trace_event.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h
index 23128df6e1..56f761a2e1 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h
@@ -12,7 +12,7 @@
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_VIDEO_H_
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h
index 7cfebd91a8..a2cd52736f 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h
@@ -13,36 +13,37 @@
// Configuration file for RTP utilities (RTPSender, RTPReceiver ...)
namespace webrtc {
-enum { NACK_BYTECOUNT_SIZE = 60}; // size of our NACK history
+enum { NACK_BYTECOUNT_SIZE = 60 }; // size of our NACK history
// A sanity for the NACK list parsing at the send-side.
enum { kSendSideNackListSizeSanity = 20000 };
enum { kDefaultMaxReorderingThreshold = 50 }; // In sequence numbers.
enum { kRtcpMaxNackFields = 253 };
-enum { RTCP_INTERVAL_VIDEO_MS = 1000 };
-enum { RTCP_INTERVAL_AUDIO_MS = 5000 };
-enum { RTCP_SEND_BEFORE_KEY_FRAME_MS= 100 };
-enum { RTCP_MAX_REPORT_BLOCKS = 31}; // RFC 3550 page 37
-enum { RTCP_MIN_FRAME_LENGTH_MS = 17};
-enum { kRtcpAppCode_DATA_SIZE = 32*4}; // multiple of 4, this is not a limitation of the size
-enum { RTCP_RPSI_DATA_SIZE = 30};
-enum { RTCP_NUMBER_OF_SR = 60 };
-
-enum { MAX_NUMBER_OF_TEMPORAL_ID = 8 }; // RFC
-enum { MAX_NUMBER_OF_DEPENDENCY_QUALITY_ID = 128 };// RFC
+enum { RTCP_INTERVAL_VIDEO_MS = 1000 };
+enum { RTCP_INTERVAL_AUDIO_MS = 5000 };
+enum { RTCP_SEND_BEFORE_KEY_FRAME_MS = 100 };
+enum { RTCP_MAX_REPORT_BLOCKS = 31 }; // RFC 3550 page 37
+enum { RTCP_MIN_FRAME_LENGTH_MS = 17 };
+enum {
+ kRtcpAppCode_DATA_SIZE = 32 * 4
+}; // multiple of 4, this is not a limitation of the size
+enum { RTCP_RPSI_DATA_SIZE = 30 };
+enum { RTCP_NUMBER_OF_SR = 60 };
+
+enum { MAX_NUMBER_OF_TEMPORAL_ID = 8 }; // RFC
+enum { MAX_NUMBER_OF_DEPENDENCY_QUALITY_ID = 128 }; // RFC
enum { MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS = 255 };
-enum { BW_HISTORY_SIZE = 35};
+enum { BW_HISTORY_SIZE = 35 };
-#define MIN_AUDIO_BW_MANAGEMENT_BITRATE 6
-#define MIN_VIDEO_BW_MANAGEMENT_BITRATE 30
+#define MIN_AUDIO_BW_MANAGEMENT_BITRATE 6
+#define MIN_VIDEO_BW_MANAGEMENT_BITRATE 30
-enum { DTMF_OUTBAND_MAX = 20};
+enum { DTMF_OUTBAND_MAX = 20 };
enum { RTP_MAX_BURST_SLEEP_TIME = 500 };
enum { RTP_AUDIO_LEVEL_UNIQUE_ID = 0xbede };
-enum { RTP_MAX_PACKETS_PER_FRAME= 512 }; // must be multiple of 32
+enum { RTP_MAX_PACKETS_PER_FRAME = 512 }; // must be multiple of 32
} // namespace webrtc
-
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_CONFIG_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_CONFIG_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 451f8bfa93..450eed698e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -183,8 +183,13 @@ int32_t ModuleRtpRtcpImpl::Process() {
set_rtt_ms(rtt_stats_->LastProcessedRtt());
}
- if (rtcp_sender_.TimeToSendRTCPReport())
- rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
+ // For sending streams, make sure to not send a SR before media has been sent.
+ if (rtcp_sender_.TimeToSendRTCPReport()) {
+ RTCPSender::FeedbackState state = GetFeedbackState();
+ // Prevent sending streams to send SR before any media has been sent.
+ if (!rtcp_sender_.Sending() || state.packets_sent > 0)
+ rtcp_sender_.SendRTCP(state, kRtcpReport);
+ }
if (UpdateRTCPReceiveInformationTimers()) {
// A receiver has timed out
@@ -402,6 +407,7 @@ int32_t ModuleRtpRtcpImpl::SendOutgoingData(
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* rtp_video_hdr) {
rtcp_sender_.SetLastRtpTime(time_stamp, capture_time_ms);
+ // Make sure an RTCP report isn't queued behind a key frame.
if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
}
@@ -794,9 +800,8 @@ int32_t ModuleRtpRtcpImpl::SetSendREDPayloadType(
}
// Get payload type for Redundant Audio Data RFC 2198.
-int32_t ModuleRtpRtcpImpl::SendREDPayloadType(
- int8_t& payload_type) const {
- return rtp_sender_.RED(&payload_type);
+int32_t ModuleRtpRtcpImpl::SendREDPayloadType(int8_t* payload_type) const {
+ return rtp_sender_.RED(payload_type);
}
void ModuleRtpRtcpImpl::SetTargetSendBitrate(uint32_t bitrate_bps) {
@@ -832,11 +837,10 @@ void ModuleRtpRtcpImpl::SetGenericFECStatus(
rtp_sender_.SetGenericFECStatus(enable, payload_type_red, payload_type_fec);
}
-void ModuleRtpRtcpImpl::GenericFECStatus(bool& enable,
- uint8_t& payload_type_red,
- uint8_t& payload_type_fec) {
- rtp_sender_.GenericFECStatus(&enable, &payload_type_red,
- &payload_type_fec);
+void ModuleRtpRtcpImpl::GenericFECStatus(bool* enable,
+ uint8_t* payload_type_red,
+ uint8_t* payload_type_fec) {
+ rtp_sender_.GenericFECStatus(enable, payload_type_red, payload_type_fec);
}
int32_t ModuleRtpRtcpImpl::SetFecParameters(
@@ -952,8 +956,8 @@ bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() {
}
// Called from RTCPsender.
-int32_t ModuleRtpRtcpImpl::BoundingSet(bool& tmmbr_owner,
- TMMBRSet*& bounding_set) {
+int32_t ModuleRtpRtcpImpl::BoundingSet(bool* tmmbr_owner,
+ TMMBRSet* bounding_set) {
return rtcp_receiver_.BoundingSet(tmmbr_owner, bounding_set);
}
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index c9b6686c0a..04e09c1217 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -12,10 +12,12 @@
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL_H_
#include <list>
+#include <set>
+#include <utility>
#include <vector>
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/source/packet_loss_stats.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
@@ -258,7 +260,7 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
int32_t SetSendREDPayloadType(int8_t payload_type) override;
// Get payload type for Redundant Audio Data RFC 2198.
- int32_t SendREDPayloadType(int8_t& payload_type) const override;
+ int32_t SendREDPayloadType(int8_t* payload_type) const override;
// Store the audio level in d_bov for header-extension-for-audio-level-
// indication.
@@ -280,9 +282,9 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
uint8_t payload_type_red,
uint8_t payload_type_fec) override;
- void GenericFECStatus(bool& enable,
- uint8_t& payload_type_red,
- uint8_t& payload_type_fec) override;
+ void GenericFECStatus(bool* enable,
+ uint8_t* payload_type_red,
+ uint8_t* payload_type_fec) override;
int32_t SetFecParameters(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params) override;
@@ -293,7 +295,7 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
bool LastReceivedXrReferenceTimeInfo(RtcpReceiveTimeInfo* info) const;
- virtual int32_t BoundingSet(bool& tmmbr_owner, TMMBRSet*& bounding_set_rec);
+ int32_t BoundingSet(bool* tmmbr_owner, TMMBRSet* bounding_set_rec);
void BitrateSent(uint32_t* total_rate,
uint32_t* video_rate,
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index 4c94764ee6..8329f603f9 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -8,13 +8,17 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <map>
+#include <set>
+
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
#include "webrtc/test/rtcp_packet_parser.h"
@@ -94,7 +98,7 @@ class SendTransport : public Transport,
class RtpRtcpModule : public RtcpPacketTypeCounterObserver {
public:
- RtpRtcpModule(SimulatedClock* clock)
+ explicit RtpRtcpModule(SimulatedClock* clock)
: receive_statistics_(ReceiveStatistics::Create(clock)) {
RtpRtcp::Configuration config;
config.audio = false;
@@ -346,6 +350,27 @@ TEST_F(RtpRtcpImplTest, RttForReceiverOnly) {
EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms());
}
+TEST_F(RtpRtcpImplTest, NoSrBeforeMedia) {
+ // Ignore fake transport delays in this test.
+ sender_.transport_.SimulateNetworkDelay(0, &clock_);
+ receiver_.transport_.SimulateNetworkDelay(0, &clock_);
+
+ sender_.impl_->Process();
+ EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
+
+ // Verify no SR is sent before media has been sent, RR should still be sent
+ // from the receiving module though.
+ clock_.AdvanceTimeMilliseconds(2000);
+ int64_t current_time = clock_.TimeInMilliseconds();
+ sender_.impl_->Process();
+ receiver_.impl_->Process();
+ EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
+ EXPECT_EQ(receiver_.RtcpSent().first_packet_time_ms, current_time);
+
+ SendFrame(&sender_, kBaseLayerTid);
+ EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, current_time);
+}
+
TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_Nack) {
EXPECT_EQ(-1, receiver_.RtcpSent().first_packet_time_ms);
EXPECT_EQ(-1, sender_.RtcpReceived().first_packet_time_ms);
@@ -522,5 +547,4 @@ TEST_F(RtpRtcpImplTest, UniqueNackRequests) {
EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests);
EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent());
}
-
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
index 50f476829d..f4933afdd9 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -11,15 +11,17 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
#include <stdlib.h> // srand
+#include <algorithm>
#include <utility>
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/trace_event.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h"
+#include "webrtc/modules/rtp_rtcp/source/time_util.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/tick_util.h"
@@ -33,6 +35,7 @@ static const uint32_t kAbsSendTimeFraction = 18;
namespace {
const size_t kRtpHeaderLength = 12;
+const uint16_t kMaxInitRtpSeqNumber = 32767; // 2^15 -1.
const char* FrameTypeToString(FrameType frame_type) {
switch (frame_type) {
@@ -125,6 +128,7 @@ RTPSender::RTPSender(
// TickTime.
clock_delta_ms_(clock_->TimeInMilliseconds() -
TickTime::MillisecondTimestamp()),
+ random_(clock_->TimeInMicroseconds()),
bitrates_(new BitrateAggregator(bitrate_callback)),
total_bitrate_sent_(clock, bitrates_->total_bitrate_observer()),
audio_configured_(audio),
@@ -182,8 +186,8 @@ RTPSender::RTPSender(
ssrc_rtx_ = ssrc_db_.CreateSSRC(); // Can't be 0.
bitrates_->set_ssrc(ssrc_);
// Random start, 16 bits. Can't be 0.
- sequence_number_rtx_ = static_cast<uint16_t>(rand() + 1) & 0x7FFF;
- sequence_number_ = static_cast<uint16_t>(rand() + 1) & 0x7FFF;
+ sequence_number_rtx_ = random_.Rand(1, kMaxInitRtpSeqNumber);
+ sequence_number_ = random_.Rand(1, kMaxInitRtpSeqNumber);
}
RTPSender::~RTPSender() {
@@ -292,7 +296,7 @@ int32_t RTPSender::RegisterPayload(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
int8_t payload_number,
uint32_t frequency,
- uint8_t channels,
+ size_t channels,
uint32_t rate) {
assert(payload_name);
CriticalSectionScoped cs(send_critsect_.get());
@@ -323,11 +327,11 @@ int32_t RTPSender::RegisterPayload(
return -1;
}
int32_t ret_val = 0;
- RtpUtility::Payload* payload = NULL;
+ RtpUtility::Payload* payload = nullptr;
if (audio_configured_) {
// TODO(mflodman): Change to CreateAudioPayload and make static.
ret_val = audio_->RegisterAudioPayload(payload_name, payload_number,
- frequency, channels, rate, payload);
+ frequency, channels, rate, &payload);
} else {
payload = video_->CreateVideoPayload(payload_name, payload_number, rate);
}
@@ -452,7 +456,7 @@ int32_t RTPSender::CheckPayloadType(int8_t payload_type,
}
if (audio_configured_) {
int8_t red_pl_type = -1;
- if (audio_->RED(red_pl_type) == 0) {
+ if (audio_->RED(&red_pl_type) == 0) {
// We have configured RED.
if (red_pl_type == payload_type) {
// And it's a match...
@@ -469,7 +473,8 @@ int32_t RTPSender::CheckPayloadType(int8_t payload_type,
std::map<int8_t, RtpUtility::Payload*>::iterator it =
payload_type_map_.find(payload_type);
if (it == payload_type_map_.end()) {
- LOG(LS_WARNING) << "Payload type " << payload_type << " not registered.";
+ LOG(LS_WARNING) << "Payload type " << static_cast<int>(payload_type)
+ << " not registered.";
return -1;
}
SetSendPayloadType(payload_type);
@@ -512,7 +517,8 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type,
}
RtpVideoCodecTypes video_type = kRtpVideoGeneric;
if (CheckPayloadType(payload_type, &video_type) != 0) {
- LOG(LS_ERROR) << "Don't send data with unknown payload type.";
+ LOG(LS_ERROR) << "Don't send data with unknown payload type: "
+ << static_cast<int>(payload_type) << ".";
return -1;
}
@@ -573,7 +579,7 @@ size_t RTPSender::TrySendRedundantPayloads(size_t bytes_to_send) {
break;
RtpUtility::RtpHeaderParser rtp_parser(buffer, length);
RTPHeader rtp_header;
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
bytes_left -= static_cast<int>(length - rtp_header.headerLength);
}
return bytes_to_send - bytes_left;
@@ -583,8 +589,7 @@ void RTPSender::BuildPaddingPacket(uint8_t* packet,
size_t header_length,
size_t padding_length) {
packet[0] |= 0x20; // Set padding bit.
- int32_t *data =
- reinterpret_cast<int32_t *>(&(packet[header_length]));
+ int32_t* data = reinterpret_cast<int32_t*>(&(packet[header_length]));
// Fill data buffer with random data.
for (size_t j = 0; j < (padding_length >> 2); ++j) {
@@ -665,7 +670,7 @@ size_t RTPSender::SendPadData(size_t bytes,
RtpUtility::RtpHeaderParser rtp_parser(padding_packet, length);
RTPHeader rtp_header;
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
if (capture_time_ms > 0) {
UpdateTransmissionTimeOffset(
@@ -717,7 +722,7 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, int64_t min_resend_time) {
if (paced_sender_) {
RtpUtility::RtpHeaderParser rtp_parser(data_buffer, length);
RTPHeader header;
- if (!rtp_parser.Parse(header)) {
+ if (!rtp_parser.Parse(&header)) {
assert(false);
return -1;
}
@@ -725,7 +730,7 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, int64_t min_resend_time) {
// TickTime.
int64_t corrected_capture_tims_ms = capture_time_ms + clock_delta_ms_;
paced_sender_->InsertPacket(
- RtpPacketSender::kHighPriority, header.ssrc, header.sequenceNumber,
+ RtpPacketSender::kNormalPriority, header.ssrc, header.sequenceNumber,
corrected_capture_tims_ms, length - header.headerLength, true);
return length;
@@ -903,11 +908,11 @@ bool RTPSender::PrepareAndSendPacket(uint8_t* buffer,
int64_t capture_time_ms,
bool send_over_rtx,
bool is_retransmit) {
- uint8_t *buffer_to_send_ptr = buffer;
+ uint8_t* buffer_to_send_ptr = buffer;
RtpUtility::RtpHeaderParser rtp_parser(buffer, length);
RTPHeader rtp_header;
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
if (!is_retransmit && rtp_header.markerBit) {
TRACE_EVENT_ASYNC_END0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PacedSend",
capture_time_ms);
@@ -996,14 +1001,14 @@ bool RTPSender::IsFecPacket(const uint8_t* buffer,
bool fec_enabled;
uint8_t pt_red;
uint8_t pt_fec;
- video_->GenericFECStatus(fec_enabled, pt_red, pt_fec);
+ video_->GenericFECStatus(&fec_enabled, &pt_red, &pt_fec);
return fec_enabled &&
header.payloadType == pt_red &&
buffer[header.headerLength] == pt_fec;
}
size_t RTPSender::TimeToSendPadding(size_t bytes) {
- if (bytes == 0)
+ if (audio_configured_ || bytes == 0)
return 0;
{
CriticalSectionScoped cs(send_critsect_.get());
@@ -1026,7 +1031,7 @@ int32_t RTPSender::SendToNetwork(uint8_t* buffer,
RtpUtility::RtpHeaderParser rtp_parser(buffer,
payload_length + rtp_header_length);
RTPHeader rtp_header;
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
int64_t now_ms = clock_->TimeInMilliseconds();
@@ -1169,7 +1174,7 @@ size_t RTPSender::CreateRtpHeader(uint8_t* header,
int32_t rtp_header_length = kRtpHeaderLength;
if (csrcs.size() > 0) {
- uint8_t *ptr = &header[rtp_header_length];
+ uint8_t* ptr = &header[rtp_header_length];
for (size_t i = 0; i < csrcs.size(); ++i) {
ByteWriter<uint32_t>::WriteBigEndian(ptr, csrcs[i]);
ptr += 4;
@@ -1638,7 +1643,7 @@ uint16_t RTPSender::UpdateTransportSequenceNumber(
void RTPSender::SetSendingStatus(bool enabled) {
if (enabled) {
uint32_t frequency_hz = SendPayloadFrequency();
- uint32_t RTPtime = RtpUtility::GetCurrentRTP(clock_, frequency_hz);
+ uint32_t RTPtime = CurrentRtp(*clock_, frequency_hz);
// Will be ignored if it's already configured via API.
SetStartTimestamp(RTPtime, false);
@@ -1653,8 +1658,7 @@ void RTPSender::SetSendingStatus(bool enabled) {
// Don't initialize seq number if SSRC passed externally.
if (!sequence_number_forced_ && !ssrc_forced_) {
// Generate a new sequence number.
- sequence_number_ =
- rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); // NOLINT
+ sequence_number_ = random_.Rand(1, kMaxInitRtpSeqNumber);
}
}
}
@@ -1716,8 +1720,7 @@ void RTPSender::SetSSRC(uint32_t ssrc) {
ssrc_ = ssrc;
bitrates_->set_ssrc(ssrc_);
if (!sequence_number_forced_) {
- sequence_number_ =
- rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); // NOLINT
+ sequence_number_ = random_.Rand(1, kMaxInitRtpSeqNumber);
}
}
@@ -1775,7 +1778,7 @@ int32_t RTPSender::RED(int8_t *payload_type) const {
if (!audio_configured_) {
return -1;
}
- return audio_->RED(*payload_type);
+ return audio_->RED(payload_type);
}
RtpVideoCodecTypes RTPSender::VideoCodecType() const {
@@ -1801,7 +1804,7 @@ void RTPSender::GenericFECStatus(bool* enable,
uint8_t* payload_type_red,
uint8_t* payload_type_fec) const {
RTC_DCHECK(!audio_configured_);
- video_->GenericFECStatus(*enable, *payload_type_red, *payload_type_fec);
+ video_->GenericFECStatus(enable, payload_type_red, payload_type_fec);
}
int32_t RTPSender::SetFecParameters(
@@ -1823,7 +1826,7 @@ void RTPSender::BuildRtxPacket(uint8_t* buffer, size_t* length,
reinterpret_cast<const uint8_t*>(buffer), *length);
RTPHeader rtp_header;
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
// Add original RTP header.
memcpy(data_buffer_rtx, buffer, rtp_header.headerLength);
@@ -1836,7 +1839,7 @@ void RTPSender::BuildRtxPacket(uint8_t* buffer, size_t* length,
}
// Replace sequence number.
- uint8_t *ptr = data_buffer_rtx + 2;
+ uint8_t* ptr = data_buffer_rtx + 2;
ByteWriter<uint16_t>::WriteBigEndian(ptr, sequence_number_rtx_++);
// Replace SSRC.
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
index a134370c76..3c62336507 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
@@ -10,14 +10,16 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_H_
-#include <assert.h>
-#include <math.h>
+#include <list>
#include <map>
+#include <utility>
+#include <vector>
+#include "webrtc/base/random.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h"
@@ -26,8 +28,6 @@
#include "webrtc/modules/rtp_rtcp/source/ssrc_database.h"
#include "webrtc/transport.h"
-#define MAX_INIT_RTP_SEQ_NUMBER 32767 // 2^15 -1.
-
namespace webrtc {
class BitrateAggregator;
@@ -116,7 +116,7 @@ class RTPSender : public RTPSenderInterface {
int32_t RegisterPayload(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const int8_t payload_type, const uint32_t frequency,
- const uint8_t channels, const uint32_t rate);
+ const size_t channels, const uint32_t rate);
int32_t DeRegisterSendPayload(const int8_t payload_type);
@@ -163,7 +163,7 @@ class RTPSender : public RTPSenderInterface {
int32_t SetTransportSequenceNumber(uint16_t sequence_number);
int32_t RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
- virtual bool IsRtpHeaderExtensionRegistered(RTPExtensionType type) override;
+ bool IsRtpHeaderExtensionRegistered(RTPExtensionType type) override;
int32_t DeregisterRtpHeaderExtension(RTPExtensionType type);
size_t RtpHeaderExtensionTotalLength() const;
@@ -202,10 +202,10 @@ class RTPSender : public RTPSenderInterface {
bool is_voiced,
uint8_t dBov) const;
- virtual bool UpdateVideoRotation(uint8_t* rtp_packet,
- size_t rtp_packet_length,
- const RTPHeader& rtp_header,
- VideoRotation rotation) const override;
+ bool UpdateVideoRotation(uint8_t* rtp_packet,
+ size_t rtp_packet_length,
+ const RTPHeader& rtp_header,
+ VideoRotation rotation) const override;
bool TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms,
bool retransmission);
@@ -386,6 +386,7 @@ class RTPSender : public RTPSenderInterface {
Clock* clock_;
int64_t clock_delta_ms_;
+ Random random_ GUARDED_BY(send_critsect_);
rtc::scoped_ptr<BitrateAggregator> bitrates_;
Bitrate total_bitrate_sent_;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc
index 1fc9a89ce1..2aa4961cdc 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc
@@ -10,12 +10,12 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
-#include <assert.h> //assert
-#include <string.h> //memcpy
+#include <string.h>
#include "webrtc/base/trace_event.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/system_wrappers/include/tick_util.h"
namespace webrtc {
@@ -47,8 +47,7 @@ RTPSenderAudio::RTPSenderAudio(Clock* clock,
_lastPayloadType(-1),
_audioLevel_dBov(0) {}
-RTPSenderAudio::~RTPSenderAudio() {
-}
+RTPSenderAudio::~RTPSenderAudio() {}
int RTPSenderAudio::AudioFrequency() const {
return kDtmfFrequencyHz;
@@ -56,22 +55,20 @@ int RTPSenderAudio::AudioFrequency() const {
// set audio packet size, used to determine when it's time to send a DTMF packet
// in silence (CNG)
-int32_t
-RTPSenderAudio::SetAudioPacketSize(const uint16_t packetSizeSamples)
-{
- CriticalSectionScoped cs(_sendAudioCritsect.get());
+int32_t RTPSenderAudio::SetAudioPacketSize(uint16_t packetSizeSamples) {
+ CriticalSectionScoped cs(_sendAudioCritsect.get());
- _packetSizeSamples = packetSizeSamples;
- return 0;
+ _packetSizeSamples = packetSizeSamples;
+ return 0;
}
int32_t RTPSenderAudio::RegisterAudioPayload(
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int8_t payloadType,
const uint32_t frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate,
- RtpUtility::Payload*& payload) {
+ RtpUtility::Payload** payload) {
if (RtpUtility::StringCompare(payloadName, "cn", 2)) {
CriticalSectionScoped cs(_sendAudioCritsect.get());
// we can have multiple CNG payload types
@@ -99,72 +96,65 @@ int32_t RTPSenderAudio::RegisterAudioPayload(
return 0;
// The default timestamp rate is 8000 Hz, but other rates may be defined.
}
- payload = new RtpUtility::Payload;
- payload->typeSpecific.Audio.frequency = frequency;
- payload->typeSpecific.Audio.channels = channels;
- payload->typeSpecific.Audio.rate = rate;
- payload->audio = true;
- payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0';
- strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
+ *payload = new RtpUtility::Payload;
+ (*payload)->typeSpecific.Audio.frequency = frequency;
+ (*payload)->typeSpecific.Audio.channels = channels;
+ (*payload)->typeSpecific.Audio.rate = rate;
+ (*payload)->audio = true;
+ (*payload)->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0';
+ strncpy((*payload)->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
return 0;
}
-bool
-RTPSenderAudio::MarkerBit(const FrameType frameType,
- const int8_t payload_type)
-{
- CriticalSectionScoped cs(_sendAudioCritsect.get());
- // for audio true for first packet in a speech burst
- bool markerBit = false;
- if (_lastPayloadType != payload_type) {
- if (payload_type != -1 && (_cngNBPayloadType == payload_type ||
- _cngWBPayloadType == payload_type ||
- _cngSWBPayloadType == payload_type ||
- _cngFBPayloadType == payload_type)) {
- // Only set a marker bit when we change payload type to a non CNG
- return false;
- }
+bool RTPSenderAudio::MarkerBit(FrameType frameType, int8_t payload_type) {
+ CriticalSectionScoped cs(_sendAudioCritsect.get());
+ // for audio true for first packet in a speech burst
+ bool markerBit = false;
+ if (_lastPayloadType != payload_type) {
+ if (payload_type != -1 && (_cngNBPayloadType == payload_type ||
+ _cngWBPayloadType == payload_type ||
+ _cngSWBPayloadType == payload_type ||
+ _cngFBPayloadType == payload_type)) {
+ // Only set a marker bit when we change payload type to a non CNG
+ return false;
+ }
- // payload_type differ
- if (_lastPayloadType == -1) {
- if (frameType != kAudioFrameCN) {
- // first packet and NOT CNG
- return true;
- } else {
- // first packet and CNG
- _inbandVADactive = true;
- return false;
- }
+ // payload_type differ
+ if (_lastPayloadType == -1) {
+ if (frameType != kAudioFrameCN) {
+ // first packet and NOT CNG
+ return true;
+ } else {
+ // first packet and CNG
+ _inbandVADactive = true;
+ return false;
}
-
- // not first packet AND
- // not CNG AND
- // payload_type changed
-
- // set a marker bit when we change payload type
- markerBit = true;
}
- // For G.723 G.729, AMR etc we can have inband VAD
- if(frameType == kAudioFrameCN)
- {
- _inbandVADactive = true;
+ // not first packet AND
+ // not CNG AND
+ // payload_type changed
- } else if(_inbandVADactive)
- {
- _inbandVADactive = false;
- markerBit = true;
- }
- return markerBit;
+ // set a marker bit when we change payload type
+ markerBit = true;
+ }
+
+ // For G.723 G.729, AMR etc we can have inband VAD
+ if (frameType == kAudioFrameCN) {
+ _inbandVADactive = true;
+ } else if (_inbandVADactive) {
+ _inbandVADactive = false;
+ markerBit = true;
+ }
+ return markerBit;
}
-int32_t RTPSenderAudio::SendAudio(
- const FrameType frameType,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const uint8_t* payloadData,
- const size_t dataSize,
- const RTPFragmentationHeader* fragmentation) {
+int32_t RTPSenderAudio::SendAudio(FrameType frameType,
+ int8_t payloadType,
+ uint32_t captureTimeStamp,
+ const uint8_t* payloadData,
+ size_t dataSize,
+ const RTPFragmentationHeader* fragmentation) {
// TODO(pwestin) Breakup function in smaller functions.
size_t payloadSize = dataSize;
size_t maxPayloadLength = _rtpSender->MaxPayloadLength();
@@ -185,8 +175,8 @@ int32_t RTPSenderAudio::SendAudio(
// Check if we have pending DTMFs to send
if (!_dtmfEventIsOn && PendingDTMF()) {
- int64_t delaySinceLastDTMF = _clock->TimeInMilliseconds() -
- _dtmfTimeLastSent;
+ int64_t delaySinceLastDTMF =
+ _clock->TimeInMilliseconds() - _dtmfTimeLastSent;
if (delaySinceLastDTMF > 100) {
// New tone to play
@@ -294,128 +284,120 @@ int32_t RTPSenderAudio::SendAudio(
// Too large payload buffer.
return -1;
}
- if (red_payload_type >= 0 && // Have we configured RED?
- fragmentation && fragmentation->fragmentationVectorSize > 1 &&
- !markerBit) {
- if (timestampOffset <= 0x3fff) {
- if (fragmentation->fragmentationVectorSize != 2) {
- // we only support 2 codecs when using RED
- return -1;
- }
- // only 0x80 if we have multiple blocks
- dataBuffer[rtpHeaderLength++] =
- 0x80 + fragmentation->fragmentationPlType[1];
- size_t blockLength = fragmentation->fragmentationLength[1];
-
- // sanity blockLength
- if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
- return -1;
- }
- uint32_t REDheader = (timestampOffset << 10) + blockLength;
- ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + rtpHeaderLength,
- REDheader);
- rtpHeaderLength += 3;
-
- dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
- // copy the RED data
- memcpy(dataBuffer + rtpHeaderLength,
- payloadData + fragmentation->fragmentationOffset[1],
- fragmentation->fragmentationLength[1]);
-
- // copy the normal data
- memcpy(dataBuffer + rtpHeaderLength +
- fragmentation->fragmentationLength[1],
- payloadData + fragmentation->fragmentationOffset[0],
- fragmentation->fragmentationLength[0]);
-
- payloadSize = fragmentation->fragmentationLength[0] +
- fragmentation->fragmentationLength[1];
- } else {
- // silence for too long send only new data
- dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
- memcpy(dataBuffer + rtpHeaderLength,
- payloadData + fragmentation->fragmentationOffset[0],
- fragmentation->fragmentationLength[0]);
+ if (red_payload_type >= 0 && // Have we configured RED?
+ fragmentation && fragmentation->fragmentationVectorSize > 1 &&
+ !markerBit) {
+ if (timestampOffset <= 0x3fff) {
+ if (fragmentation->fragmentationVectorSize != 2) {
+ // we only support 2 codecs when using RED
+ return -1;
+ }
+ // only 0x80 if we have multiple blocks
+ dataBuffer[rtpHeaderLength++] =
+ 0x80 + fragmentation->fragmentationPlType[1];
+ size_t blockLength = fragmentation->fragmentationLength[1];
- payloadSize = fragmentation->fragmentationLength[0];
+ // sanity blockLength
+ if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
+ return -1;
}
+ uint32_t REDheader = (timestampOffset << 10) + blockLength;
+ ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + rtpHeaderLength,
+ REDheader);
+ rtpHeaderLength += 3;
+
+ dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
+ // copy the RED data
+ memcpy(dataBuffer + rtpHeaderLength,
+ payloadData + fragmentation->fragmentationOffset[1],
+ fragmentation->fragmentationLength[1]);
+
+ // copy the normal data
+ memcpy(
+ dataBuffer + rtpHeaderLength + fragmentation->fragmentationLength[1],
+ payloadData + fragmentation->fragmentationOffset[0],
+ fragmentation->fragmentationLength[0]);
+
+ payloadSize = fragmentation->fragmentationLength[0] +
+ fragmentation->fragmentationLength[1];
} else {
- if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
- // use the fragment info if we have one
- dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
- memcpy(dataBuffer + rtpHeaderLength,
- payloadData + fragmentation->fragmentationOffset[0],
- fragmentation->fragmentationLength[0]);
-
- payloadSize = fragmentation->fragmentationLength[0];
- } else {
- memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize);
- }
+ // silence for too long send only new data
+ dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
+ memcpy(dataBuffer + rtpHeaderLength,
+ payloadData + fragmentation->fragmentationOffset[0],
+ fragmentation->fragmentationLength[0]);
+
+ payloadSize = fragmentation->fragmentationLength[0];
}
- {
- CriticalSectionScoped cs(_sendAudioCritsect.get());
- _lastPayloadType = payloadType;
+ } else {
+ if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
+ // use the fragment info if we have one
+ dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
+ memcpy(dataBuffer + rtpHeaderLength,
+ payloadData + fragmentation->fragmentationOffset[0],
+ fragmentation->fragmentationLength[0]);
+
+ payloadSize = fragmentation->fragmentationLength[0];
+ } else {
+ memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize);
}
- // Update audio level extension, if included.
- size_t packetSize = payloadSize + rtpHeaderLength;
- RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
- RTPHeader rtp_header;
- rtp_parser.Parse(rtp_header);
- _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
- (frameType == kAudioFrameSpeech),
- audio_level_dbov);
- TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp",
- _rtpSender->Timestamp(), "seqnum",
- _rtpSender->SequenceNumber());
- return _rtpSender->SendToNetwork(dataBuffer, payloadSize, rtpHeaderLength,
- -1, kAllowRetransmission,
- RtpPacketSender::kHighPriority);
}
-
- // Audio level magnitude and voice activity flag are set for each RTP packet
-int32_t
-RTPSenderAudio::SetAudioLevel(const uint8_t level_dBov)
-{
- if (level_dBov > 127)
- {
- return -1;
- }
+ {
CriticalSectionScoped cs(_sendAudioCritsect.get());
- _audioLevel_dBov = level_dBov;
- return 0;
+ _lastPayloadType = payloadType;
+ }
+ // Update audio level extension, if included.
+ size_t packetSize = payloadSize + rtpHeaderLength;
+ RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
+ RTPHeader rtp_header;
+ rtp_parser.Parse(&rtp_header);
+ _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
+ (frameType == kAudioFrameSpeech),
+ audio_level_dbov);
+ TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp",
+ _rtpSender->Timestamp(), "seqnum",
+ _rtpSender->SequenceNumber());
+ return _rtpSender->SendToNetwork(dataBuffer, payloadSize, rtpHeaderLength,
+ TickTime::MillisecondTimestamp(),
+ kAllowRetransmission,
+ RtpPacketSender::kHighPriority);
}
- // Set payload type for Redundant Audio Data RFC 2198
-int32_t
-RTPSenderAudio::SetRED(const int8_t payloadType)
-{
- if(payloadType < -1 )
- {
- return -1;
- }
- CriticalSectionScoped cs(_sendAudioCritsect.get());
- _REDPayloadType = payloadType;
- return 0;
+// Audio level magnitude and voice activity flag are set for each RTP packet
+int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dBov) {
+ if (level_dBov > 127) {
+ return -1;
+ }
+ CriticalSectionScoped cs(_sendAudioCritsect.get());
+ _audioLevel_dBov = level_dBov;
+ return 0;
}
- // Get payload type for Redundant Audio Data RFC 2198
-int32_t
-RTPSenderAudio::RED(int8_t& payloadType) const
-{
- CriticalSectionScoped cs(_sendAudioCritsect.get());
- if(_REDPayloadType == -1)
- {
- // not configured
- return -1;
- }
- payloadType = _REDPayloadType;
- return 0;
+// Set payload type for Redundant Audio Data RFC 2198
+int32_t RTPSenderAudio::SetRED(int8_t payloadType) {
+ if (payloadType < -1) {
+ return -1;
+ }
+ CriticalSectionScoped cs(_sendAudioCritsect.get());
+ _REDPayloadType = payloadType;
+ return 0;
+}
+
+// Get payload type for Redundant Audio Data RFC 2198
+int32_t RTPSenderAudio::RED(int8_t* payloadType) const {
+ CriticalSectionScoped cs(_sendAudioCritsect.get());
+ if (_REDPayloadType == -1) {
+ // not configured
+ return -1;
+ }
+ *payloadType = _REDPayloadType;
+ return 0;
}
// Send a TelephoneEvent tone using RFC 2833 (4733)
-int32_t RTPSenderAudio::SendTelephoneEvent(const uint8_t key,
- const uint16_t time_ms,
- const uint8_t level) {
+int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key,
+ uint16_t time_ms,
+ uint8_t level) {
{
CriticalSectionScoped lock(_sendAudioCritsect.get());
if (_dtmfPayloadType < 0) {
@@ -426,63 +408,57 @@ int32_t RTPSenderAudio::SendTelephoneEvent(const uint8_t key,
return AddDTMF(key, time_ms, level);
}
-int32_t
-RTPSenderAudio::SendTelephoneEventPacket(bool ended,
- int8_t dtmf_payload_type,
- uint32_t dtmfTimeStamp,
- uint16_t duration,
- bool markerBit)
-{
- uint8_t dtmfbuffer[IP_PACKET_SIZE];
- uint8_t sendCount = 1;
- int32_t retVal = 0;
-
- if(ended)
- {
- // resend last packet in an event 3 times
- sendCount = 3;
- }
- do
- {
- //Send DTMF data
- _rtpSender->BuildRTPheader(dtmfbuffer, dtmf_payload_type, markerBit,
- dtmfTimeStamp, _clock->TimeInMilliseconds());
-
- // reset CSRC and X bit
- dtmfbuffer[0] &= 0xe0;
-
- //Create DTMF data
- /* From RFC 2833:
-
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | event |E|R| volume | duration |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- // R bit always cleared
- uint8_t R = 0x00;
- uint8_t volume = _dtmfLevel;
-
- // First packet un-ended
- uint8_t E = ended ? 0x80 : 0x00;
-
- // First byte is Event number, equals key number
- dtmfbuffer[12] = _dtmfKey;
- dtmfbuffer[13] = E|R|volume;
- ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration);
-
- TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
- "Audio::SendTelephoneEvent", "timestamp",
- dtmfTimeStamp, "seqnum",
- _rtpSender->SequenceNumber());
- retVal = _rtpSender->SendToNetwork(dtmfbuffer, 4, 12, -1,
- kAllowRetransmission,
- RtpPacketSender::kHighPriority);
- sendCount--;
-
- }while (sendCount > 0 && retVal == 0);
-
- return retVal;
+int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended,
+ int8_t dtmf_payload_type,
+ uint32_t dtmfTimeStamp,
+ uint16_t duration,
+ bool markerBit) {
+ uint8_t dtmfbuffer[IP_PACKET_SIZE];
+ uint8_t sendCount = 1;
+ int32_t retVal = 0;
+
+ if (ended) {
+ // resend last packet in an event 3 times
+ sendCount = 3;
+ }
+ do {
+ // Send DTMF data
+ _rtpSender->BuildRTPheader(dtmfbuffer, dtmf_payload_type, markerBit,
+ dtmfTimeStamp, _clock->TimeInMilliseconds());
+
+ // reset CSRC and X bit
+ dtmfbuffer[0] &= 0xe0;
+
+ // Create DTMF data
+ /* From RFC 2833:
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | event |E|R| volume | duration |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ // R bit always cleared
+ uint8_t R = 0x00;
+ uint8_t volume = _dtmfLevel;
+
+ // First packet un-ended
+ uint8_t E = ended ? 0x80 : 0x00;
+
+ // First byte is Event number, equals key number
+ dtmfbuffer[12] = _dtmfKey;
+ dtmfbuffer[13] = E | R | volume;
+ ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration);
+
+ TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
+ "Audio::SendTelephoneEvent", "timestamp",
+ dtmfTimeStamp, "seqnum", _rtpSender->SequenceNumber());
+ retVal = _rtpSender->SendToNetwork(
+ dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(),
+ kAllowRetransmission, RtpPacketSender::kHighPriority);
+ sendCount--;
+ } while (sendCount > 0 && retVal == 0);
+
+ return retVal;
}
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h
index dd16fe51b4..1e96d17a67 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h
@@ -19,92 +19,91 @@
#include "webrtc/typedefs.h"
namespace webrtc {
-class RTPSenderAudio: public DTMFqueue
-{
-public:
- RTPSenderAudio(Clock* clock,
- RTPSender* rtpSender,
- RtpAudioFeedback* audio_feedback);
- virtual ~RTPSenderAudio();
-
- int32_t RegisterAudioPayload(const char payloadName[RTP_PAYLOAD_NAME_SIZE],
- const int8_t payloadType,
- const uint32_t frequency,
- const uint8_t channels,
- const uint32_t rate,
- RtpUtility::Payload*& payload);
-
- int32_t SendAudio(const FrameType frameType,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const uint8_t* payloadData,
- const size_t payloadSize,
- const RTPFragmentationHeader* fragmentation);
-
- // set audio packet size, used to determine when it's time to send a DTMF packet in silence (CNG)
- int32_t SetAudioPacketSize(const uint16_t packetSizeSamples);
-
- // Store the audio level in dBov for header-extension-for-audio-level-indication.
- // Valid range is [0,100]. Actual value is negative.
- int32_t SetAudioLevel(const uint8_t level_dBov);
-
- // Send a DTMF tone using RFC 2833 (4733)
- int32_t SendTelephoneEvent(const uint8_t key,
- const uint16_t time_ms,
- const uint8_t level);
-
- int AudioFrequency() const;
-
- // Set payload type for Redundant Audio Data RFC 2198
- int32_t SetRED(const int8_t payloadType);
-
- // Get payload type for Redundant Audio Data RFC 2198
- int32_t RED(int8_t& payloadType) const;
-
-protected:
- int32_t SendTelephoneEventPacket(bool ended,
- int8_t dtmf_payload_type,
- uint32_t dtmfTimeStamp,
- uint16_t duration,
- bool markerBit); // set on first packet in talk burst
-
- bool MarkerBit(const FrameType frameType,
- const int8_t payloadType);
-
-private:
- Clock* const _clock;
- RTPSender* const _rtpSender;
- RtpAudioFeedback* const _audioFeedback;
-
- rtc::scoped_ptr<CriticalSectionWrapper> _sendAudioCritsect;
-
- uint16_t _packetSizeSamples GUARDED_BY(_sendAudioCritsect);
-
- // DTMF
- bool _dtmfEventIsOn;
- bool _dtmfEventFirstPacketSent;
- int8_t _dtmfPayloadType GUARDED_BY(_sendAudioCritsect);
- uint32_t _dtmfTimestamp;
- uint8_t _dtmfKey;
- uint32_t _dtmfLengthSamples;
- uint8_t _dtmfLevel;
- int64_t _dtmfTimeLastSent;
- uint32_t _dtmfTimestampLastSent;
-
- int8_t _REDPayloadType GUARDED_BY(_sendAudioCritsect);
-
- // VAD detection, used for markerbit
- bool _inbandVADactive GUARDED_BY(_sendAudioCritsect);
- int8_t _cngNBPayloadType GUARDED_BY(_sendAudioCritsect);
- int8_t _cngWBPayloadType GUARDED_BY(_sendAudioCritsect);
- int8_t _cngSWBPayloadType GUARDED_BY(_sendAudioCritsect);
- int8_t _cngFBPayloadType GUARDED_BY(_sendAudioCritsect);
- int8_t _lastPayloadType GUARDED_BY(_sendAudioCritsect);
-
- // Audio level indication
- // (https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/)
- uint8_t _audioLevel_dBov GUARDED_BY(_sendAudioCritsect);
+class RTPSenderAudio : public DTMFqueue {
+ public:
+ RTPSenderAudio(Clock* clock,
+ RTPSender* rtpSender,
+ RtpAudioFeedback* audio_feedback);
+ virtual ~RTPSenderAudio();
+
+ int32_t RegisterAudioPayload(const char payloadName[RTP_PAYLOAD_NAME_SIZE],
+ int8_t payloadType,
+ uint32_t frequency,
+ size_t channels,
+ uint32_t rate,
+ RtpUtility::Payload** payload);
+
+ int32_t SendAudio(FrameType frameType,
+ int8_t payloadType,
+ uint32_t captureTimeStamp,
+ const uint8_t* payloadData,
+ size_t payloadSize,
+ const RTPFragmentationHeader* fragmentation);
+
+ // set audio packet size, used to determine when it's time to send a DTMF
+ // packet in silence (CNG)
+ int32_t SetAudioPacketSize(uint16_t packetSizeSamples);
+
+ // Store the audio level in dBov for
+ // header-extension-for-audio-level-indication.
+ // Valid range is [0,100]. Actual value is negative.
+ int32_t SetAudioLevel(uint8_t level_dBov);
+
+ // Send a DTMF tone using RFC 2833 (4733)
+ int32_t SendTelephoneEvent(uint8_t key, uint16_t time_ms, uint8_t level);
+
+ int AudioFrequency() const;
+
+ // Set payload type for Redundant Audio Data RFC 2198
+ int32_t SetRED(int8_t payloadType);
+
+ // Get payload type for Redundant Audio Data RFC 2198
+ int32_t RED(int8_t* payloadType) const;
+
+ protected:
+ int32_t SendTelephoneEventPacket(
+ bool ended,
+ int8_t dtmf_payload_type,
+ uint32_t dtmfTimeStamp,
+ uint16_t duration,
+ bool markerBit); // set on first packet in talk burst
+
+ bool MarkerBit(const FrameType frameType, const int8_t payloadType);
+
+ private:
+ Clock* const _clock;
+ RTPSender* const _rtpSender;
+ RtpAudioFeedback* const _audioFeedback;
+
+ rtc::scoped_ptr<CriticalSectionWrapper> _sendAudioCritsect;
+
+ uint16_t _packetSizeSamples GUARDED_BY(_sendAudioCritsect);
+
+ // DTMF
+ bool _dtmfEventIsOn;
+ bool _dtmfEventFirstPacketSent;
+ int8_t _dtmfPayloadType GUARDED_BY(_sendAudioCritsect);
+ uint32_t _dtmfTimestamp;
+ uint8_t _dtmfKey;
+ uint32_t _dtmfLengthSamples;
+ uint8_t _dtmfLevel;
+ int64_t _dtmfTimeLastSent;
+ uint32_t _dtmfTimestampLastSent;
+
+ int8_t _REDPayloadType GUARDED_BY(_sendAudioCritsect);
+
+ // VAD detection, used for markerbit
+ bool _inbandVADactive GUARDED_BY(_sendAudioCritsect);
+ int8_t _cngNBPayloadType GUARDED_BY(_sendAudioCritsect);
+ int8_t _cngWBPayloadType GUARDED_BY(_sendAudioCritsect);
+ int8_t _cngSWBPayloadType GUARDED_BY(_sendAudioCritsect);
+ int8_t _cngFBPayloadType GUARDED_BY(_sendAudioCritsect);
+ int8_t _lastPayloadType GUARDED_BY(_sendAudioCritsect);
+
+ // Audio level indication
+ // (https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/)
+ uint8_t _audioLevel_dBov GUARDED_BY(_sendAudioCritsect);
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_AUDIO_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_AUDIO_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index fde6d47ceb..6bc122201a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -12,20 +12,22 @@
* This file includes unit tests for the RTPSender.
*/
+#include <list>
+#include <vector>
+
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-
#include "webrtc/base/buffer.h"
#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h"
-#include "webrtc/system_wrappers/include/stl_util.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/system_wrappers/include/stl_util.h"
#include "webrtc/test/mock_transport.h"
#include "webrtc/typedefs.h"
@@ -90,9 +92,7 @@ class LoopbackTransportTest : public webrtc::Transport {
sent_packets_.push_back(buffer);
return true;
}
- bool SendRtcp(const uint8_t* data, size_t len) override {
- return false;
- }
+ bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
int packets_sent_;
size_t last_sent_packet_len_;
size_t total_bytes_sent_;
@@ -163,11 +163,8 @@ class RtpSenderTest : public ::testing::Test {
void SendPacket(int64_t capture_time_ms, int payload_length) {
uint32_t timestamp = capture_time_ms * 90;
- int32_t rtp_length = rtp_sender_->BuildRTPheader(packet_,
- kPayload,
- kMarkerBit,
- timestamp,
- capture_time_ms);
+ int32_t rtp_length = rtp_sender_->BuildRTPheader(
+ packet_, kPayload, kMarkerBit, timestamp, capture_time_ms);
ASSERT_GE(rtp_length, 0);
// Packet should be stored in a send bucket.
@@ -186,7 +183,7 @@ class RtpSenderTestWithoutPacer : public RtpSenderTest {
class RtpSenderVideoTest : public RtpSenderTest {
protected:
- virtual void SetUp() override {
+ void SetUp() override {
// TODO(pbos): Set up to use pacer.
SetUpRtpSender(false);
rtp_sender_video_.reset(
@@ -211,7 +208,7 @@ class RtpSenderVideoTest : public RtpSenderTest {
} else {
ASSERT_EQ(kRtpHeaderSize, length);
}
- ASSERT_TRUE(rtp_parser.Parse(rtp_header, map));
+ ASSERT_TRUE(rtp_parser.Parse(&rtp_header, map));
ASSERT_FALSE(rtp_parser.RTCP());
EXPECT_EQ(payload_, rtp_header.payloadType);
EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
@@ -228,53 +225,57 @@ TEST_F(RtpSenderTestWithoutPacer,
RegisterRtpTransmissionTimeOffsetHeaderExtension) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(kRtpOneByteHeaderLength + kTransmissionTimeOffsetLength,
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset));
+ kRtpExtensionTransmissionTimeOffset));
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
}
TEST_F(RtpSenderTestWithoutPacer, RegisterRtpAbsoluteSendTimeHeaderExtension) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kAbsoluteSendTimeLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime));
+ kRtpExtensionAbsoluteSendTime));
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
}
TEST_F(RtpSenderTestWithoutPacer, RegisterRtpAudioLevelHeaderExtension) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAudioLevel, kAudioLevelExtensionId));
+ EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
+ kAudioLevelExtensionId));
EXPECT_EQ(
RtpUtility::Word32Align(kRtpOneByteHeaderLength + kAudioLevelLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
- EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
- kRtpExtensionAudioLevel));
+ EXPECT_EQ(0,
+ rtp_sender_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel));
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
}
TEST_F(RtpSenderTestWithoutPacer, RegisterRtpHeaderExtensions) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kTransmissionTimeOffsetLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kTransmissionTimeOffsetLength +
kAbsoluteSendTimeLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAudioLevel, kAudioLevelExtensionId));
+ EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
+ kAudioLevelExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(
kRtpOneByteHeaderLength + kTransmissionTimeOffsetLength +
kAbsoluteSendTimeLength + kAudioLevelLength),
@@ -290,18 +291,18 @@ TEST_F(RtpSenderTestWithoutPacer, RegisterRtpHeaderExtensions) {
// Deregister starts.
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset));
+ kRtpExtensionTransmissionTimeOffset));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kAbsoluteSendTimeLength +
kAudioLevelLength + kVideoRotationLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime));
+ kRtpExtensionAbsoluteSendTime));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kAudioLevelLength + kVideoRotationLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
- EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
- kRtpExtensionAudioLevel));
+ EXPECT_EQ(0,
+ rtp_sender_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel));
EXPECT_EQ(
RtpUtility::Word32Align(kRtpOneByteHeaderLength + kVideoRotationLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
@@ -334,7 +335,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacket) {
webrtc::RtpUtility::RtpHeaderParser rtp_parser(packet_, length);
webrtc::RTPHeader rtp_header;
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, nullptr);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, nullptr);
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
@@ -354,7 +355,8 @@ TEST_F(RtpSenderTestWithoutPacer,
BuildRTPPacketWithTransmissionOffsetExtension) {
EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kTimeOffset));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@@ -368,7 +370,7 @@ TEST_F(RtpSenderTestWithoutPacer,
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId);
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, &map);
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
@@ -379,7 +381,7 @@ TEST_F(RtpSenderTestWithoutPacer,
// Parse without map extension
webrtc::RTPHeader rtp_header2;
- const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, nullptr);
+ const bool valid_rtp_header2 = rtp_parser.Parse(&rtp_header2, nullptr);
ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2);
@@ -393,7 +395,8 @@ TEST_F(RtpSenderTestWithoutPacer,
const int kNegTimeOffset = -500;
EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kNegTimeOffset));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@@ -407,7 +410,7 @@ TEST_F(RtpSenderTestWithoutPacer,
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId);
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, &map);
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
@@ -419,8 +422,9 @@ TEST_F(RtpSenderTestWithoutPacer,
TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAbsoluteSendTimeExtension) {
EXPECT_EQ(0, rtp_sender_->SetAbsoluteSendTime(kAbsoluteSendTime));
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@@ -433,7 +437,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAbsoluteSendTimeExtension) {
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId);
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, &map);
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
@@ -444,7 +448,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAbsoluteSendTimeExtension) {
// Parse without map extension
webrtc::RTPHeader rtp_header2;
- const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, nullptr);
+ const bool valid_rtp_header2 = rtp_parser.Parse(&rtp_header2, nullptr);
ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2);
@@ -472,7 +476,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithVideoRotation_MarkerBit) {
webrtc::RtpUtility::RtpHeaderParser rtp_parser(packet_, length);
webrtc::RTPHeader rtp_header;
- ASSERT_TRUE(rtp_parser.Parse(rtp_header, &map));
+ ASSERT_TRUE(rtp_parser.Parse(&rtp_header, &map));
ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.headerLength);
@@ -500,7 +504,7 @@ TEST_F(RtpSenderTestWithoutPacer,
webrtc::RtpUtility::RtpHeaderParser rtp_parser(packet_, length);
webrtc::RTPHeader rtp_header;
- ASSERT_TRUE(rtp_parser.Parse(rtp_header, &map));
+ ASSERT_TRUE(rtp_parser.Parse(&rtp_header, &map));
ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header, false);
EXPECT_EQ(length, rtp_header.headerLength);
@@ -508,8 +512,8 @@ TEST_F(RtpSenderTestWithoutPacer,
}
TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAudioLevelExtension) {
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAudioLevel, kAudioLevelExtensionId));
+ EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
+ kAudioLevelExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@@ -521,12 +525,12 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAudioLevelExtension) {
webrtc::RTPHeader rtp_header;
// Updating audio level is done in RTPSenderAudio, so simulate it here.
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
rtp_sender_->UpdateAudioLevel(packet_, length, rtp_header, true, kAudioLevel);
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, &map);
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
@@ -538,7 +542,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAudioLevelExtension) {
// Parse without map extension
webrtc::RTPHeader rtp_header2;
- const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, nullptr);
+ const bool valid_rtp_header2 = rtp_parser.Parse(&rtp_header2, nullptr);
ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2);
@@ -554,11 +558,13 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithHeaderExtensions) {
EXPECT_EQ(0,
rtp_sender_->SetTransportSequenceNumber(kTransportSequenceNumber));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAudioLevel, kAudioLevelExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
+ EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
+ kAudioLevelExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransportSequenceNumber,
kTransportSequenceNumberExtensionId));
@@ -573,7 +579,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithHeaderExtensions) {
webrtc::RTPHeader rtp_header;
// Updating audio level is done in RTPSenderAudio, so simulate it here.
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
rtp_sender_->UpdateAudioLevel(packet_, length, rtp_header, true, kAudioLevel);
RtpHeaderExtensionMap map;
@@ -583,7 +589,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithHeaderExtensions) {
map.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
map.Register(kRtpExtensionTransportSequenceNumber,
kTransportSequenceNumberExtensionId);
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, &map);
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
@@ -602,7 +608,7 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithHeaderExtensions) {
// Parse without map extension
webrtc::RTPHeader rtp_header2;
- const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, nullptr);
+ const bool valid_rtp_header2 = rtp_parser.Parse(&rtp_header2, nullptr);
ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2);
@@ -626,9 +632,11 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) {
rtp_sender_->SetStorePacketsStatus(true, 10);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
rtp_sender_->SetTargetBitrate(300000);
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
int rtp_length_int = rtp_sender_->BuildRTPheader(
@@ -659,7 +667,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) {
map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId);
map.Register(kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId);
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, &map);
ASSERT_TRUE(valid_rtp_header);
// Verify transmission time offset.
@@ -676,9 +684,11 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) {
rtp_sender_->SetStorePacketsStatus(true, 10);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
rtp_sender_->SetTargetBitrate(300000);
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
int rtp_length_int = rtp_sender_->BuildRTPheader(
@@ -717,7 +727,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) {
map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId);
map.Register(kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId);
- const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
+ const bool valid_rtp_header = rtp_parser.Parse(&rtp_header, &map);
ASSERT_TRUE(valid_rtp_header);
// Verify transmission time offset.
@@ -740,10 +750,12 @@ TEST_F(RtpSenderTest, SendPadding) {
rtp_sender_->SetStorePacketsStatus(true, 10);
size_t rtp_header_len = kRtpHeaderSize;
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
+ kRtpExtensionTransmissionTimeOffset,
+ kTransmissionTimeOffsetExtensionId));
rtp_header_len += 4; // 4 bytes extension.
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
rtp_header_len += 4; // 4 bytes extension.
rtp_header_len += 4; // 4 extra bytes common to all extension headers.
@@ -815,8 +827,8 @@ TEST_F(RtpSenderTest, SendPadding) {
// Send a regular video packet again.
capture_time_ms = fake_clock_.TimeInMilliseconds();
- rtp_length_int = rtp_sender_->BuildRTPheader(
- packet_, kPayload, kMarkerBit, timestamp, capture_time_ms);
+ rtp_length_int = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit,
+ timestamp, capture_time_ms);
ASSERT_NE(-1, rtp_length_int);
rtp_length = static_cast<size_t>(rtp_length_int);
@@ -830,8 +842,8 @@ TEST_F(RtpSenderTest, SendPadding) {
EXPECT_EQ(++total_packets_sent, transport_.packets_sent_);
EXPECT_EQ(rtp_length, transport_.last_sent_packet_len_);
// Parse sent packet.
- ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_, rtp_length,
- &rtp_header));
+ ASSERT_TRUE(
+ rtp_parser->Parse(transport_.last_sent_packet_, rtp_length, &rtp_header));
// Verify sequence number and timestamp.
EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
@@ -858,8 +870,9 @@ TEST_F(RtpSenderTest, SendRedundantPayloads) {
uint16_t seq_num = kSeqNum;
rtp_sender_->SetStorePacketsStatus(true, 10);
int32_t rtp_header_len = kRtpHeaderSize;
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
+ EXPECT_EQ(
+ 0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+ kAbsoluteSendTimeExtensionId));
rtp_header_len += 4; // 4 bytes extension.
rtp_header_len += 4; // 4 extra bytes common to all extension headers.
@@ -876,8 +889,8 @@ TEST_F(RtpSenderTest, SendRedundantPayloads) {
kAbsoluteSendTimeExtensionId);
rtp_sender_->SetTargetBitrate(300000);
const size_t kNumPayloadSizes = 10;
- const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700, 750,
- 800, 850, 900, 950};
+ const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700,
+ 750, 800, 850, 900, 950};
// Send 10 packets of increasing size.
for (size_t i = 0; i < kNumPayloadSizes; ++i) {
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
@@ -921,10 +934,10 @@ TEST_F(RtpSenderTestWithoutPacer, SendGenericVideo) {
RtpUtility::RtpHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_);
webrtc::RTPHeader rtp_header;
- ASSERT_TRUE(rtp_parser.Parse(rtp_header));
+ ASSERT_TRUE(rtp_parser.Parse(&rtp_header));
- const uint8_t* payload_data = GetPayloadData(rtp_header,
- transport_.last_sent_packet_);
+ const uint8_t* payload_data =
+ GetPayloadData(rtp_header, transport_.last_sent_packet_);
uint8_t generic_header = *payload_data++;
ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
@@ -946,7 +959,7 @@ TEST_F(RtpSenderTestWithoutPacer, SendGenericVideo) {
RtpUtility::RtpHeaderParser rtp_parser2(transport_.last_sent_packet_,
transport_.last_sent_packet_len_);
- ASSERT_TRUE(rtp_parser.Parse(rtp_header));
+ ASSERT_TRUE(rtp_parser.Parse(&rtp_header));
payload_data = GetPayloadData(rtp_header, transport_.last_sent_packet_);
generic_header = *payload_data++;
@@ -1043,9 +1056,8 @@ TEST_F(RtpSenderTest, BitrateCallbacks) {
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC";
const uint8_t payload_type = 127;
- ASSERT_EQ(
- 0,
- rtp_sender_->RegisterPayload(payload_name, payload_type, 90000, 0, 1500));
+ ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000,
+ 0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89};
rtp_sender_->SetStorePacketsStatus(true, 1);
uint32_t ssrc = rtp_sender_->SSRC();
@@ -1057,13 +1069,8 @@ TEST_F(RtpSenderTest, BitrateCallbacks) {
// Send a few frames.
for (uint32_t i = 0; i < kNumPackets; ++i) {
ASSERT_EQ(0,
- rtp_sender_->SendOutgoingData(kVideoFrameKey,
- payload_type,
- 1234,
- 4321,
- payload,
- sizeof(payload),
- 0));
+ rtp_sender_->SendOutgoingData(kVideoFrameKey, payload_type, 1234,
+ 4321, payload, sizeof(payload), 0));
fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
}
@@ -1100,8 +1107,7 @@ class RtpSenderAudioTest : public RtpSenderTest {
TEST_F(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
class TestCallback : public StreamDataCountersCallback {
public:
- TestCallback()
- : StreamDataCountersCallback(), ssrc_(0), counters_() {}
+ TestCallback() : StreamDataCountersCallback(), ssrc_(0), counters_() {}
virtual ~TestCallback() {}
void DataCountersUpdated(const StreamDataCounters& counters,
@@ -1127,7 +1133,6 @@ TEST_F(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
MatchPacketCounter(counters.retransmitted, counters_.retransmitted);
EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
}
-
} callback;
const uint8_t kRedPayloadType = 96;
@@ -1212,10 +1217,10 @@ TEST_F(RtpSenderAudioTest, SendAudio) {
RtpUtility::RtpHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_);
webrtc::RTPHeader rtp_header;
- ASSERT_TRUE(rtp_parser.Parse(rtp_header));
+ ASSERT_TRUE(rtp_parser.Parse(&rtp_header));
- const uint8_t* payload_data = GetPayloadData(rtp_header,
- transport_.last_sent_packet_);
+ const uint8_t* payload_data =
+ GetPayloadData(rtp_header, transport_.last_sent_packet_);
ASSERT_EQ(sizeof(payload),
GetPayloadDataLength(rtp_header, transport_.last_sent_packet_len_));
@@ -1225,8 +1230,8 @@ TEST_F(RtpSenderAudioTest, SendAudio) {
TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
EXPECT_EQ(0, rtp_sender_->SetAudioLevel(kAudioLevel));
- EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
- kRtpExtensionAudioLevel, kAudioLevelExtensionId));
+ EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
+ kAudioLevelExtensionId));
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "PAYLOAD_NAME";
const uint8_t payload_type = 127;
@@ -1241,21 +1246,22 @@ TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
RtpUtility::RtpHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_);
webrtc::RTPHeader rtp_header;
- ASSERT_TRUE(rtp_parser.Parse(rtp_header));
+ ASSERT_TRUE(rtp_parser.Parse(&rtp_header));
- const uint8_t* payload_data = GetPayloadData(rtp_header,
- transport_.last_sent_packet_);
+ const uint8_t* payload_data =
+ GetPayloadData(rtp_header, transport_.last_sent_packet_);
ASSERT_EQ(sizeof(payload),
GetPayloadDataLength(rtp_header, transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
- uint8_t extension[] = { 0xbe, 0xde, 0x00, 0x01,
- (kAudioLevelExtensionId << 4) + 0, // ID + length.
- kAudioLevel, // Data.
- 0x00, 0x00 // Padding.
- };
+ uint8_t extension[] = {
+ 0xbe, 0xde, 0x00, 0x01,
+ (kAudioLevelExtensionId << 4) + 0, // ID + length.
+ kAudioLevel, // Data.
+ 0x00, 0x00 // Padding.
+ };
EXPECT_EQ(0, memcmp(extension, payload_data - sizeof(extension),
sizeof(extension)));
@@ -1270,14 +1276,14 @@ TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "telephone-event";
uint8_t payload_type = 126;
- ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 0,
- 0, 0));
+ ASSERT_EQ(0,
+ rtp_sender_->RegisterPayload(payload_name, payload_type, 0, 0, 0));
// For Telephone events, payload is not added to the registered payload list,
// it will register only the payload used for audio stream.
// Registering the payload again for audio stream with different payload name.
- strcpy(payload_name, "payload_name");
- ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 8000,
- 1, 0));
+ const char kPayloadName[] = "payload_name";
+ ASSERT_EQ(
+ 0, rtp_sender_->RegisterPayload(kPayloadName, payload_type, 8000, 1, 0));
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
// DTMF event key=9, duration=500 and attenuationdB=10
rtp_sender_->SendTelephoneEvent(9, 500, 10);
@@ -1298,8 +1304,7 @@ TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
ASSERT_TRUE(rtp_parser.get() != nullptr);
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_,
- transport_.last_sent_packet_len_,
- &rtp_header));
+ transport_.last_sent_packet_len_, &rtp_header));
// Marker Bit should be set to 1 for first packet.
EXPECT_TRUE(rtp_header.markerBit);
@@ -1307,8 +1312,7 @@ TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
capture_time_ms + 4000, 0, nullptr,
0, nullptr));
ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_,
- transport_.last_sent_packet_len_,
- &rtp_header));
+ transport_.last_sent_packet_len_, &rtp_header));
// Marker Bit should be set to 0 for rest of the packets.
EXPECT_FALSE(rtp_header.markerBit);
}
@@ -1321,19 +1325,13 @@ TEST_F(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
rtp_sender_->SetRtxPayloadType(kPayloadType - 1, kPayloadType);
rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
- ASSERT_EQ(
- 0,
- rtp_sender_->RegisterPayload(kPayloadName, kPayloadType, 90000, 0, 1500));
+ ASSERT_EQ(0, rtp_sender_->RegisterPayload(kPayloadName, kPayloadType, 90000,
+ 0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89};
- ASSERT_EQ(0,
- rtp_sender_->SendOutgoingData(kVideoFrameKey,
- kPayloadType,
- 1234,
- 4321,
- payload,
- sizeof(payload),
- 0));
+ ASSERT_EQ(
+ 0, rtp_sender_->SendOutgoingData(kVideoFrameKey, kPayloadType, 1234, 4321,
+ payload, sizeof(payload), 0));
// Will send 2 full-size padding packets.
rtp_sender_->TimeToSendPadding(1);
@@ -1353,17 +1351,17 @@ TEST_F(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
- rtp_stats.transmitted.payload_bytes +
- rtp_stats.transmitted.header_bytes +
- rtp_stats.transmitted.padding_bytes);
+ rtp_stats.transmitted.payload_bytes +
+ rtp_stats.transmitted.header_bytes +
+ rtp_stats.transmitted.padding_bytes);
EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
- rtx_stats.transmitted.payload_bytes +
- rtx_stats.transmitted.header_bytes +
- rtx_stats.transmitted.padding_bytes);
+ rtx_stats.transmitted.payload_bytes +
+ rtx_stats.transmitted.header_bytes +
+ rtx_stats.transmitted.padding_bytes);
- EXPECT_EQ(transport_.total_bytes_sent_,
- rtp_stats.transmitted.TotalBytes() +
- rtx_stats.transmitted.TotalBytes());
+ EXPECT_EQ(
+ transport_.total_bytes_sent_,
+ rtp_stats.transmitted.TotalBytes() + rtx_stats.transmitted.TotalBytes());
}
TEST_F(RtpSenderTestWithoutPacer, RespectsNackBitrateLimit) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
index 66062771de..5a565dfa99 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -18,7 +18,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/trace_event.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/producer_fec.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
@@ -42,13 +42,13 @@ RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtpSender)
_retransmissionSettings(kRetransmitBaseLayer),
// Generic FEC
- _fec(),
- _fecEnabled(false),
- _payloadTypeRED(-1),
- _payloadTypeFEC(-1),
+ fec_(),
+ fec_enabled_(false),
+ red_payload_type_(-1),
+ fec_payload_type_(-1),
delta_fec_params_(),
key_fec_params_(),
- producer_fec_(&_fec),
+ producer_fec_(&fec_),
_fecOverheadRate(clock, NULL),
_videoBitrate(clock, NULL) {
memset(&delta_fec_params_, 0, sizeof(delta_fec_params_));
@@ -104,7 +104,7 @@ void RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer,
StorageType storage) {
if (_rtpSender.SendToNetwork(data_buffer, payload_length, rtp_header_length,
capture_time_ms, storage,
- RtpPacketSender::kNormalPriority) == 0) {
+ RtpPacketSender::kLowPriority) == 0) {
_videoBitrate.Update(payload_length + rtp_header_length);
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"Video::PacketNormal", "timestamp", capture_timestamp,
@@ -130,7 +130,7 @@ void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer,
// Only protect while creating RED and FEC packets, not when sending.
CriticalSectionScoped cs(crit_.get());
red_packet.reset(producer_fec_.BuildRedPacket(
- data_buffer, payload_length, rtp_header_length, _payloadTypeRED));
+ data_buffer, payload_length, rtp_header_length, red_payload_type_));
if (protect) {
producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length,
rtp_header_length);
@@ -140,7 +140,7 @@ void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer,
next_fec_sequence_number =
_rtpSender.AllocateSequenceNumber(num_fec_packets);
fec_packets = producer_fec_.GetFecPackets(
- _payloadTypeRED, _payloadTypeFEC, next_fec_sequence_number,
+ red_payload_type_, fec_payload_type_, next_fec_sequence_number,
rtp_header_length);
RTC_DCHECK_EQ(num_fec_packets, fec_packets.size());
if (_retransmissionSettings & kRetransmitFECPackets)
@@ -150,7 +150,7 @@ void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer,
if (_rtpSender.SendToNetwork(
red_packet->data(), red_packet->length() - rtp_header_length,
rtp_header_length, capture_time_ms, media_packet_storage,
- RtpPacketSender::kNormalPriority) == 0) {
+ RtpPacketSender::kLowPriority) == 0) {
_videoBitrate.Update(red_packet->length());
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"Video::PacketRed", "timestamp", capture_timestamp,
@@ -162,7 +162,7 @@ void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer,
if (_rtpSender.SendToNetwork(
fec_packet->data(), fec_packet->length() - rtp_header_length,
rtp_header_length, capture_time_ms, fec_storage,
- RtpPacketSender::kNormalPriority) == 0) {
+ RtpPacketSender::kLowPriority) == 0) {
_fecOverheadRate.Update(fec_packet->length());
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"Video::PacketFec", "timestamp", capture_timestamp,
@@ -180,9 +180,9 @@ void RTPSenderVideo::SetGenericFECStatus(const bool enable,
const uint8_t payloadTypeRED,
const uint8_t payloadTypeFEC) {
CriticalSectionScoped cs(crit_.get());
- _fecEnabled = enable;
- _payloadTypeRED = payloadTypeRED;
- _payloadTypeFEC = payloadTypeFEC;
+ fec_enabled_ = enable;
+ red_payload_type_ = payloadTypeRED;
+ fec_payload_type_ = payloadTypeFEC;
memset(&delta_fec_params_, 0, sizeof(delta_fec_params_));
memset(&key_fec_params_, 0, sizeof(key_fec_params_));
delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1;
@@ -190,18 +190,18 @@ void RTPSenderVideo::SetGenericFECStatus(const bool enable,
kFecMaskRandom;
}
-void RTPSenderVideo::GenericFECStatus(bool& enable,
- uint8_t& payloadTypeRED,
- uint8_t& payloadTypeFEC) const {
+void RTPSenderVideo::GenericFECStatus(bool* enable,
+ uint8_t* payloadTypeRED,
+ uint8_t* payloadTypeFEC) const {
CriticalSectionScoped cs(crit_.get());
- enable = _fecEnabled;
- payloadTypeRED = _payloadTypeRED;
- payloadTypeFEC = _payloadTypeFEC;
+ *enable = fec_enabled_;
+ *payloadTypeRED = red_payload_type_;
+ *payloadTypeFEC = fec_payload_type_;
}
size_t RTPSenderVideo::FECPacketOverhead() const {
CriticalSectionScoped cs(crit_.get());
- if (_fecEnabled) {
+ if (fec_enabled_) {
// Overhead is FEC headers plus RED for FEC header plus anything in RTP
// header beyond the 12 bytes base header (CSRC list, extensions...)
// This reason for the header extensions to be included here is that
@@ -247,7 +247,7 @@ int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
frameType == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_;
producer_fec_.SetFecParameters(fec_params, 0);
storage = packetizer->GetStorageType(_retransmissionSettings);
- fec_enabled = _fecEnabled;
+ fec_enabled = fec_enabled_;
}
// Register CVO rtp header extension at the first time when we receive a frame
@@ -304,7 +304,7 @@ int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
size_t packetSize = payloadSize + rtp_header_length;
RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
RTPHeader rtp_header;
- rtp_parser.Parse(rtp_header);
+ rtp_parser.Parse(&rtp_header);
_rtpSender.UpdateVideoRotation(dataBuffer, packetSize, rtp_header,
rtpHdr->rotation);
}
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h
index f412542d86..e59321ab93 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -16,7 +16,7 @@
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/modules/rtp_rtcp/source/producer_fec.h"
@@ -67,9 +67,9 @@ class RTPSenderVideo {
const uint8_t payloadTypeRED,
const uint8_t payloadTypeFEC);
- void GenericFECStatus(bool& enable,
- uint8_t& payloadTypeRED,
- uint8_t& payloadTypeFEC) const;
+ void GenericFECStatus(bool* enable,
+ uint8_t* payloadTypeRED,
+ uint8_t* payloadTypeFEC) const;
void SetFecParameters(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params);
@@ -82,7 +82,7 @@ class RTPSenderVideo {
int SelectiveRetransmissions() const;
void SetSelectiveRetransmissions(uint8_t settings);
-private:
+ private:
void SendVideoPacket(uint8_t* dataBuffer,
const size_t payloadLength,
const size_t rtpHeaderLength,
@@ -110,10 +110,10 @@ private:
int32_t _retransmissionSettings GUARDED_BY(crit_);
// FEC
- ForwardErrorCorrection _fec;
- bool _fecEnabled GUARDED_BY(crit_);
- int8_t _payloadTypeRED GUARDED_BY(crit_);
- int8_t _payloadTypeFEC GUARDED_BY(crit_);
+ ForwardErrorCorrection fec_;
+ bool fec_enabled_ GUARDED_BY(crit_);
+ int8_t red_payload_type_ GUARDED_BY(crit_);
+ int8_t fec_payload_type_ GUARDED_BY(crit_);
FecProtectionParams delta_fec_params_ GUARDED_BY(crit_);
FecProtectionParams key_fec_params_ GUARDED_BY(crit_);
ProducerFec producer_fec_ GUARDED_BY(crit_);
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
index bf0b30a064..0f0ad835b1 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
@@ -10,38 +10,10 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
-#include <assert.h>
-#include <math.h> // ceil
-#include <string.h> // memcpy
-
-#if defined(_WIN32)
-// Order for these headers are important
-#include <winsock2.h> // timeval
-#include <windows.h> // FILETIME
-#include <MMSystem.h> // timeGetTime
-#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))
-#include <sys/time.h> // gettimeofday
-#include <time.h>
-#endif
-#if (defined(_DEBUG) && defined(_WIN32) && (_MSC_VER >= 1400))
-#include <stdio.h>
-#endif
+#include <string.h>
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-
-#if (defined(_DEBUG) && defined(_WIN32) && (_MSC_VER >= 1400))
-#define DEBUG_PRINT(...) \
- { \
- char msg[256]; \
- sprintf(msg, __VA_ARGS__); \
- OutputDebugString(msg); \
- }
-#else
-// special fix for visual 2003
-#define DEBUG_PRINT(exp) ((void)0)
-#endif // defined(_DEBUG) && defined(_WIN32)
namespace webrtc {
@@ -77,50 +49,18 @@ enum {
};
/*
- * Time routines.
- */
-
-uint32_t GetCurrentRTP(Clock* clock, uint32_t freq) {
- const bool use_global_clock = (clock == NULL);
- Clock* local_clock = clock;
- if (use_global_clock) {
- local_clock = Clock::GetRealTimeClock();
- }
- uint32_t secs = 0, frac = 0;
- local_clock->CurrentNtp(secs, frac);
- if (use_global_clock) {
- delete local_clock;
- }
- return ConvertNTPTimeToRTP(secs, frac, freq);
-}
-
-uint32_t ConvertNTPTimeToRTP(uint32_t NTPsec, uint32_t NTPfrac, uint32_t freq) {
- float ftemp = (float)NTPfrac / (float)NTP_FRAC;
- uint32_t tmp = (uint32_t)(ftemp * freq);
- return NTPsec * freq + tmp;
-}
-
-uint32_t ConvertNTPTimeToMS(uint32_t NTPsec, uint32_t NTPfrac) {
- int freq = 1000;
- float ftemp = (float)NTPfrac / (float)NTP_FRAC;
- uint32_t tmp = (uint32_t)(ftemp * freq);
- uint32_t MStime = NTPsec * freq + tmp;
- return MStime;
-}
-
-/*
* Misc utility routines
*/
#if defined(_WIN32)
bool StringCompare(const char* str1, const char* str2,
const uint32_t length) {
- return (_strnicmp(str1, str2, length) == 0) ? true : false;
+ return _strnicmp(str1, str2, length) == 0;
}
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
bool StringCompare(const char* str1, const char* str2,
const uint32_t length) {
- return (strncasecmp(str1, str2, length) == 0) ? true : false;
+ return strncasecmp(str1, str2, length) == 0;
}
#endif
@@ -131,10 +71,6 @@ size_t Word32Align(size_t size) {
return size;
}
-uint32_t pow2(uint8_t exp) {
- return 1 << exp;
-}
-
RtpHeaderParser::RtpHeaderParser(const uint8_t* rtpData,
const size_t rtpDataLength)
: _ptrRTPDataBegin(rtpData),
@@ -244,7 +180,7 @@ bool RtpHeaderParser::ParseRtcp(RTPHeader* header) const {
return true;
}
-bool RtpHeaderParser::Parse(RTPHeader& header,
+bool RtpHeaderParser::Parse(RTPHeader* header,
RtpHeaderExtensionMap* ptrExtensionMap) const {
const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
if (length < kRtpMinParseLength) {
@@ -283,39 +219,39 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
return false;
}
- header.markerBit = M;
- header.payloadType = PT;
- header.sequenceNumber = sequenceNumber;
- header.timestamp = RTPTimestamp;
- header.ssrc = SSRC;
- header.numCSRCs = CC;
- header.paddingLength = P ? *(_ptrRTPDataEnd - 1) : 0;
+ header->markerBit = M;
+ header->payloadType = PT;
+ header->sequenceNumber = sequenceNumber;
+ header->timestamp = RTPTimestamp;
+ header->ssrc = SSRC;
+ header->numCSRCs = CC;
+ header->paddingLength = P ? *(_ptrRTPDataEnd - 1) : 0;
for (uint8_t i = 0; i < CC; ++i) {
uint32_t CSRC = ByteReader<uint32_t>::ReadBigEndian(ptr);
ptr += 4;
- header.arrOfCSRCs[i] = CSRC;
+ header->arrOfCSRCs[i] = CSRC;
}
- header.headerLength = 12 + CSRCocts;
+ header->headerLength = 12 + CSRCocts;
// If in effect, MAY be omitted for those packets for which the offset
// is zero.
- header.extension.hasTransmissionTimeOffset = false;
- header.extension.transmissionTimeOffset = 0;
+ header->extension.hasTransmissionTimeOffset = false;
+ header->extension.transmissionTimeOffset = 0;
// May not be present in packet.
- header.extension.hasAbsoluteSendTime = false;
- header.extension.absoluteSendTime = 0;
+ header->extension.hasAbsoluteSendTime = false;
+ header->extension.absoluteSendTime = 0;
// May not be present in packet.
- header.extension.hasAudioLevel = false;
- header.extension.voiceActivity = false;
- header.extension.audioLevel = 0;
+ header->extension.hasAudioLevel = false;
+ header->extension.voiceActivity = false;
+ header->extension.audioLevel = 0;
// May not be present in packet.
- header.extension.hasVideoRotation = false;
- header.extension.videoRotation = 0;
+ header->extension.hasVideoRotation = false;
+ header->extension.videoRotation = 0;
if (X) {
/* RTP header extension, RFC 3550.
@@ -332,7 +268,7 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
return false;
}
- header.headerLength += 4;
+ header->headerLength += 4;
uint16_t definedByProfile = ByteReader<uint16_t>::ReadBigEndian(ptr);
ptr += 2;
@@ -352,15 +288,16 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
ptrRTPDataExtensionEnd,
ptr);
}
- header.headerLength += XLen;
+ header->headerLength += XLen;
}
- if (header.headerLength + header.paddingLength > static_cast<size_t>(length))
+ if (header->headerLength + header->paddingLength >
+ static_cast<size_t>(length))
return false;
return true;
}
void RtpHeaderParser::ParseOneByteExtensionHeader(
- RTPHeader& header,
+ RTPHeader* header,
const RtpHeaderExtensionMap* ptrExtensionMap,
const uint8_t* ptrRTPDataExtensionEnd,
const uint8_t* ptr) const {
@@ -377,8 +314,8 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
// Note that 'len' is the header extension element length, which is the
// number of bytes - 1.
- const uint8_t id = (*ptr & 0xf0) >> 4;
- const uint8_t len = (*ptr & 0x0f);
+ const int id = (*ptr & 0xf0) >> 4;
+ const int len = (*ptr & 0x0f);
ptr++;
if (id == 15) {
@@ -390,8 +327,7 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
RTPExtensionType type;
if (ptrExtensionMap->GetType(id, &type) != 0) {
// If we encounter an unknown extension, just skip over it.
- LOG(LS_WARNING) << "Failed to find extension id: "
- << static_cast<int>(id);
+ LOG(LS_WARNING) << "Failed to find extension id: " << id;
} else {
switch (type) {
case kRtpExtensionTransmissionTimeOffset: {
@@ -406,9 +342,9 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
// | ID | len=2 | transmission offset |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- header.extension.transmissionTimeOffset =
+ header->extension.transmissionTimeOffset =
ByteReader<int32_t, 3>::ReadBigEndian(ptr);
- header.extension.hasTransmissionTimeOffset = true;
+ header->extension.hasTransmissionTimeOffset = true;
break;
}
case kRtpExtensionAudioLevel: {
@@ -422,9 +358,9 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
// | ID | len=0 |V| level |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
- header.extension.audioLevel = ptr[0] & 0x7f;
- header.extension.voiceActivity = (ptr[0] & 0x80) != 0;
- header.extension.hasAudioLevel = true;
+ header->extension.audioLevel = ptr[0] & 0x7f;
+ header->extension.voiceActivity = (ptr[0] & 0x80) != 0;
+ header->extension.hasAudioLevel = true;
break;
}
case kRtpExtensionAbsoluteSendTime: {
@@ -438,9 +374,9 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
// | ID | len=2 | absolute send time |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- header.extension.absoluteSendTime =
+ header->extension.absoluteSendTime =
ByteReader<uint32_t, 3>::ReadBigEndian(ptr);
- header.extension.hasAbsoluteSendTime = true;
+ header->extension.hasAbsoluteSendTime = true;
break;
}
case kRtpExtensionVideoRotation: {
@@ -454,14 +390,14 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ID | len=0 |0 0 0 0 C F R R|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- header.extension.hasVideoRotation = true;
- header.extension.videoRotation = ptr[0];
+ header->extension.hasVideoRotation = true;
+ header->extension.videoRotation = ptr[0];
break;
}
case kRtpExtensionTransportSequenceNumber: {
if (len != 1) {
- LOG(LS_WARNING)
- << "Incorrect peer connection sequence number len: " << len;
+ LOG(LS_WARNING) << "Incorrect transport sequence number len: "
+ << len;
return;
}
// 0 1 2
@@ -472,8 +408,8 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
uint16_t sequence_number = ptr[0] << 8;
sequence_number += ptr[1];
- header.extension.transportSequenceNumber = sequence_number;
- header.extension.hasTransportSequenceNumber = true;
+ header->extension.transportSequenceNumber = sequence_number;
+ header->extension.hasTransportSequenceNumber = true;
break;
}
default: {
@@ -502,5 +438,4 @@ uint8_t RtpHeaderParser::ParsePaddingBytes(
return num_zero_bytes;
}
} // namespace RtpUtility
-
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_utility.h b/webrtc/modules/rtp_rtcp/source/rtp_utility.h
index af20f97e82..23c175356a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_utility.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_utility.h
@@ -11,10 +11,11 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_UTILITY_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_UTILITY_H_
-#include <stddef.h> // size_t, ptrdiff_t
+#include <map>
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
+#include "webrtc/base/deprecation.h"
+#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
#include "webrtc/typedefs.h"
@@ -29,71 +30,48 @@ RtpAudioFeedback* NullObjectRtpAudioFeedback();
ReceiveStatistics* NullObjectReceiveStatistics();
namespace RtpUtility {
- // January 1970, in NTP seconds.
- const uint32_t NTP_JAN_1970 = 2208988800UL;
-
- // Magic NTP fractional unit.
- const double NTP_FRAC = 4.294967296E+9;
-
- struct Payload
- {
- char name[RTP_PAYLOAD_NAME_SIZE];
- bool audio;
- PayloadUnion typeSpecific;
- };
-
- typedef std::map<int8_t, Payload*> PayloadTypeMap;
-
- // Return the current RTP timestamp from the NTP timestamp
- // returned by the specified clock.
- uint32_t GetCurrentRTP(Clock* clock, uint32_t freq);
-
- // Return the current RTP absolute timestamp.
- uint32_t ConvertNTPTimeToRTP(uint32_t NTPsec,
- uint32_t NTPfrac,
- uint32_t freq);
-
- uint32_t pow2(uint8_t exp);
-
- // Returns true if |newTimestamp| is older than |existingTimestamp|.
- // |wrapped| will be set to true if there has been a wraparound between the
- // two timestamps.
- bool OldTimestamp(uint32_t newTimestamp,
- uint32_t existingTimestamp,
- bool* wrapped);
-
- bool StringCompare(const char* str1,
- const char* str2,
- const uint32_t length);
-
- // Round up to the nearest size that is a multiple of 4.
- size_t Word32Align(size_t size);
-
- class RtpHeaderParser {
- public:
- RtpHeaderParser(const uint8_t* rtpData, size_t rtpDataLength);
- ~RtpHeaderParser();
-
- bool RTCP() const;
- bool ParseRtcp(RTPHeader* header) const;
- bool Parse(RTPHeader& parsedPacket,
- RtpHeaderExtensionMap* ptrExtensionMap = NULL) const;
-
- private:
- void ParseOneByteExtensionHeader(
- RTPHeader& parsedPacket,
- const RtpHeaderExtensionMap* ptrExtensionMap,
- const uint8_t* ptrRTPDataExtensionEnd,
- const uint8_t* ptr) const;
-
- uint8_t ParsePaddingBytes(
- const uint8_t* ptrRTPDataExtensionEnd,
- const uint8_t* ptr) const;
-
- const uint8_t* const _ptrRTPDataBegin;
- const uint8_t* const _ptrRTPDataEnd;
- };
+
+struct Payload {
+ char name[RTP_PAYLOAD_NAME_SIZE];
+ bool audio;
+ PayloadUnion typeSpecific;
+};
+
+typedef std::map<int8_t, Payload*> PayloadTypeMap;
+
+bool StringCompare(const char* str1, const char* str2, const uint32_t length);
+
+// Round up to the nearest size that is a multiple of 4.
+size_t Word32Align(size_t size);
+
+class RtpHeaderParser {
+ public:
+ RtpHeaderParser(const uint8_t* rtpData, size_t rtpDataLength);
+ ~RtpHeaderParser();
+
+ bool RTCP() const;
+ bool ParseRtcp(RTPHeader* header) const;
+ bool Parse(RTPHeader* parsedPacket,
+ RtpHeaderExtensionMap* ptrExtensionMap = nullptr) const;
+ RTC_DEPRECATED bool Parse(
+ RTPHeader& parsedPacket, // NOLINT(runtime/references)
+ RtpHeaderExtensionMap* ptrExtensionMap = nullptr) const {
+ return Parse(&parsedPacket, ptrExtensionMap);
+ }
+
+ private:
+ void ParseOneByteExtensionHeader(RTPHeader* parsedPacket,
+ const RtpHeaderExtensionMap* ptrExtensionMap,
+ const uint8_t* ptrRTPDataExtensionEnd,
+ const uint8_t* ptr) const;
+
+ uint8_t ParsePaddingBytes(const uint8_t* ptrRTPDataExtensionEnd,
+ const uint8_t* ptr) const;
+
+ const uint8_t* const _ptrRTPDataBegin;
+ const uint8_t* const _ptrRTPDataEnd;
+};
} // namespace RtpUtility
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_UTILITY_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_UTILITY_H_
diff --git a/webrtc/modules/rtp_rtcp/source/ssrc_database.cc b/webrtc/modules/rtp_rtcp/source/ssrc_database.cc
index 6fb7c4701a..fb02b7ef12 100644
--- a/webrtc/modules/rtp_rtcp/source/ssrc_database.cc
+++ b/webrtc/modules/rtp_rtcp/source/ssrc_database.cc
@@ -10,110 +10,51 @@
#include "webrtc/modules/rtp_rtcp/source/ssrc_database.h"
-#include <assert.h>
-#include <stdlib.h>
-
+#include "webrtc/base/checks.h"
+#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#ifdef _WIN32
- #include <windows.h>
- #include <MMSystem.h> //timeGetTime
-
-// TODO(hellner): investigate if it is necessary to disable these warnings.
- #pragma warning(disable:4311)
- #pragma warning(disable:4312)
-#else
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <sys/time.h>
-#endif
-
namespace webrtc {
-SSRCDatabase*
-SSRCDatabase::StaticInstance(CountOperation count_operation)
-{
- SSRCDatabase* impl =
- GetStaticInstance<SSRCDatabase>(count_operation);
- return impl;
+namespace {
+uint64_t Seed() {
+ return Clock::GetRealTimeClock()->TimeInMicroseconds();
}
+} // namespace
-SSRCDatabase*
-SSRCDatabase::GetSSRCDatabase()
-{
- return StaticInstance(kAddRef);
+SSRCDatabase* SSRCDatabase::GetSSRCDatabase() {
+ return GetStaticInstance<SSRCDatabase>(kAddRef);
}
-void
-SSRCDatabase::ReturnSSRCDatabase()
-{
- StaticInstance(kRelease);
+void SSRCDatabase::ReturnSSRCDatabase() {
+ GetStaticInstance<SSRCDatabase>(kRelease);
}
-uint32_t
-SSRCDatabase::CreateSSRC()
-{
- CriticalSectionScoped lock(_critSect);
+uint32_t SSRCDatabase::CreateSSRC() {
+ CriticalSectionScoped lock(crit_.get());
- uint32_t ssrc = GenerateRandom();
-
- while(_ssrcMap.find(ssrc) != _ssrcMap.end())
- {
- ssrc = GenerateRandom();
+ while (true) { // Try until get a new ssrc.
+ // 0 and 0xffffffff are invalid values for SSRC.
+ uint32_t ssrc = random_.Rand(1u, 0xfffffffe);
+ if (ssrcs_.insert(ssrc).second) {
+ return ssrc;
}
- _ssrcMap[ssrc] = 0;
-
- return ssrc;
+ }
}
-int32_t
-SSRCDatabase::RegisterSSRC(const uint32_t ssrc)
-{
- CriticalSectionScoped lock(_critSect);
- _ssrcMap[ssrc] = 0;
- return 0;
+void SSRCDatabase::RegisterSSRC(uint32_t ssrc) {
+ CriticalSectionScoped lock(crit_.get());
+ ssrcs_.insert(ssrc);
}
-int32_t
-SSRCDatabase::ReturnSSRC(const uint32_t ssrc)
-{
- CriticalSectionScoped lock(_critSect);
- _ssrcMap.erase(ssrc);
- return 0;
+void SSRCDatabase::ReturnSSRC(uint32_t ssrc) {
+ CriticalSectionScoped lock(crit_.get());
+ ssrcs_.erase(ssrc);
}
SSRCDatabase::SSRCDatabase()
-{
- // we need to seed the random generator, otherwise we get 26500 each time, hardly a random value :)
-#ifdef _WIN32
- srand(timeGetTime());
-#else
- struct timeval tv;
- struct timezone tz;
- gettimeofday(&tv, &tz);
- srand(tv.tv_usec);
-#endif
+ : crit_(CriticalSectionWrapper::CreateCriticalSection()), random_(Seed()) {}
- _critSect = CriticalSectionWrapper::CreateCriticalSection();
+SSRCDatabase::~SSRCDatabase() {
}
-SSRCDatabase::~SSRCDatabase()
-{
- _ssrcMap.clear();
- delete _critSect;
-}
-
-uint32_t SSRCDatabase::GenerateRandom()
-{
- uint32_t ssrc = 0;
- do
- {
- ssrc = rand();
- ssrc = ssrc <<16;
- ssrc += rand();
-
- } while (ssrc == 0 || ssrc == 0xffffffff);
-
- return ssrc;
-}
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/ssrc_database.h b/webrtc/modules/rtp_rtcp/source/ssrc_database.h
index 7129d0de76..7a3133638d 100644
--- a/webrtc/modules/rtp_rtcp/source/ssrc_database.h
+++ b/webrtc/modules/rtp_rtcp/source/ssrc_database.h
@@ -11,43 +11,41 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_
-#include <map>
+#include <set>
+#include "webrtc/base/random.h"
+#include "webrtc/base/scoped_ptr.h"
#include "webrtc/system_wrappers/include/static_instance.h"
#include "webrtc/typedefs.h"
namespace webrtc {
class CriticalSectionWrapper;
-class SSRCDatabase
-{
-public:
- static SSRCDatabase* GetSSRCDatabase();
- static void ReturnSSRCDatabase();
+class SSRCDatabase {
+ public:
+ static SSRCDatabase* GetSSRCDatabase();
+ static void ReturnSSRCDatabase();
- uint32_t CreateSSRC();
- int32_t RegisterSSRC(const uint32_t ssrc);
- int32_t ReturnSSRC(const uint32_t ssrc);
+ uint32_t CreateSSRC();
+ void RegisterSSRC(uint32_t ssrc);
+ void ReturnSSRC(uint32_t ssrc);
-protected:
- SSRCDatabase();
- virtual ~SSRCDatabase();
+ protected:
+ SSRCDatabase();
+ virtual ~SSRCDatabase();
- static SSRCDatabase* CreateInstance() { return new SSRCDatabase(); }
+ static SSRCDatabase* CreateInstance() { return new SSRCDatabase(); }
-private:
- // Friend function to allow the SSRC destructor to be accessed from the
- // template class.
- friend SSRCDatabase* GetStaticInstance<SSRCDatabase>(
- CountOperation count_operation);
- static SSRCDatabase* StaticInstance(CountOperation count_operation);
+ private:
+ // Friend function to allow the SSRC destructor to be accessed from the
+ // template class.
+ friend SSRCDatabase* GetStaticInstance<SSRCDatabase>(
+ CountOperation count_operation);
- uint32_t GenerateRandom();
-
- std::map<uint32_t, uint32_t> _ssrcMap;
-
- CriticalSectionWrapper* _critSect;
+ rtc::scoped_ptr<CriticalSectionWrapper> crit_;
+ Random random_ GUARDED_BY(crit_);
+ std::set<uint32_t> ssrcs_ GUARDED_BY(crit_);
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_
diff --git a/webrtc/modules/rtp_rtcp/source/time_util.h b/webrtc/modules/rtp_rtcp/source/time_util.h
new file mode 100644
index 0000000000..5b544ddf9a
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/time_util.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 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_TIME_UTIL_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_TIME_UTIL_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/system_wrappers/include/ntp_time.h"
+
+namespace webrtc {
+
+// Converts NTP timestamp to RTP timestamp.
+inline uint32_t NtpToRtp(NtpTime ntp, uint32_t freq) {
+ uint32_t tmp = (static_cast<uint64_t>(ntp.fractions()) * freq) >> 32;
+ return ntp.seconds() * freq + tmp;
+}
+// Return the current RTP timestamp from the NTP timestamp
+// returned by the specified clock.
+inline uint32_t CurrentRtp(const Clock& clock, uint32_t freq) {
+ return NtpToRtp(NtpTime(clock), freq);
+}
+
+// Helper function for compact ntp representation:
+// RFC 3550, Section 4. Time Format.
+// Wallclock time is represented using the timestamp format of
+// the Network Time Protocol (NTP).
+// ...
+// In some fields where a more compact representation is
+// appropriate, only the middle 32 bits are used; that is, the low 16
+// bits of the integer part and the high 16 bits of the fractional part.
+inline uint32_t CompactNtp(NtpTime ntp) {
+ return (ntp.seconds() << 16) | (ntp.fractions() >> 16);
+}
+// Converts interval between compact ntp timestamps to milliseconds.
+// This interval can be upto ~18.2 hours (2^16 seconds).
+inline uint32_t CompactNtpIntervalToMs(uint32_t compact_ntp_interval) {
+ return static_cast<uint64_t>(compact_ntp_interval) * 1000 / (1 << 16);
+}
+
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_TIME_UTIL_H_
diff --git a/webrtc/modules/rtp_rtcp/source/time_util_unittest.cc b/webrtc/modules/rtp_rtcp/source/time_util_unittest.cc
new file mode 100644
index 0000000000..7efb83ccad
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/time_util_unittest.cc
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015 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/time_util.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace webrtc {
+
+TEST(TimeUtilTest, CompactNtp) {
+ const uint32_t kNtpSec = 0x12345678;
+ const uint32_t kNtpFrac = 0x23456789;
+ const NtpTime kNtp(kNtpSec, kNtpFrac);
+ const uint32_t kNtpMid = 0x56782345;
+ EXPECT_EQ(kNtpMid, CompactNtp(kNtp));
+}
+
+TEST(TimeUtilTest, CompactNtpToMs) {
+ const NtpTime ntp1(0x12345, 0x23456);
+ const NtpTime ntp2(0x12654, 0x64335);
+ uint32_t ms_diff = ntp2.ToMs() - ntp1.ToMs();
+ uint32_t ntp_diff = CompactNtp(ntp2) - CompactNtp(ntp1);
+
+ uint32_t ntp_to_ms_diff = CompactNtpIntervalToMs(ntp_diff);
+
+ EXPECT_NEAR(ms_diff, ntp_to_ms_diff, 1);
+}
+
+TEST(TimeUtilTest, CompactNtpToMsWithWrap) {
+ const NtpTime ntp1(0x1ffff, 0x23456);
+ const NtpTime ntp2(0x20000, 0x64335);
+ uint32_t ms_diff = ntp2.ToMs() - ntp1.ToMs();
+
+ // While ntp2 > ntp1, there compact ntp presentation happen to be opposite.
+ // That shouldn't be a problem as long as unsigned arithmetic is used.
+ ASSERT_GT(ntp2.ToMs(), ntp1.ToMs());
+ ASSERT_LT(CompactNtp(ntp2), CompactNtp(ntp1));
+
+ uint32_t ntp_diff = CompactNtp(ntp2) - CompactNtp(ntp1);
+ uint32_t ntp_to_ms_diff = CompactNtpIntervalToMs(ntp_diff);
+
+ EXPECT_NEAR(ms_diff, ntp_to_ms_diff, 1);
+}
+
+TEST(TimeUtilTest, CompactNtpToMsLarge) {
+ const NtpTime ntp1(0x10000, 0x23456);
+ const NtpTime ntp2(0x1ffff, 0x64335);
+ uint32_t ms_diff = ntp2.ToMs() - ntp1.ToMs();
+ // Ntp difference close to maximum of ~18 hours should convert correctly too.
+ ASSERT_GT(ms_diff, 18u * 3600 * 1000);
+ uint32_t ntp_diff = CompactNtp(ntp2) - CompactNtp(ntp1);
+ uint32_t ntp_to_ms_diff = CompactNtpIntervalToMs(ntp_diff);
+
+ EXPECT_NEAR(ms_diff, ntp_to_ms_diff, 1);
+}
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/tmmbr_help.cc b/webrtc/modules/rtp_rtcp/source/tmmbr_help.cc
index fb1ed625ed..f994ff7049 100644
--- a/webrtc/modules/rtp_rtcp/source/tmmbr_help.cc
+++ b/webrtc/modules/rtp_rtcp/source/tmmbr_help.cc
@@ -11,8 +11,10 @@
#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
#include <assert.h>
-#include <limits>
#include <string.h>
+
+#include <limits>
+
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
namespace webrtc {
diff --git a/webrtc/modules/rtp_rtcp/source/video_codec_information.h b/webrtc/modules/rtp_rtcp/source/video_codec_information.h
index 456b3bb934..7b819d060f 100644
--- a/webrtc/modules/rtp_rtcp/source/video_codec_information.h
+++ b/webrtc/modules/rtp_rtcp/source/video_codec_information.h
@@ -15,14 +15,13 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
namespace webrtc {
-class VideoCodecInformation
-{
-public:
- virtual void Reset() = 0;
+class VideoCodecInformation {
+ public:
+ virtual void Reset() = 0;
- virtual RtpVideoCodecTypes Type() = 0;
- virtual ~VideoCodecInformation(){};
+ virtual RtpVideoCodecTypes Type() = 0;
+ virtual ~VideoCodecInformation() {}
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_VIDEO_CODEC_INFORMATION_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_VIDEO_CODEC_INFORMATION_H_
diff --git a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc b/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
index feed784839..9721a7e9ac 100644
--- a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
+++ b/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
@@ -37,9 +37,8 @@ PartitionTreeNode::PartitionTreeNode(PartitionTreeNode* parent,
PartitionTreeNode* PartitionTreeNode::CreateRootNode(const size_t* size_vector,
size_t num_partitions) {
- PartitionTreeNode* root_node =
- new PartitionTreeNode(NULL, &size_vector[1], num_partitions - 1,
- size_vector[0]);
+ PartitionTreeNode* root_node = new PartitionTreeNode(
+ NULL, &size_vector[1], num_partitions - 1, size_vector[0]);
root_node->set_packet_start(true);
return root_node;
}
@@ -54,7 +53,7 @@ int PartitionTreeNode::Cost(size_t penalty) {
if (num_partitions_ == 0) {
// This is a solution node.
cost = std::max(max_parent_size_, this_size_int()) -
- std::min(min_parent_size_, this_size_int());
+ std::min(min_parent_size_, this_size_int());
} else {
cost = std::max(max_parent_size_, this_size_int()) - min_parent_size_;
}
@@ -68,9 +67,7 @@ bool PartitionTreeNode::CreateChildren(size_t max_size) {
if (this_size_ + size_vector_[0] <= max_size) {
assert(!children_[kLeftChild]);
children_[kLeftChild] =
- new PartitionTreeNode(this,
- &size_vector_[1],
- num_partitions_ - 1,
+ new PartitionTreeNode(this, &size_vector_[1], num_partitions_ - 1,
this_size_ + size_vector_[0]);
children_[kLeftChild]->set_max_parent_size(max_parent_size_);
children_[kLeftChild]->set_min_parent_size(min_parent_size_);
@@ -80,10 +77,8 @@ bool PartitionTreeNode::CreateChildren(size_t max_size) {
}
if (this_size_ > 0) {
assert(!children_[kRightChild]);
- children_[kRightChild] = new PartitionTreeNode(this,
- &size_vector_[1],
- num_partitions_ - 1,
- size_vector_[0]);
+ children_[kRightChild] = new PartitionTreeNode(
+ this, &size_vector_[1], num_partitions_ - 1, size_vector_[0]);
children_[kRightChild]->set_max_parent_size(
std::max(max_parent_size_, this_size_int()));
children_[kRightChild]->set_min_parent_size(
@@ -148,7 +143,8 @@ PartitionTreeNode* PartitionTreeNode::GetOptimalNode(size_t max_size,
Vp8PartitionAggregator::Vp8PartitionAggregator(
const RTPFragmentationHeader& fragmentation,
- size_t first_partition_idx, size_t last_partition_idx)
+ size_t first_partition_idx,
+ size_t last_partition_idx)
: root_(NULL),
num_partitions_(last_partition_idx - first_partition_idx + 1),
size_vector_(new size_t[num_partitions_]),
@@ -158,14 +154,14 @@ Vp8PartitionAggregator::Vp8PartitionAggregator(
for (size_t i = 0; i < num_partitions_; ++i) {
size_vector_[i] =
fragmentation.fragmentationLength[i + first_partition_idx];
- largest_partition_size_ = std::max(largest_partition_size_,
- size_vector_[i]);
+ largest_partition_size_ =
+ std::max(largest_partition_size_, size_vector_[i]);
}
root_ = PartitionTreeNode::CreateRootNode(size_vector_, num_partitions_);
}
Vp8PartitionAggregator::~Vp8PartitionAggregator() {
- delete [] size_vector_;
+ delete[] size_vector_;
delete root_;
}
@@ -190,14 +186,16 @@ Vp8PartitionAggregator::FindOptimalConfiguration(size_t max_size,
assert(packet_index > 0);
assert(temp_node != NULL);
config_vector[i - 1] = packet_index - 1;
- if (temp_node->packet_start()) --packet_index;
+ if (temp_node->packet_start())
+ --packet_index;
temp_node = temp_node->parent();
}
return config_vector;
}
void Vp8PartitionAggregator::CalcMinMax(const ConfigVec& config,
- int* min_size, int* max_size) const {
+ int* min_size,
+ int* max_size) const {
if (*min_size < 0) {
*min_size = std::numeric_limits<int>::max();
}
@@ -263,8 +261,8 @@ size_t Vp8PartitionAggregator::CalcNumberOfFragments(
}
assert(num_fragments > 0);
// TODO(mflodman) Assert disabled since it's falsely triggered, see issue 293.
- //assert(large_partition_size / num_fragments + 1 <= max_payload_size);
+ // assert(large_partition_size / num_fragments + 1 <= max_payload_size);
return num_fragments;
}
-} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h b/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h
index 53b678f3b9..ccd22e5be2 100644
--- a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h
+++ b/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h
@@ -14,7 +14,7 @@
#include <vector>
#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -132,6 +132,6 @@ class Vp8PartitionAggregator {
RTC_DISALLOW_COPY_AND_ASSIGN(Vp8PartitionAggregator);
};
-} // namespace
+} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_VP8_PARTITION_AGGREGATOR_H_
diff --git a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator_unittest.cc b/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator_unittest.cc
index 4650c94047..726d83ec50 100644
--- a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator_unittest.cc
@@ -209,4 +209,4 @@ TEST(Vp8PartitionAggregator, TestCalcNumberOfFragments) {
1600, kMTU, 1, 900, 1000));
}
-} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/BWEStandAlone.cc b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/BWEStandAlone.cc
deleted file mode 100644
index 711be4a623..0000000000
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/BWEStandAlone.cc
+++ /dev/null
@@ -1,199 +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.
- */
-
-// BWEStandAlone.cpp : Defines the entry point for the console application.
-//
-
-#include <stdio.h>
-#include <string>
-
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/system_wrappers/include/event_wrapper.h"
-#include "webrtc/system_wrappers/include/trace.h"
-#include "webrtc/test/channel_transport/udp_transport.h"
-
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h"
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h"
-
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h"
-
-//#include "vld.h"
-
-class myTransportCB: public UdpTransportData
-{
-public:
- myTransportCB (RtpRtcp *rtpMod) : _rtpMod(rtpMod) {};
-protected:
- // Inherited from UdpTransportData
- void IncomingRTPPacket(const int8_t* incomingRtpPacket,
- const size_t rtpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort) override;
-
- void IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
- const size_t rtcpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort) override;
-
-private:
- RtpRtcp *_rtpMod;
-};
-
-void myTransportCB::IncomingRTPPacket(const int8_t* incomingRtpPacket,
- const size_t rtpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort)
-{
- printf("Receiving RTP from IP %s, port %u\n", fromIP, fromPort);
- _rtpMod->IncomingPacket((uint8_t *) incomingRtpPacket, rtpPacketLength);
-}
-
-void myTransportCB::IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
- const size_t rtcpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort)
-{
- printf("Receiving RTCP from IP %s, port %u\n", fromIP, fromPort);
- _rtpMod->IncomingPacket((uint8_t *) incomingRtcpPacket, rtcpPacketLength);
-}
-
-
-int main(int argc, char* argv[])
-{
- bool isSender = false;
- bool isReceiver = false;
- uint16_t port;
- std::string ip;
- TestSenderReceiver *sendrec = new TestSenderReceiver();
- TestLoadGenerator *gen;
-
- if (argc == 2)
- {
- // receiver only
- isReceiver = true;
-
- // read port
- port = atoi(argv[1]);
- }
- else if (argc == 3)
- {
- // sender and receiver
- isSender = true;
- isReceiver = true;
-
- // read IP
- ip = argv[1];
-
- // read port
- port = atoi(argv[2]);
- }
-
- Trace::CreateTrace();
- Trace::SetTraceFile("BWEStandAloneTrace.txt");
- Trace::set_level_filter(webrtc::kTraceAll);
-
- sendrec->InitReceiver(port);
-
- sendrec->Start();
-
- if (isSender)
- {
- const uint32_t startRateKbps = 1000;
- //gen = new CBRGenerator(sendrec, 1000, 500);
- gen = new CBRFixFRGenerator(sendrec, startRateKbps, 90000, 30, 0.2);
- //gen = new PeriodicKeyFixFRGenerator(sendrec, startRateKbps, 90000, 30, 0.2, 7, 300);
- //const uint16_t numFrameRates = 5;
- //const uint8_t frameRates[numFrameRates] = {30, 15, 20, 23, 25};
- //gen = new CBRVarFRGenerator(sendrec, 1000, frameRates, numFrameRates, 90000, 4.0, 0.1, 0.2);
- //gen = new CBRFrameDropGenerator(sendrec, startRateKbps, 90000, 0.2);
- sendrec->SetLoadGenerator(gen);
- sendrec->InitSender(startRateKbps, ip.c_str(), port);
- gen->Start();
- }
-
- while (1)
- {
- }
-
- if (isSender)
- {
- gen->Stop();
- delete gen;
- }
-
- delete sendrec;
-
- //uint8_t numberOfSocketThreads = 1;
- //UdpTransport* transport = UdpTransport::Create(0, numberOfSocketThreads);
-
- //RtpRtcp* rtp = RtpRtcp::CreateRtpRtcp(1, false);
- //if (rtp->InitSender() != 0)
- //{
- // exit(1);
- //}
- //if (rtp->RegisterSendTransport(transport) != 0)
- //{
- // exit(1);
- //}
-
-// transport->InitializeSendSockets("192.168.200.39", 8000);
- //transport->InitializeSendSockets("127.0.0.1", 10000);
- //transport->InitializeSourcePorts(8000);
-
-
- return(0);
- // myTransportCB *tp = new myTransportCB(rtp);
- // transport->InitializeReceiveSockets(tp, 10000, "0.0.0.0");
- // transport->StartReceiving(500);
-
- // int8_t data[100];
- // for (int i = 0; i < 100; data[i] = i++);
-
- // for (int i = 0; i < 100; i++)
- // {
- // transport->SendRaw(data, 100, false);
- // }
-
-
-
- // int32_t totTime = 0;
- // while (totTime < 10000)
- // {
- // transport->Process();
- // int32_t wTime = transport->TimeUntilNextProcess();
- // totTime += wTime;
- // Sleep(wTime);
- // }
-
-
- //if (transport)
- //{
- // // Destroy the Socket Transport module
- // transport->StopReceiving();
- // transport->InitializeReceiveSockets(NULL,0);// deregister callback
- // UdpTransport::Destroy(transport);
- // transport = NULL;
- // }
-
- // if (tp)
- // {
- // delete tp;
- // tp = NULL;
- // }
-
- // if (rtp)
- // {
- // RtpRtcp::DestroyRtpRtcp(rtp);
- // rtp = NULL;
- // }
-
-
- //return 0;
-}
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc
deleted file mode 100644
index fe54d67ee7..0000000000
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc
+++ /dev/null
@@ -1,1055 +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.
- */
-
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h"
-
-#include <math.h>
-#include <stdio.h>
-
-#include <algorithm>
-#include <sstream>
-
-#ifdef MATLAB
-#include "engine.h"
-#endif
-
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/event_wrapper.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-
-using namespace webrtc;
-
-#ifdef MATLAB
-MatlabEngine eng;
-
-MatlabLine::MatlabLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/)
-:
-_xArray(NULL),
-_yArray(NULL),
-_maxLen(maxLen),
-_plotAttribute(),
-_name()
-{
- if (_maxLen > 0)
- {
- _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
- _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
- }
-
- if (plotAttrib)
- {
- _plotAttribute = plotAttrib;
- }
-
- if (name)
- {
- _name = name;
- }
-}
-
-MatlabLine::~MatlabLine()
-{
- if (_xArray != NULL)
- {
- mxDestroyArray(_xArray);
- }
- if (_yArray != NULL)
- {
- mxDestroyArray(_yArray);
- }
-}
-
-void MatlabLine::Append(double x, double y)
-{
- if (_maxLen > 0 && _xData.size() > static_cast<uint32_t>(_maxLen))
- {
- _xData.resize(_maxLen);
- _yData.resize(_maxLen);
- }
-
- _xData.push_front(x);
- _yData.push_front(y);
-}
-
-
-// append y-data with running integer index as x-data
-void MatlabLine::Append(double y)
-{
- if (_xData.empty())
- {
- // first element is index 0
- Append(0, y);
- }
- else
- {
- // take last x-value and increment
- double temp = _xData.back(); // last x-value
- Append(temp + 1, y);
- }
-}
-
-
-void MatlabLine::SetMaxLen(int maxLen)
-{
- if (maxLen <= 0)
- {
- // means no maxLen
- _maxLen = -1;
- }
- else
- {
- _maxLen = maxLen;
-
- if (_xArray != NULL)
- {
- mxDestroyArray(_xArray);
- mxDestroyArray(_yArray);
- }
- _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
- _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
-
- maxLen = ((unsigned int)maxLen <= _xData.size()) ? maxLen : (int)_xData.size();
- _xData.resize(maxLen);
- _yData.resize(maxLen);
-
- //// reserve the right amount of memory
- //_xData.reserve(_maxLen);
- //_yData.reserve(_maxLen);
- }
-}
-
-void MatlabLine::SetAttribute(char *plotAttrib)
-{
- _plotAttribute = plotAttrib;
-}
-
-void MatlabLine::SetName(char *name)
-{
- _name = name;
-}
-
-void MatlabLine::GetPlotData(mxArray** xData, mxArray** yData)
-{
- // Make sure we have enough Matlab allocated memory.
- // Assuming both arrays (x and y) are of the same size.
- if (_xData.empty())
- {
- return; // No data
- }
- unsigned int size = 0;
- if (_xArray != NULL)
- {
- size = (unsigned int)mxGetNumberOfElements(_xArray);
- }
- if (size < _xData.size())
- {
- if (_xArray != NULL)
- {
- mxDestroyArray(_xArray);
- mxDestroyArray(_yArray);
- }
- _xArray = mxCreateDoubleMatrix(1, _xData.size(), mxREAL);
- _yArray = mxCreateDoubleMatrix(1, _yData.size(), mxREAL);
- }
-
- if (!_xData.empty())
- {
- double* x = mxGetPr(_xArray);
-
- std::list<double>::iterator it = _xData.begin();
-
- for (int i = 0; it != _xData.end(); it++, i++)
- {
- x[i] = *it;
- }
- }
-
- if (!_yData.empty())
- {
- double* y = mxGetPr(_yArray);
-
- std::list<double>::iterator it = _yData.begin();
-
- for (int i = 0; it != _yData.end(); it++, i++)
- {
- y[i] = *it;
- }
- }
- *xData = _xArray;
- *yData = _yArray;
-}
-
-std::string MatlabLine::GetXName()
-{
- std::ostringstream xString;
- xString << "x_" << _name;
- return xString.str();
-}
-
-std::string MatlabLine::GetYName()
-{
- std::ostringstream yString;
- yString << "y_" << _name;
- return yString.str();
-}
-
-std::string MatlabLine::GetPlotString()
-{
-
- std::ostringstream s;
-
- if (_xData.size() == 0)
- {
- s << "[0 1], [0 1]"; // To get an empty plot
- }
- else
- {
- s << GetXName() << "(1:" << _xData.size() << "),";
- s << GetYName() << "(1:" << _yData.size() << ")";
- }
-
- s << ", '";
- s << _plotAttribute;
- s << "'";
-
- return s.str();
-}
-
-std::string MatlabLine::GetRefreshString()
-{
- std::ostringstream s;
-
- if (_xData.size() > 0)
- {
- s << "set(h,'xdata',"<< GetXName() <<"(1:" << _xData.size() << "),'ydata',"<< GetYName() << "(1:" << _yData.size() << "));";
- }
- else
- {
- s << "set(h,'xdata',[NaN],'ydata',[NaN]);";
- }
- return s.str();
-}
-
-std::string MatlabLine::GetLegendString()
-{
- return ("'" + _name + "'");
-}
-
-bool MatlabLine::hasLegend()
-{
- return (!_name.empty());
-}
-
-
-// remove data points, but keep attributes
-void MatlabLine::Reset()
-{
- _xData.clear();
- _yData.clear();
-}
-
-
-void MatlabLine::UpdateTrendLine(MatlabLine * sourceData, double slope, double offset)
-{
- Reset(); // reset data, not attributes and name
-
- double thexMin = sourceData->xMin();
- double thexMax = sourceData->xMax();
- Append(thexMin, thexMin * slope + offset);
- Append(thexMax, thexMax * slope + offset);
-}
-
-double MatlabLine::xMin()
-{
- if (!_xData.empty())
- {
- std::list<double>::iterator theStart = _xData.begin();
- std::list<double>::iterator theEnd = _xData.end();
- return(*min_element(theStart, theEnd));
- }
- return (0.0);
-}
-
-double MatlabLine::xMax()
-{
- if (!_xData.empty())
- {
- std::list<double>::iterator theStart = _xData.begin();
- std::list<double>::iterator theEnd = _xData.end();
- return(*max_element(theStart, theEnd));
- }
- return (0.0);
-}
-
-double MatlabLine::yMin()
-{
- if (!_yData.empty())
- {
- std::list<double>::iterator theStart = _yData.begin();
- std::list<double>::iterator theEnd = _yData.end();
- return(*min_element(theStart, theEnd));
- }
- return (0.0);
-}
-
-double MatlabLine::yMax()
-{
- if (!_yData.empty())
- {
- std::list<double>::iterator theStart = _yData.begin();
- std::list<double>::iterator theEnd = _yData.end();
- return(*max_element(theStart, theEnd));
- }
- return (0.0);
-}
-
-
-
-MatlabTimeLine::MatlabTimeLine(int horizonSeconds /*= -1*/, const char *plotAttrib /*= NULL*/,
- const char *name /*= NULL*/,
- int64_t refTimeMs /* = -1*/)
- :
-_timeHorizon(horizonSeconds),
-MatlabLine(-1, plotAttrib, name) // infinite number of elements
-{
- if (refTimeMs < 0)
- _refTimeMs = TickTime::MillisecondTimestamp();
- else
- _refTimeMs = refTimeMs;
-}
-
-void MatlabTimeLine::Append(double y)
-{
- MatlabLine::Append(static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0, y);
-
- PurgeOldData();
-}
-
-
-void MatlabTimeLine::PurgeOldData()
-{
- if (_timeHorizon > 0)
- {
- // remove old data
- double historyLimit = static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0
- - _timeHorizon; // remove data points older than this
-
- std::list<double>::reverse_iterator ritx = _xData.rbegin();
- uint32_t removeCount = 0;
- while (ritx != _xData.rend())
- {
- if (*ritx >= historyLimit)
- {
- break;
- }
- ritx++;
- removeCount++;
- }
- if (removeCount == 0)
- {
- return;
- }
-
- // remove the range [begin, it).
- //if (removeCount > 10)
- //{
- // printf("Removing %lu elements\n", removeCount);
- //}
- _xData.resize(_xData.size() - removeCount);
- _yData.resize(_yData.size() - removeCount);
- }
-}
-
-
-int64_t MatlabTimeLine::GetRefTime()
-{
- return(_refTimeMs);
-}
-
-
-
-
-MatlabPlot::MatlabPlot()
-:
-_figHandle(-1),
-_smartAxis(false),
-_critSect(CriticalSectionWrapper::CreateCriticalSection()),
-_timeToPlot(false),
-_plotting(false),
-_enabled(true),
-_firstPlot(true),
-_legendEnabled(true),
-_donePlottingEvent(EventWrapper::Create())
-{
- CriticalSectionScoped cs(_critSect);
-
- _xlim[0] = 0;
- _xlim[1] = 0;
- _ylim[0] = 0;
- _ylim[1] = 0;
-
-#ifdef PLOT_TESTING
- _plotStartTime = -1;
- _plotDelay = 0;
-#endif
-
-}
-
-
-MatlabPlot::~MatlabPlot()
-{
- _critSect->Enter();
-
- // delete all line objects
- while (!_line.empty())
- {
- delete *(_line.end() - 1);
- _line.pop_back();
- }
-
- delete _critSect;
- delete _donePlottingEvent;
-}
-
-
-int MatlabPlot::AddLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/)
-{
- CriticalSectionScoped cs(_critSect);
- if (!_enabled)
- {
- return -1;
- }
-
- MatlabLine *newLine = new MatlabLine(maxLen, plotAttrib, name);
- _line.push_back(newLine);
-
- return (static_cast<int>(_line.size() - 1)); // index of newly inserted line
-}
-
-
-int MatlabPlot::AddTimeLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/,
- int64_t refTimeMs /*= -1*/)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return -1;
- }
-
- MatlabTimeLine *newLine = new MatlabTimeLine(maxLen, plotAttrib, name, refTimeMs);
- _line.push_back(newLine);
-
- return (static_cast<int>(_line.size() - 1)); // index of newly inserted line
-}
-
-
-int MatlabPlot::GetLineIx(const char *name)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return -1;
- }
-
- // search the list for a matching line name
- std::vector<MatlabLine*>::iterator it = _line.begin();
- bool matchFound = false;
- int lineIx = 0;
-
- for (; it != _line.end(); it++, lineIx++)
- {
- if ((*it)->_name == name)
- {
- matchFound = true;
- break;
- }
- }
-
- if (matchFound)
- {
- return (lineIx);
- }
- else
- {
- return (-1);
- }
-}
-
-
-void MatlabPlot::Append(int lineIndex, double x, double y)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return;
- }
-
- // sanity for index
- if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size()))
- {
- throw "Line index out of range";
- exit(1);
- }
-
- return (_line[lineIndex]->Append(x, y));
-}
-
-
-void MatlabPlot::Append(int lineIndex, double y)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return;
- }
-
- // sanity for index
- if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size()))
- {
- throw "Line index out of range";
- exit(1);
- }
-
- return (_line[lineIndex]->Append(y));
-}
-
-
-int MatlabPlot::Append(const char *name, double x, double y)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return -1;
- }
-
- // search the list for a matching line name
- int lineIx = GetLineIx(name);
-
- if (lineIx < 0) //(!matchFound)
- {
- // no match; append new line
- lineIx = AddLine(-1, NULL, name);
- }
-
- // append data to line
- Append(lineIx, x, y);
- return (lineIx);
-}
-
-int MatlabPlot::Append(const char *name, double y)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return -1;
- }
-
- // search the list for a matching line name
- int lineIx = GetLineIx(name);
-
- if (lineIx < 0) //(!matchFound)
- {
- // no match; append new line
- lineIx = AddLine(-1, NULL, name);
- }
-
- // append data to line
- Append(lineIx, y);
- return (lineIx);
-}
-
-int MatlabPlot::Length(char *name)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return -1;
- }
-
- int ix = GetLineIx(name);
- if (ix >= 0)
- {
- return (static_cast<int>(_line[ix]->_xData.size()));
- }
- else
- {
- return (-1);
- }
-}
-
-
-void MatlabPlot::SetPlotAttribute(char *name, char *plotAttrib)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (!_enabled)
- {
- return;
- }
-
- int lineIx = GetLineIx(name);
-
- if (lineIx >= 0)
- {
- _line[lineIx]->SetAttribute(plotAttrib);
- }
-}
-
-// Must be called under critical section _critSect
-void MatlabPlot::UpdateData(Engine* ep)
-{
- if (!_enabled)
- {
- return;
- }
-
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
- {
- mxArray* xData = NULL;
- mxArray* yData = NULL;
- (*it)->GetPlotData(&xData, &yData);
- if (xData != NULL)
- {
- std::string xName = (*it)->GetXName();
- std::string yName = (*it)->GetYName();
- _critSect->Leave();
-#ifdef MATLAB6
- mxSetName(xData, xName.c_str());
- mxSetName(yData, yName.c_str());
- engPutArray(ep, xData);
- engPutArray(ep, yData);
-#else
- int ret = engPutVariable(ep, xName.c_str(), xData);
- assert(ret == 0);
- ret = engPutVariable(ep, yName.c_str(), yData);
- assert(ret == 0);
-#endif
- _critSect->Enter();
- }
- }
-}
-
-bool MatlabPlot::GetPlotCmd(std::ostringstream & cmd, Engine* ep)
-{
- _critSect->Enter();
-
- if (!DataAvailable())
- {
- return false;
- }
-
- if (_firstPlot)
- {
- GetPlotCmd(cmd);
- _firstPlot = false;
- }
- else
- {
- GetRefreshCmd(cmd);
- }
-
- UpdateData(ep);
-
- _critSect->Leave();
-
- return true;
-}
-
-// Call inside critsect
-void MatlabPlot::GetPlotCmd(std::ostringstream & cmd)
-{
- // we have something to plot
- // empty the stream
- cmd.str(""); // (this seems to be the only way)
-
- cmd << "figure; h" << _figHandle << "= plot(";
-
- // first line
- std::vector<MatlabLine*>::iterator it = _line.begin();
- cmd << (*it)->GetPlotString();
-
- it++;
-
- // remaining lines
- for (; it != _line.end(); it++)
- {
- cmd << ", ";
- cmd << (*it)->GetPlotString();
- }
-
- cmd << "); ";
-
- if (_legendEnabled)
- {
- GetLegendCmd(cmd);
- }
-
- if (_smartAxis)
- {
- double xMin = _xlim[0];
- double xMax = _xlim[1];
- double yMax = _ylim[1];
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
- {
- xMax = std::max(xMax, (*it)->xMax());
- xMin = std::min(xMin, (*it)->xMin());
-
- yMax = std::max(yMax, (*it)->yMax());
- yMax = std::max(yMax, fabs((*it)->yMin()));
- }
- _xlim[0] = xMin;
- _xlim[1] = xMax;
- _ylim[0] = -yMax;
- _ylim[1] = yMax;
-
- cmd << "axis([" << _xlim[0] << ", " << _xlim[1] << ", " << _ylim[0] << ", " << _ylim[1] << "]);";
- }
-
- int i=1;
- for (it = _line.begin(); it != _line.end(); i++, it++)
- {
- cmd << "set(h" << _figHandle << "(" << i << "), 'Tag', " << (*it)->GetLegendString() << ");";
- }
-}
-
-// Call inside critsect
-void MatlabPlot::GetRefreshCmd(std::ostringstream & cmd)
-{
- cmd.str(""); // (this seems to be the only way)
- std::vector<MatlabLine*>::iterator it = _line.begin();
- for (it = _line.begin(); it != _line.end(); it++)
- {
- cmd << "h = findobj(0, 'Tag', " << (*it)->GetLegendString() << ");";
- cmd << (*it)->GetRefreshString();
- }
- //if (_legendEnabled)
- //{
- // GetLegendCmd(cmd);
- //}
-}
-
-void MatlabPlot::GetLegendCmd(std::ostringstream & cmd)
-{
- std::vector<MatlabLine*>::iterator it = _line.begin();
- bool anyLegend = false;
- for (; it != _line.end(); it++)
- {
- anyLegend = anyLegend || (*it)->hasLegend();
- }
- if (anyLegend)
- {
- // create the legend
-
- cmd << "legend(h" << _figHandle << ",{";
-
-
- // iterate lines
- int i = 0;
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
- {
- if (i > 0)
- {
- cmd << ", ";
- }
- cmd << (*it)->GetLegendString();
- i++;
- }
-
- cmd << "}, 2); "; // place legend in upper-left corner
- }
-}
-
-// Call inside critsect
-bool MatlabPlot::DataAvailable()
-{
- if (!_enabled)
- {
- return false;
- }
-
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
- {
- (*it)->PurgeOldData();
- }
-
- return true;
-}
-
-void MatlabPlot::Plot()
-{
- CriticalSectionScoped cs(_critSect);
-
- _timeToPlot = true;
-
-#ifdef PLOT_TESTING
- _plotStartTime = TickTime::MillisecondTimestamp();
-#endif
-}
-
-
-void MatlabPlot::Reset()
-{
- CriticalSectionScoped cs(_critSect);
-
- _enabled = true;
-
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
- {
- (*it)->Reset();
- }
-
-}
-
-void MatlabPlot::SetFigHandle(int handle)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (handle > 0)
- _figHandle = handle;
-}
-
-bool
-MatlabPlot::TimeToPlot()
-{
- CriticalSectionScoped cs(_critSect);
- return _enabled && _timeToPlot;
-}
-
-void
-MatlabPlot::Plotting()
-{
- CriticalSectionScoped cs(_critSect);
- _plotting = true;
-}
-
-void
-MatlabPlot::DonePlotting()
-{
- CriticalSectionScoped cs(_critSect);
- _timeToPlot = false;
- _plotting = false;
- _donePlottingEvent->Set();
-}
-
-void
-MatlabPlot::DisablePlot()
-{
- _critSect->Enter();
- while (_plotting)
- {
- _critSect->Leave();
- _donePlottingEvent->Wait(WEBRTC_EVENT_INFINITE);
- _critSect->Enter();
- }
- _enabled = false;
-}
-
-int MatlabPlot::MakeTrend(const char *sourceName, const char *trendName, double slope, double offset, const char *plotAttrib)
-{
- CriticalSectionScoped cs(_critSect);
-
- int sourceIx;
- int trendIx;
-
- sourceIx = GetLineIx(sourceName);
- if (sourceIx < 0)
- {
- // could not find source
- return (-1);
- }
-
- trendIx = GetLineIx(trendName);
- if (trendIx < 0)
- {
- // no trend found; add new line
- trendIx = AddLine(2 /*maxLen*/, plotAttrib, trendName);
- }
-
- _line[trendIx]->UpdateTrendLine(_line[sourceIx], slope, offset);
-
- return (trendIx);
-
-}
-
-
-MatlabEngine::MatlabEngine()
-:
-_critSect(CriticalSectionWrapper::CreateCriticalSection()),
-_eventPtr(NULL),
-_running(false),
-_numPlots(0)
-{
- _eventPtr = EventWrapper::Create();
-
- _plotThread = ThreadWrapper::CreateThread(MatlabEngine::PlotThread, this,
- kLowPriority, "MatlabPlot");
- _running = true;
- _plotThread->Start();
-}
-
-MatlabEngine::~MatlabEngine()
-{
- _critSect->Enter();
-
- if (_plotThread)
- {
- _running = false;
- _eventPtr->Set();
-
- _plotThread->Stop();
- }
-
- _plots.clear();
-
- delete _eventPtr;
- _eventPtr = NULL;
-
- _critSect->Leave();
- delete _critSect;
-
-}
-
-MatlabPlot * MatlabEngine::NewPlot(MatlabPlot *newPlot)
-{
- CriticalSectionScoped cs(_critSect);
-
- //MatlabPlot *newPlot = new MatlabPlot();
-
- if (newPlot)
- {
- newPlot->SetFigHandle(++_numPlots); // first plot is number 1
- _plots.push_back(newPlot);
- }
-
- return (newPlot);
-
-}
-
-
-void MatlabEngine::DeletePlot(MatlabPlot *plot)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (plot == NULL)
- {
- return;
- }
-
- std::vector<MatlabPlot *>::iterator it;
- for (it = _plots.begin(); it < _plots.end(); it++)
- {
- if (plot == *it)
- {
- break;
- }
- }
-
- assert (plot == *it);
-
- (*it)->DisablePlot();
-
- _plots.erase(it);
- --_numPlots;
-
- delete plot;
-}
-
-
-bool MatlabEngine::PlotThread(void *obj)
-{
- if (!obj)
- {
- return (false);
- }
-
- MatlabEngine *eng = (MatlabEngine *) obj;
-
- Engine *ep = engOpen(NULL);
- if (!ep)
- {
- throw "Cannot open Matlab engine";
- return (false);
- }
-
- engSetVisible(ep, true);
- engEvalString(ep, "close all;");
-
- while (eng->_running)
- {
- eng->_critSect->Enter();
-
- // iterate through all plots
- for (unsigned int ix = 0; ix < eng->_plots.size(); ix++)
- {
- MatlabPlot *plot = eng->_plots[ix];
- if (plot->TimeToPlot())
- {
- plot->Plotting();
- eng->_critSect->Leave();
- std::ostringstream cmd;
-
- if (engEvalString(ep, cmd.str().c_str()))
- {
- // engine dead
- return (false);
- }
-
- // empty the stream
- cmd.str(""); // (this seems to be the only way)
- if (plot->GetPlotCmd(cmd, ep))
- {
- // things to plot, we have already accessed what we need in the plot
- plot->DonePlotting();
-
- int64_t start = TickTime::MillisecondTimestamp();
- // plot it
- int ret = engEvalString(ep, cmd.str().c_str());
- printf("time=%I64i\n", TickTime::MillisecondTimestamp() - start);
- if (ret)
- {
- // engine dead
- return (false);
- }
-
-#ifdef PLOT_TESTING
- if(plot->_plotStartTime >= 0)
- {
- plot->_plotDelay = TickTime::MillisecondTimestamp() - plot->_plotStartTime;
- plot->_plotStartTime = -1;
- }
-#endif
- }
- eng->_critSect->Enter();
- }
- }
-
- eng->_critSect->Leave();
- // wait a while
- eng->_eventPtr->Wait(66); // 33 ms
- }
-
- if (ep)
- {
- engClose(ep);
- ep = NULL;
- }
-
- return (true);
-
-}
-
-#endif // MATLAB
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h
deleted file mode 100644
index 3ed89f8f91..0000000000
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h
+++ /dev/null
@@ -1,170 +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.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_MATLABPLOT_H_
-#define WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_MATLABPLOT_H_
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "webrtc/typedefs.h"
-#include "webrtc/system_wrappers/include/thread_wrapper.h"
-
-namespace webrtc {
-class CriticalSectionWrapper;
-class EventWrapper;
-}
-
-//#define PLOT_TESTING
-
-#ifdef MATLAB
-
-typedef struct engine Engine;
-typedef struct mxArray_tag mxArray;
-
-class MatlabLine
-{
- friend class MatlabPlot;
-
-public:
- MatlabLine(int maxLen = -1, const char *plotAttrib = NULL, const char *name = NULL);
- ~MatlabLine();
- virtual void Append(double x, double y);
- virtual void Append(double y);
- void SetMaxLen(int maxLen);
- void SetAttribute(char *plotAttrib);
- void SetName(char *name);
- void Reset();
- virtual void PurgeOldData() {};
-
- void UpdateTrendLine(MatlabLine * sourceData, double slope, double offset);
-
- double xMin();
- double xMax();
- double yMin();
- double yMax();
-
-protected:
- void GetPlotData(mxArray** xData, mxArray** yData);
- std::string GetXName();
- std::string GetYName();
- std::string GetPlotString();
- std::string GetRefreshString();
- std::string GetLegendString();
- bool hasLegend();
- std::list<double> _xData;
- std::list<double> _yData;
- mxArray* _xArray;
- mxArray* _yArray;
- int _maxLen;
- std::string _plotAttribute;
- std::string _name;
-};
-
-
-class MatlabTimeLine : public MatlabLine
-{
-public:
- MatlabTimeLine(int horizonSeconds = -1, const char *plotAttrib = NULL, const char *name = NULL,
- int64_t refTimeMs = -1);
- ~MatlabTimeLine() {};
- void Append(double y);
- void PurgeOldData();
- int64_t GetRefTime();
-
-private:
- int64_t _refTimeMs;
- int _timeHorizon;
-};
-
-
-class MatlabPlot
-{
- friend class MatlabEngine;
-
-public:
- MatlabPlot();
- ~MatlabPlot();
-
- int AddLine(int maxLen = -1, const char *plotAttrib = NULL, const char *name = NULL);
- int AddTimeLine(int maxLen = -1, const char *plotAttrib = NULL, const char *name = NULL,
- int64_t refTimeMs = -1);
- int GetLineIx(const char *name);
- void Append(int lineIndex, double x, double y);
- void Append(int lineIndex, double y);
- int Append(const char *name, double x, double y);
- int Append(const char *name, double y);
- int Length(char *name);
- void SetPlotAttribute(char *name, char *plotAttrib);
- void Plot();
- void Reset();
- void SmartAxis(bool status = true) { _smartAxis = status; };
- void SetFigHandle(int handle);
- void EnableLegend(bool enable) { _legendEnabled = enable; };
-
- bool TimeToPlot();
- void Plotting();
- void DonePlotting();
- void DisablePlot();
-
- int MakeTrend(const char *sourceName, const char *trendName, double slope, double offset, const char *plotAttrib = NULL);
-
-#ifdef PLOT_TESTING
- int64_t _plotStartTime;
- int64_t _plotDelay;
-#endif
-
-private:
- void UpdateData(Engine* ep);
- bool GetPlotCmd(std::ostringstream & cmd, Engine* ep);
- void GetPlotCmd(std::ostringstream & cmd); // call inside crit sect
- void GetRefreshCmd(std::ostringstream & cmd); // call inside crit sect
- void GetLegendCmd(std::ostringstream & cmd);
- bool DataAvailable();
-
- std::vector<MatlabLine *> _line;
- int _figHandle;
- bool _smartAxis;
- double _xlim[2];
- double _ylim[2];
- webrtc::CriticalSectionWrapper *_critSect;
- bool _timeToPlot;
- bool _plotting;
- bool _enabled;
- bool _firstPlot;
- bool _legendEnabled;
- webrtc::EventWrapper* _donePlottingEvent;
-};
-
-
-class MatlabEngine
-{
-public:
- MatlabEngine();
- ~MatlabEngine();
-
- MatlabPlot * NewPlot(MatlabPlot *newPlot);
- void DeletePlot(MatlabPlot *plot);
-
-private:
- static bool PlotThread(void *obj);
-
- std::vector<MatlabPlot *> _plots;
- webrtc::CriticalSectionWrapper *_critSect;
- webrtc::EventWrapper *_eventPtr;
- rtc::scoped_ptr<webrtc::ThreadWrapper> _plotThread;
- bool _running;
- int _numPlots;
-};
-
-#endif //MATLAB
-
-#endif // WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_MATLABPLOT_H_
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.cc b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.cc
deleted file mode 100644
index 0e3e87976c..0000000000
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.cc
+++ /dev/null
@@ -1,432 +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.
- */
-
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h"
-
-#include <stdio.h>
-
-#include <algorithm>
-
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/event_wrapper.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-
-
-bool SenderThreadFunction(void *obj)
-{
- if (obj == NULL)
- {
- return false;
- }
- TestLoadGenerator *_genObj = static_cast<TestLoadGenerator *>(obj);
-
- return _genObj->GeneratorLoop();
-}
-
-
-TestLoadGenerator::TestLoadGenerator(TestSenderReceiver *sender, int32_t rtpSampleRate)
-:
-_critSect(CriticalSectionWrapper::CreateCriticalSection()),
-_eventPtr(NULL),
-_bitrateKbps(0),
-_sender(sender),
-_running(false),
-_rtpSampleRate(rtpSampleRate)
-{
-}
-
-TestLoadGenerator::~TestLoadGenerator ()
-{
- if (_running)
- {
- Stop();
- }
-
- delete _critSect;
-}
-
-int32_t TestLoadGenerator::SetBitrate (int32_t newBitrateKbps)
-{
- CriticalSectionScoped cs(_critSect);
-
- if (newBitrateKbps < 0)
- {
- return -1;
- }
-
- _bitrateKbps = newBitrateKbps;
-
- printf("New bitrate = %i kbps\n", _bitrateKbps);
-
- return _bitrateKbps;
-}
-
-
-int32_t TestLoadGenerator::Start (const char *threadName)
-{
- CriticalSectionScoped cs(_critSect);
-
- _eventPtr = EventWrapper::Create();
-
- _genThread = ThreadWrapper::CreateThread(SenderThreadFunction, this,
- threadName);
- _running = true;
-
- _genThread->Start();
- _genThread->SetPriority(kRealtimePriority);
-
- return 0;
-}
-
-
-int32_t TestLoadGenerator::Stop ()
-{
- _critSect.Enter();
-
- if (_genThread)
- {
- _running = false;
- _eventPtr->Set();
-
- _genThread->Stop();
- _genThread.reset();
-
- delete _eventPtr;
- _eventPtr = NULL;
- }
-
- _critSect.Leave();
- return (0);
-}
-
-
-int TestLoadGenerator::generatePayload ()
-{
- return(generatePayload( static_cast<uint32_t>( TickTime::MillisecondTimestamp() * _rtpSampleRate / 1000 )));
-}
-
-
-int TestLoadGenerator::sendPayload (const uint32_t timeStamp,
- const uint8_t* payloadData,
- const size_t payloadSize,
- const webrtc::FrameType frameType /*= webrtc::kVideoFrameDelta*/)
-{
-
- return (_sender->SendOutgoingData(timeStamp, payloadData, payloadSize, frameType));
-}
-
-
-CBRGenerator::CBRGenerator (TestSenderReceiver *sender,
- size_t payloadSizeBytes,
- int32_t bitrateKbps,
- int32_t rtpSampleRate)
-:
-//_eventPtr(NULL),
-_payloadSizeBytes(payloadSizeBytes),
-_payload(new uint8_t[payloadSizeBytes]),
-TestLoadGenerator(sender, rtpSampleRate)
-{
- SetBitrate (bitrateKbps);
-}
-
-CBRGenerator::~CBRGenerator ()
-{
- if (_running)
- {
- Stop();
- }
-
- if (_payload)
- {
- delete [] _payload;
- }
-
-}
-
-bool CBRGenerator::GeneratorLoop ()
-{
- double periodMs;
- int64_t nextSendTime = TickTime::MillisecondTimestamp();
-
-
- // no critSect
- while (_running)
- {
- // send data (critSect inside)
- generatePayload( static_cast<uint32_t>(nextSendTime * _rtpSampleRate / 1000) );
-
- // calculate wait time
- periodMs = 8.0 * _payloadSizeBytes / ( _bitrateKbps );
-
- nextSendTime = static_cast<int64_t>(nextSendTime + periodMs);
-
- int32_t waitTime = static_cast<int32_t>(nextSendTime - TickTime::MillisecondTimestamp());
- if (waitTime < 0)
- {
- waitTime = 0;
- }
- // wait
- _eventPtr->Wait(static_cast<int32_t>(waitTime));
- }
-
- return true;
-}
-
-int CBRGenerator::generatePayload ( uint32_t timestamp )
-{
- CriticalSectionScoped cs(_critSect);
-
- //uint8_t *payload = new uint8_t[_payloadSizeBytes];
-
- int ret = sendPayload(timestamp, _payload, _payloadSizeBytes);
-
- //delete [] payload;
- return ret;
-}
-
-
-
-
-/////////////////////
-
-CBRFixFRGenerator::CBRFixFRGenerator (TestSenderReceiver *sender, int32_t bitrateKbps,
- int32_t rtpSampleRate, int32_t frameRateFps /*= 30*/,
- double spread /*= 0.0*/)
-:
-//_eventPtr(NULL),
-_payloadSizeBytes(0),
-_payload(NULL),
-_payloadAllocLen(0),
-_frameRateFps(frameRateFps),
-_spreadFactor(spread),
-TestLoadGenerator(sender, rtpSampleRate)
-{
- SetBitrate (bitrateKbps);
-}
-
-CBRFixFRGenerator::~CBRFixFRGenerator ()
-{
- if (_running)
- {
- Stop();
- }
-
- if (_payload)
- {
- delete [] _payload;
- _payloadAllocLen = 0;
- }
-
-}
-
-bool CBRFixFRGenerator::GeneratorLoop ()
-{
- double periodMs;
- int64_t nextSendTime = TickTime::MillisecondTimestamp();
-
- _critSect.Enter();
-
- if (_frameRateFps <= 0)
- {
- return false;
- }
-
- _critSect.Leave();
-
- // no critSect
- while (_running)
- {
- _critSect.Enter();
-
- // calculate payload size
- _payloadSizeBytes = nextPayloadSize();
-
- if (_payloadSizeBytes > 0)
- {
-
- if (_payloadAllocLen < _payloadSizeBytes * (1 + _spreadFactor))
- {
- // re-allocate _payload
- if (_payload)
- {
- delete [] _payload;
- _payload = NULL;
- }
-
- _payloadAllocLen = static_cast<int32_t>((_payloadSizeBytes * (1 + _spreadFactor) * 3) / 2 + .5); // 50% extra to avoid frequent re-alloc
- _payload = new uint8_t[_payloadAllocLen];
- }
-
-
- // send data (critSect inside)
- generatePayload( static_cast<uint32_t>(nextSendTime * _rtpSampleRate / 1000) );
- }
-
- _critSect.Leave();
-
- // calculate wait time
- periodMs = 1000.0 / _frameRateFps;
- nextSendTime = static_cast<int64_t>(nextSendTime + periodMs + 0.5);
-
- int32_t waitTime = static_cast<int32_t>(nextSendTime - TickTime::MillisecondTimestamp());
- if (waitTime < 0)
- {
- waitTime = 0;
- }
- // wait
- _eventPtr->Wait(waitTime);
- }
-
- return true;
-}
-
-size_t CBRFixFRGenerator::nextPayloadSize()
-{
- const double periodMs = 1000.0 / _frameRateFps;
- return static_cast<size_t>(_bitrateKbps * periodMs / 8 + 0.5);
-}
-
-int CBRFixFRGenerator::generatePayload ( uint32_t timestamp )
-{
- CriticalSectionScoped cs(_critSect);
-
- double factor = ((double) rand() - RAND_MAX/2) / RAND_MAX; // [-0.5; 0.5]
- factor = 1 + 2 * _spreadFactor * factor; // [1 - _spreadFactor ; 1 + _spreadFactor]
-
- size_t thisPayloadBytes = static_cast<size_t>(_payloadSizeBytes * factor);
- // sanity
- if (thisPayloadBytes > _payloadAllocLen)
- {
- thisPayloadBytes = _payloadAllocLen;
- }
-
- int ret = sendPayload(timestamp, _payload, thisPayloadBytes);
- return ret;
-}
-
-
-/////////////////////
-
-PeriodicKeyFixFRGenerator::PeriodicKeyFixFRGenerator (TestSenderReceiver *sender, int32_t bitrateKbps,
- int32_t rtpSampleRate, int32_t frameRateFps /*= 30*/,
- double spread /*= 0.0*/, double keyFactor /*= 4.0*/, uint32_t keyPeriod /*= 300*/)
-:
-_keyFactor(keyFactor),
-_keyPeriod(keyPeriod),
-_frameCount(0),
-CBRFixFRGenerator(sender, bitrateKbps, rtpSampleRate, frameRateFps, spread)
-{
-}
-
-size_t PeriodicKeyFixFRGenerator::nextPayloadSize()
-{
- // calculate payload size for a delta frame
- size_t payloadSizeBytes = static_cast<size_t>(1000 * _bitrateKbps /
- (8.0 * _frameRateFps * (1.0 + (_keyFactor - 1.0) / _keyPeriod)) + 0.5);
-
- if (_frameCount % _keyPeriod == 0)
- {
- // this is a key frame, scale the payload size
- payloadSizeBytes =
- static_cast<size_t>(_keyFactor * _payloadSizeBytes + 0.5);
- }
- _frameCount++;
-
- return payloadSizeBytes;
-}
-
-////////////////////
-
-CBRVarFRGenerator::CBRVarFRGenerator(TestSenderReceiver *sender, int32_t bitrateKbps, const uint8_t* frameRates,
- uint16_t numFrameRates, int32_t rtpSampleRate, double avgFrPeriodMs,
- double frSpreadFactor, double spreadFactor)
-:
-_avgFrPeriodMs(avgFrPeriodMs),
-_frSpreadFactor(frSpreadFactor),
-_frameRates(NULL),
-_numFrameRates(numFrameRates),
-_frChangeTimeMs(TickTime::MillisecondTimestamp() + _avgFrPeriodMs),
-CBRFixFRGenerator(sender, bitrateKbps, rtpSampleRate, frameRates[0], spreadFactor)
-{
- _frameRates = new uint8_t[_numFrameRates];
- memcpy(_frameRates, frameRates, _numFrameRates);
-}
-
-CBRVarFRGenerator::~CBRVarFRGenerator()
-{
- delete [] _frameRates;
-}
-
-void CBRVarFRGenerator::ChangeFrameRate()
-{
- const int64_t nowMs = TickTime::MillisecondTimestamp();
- if (nowMs < _frChangeTimeMs)
- {
- return;
- }
- // Time to change frame rate
- uint16_t frIndex = static_cast<uint16_t>(static_cast<double>(rand()) / RAND_MAX
- * (_numFrameRates - 1) + 0.5) ;
- assert(frIndex < _numFrameRates);
- _frameRateFps = _frameRates[frIndex];
- // Update the next frame rate change time
- double factor = ((double) rand() - RAND_MAX/2) / RAND_MAX; // [-0.5; 0.5]
- factor = 1 + 2 * _frSpreadFactor * factor; // [1 - _frSpreadFactor ; 1 + _frSpreadFactor]
- _frChangeTimeMs = nowMs + static_cast<int64_t>(1000.0 * factor *
- _avgFrPeriodMs + 0.5);
-
- printf("New frame rate: %d\n", _frameRateFps);
-}
-
-size_t CBRVarFRGenerator::nextPayloadSize()
-{
- ChangeFrameRate();
- return CBRFixFRGenerator::nextPayloadSize();
-}
-
-////////////////////
-
-CBRFrameDropGenerator::CBRFrameDropGenerator(TestSenderReceiver *sender, int32_t bitrateKbps,
- int32_t rtpSampleRate, double spreadFactor)
-:
-_accBits(0),
-CBRFixFRGenerator(sender, bitrateKbps, rtpSampleRate, 30, spreadFactor)
-{
-}
-
-CBRFrameDropGenerator::~CBRFrameDropGenerator()
-{
-}
-
-size_t CBRFrameDropGenerator::nextPayloadSize()
-{
- _accBits -= 1000 * _bitrateKbps / _frameRateFps;
- if (_accBits < 0)
- {
- _accBits = 0;
- }
- if (_accBits > 0.3 * _bitrateKbps * 1000)
- {
- //printf("drop\n");
- return 0;
- }
- else
- {
- //printf("keep\n");
- const double periodMs = 1000.0 / _frameRateFps;
- size_t frameSize =
- static_cast<size_t>(_bitrateKbps * periodMs / 8 + 0.5);
- frameSize =
- std::max(frameSize, static_cast<size_t>(300 * periodMs / 8 + 0.5));
- _accBits += frameSize * 8;
- return frameSize;
- }
-}
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h
deleted file mode 100644
index bd83962fa3..0000000000
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h
+++ /dev/null
@@ -1,149 +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.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_TESTLOADGENERATOR_H_
-#define WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_TESTLOADGENERATOR_H_
-
-#include <stdlib.h>
-
-#include "webrtc/modules/interface/module_common_types.h"
-#include "webrtc/system_wrappers/include/thread_wrapper.h"
-#include "webrtc/typedefs.h"
-
-class TestSenderReceiver;
-namespace webrtc {
-class CriticalSectionWrapper;
-class EventWrapper;
-}
-
-class TestLoadGenerator
-{
-public:
- TestLoadGenerator (TestSenderReceiver *sender, int32_t rtpSampleRate = 90000);
- virtual ~TestLoadGenerator ();
-
- int32_t SetBitrate (int32_t newBitrateKbps);
- virtual int32_t Start (const char *threadName = NULL);
- virtual int32_t Stop ();
- virtual bool GeneratorLoop () = 0;
-
-protected:
- virtual int generatePayload ( uint32_t timestamp ) = 0;
- int generatePayload ();
- int sendPayload (const uint32_t timeStamp,
- const uint8_t* payloadData,
- const size_t payloadSize,
- const webrtc::FrameType frameType = webrtc::kVideoFrameDelta);
-
- webrtc::CriticalSectionWrapper* _critSect;
- webrtc::EventWrapper *_eventPtr;
- rtc::scoped_ptr<webrtc::ThreadWrapper> _genThread;
- int32_t _bitrateKbps;
- TestSenderReceiver *_sender;
- bool _running;
- int32_t _rtpSampleRate;
-};
-
-
-class CBRGenerator : public TestLoadGenerator
-{
-public:
- CBRGenerator (TestSenderReceiver *sender,
- size_t payloadSizeBytes,
- int32_t bitrateKbps,
- int32_t rtpSampleRate = 90000);
- virtual ~CBRGenerator ();
-
- virtual int32_t Start () {return (TestLoadGenerator::Start("CBRGenerator"));};
-
- virtual bool GeneratorLoop ();
-
-protected:
- virtual int generatePayload ( uint32_t timestamp );
-
- size_t _payloadSizeBytes;
- uint8_t *_payload;
-};
-
-
-class CBRFixFRGenerator : public TestLoadGenerator // constant bitrate and fixed frame rate
-{
-public:
- CBRFixFRGenerator (TestSenderReceiver *sender, int32_t bitrateKbps, int32_t rtpSampleRate = 90000,
- int32_t frameRateFps = 30, double spread = 0.0);
- virtual ~CBRFixFRGenerator ();
-
- virtual int32_t Start () {return (TestLoadGenerator::Start("CBRFixFRGenerator"));};
-
- virtual bool GeneratorLoop ();
-
-protected:
- virtual size_t nextPayloadSize ();
- virtual int generatePayload ( uint32_t timestamp );
-
- size_t _payloadSizeBytes;
- uint8_t *_payload;
- size_t _payloadAllocLen;
- int32_t _frameRateFps;
- double _spreadFactor;
-};
-
-class PeriodicKeyFixFRGenerator : public CBRFixFRGenerator // constant bitrate and fixed frame rate with periodically large frames
-{
-public:
- PeriodicKeyFixFRGenerator (TestSenderReceiver *sender, int32_t bitrateKbps, int32_t rtpSampleRate = 90000,
- int32_t frameRateFps = 30, double spread = 0.0, double keyFactor = 4.0, uint32_t keyPeriod = 300);
- virtual ~PeriodicKeyFixFRGenerator () {}
-
-protected:
- virtual size_t nextPayloadSize ();
-
- double _keyFactor;
- uint32_t _keyPeriod;
- uint32_t _frameCount;
-};
-
-// Probably better to inherit CBRFixFRGenerator from CBRVarFRGenerator, but since
-// the fix FR version already existed this was easier.
-class CBRVarFRGenerator : public CBRFixFRGenerator // constant bitrate and variable frame rate
-{
-public:
- CBRVarFRGenerator(TestSenderReceiver *sender, int32_t bitrateKbps, const uint8_t* frameRates,
- uint16_t numFrameRates, int32_t rtpSampleRate = 90000, double avgFrPeriodMs = 5.0,
- double frSpreadFactor = 0.05, double spreadFactor = 0.0);
-
- ~CBRVarFRGenerator();
-
-protected:
- virtual void ChangeFrameRate();
- virtual size_t nextPayloadSize ();
-
- double _avgFrPeriodMs;
- double _frSpreadFactor;
- uint8_t* _frameRates;
- uint16_t _numFrameRates;
- int64_t _frChangeTimeMs;
-};
-
-class CBRFrameDropGenerator : public CBRFixFRGenerator // constant bitrate and variable frame rate
-{
-public:
- CBRFrameDropGenerator(TestSenderReceiver *sender, int32_t bitrateKbps,
- int32_t rtpSampleRate = 90000, double spreadFactor = 0.0);
-
- ~CBRFrameDropGenerator();
-
-protected:
- virtual size_t nextPayloadSize();
-
- double _accBits;
-};
-
-#endif // WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_TESTLOADGENERATOR_H_
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.cc b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.cc
deleted file mode 100644
index 47f2880638..0000000000
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.cc
+++ /dev/null
@@ -1,411 +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.
- */
-
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/event_wrapper.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/test/channel_transport/udp_transport.h"
-
-#define NR_OF_SOCKET_BUFFERS 500
-
-
-bool ProcThreadFunction(void *obj)
-{
- if (obj == NULL)
- {
- return false;
- }
- TestSenderReceiver *theObj = static_cast<TestSenderReceiver *>(obj);
-
- return theObj->ProcLoop();
-}
-
-
-TestSenderReceiver::TestSenderReceiver (void)
-:
-_critSect(CriticalSectionWrapper::CreateCriticalSection()),
-_eventPtr(NULL),
-_running(false),
-_payloadType(0),
-_loadGenerator(NULL),
-_isSender(false),
-_isReceiver(false),
-_sendRecCB(NULL),
-_lastBytesReceived(0),
-_lastTime(-1)
-{
- // RTP/RTCP module
- _rtp = RtpRtcp::CreateRtpRtcp(0, false);
- if (!_rtp)
- {
- throw "Could not create RTP/RTCP module";
- exit(1);
- }
-
- if (_rtp->InitReceiver() != 0)
- {
- throw "_rtp->InitReceiver()";
- exit(1);
- }
-
- if (_rtp->InitSender() != 0)
- {
- throw "_rtp->InitSender()";
- exit(1);
- }
-
- // SocketTransport module
- uint8_t numberOfThreads = 1;
- _transport = UdpTransport::Create(0, numberOfThreads);
- if (!_transport)
- {
- throw "Could not create transport module";
- exit(1);
- }
-}
-
-TestSenderReceiver::~TestSenderReceiver (void)
-{
-
- Stop(); // N.B. without critSect
-
- _critSect->Enter();
-
- if (_rtp)
- {
- RtpRtcp::DestroyRtpRtcp(_rtp);
- _rtp = NULL;
- }
-
- if (_transport)
- {
- UdpTransport::Destroy(_transport);
- _transport = NULL;
- }
-
- delete _critSect;
-
-}
-
-
-int32_t TestSenderReceiver::InitReceiver (const uint16_t rtpPort,
- const uint16_t rtcpPort,
- const int8_t payloadType /*= 127*/)
-{
- CriticalSectionScoped cs(_critSect);
-
- // init transport
- if (_transport->InitializeReceiveSockets(this, rtpPort/*, 0, NULL, 0, true*/) != 0)
- {
- throw "_transport->InitializeReceiveSockets";
- exit(1);
- }
-
- if (_rtp->RegisterIncomingRTPCallback(this) != 0)
- {
- throw "_rtp->RegisterIncomingRTPCallback";
- exit(1);
- }
-
- if (_rtp->RegisterIncomingDataCallback(this) != 0)
- {
- throw "_rtp->RegisterIncomingRTPCallback";
- exit(1);
- }
-
- if (_rtp->SetRTCPStatus(RtcpMode::kReducedSize) != 0) {
- throw "_rtp->SetRTCPStatus";
- exit(1);
- }
-
- if (_rtp->SetTMMBRStatus(true) != 0)
- {
- throw "_rtp->SetTMMBRStatus";
- exit(1);
- }
-
- if (_rtp->RegisterReceivePayload("I420", payloadType, 90000) != 0)
- {
- throw "_rtp->RegisterReceivePayload";
- exit(1);
- }
-
- _isReceiver = true;
-
- return (0);
-}
-
-
-int32_t TestSenderReceiver::Start()
-{
- CriticalSectionScoped cs(_critSect);
-
- _eventPtr = EventWrapper::Create();
-
- if (_rtp->SetSendingStatus(true) != 0)
- {
- throw "_rtp->SetSendingStatus";
- exit(1);
- }
-
- _procThread = ThreadWrapper::CreateThread(ProcThreadFunction, this,
- "TestSenderReceiver");
-
- _running = true;
-
- if (_isReceiver)
- {
- if (_transport->StartReceiving(NR_OF_SOCKET_BUFFERS) != 0)
- {
- throw "_transport->StartReceiving";
- exit(1);
- }
- }
-
- _procThread->Start();
- _procThread->SetPriority(kRealtimePriority);
-
- return 0;
-
-}
-
-
-int32_t TestSenderReceiver::Stop ()
-{
- CriticalSectionScoped cs(_critSect);
-
- _transport->StopReceiving();
-
- if (_procThread)
- {
- _running = false;
- _eventPtr->Set();
-
- _procThread->Stop();
- _procThread.reset();
-
- delete _eventPtr;
- }
-
- return (0);
-}
-
-
-bool TestSenderReceiver::ProcLoop(void)
-{
-
- // process RTP/RTCP module
- _rtp->Process();
-
- // process SocketTransport module
- _transport->Process();
-
- // no critSect
- while (_running)
- {
- // ask RTP/RTCP module for wait time
- int32_t rtpWait = _rtp->TimeUntilNextProcess();
-
- // ask SocketTransport module for wait time
- int32_t tpWait = _transport->TimeUntilNextProcess();
-
- int32_t minWait = (rtpWait < tpWait) ? rtpWait: tpWait;
- minWait = (minWait > 0) ? minWait : 0;
- // wait
- _eventPtr->Wait(minWait);
-
- // process RTP/RTCP module
- _rtp->Process();
-
- // process SocketTransport module
- _transport->Process();
-
- }
-
- return true;
-}
-
-
-int32_t TestSenderReceiver::ReceiveBitrateKbps ()
-{
- size_t bytesSent;
- uint32_t packetsSent;
- size_t bytesReceived;
- uint32_t packetsReceived;
-
- if (_rtp->DataCountersRTP(&bytesSent, &packetsSent, &bytesReceived, &packetsReceived) == 0)
- {
- int64_t now = TickTime::MillisecondTimestamp();
- int32_t kbps = 0;
- if (now > _lastTime)
- {
- if (_lastTime > 0)
- {
- // 8 * bytes / ms = kbps
- kbps = static_cast<int32_t>(
- (8 * (bytesReceived - _lastBytesReceived)) / (now - _lastTime));
- }
- _lastTime = now;
- _lastBytesReceived = bytesReceived;
- }
- return (kbps);
- }
-
- return (-1);
-}
-
-
-int32_t TestSenderReceiver::SetPacketTimeout(const uint32_t timeoutMS)
-{
- return (_rtp->SetPacketTimeout(timeoutMS, 0 /* RTCP timeout */));
-}
-
-
-int32_t TestSenderReceiver::OnReceivedPayloadData(const uint8_t* payloadData,
- const size_t payloadSize,
- const webrtc::WebRtcRTPHeader* rtpHeader)
-{
- //printf("OnReceivedPayloadData\n");
- return (0);
-}
-
-
-void TestSenderReceiver::IncomingRTPPacket(const int8_t* incomingRtpPacket,
- const size_t rtpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort)
-{
- _rtp->IncomingPacket((uint8_t *) incomingRtpPacket, rtpPacketLength);
-}
-
-
-
-void TestSenderReceiver::IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
- const size_t rtcpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort)
-{
- _rtp->IncomingPacket((uint8_t *) incomingRtcpPacket, rtcpPacketLength);
-}
-
-
-
-
-
-///////////////////
-
-
-int32_t TestSenderReceiver::InitSender (const uint32_t startBitrateKbps,
- const int8_t* ipAddr,
- const uint16_t rtpPort,
- const uint16_t rtcpPort /*= 0*/,
- const int8_t payloadType /*= 127*/)
-{
- CriticalSectionScoped cs(_critSect);
-
- _payloadType = payloadType;
-
- // check load generator valid
- if (_loadGenerator)
- {
- _loadGenerator->SetBitrate(startBitrateKbps);
- }
-
- if (_rtp->RegisterSendTransport(_transport) != 0)
- {
- throw "_rtp->RegisterSendTransport";
- exit(1);
- }
- if (_rtp->RegisterSendPayload("I420", _payloadType, 90000) != 0)
- {
- throw "_rtp->RegisterSendPayload";
- exit(1);
- }
-
- if (_rtp->RegisterIncomingVideoCallback(this) != 0)
- {
- throw "_rtp->RegisterIncomingVideoCallback";
- exit(1);
- }
-
- if (_rtp->SetRTCPStatus(RtcpMode::kReducedSize) != 0) {
- throw "_rtp->SetRTCPStatus";
- exit(1);
- }
-
- if (_rtp->SetSendBitrate(startBitrateKbps*1000, 0, MAX_BITRATE_KBPS) != 0)
- {
- throw "_rtp->SetSendBitrate";
- exit(1);
- }
-
-
- // SocketTransport
- if (_transport->InitializeSendSockets(ipAddr, rtpPort, rtcpPort))
- {
- throw "_transport->InitializeSendSockets";
- exit(1);
- }
-
- _isSender = true;
-
- return (0);
-}
-
-
-
-int32_t
-TestSenderReceiver::SendOutgoingData(const uint32_t timeStamp,
- const uint8_t* payloadData,
- const size_t payloadSize,
- const webrtc::FrameType frameType /*= webrtc::kVideoFrameDelta*/)
-{
- return (_rtp->SendOutgoingData(frameType, _payloadType, timeStamp, payloadData, payloadSize));
-}
-
-
-int32_t TestSenderReceiver::SetLoadGenerator(TestLoadGenerator *generator)
-{
- CriticalSectionScoped cs(_critSect);
-
- _loadGenerator = generator;
- return(0);
-
-}
-
-void TestSenderReceiver::OnNetworkChanged(const int32_t id,
- const uint32_t minBitrateBps,
- const uint32_t maxBitrateBps,
- const uint8_t fractionLost,
- const uint16_t roundTripTimeMs,
- const uint16_t bwEstimateKbitMin,
- const uint16_t bwEstimateKbitMax)
-{
- if (_loadGenerator)
- {
- _loadGenerator->SetBitrate(maxBitrateBps/1000);
- }
-
- if (_sendRecCB)
- {
- _sendRecCB->OnOnNetworkChanged(maxBitrateBps,
- fractionLost,
- roundTripTimeMs,
- bwEstimateKbitMin,
- bwEstimateKbitMax);
- }
-}
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h
deleted file mode 100644
index f394412a73..0000000000
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h
+++ /dev/null
@@ -1,153 +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.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_TESTSENDERRECEIVER_H_
-#define WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_TESTSENDERRECEIVER_H_
-
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/system_wrappers/include/thread_wrapper.h"
-#include "webrtc/test/channel_transport/udp_transport.h"
-#include "webrtc/typedefs.h"
-
-class TestLoadGenerator;
-namespace webrtc {
-class CriticalSectionWrapper;
-class EventWrapper;
-}
-
-using namespace webrtc;
-
-#define MAX_BITRATE_KBPS 50000
-
-
-class SendRecCB
-{
-public:
- virtual void OnOnNetworkChanged(const uint32_t bitrateTarget,
- const uint8_t fractionLost,
- const uint16_t roundTripTimeMs,
- const uint16_t bwEstimateKbitMin,
- const uint16_t bwEstimateKbitMax) = 0;
-
- virtual ~SendRecCB() {};
-};
-
-
-class TestSenderReceiver : public RtpFeedback, public RtpData, public UdpTransportData, public RtpVideoFeedback
-{
-
-public:
- TestSenderReceiver (void);
-
- ~TestSenderReceiver (void);
-
- void SetCallback (SendRecCB *cb) { _sendRecCB = cb; };
-
- int32_t Start();
-
- int32_t Stop();
-
- bool ProcLoop();
-
- /////////////////////////////////////////////
- // Receiver methods
-
- int32_t InitReceiver (const uint16_t rtpPort,
- const uint16_t rtcpPort = 0,
- const int8_t payloadType = 127);
-
- int32_t ReceiveBitrateKbps ();
-
- int32_t SetPacketTimeout(const uint32_t timeoutMS);
-
- // Inherited from RtpFeedback
- int32_t OnInitializeDecoder(const int32_t id,
- const int8_t payloadType,
- const int8_t payloadName[RTP_PAYLOAD_NAME_SIZE],
- const uint32_t frequency,
- const uint8_t channels,
- const uint32_t rate) override {
- return 0;
- }
-
- void OnIncomingSSRCChanged(const int32_t id, const uint32_t SSRC) override {
- }
-
- void OnIncomingCSRCChanged(const int32_t id,
- const uint32_t CSRC,
- const bool added) override {}
-
- // Inherited from RtpData
- int32_t OnReceivedPayloadData(
- const uint8_t* payloadData,
- const size_t payloadSize,
- const webrtc::WebRtcRTPHeader* rtpHeader) override;
-
- // Inherited from UdpTransportData
- void IncomingRTPPacket(const int8_t* incomingRtpPacket,
- const size_t rtpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort) override;
-
- void IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
- const size_t rtcpPacketLength,
- const int8_t* fromIP,
- const uint16_t fromPort) override;
-
- /////////////////////////////////
- // Sender methods
-
- int32_t InitSender (const uint32_t startBitrateKbps,
- const int8_t* ipAddr,
- const uint16_t rtpPort,
- const uint16_t rtcpPort = 0,
- const int8_t payloadType = 127);
-
- int32_t SendOutgoingData(const uint32_t timeStamp,
- const uint8_t* payloadData,
- const size_t payloadSize,
- const webrtc::FrameType frameType = webrtc::kVideoFrameDelta);
-
- int32_t SetLoadGenerator(TestLoadGenerator *generator);
-
- uint32_t BitrateSent() { return (_rtp->BitrateSent()); };
-
-
- // Inherited from RtpVideoFeedback
- virtual void OnReceivedIntraFrameRequest(const int32_t id,
- const uint8_t message = 0) {};
-
- virtual void OnNetworkChanged(const int32_t id,
- const uint32_t minBitrateBps,
- const uint32_t maxBitrateBps,
- const uint8_t fractionLost,
- const uint16_t roundTripTimeMs,
- const uint16_t bwEstimateKbitMin,
- const uint16_t bwEstimateKbitMax);
-
-private:
- RtpRtcp* _rtp;
- UdpTransport* _transport;
- webrtc::CriticalSectionWrapper* _critSect;
- webrtc::EventWrapper *_eventPtr;
- rtc::scoped_ptr<webrtc::ThreadWrapper> _procThread;
- bool _running;
- int8_t _payloadType;
- TestLoadGenerator* _loadGenerator;
- bool _isSender;
- bool _isReceiver;
- SendRecCB * _sendRecCB;
- size_t _lastBytesReceived;
- int64_t _lastTime;
-
-};
-
-#endif // WEBRTC_MODULES_RTP_RTCP_TEST_BWESTANDALONE_TESTSENDERRECEIVER_H_
diff --git a/webrtc/modules/rtp_rtcp/test/bwe_standalone.gypi b/webrtc/modules/rtp_rtcp/test/bwe_standalone.gypi
deleted file mode 100644
index e45daec77d..0000000000
--- a/webrtc/modules/rtp_rtcp/test/bwe_standalone.gypi
+++ /dev/null
@@ -1,85 +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': 'bwe_standalone',
- 'type': 'executable',
- 'dependencies': [
- 'matlab_plotting',
- 'rtp_rtcp',
- 'udp_transport',
- '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers',
- ],
- 'sources': [
- 'BWEStandAlone/BWEStandAlone.cc',
- 'BWEStandAlone/TestLoadGenerator.cc',
- 'BWEStandAlone/TestLoadGenerator.h',
- 'BWEStandAlone/TestSenderReceiver.cc',
- 'BWEStandAlone/TestSenderReceiver.h',
- ], # source
- 'conditions': [
- ['OS=="linux"', {
- 'cflags': [
- '-fexceptions', # enable exceptions
- ],
- },
- ],
- ],
- },
-
- {
- 'target_name': 'matlab_plotting',
- 'type': 'static_library',
- 'dependencies': [
- 'matlab_plotting_include',
- '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers',
- ],
- 'include_dirs': [
- '/opt/matlab2010a/extern/include',
- ],
- 'export_dependent_settings': [
- 'matlab_plotting_include',
- ],
- 'sources': [
- 'BWEStandAlone/MatlabPlot.cc',
- 'BWEStandAlone/MatlabPlot.h',
- ],
- 'link_settings': {
- 'ldflags' : [
- '-L/opt/matlab2010a/bin/glnxa64',
- '-leng',
- '-lmx',
- '-Wl,-rpath,/opt/matlab2010a/bin/glnxa64',
- ],
- },
- 'defines': [
- 'MATLAB',
- ],
- 'conditions': [
- ['OS=="linux"', {
- 'cflags': [
- '-fexceptions', # enable exceptions
- ],
- },
- ],
- ],
- },
-
- {
- 'target_name': 'matlab_plotting_include',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'include_dirs': [
- 'BWEStandAlone',
- ],
- },
- },
- ],
-}
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
index 0270e55802..1d4d6d04a5 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -9,14 +9,14 @@
*/
#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
-#include "webrtc/test/null_transport.h"
#include <algorithm>
#include <vector>
-using namespace webrtc;
+#include "webrtc/test/null_transport.h"
namespace webrtc {
+
void LoopBackTransport::SetSendModule(RtpRtcp* rtp_rtcp_module,
RTPPayloadRegistry* payload_registry,
RtpReceiver* receiver,
@@ -76,7 +76,6 @@ int32_t TestRtpReceiver::OnReceivedPayloadData(
payload_size_ = payload_size;
return 0;
}
-} // namespace webrtc
class RtpRtcpAPITest : public ::testing::Test {
protected:
@@ -187,3 +186,5 @@ TEST_F(RtpRtcpAPITest, RtxReceiver) {
rtx_header.payloadType = 0;
EXPECT_TRUE(rtp_payload_registry_->IsRtx(rtx_header));
}
+
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h
index 73334a8b26..d8040f7902 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api.h
@@ -7,16 +7,18 @@
* 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_TEST_TESTAPI_TEST_API_H_
+#define WEBRTC_MODULES_RTP_RTCP_TEST_TESTAPI_TEST_API_H_
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.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/include/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/transport.h"
namespace webrtc {
@@ -68,3 +70,4 @@ class TestRtpReceiver : public NullRtpData {
};
} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_TEST_TESTAPI_TEST_API_H_
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
index 745386d485..634969b311 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
@@ -15,12 +15,12 @@
#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.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/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
-using namespace webrtc;
-
+namespace webrtc {
+namespace {
#define test_rate 64000u
class VerifyingAudioReceiver : public NullRtpData {
@@ -64,7 +64,7 @@ class RTPCallback : public NullRtpFeedback {
int32_t OnInitializeDecoder(const int8_t payloadType,
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int frequency,
- const uint8_t channels,
+ const size_t channels,
const uint32_t rate) override {
if (payloadType == 96) {
EXPECT_EQ(test_rate, rate) <<
@@ -165,7 +165,7 @@ TEST_F(RtpRtcpAudioTest, Basic) {
module1->SetStartTimestamp(test_timestamp);
// Test detection at the end of a DTMF tone.
- //EXPECT_EQ(0, module2->SetTelephoneEventForwardToDecoder(true));
+ // EXPECT_EQ(0, module2->SetTelephoneEventForwardToDecoder(true));
EXPECT_EQ(0, module1->SetSendingStatus(true));
@@ -241,7 +241,7 @@ TEST_F(RtpRtcpAudioTest, RED) {
EXPECT_EQ(0, module1->SetSendREDPayloadType(voice_codec.pltype));
int8_t red = 0;
- EXPECT_EQ(0, module1->SendREDPayloadType(red));
+ EXPECT_EQ(0, module1->SendREDPayloadType(&red));
EXPECT_EQ(voice_codec.pltype, red);
EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
voice_codec.plname,
@@ -278,7 +278,7 @@ TEST_F(RtpRtcpAudioTest, RED) {
&fragmentation));
EXPECT_EQ(0, module1->SetSendREDPayloadType(-1));
- EXPECT_EQ(-1, module1->SendREDPayloadType(red));
+ EXPECT_EQ(-1, module1->SendREDPayloadType(&red));
}
TEST_F(RtpRtcpAudioTest, DTMF) {
@@ -334,7 +334,7 @@ TEST_F(RtpRtcpAudioTest, DTMF) {
// Send RTP packets for 16 tones a 160 ms 100ms
// pause between = 2560ms + 1600ms = 4160ms
- for (;timeStamp <= 250 * 160; timeStamp += 160) {
+ for (; timeStamp <= 250 * 160; timeStamp += 160) {
EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96,
timeStamp, -1, test, 4));
fake_clock.AdvanceTimeMilliseconds(20);
@@ -342,10 +342,13 @@ TEST_F(RtpRtcpAudioTest, DTMF) {
}
EXPECT_EQ(0, module1->SendTelephoneEventOutband(32, 9000, 10));
- for (;timeStamp <= 740 * 160; timeStamp += 160) {
+ for (; timeStamp <= 740 * 160; timeStamp += 160) {
EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96,
timeStamp, -1, test, 4));
fake_clock.AdvanceTimeMilliseconds(20);
module1->Process();
}
}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
index e9d81122b1..6c60bf1f6d 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
@@ -14,13 +14,14 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.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/include/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
-using namespace webrtc;
+namespace webrtc {
+namespace {
const uint64_t kTestPictureId = 12345678;
const uint8_t kSliPictureId = 156;
@@ -29,30 +30,29 @@ class RtcpCallback : public RtcpIntraFrameObserver {
public:
void SetModule(RtpRtcp* module) {
_rtpRtcpModule = module;
- };
+ }
virtual void OnRTCPPacketTimeout(const int32_t id) {
}
virtual void OnLipSyncUpdate(const int32_t id,
- const int32_t audioVideoOffset) {
- };
- virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {
- };
+ const int32_t audioVideoOffset) {}
+ virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {}
virtual void OnReceivedSLI(uint32_t ssrc,
uint8_t pictureId) {
EXPECT_EQ(kSliPictureId & 0x3f, pictureId);
- };
+ }
virtual void OnReceivedRPSI(uint32_t ssrc,
uint64_t pictureId) {
EXPECT_EQ(kTestPictureId, pictureId);
- };
- virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {};
+ }
+ virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {}
+
private:
RtpRtcp* _rtpRtcpModule;
};
class TestRtpFeedback : public NullRtpFeedback {
public:
- TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
+ explicit TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
virtual ~TestRtpFeedback() {}
void OnIncomingSSRCChanged(const uint32_t ssrc) override {
@@ -266,3 +266,6 @@ TEST_F(RtpRtcpRtcpTest, RemoteRTCPStatRemote) {
EXPECT_EQ(test_sequence_number, report_blocks[0].extendedHighSeqNum);
EXPECT_EQ(0u, report_blocks[0].fractionLost);
}
+
+} // namespace
+} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc
index 30a6a1c303..16ea540bd5 100644
--- a/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc
+++ b/webrtc/modules/rtp_rtcp/test/testAPI/test_api_video.cc
@@ -15,9 +15,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.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/include/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
diff --git a/webrtc/modules/rtp_rtcp/test/testFec/average_residual_loss_xor_codes.h b/webrtc/modules/rtp_rtcp/test/testFec/average_residual_loss_xor_codes.h
index 2e8d676e47..6c233bba17 100644
--- a/webrtc/modules/rtp_rtcp/test/testFec/average_residual_loss_xor_codes.h
+++ b/webrtc/modules/rtp_rtcp/test/testFec/average_residual_loss_xor_codes.h
@@ -7,8 +7,10 @@
* 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_TEST_TESTFEC_AVERAGE_RESIDUAL_LOSS_XOR_CODES_H_
+#define WEBRTC_MODULES_RTP_RTCP_TEST_TESTFEC_AVERAGE_RESIDUAL_LOSS_XOR_CODES_H_
-namespace {
+namespace webrtc {
// Maximum number of media packets allowed in this test. The burst mask types
// are currently defined up to (kMaxMediaPacketsTest, kMaxMediaPacketsTest).
@@ -185,4 +187,5 @@ const float kMaxResidualLossBurstyMask[kNumberCodes] = {
0.009657f
};
-} // namespace
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_TEST_TESTFEC_AVERAGE_RESIDUAL_LOSS_XOR_CODES_H_
diff --git a/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc b/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc
index a8eafdd27e..b164b7e04c 100644
--- a/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc
+++ b/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc
@@ -22,43 +22,49 @@
#include <list>
#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h"
+#include "webrtc/base/random.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h"
-
-#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/test/testsupport/fileutils.h"
-//#define VERBOSE_OUTPUT
+// #define VERBOSE_OUTPUT
namespace webrtc {
+namespace fec_private_tables {
+extern const uint8_t** kPacketMaskBurstyTbl[12];
+}
namespace test {
+using fec_private_tables::kPacketMaskBurstyTbl;
void ReceivePackets(
ForwardErrorCorrection::ReceivedPacketList* toDecodeList,
ForwardErrorCorrection::ReceivedPacketList* receivedPacketList,
- uint32_t numPacketsToDecode, float reorderRate, float duplicateRate) {
+ size_t numPacketsToDecode,
+ float reorderRate,
+ float duplicateRate,
+ Random* random) {
assert(toDecodeList->empty());
assert(numPacketsToDecode <= receivedPacketList->size());
ForwardErrorCorrection::ReceivedPacketList::iterator it;
- for (uint32_t i = 0; i < numPacketsToDecode; i++) {
+ for (size_t i = 0; i < numPacketsToDecode; i++) {
it = receivedPacketList->begin();
// Reorder packets.
- float randomVariable = static_cast<float>(rand()) / RAND_MAX;
+ float randomVariable = random->Rand<float>();
while (randomVariable < reorderRate) {
++it;
if (it == receivedPacketList->end()) {
--it;
break;
}
- randomVariable = static_cast<float>(rand()) / RAND_MAX;
+ randomVariable = random->Rand<float>();
}
ForwardErrorCorrection::ReceivedPacket* receivedPacket = *it;
toDecodeList->push_back(receivedPacket);
// Duplicate packets.
- randomVariable = static_cast<float>(rand()) / RAND_MAX;
+ randomVariable = random->Rand<float>();
while (randomVariable < duplicateRate) {
ForwardErrorCorrection::ReceivedPacket* duplicatePacket =
new ForwardErrorCorrection::ReceivedPacket;
@@ -69,7 +75,7 @@ void ReceivePackets(
duplicatePacket->pkt->length = receivedPacket->pkt->length;
toDecodeList->push_back(duplicatePacket);
- randomVariable = static_cast<float>(rand()) / RAND_MAX;
+ randomVariable = random->Rand<float>();
}
receivedPacketList->erase(it);
}
@@ -77,12 +83,8 @@ void ReceivePackets(
TEST(FecTest, FecTest) {
// TODO(marpan): Split this function into subroutines/helper functions.
- enum {
- kMaxNumberMediaPackets = 48
- };
- enum {
- kMaxNumberFecPackets = 48
- };
+ enum { kMaxNumberMediaPackets = 48 };
+ enum { kMaxNumberFecPackets = 48 };
const uint32_t kNumMaskBytesL0 = 2;
const uint32_t kNumMaskBytesL1 = 6;
@@ -91,15 +93,12 @@ TEST(FecTest, FecTest) {
const bool kUseUnequalProtection = true;
// FEC mask types.
- const FecMaskType kMaskTypes[] = { kFecMaskRandom, kFecMaskBursty };
+ const FecMaskType kMaskTypes[] = {kFecMaskRandom, kFecMaskBursty};
const int kNumFecMaskTypes = sizeof(kMaskTypes) / sizeof(*kMaskTypes);
- // TODO(pbos): Fix this. Hack to prevent a warning
- // ('-Wunneeded-internal-declaration') from clang.
- (void) kPacketMaskBurstyTbl;
-
// Maximum number of media packets allowed for the mask type.
- const uint16_t kMaxMediaPackets[] = {kMaxNumberMediaPackets,
+ const uint16_t kMaxMediaPackets[] = {
+ kMaxNumberMediaPackets,
sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)};
ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not "
@@ -115,7 +114,7 @@ TEST(FecTest, FecTest) {
ForwardErrorCorrection::Packet* mediaPacket = NULL;
// Running over only one loss rate to limit execution time.
- const float lossRate[] = { 0.5f };
+ const float lossRate[] = {0.5f};
const uint32_t lossRateSize = sizeof(lossRate) / sizeof(*lossRate);
const float reorderRate = 0.1f;
const float duplicateRate = 0.1f;
@@ -127,7 +126,7 @@ TEST(FecTest, FecTest) {
// Seed the random number generator, storing the seed to file in order to
// reproduce past results.
const unsigned int randomSeed = static_cast<unsigned int>(time(NULL));
- srand(randomSeed);
+ Random random(randomSeed);
std::string filename = webrtc::test::OutputPath() + "randomSeedLog.txt";
FILE* randomSeedFile = fopen(filename.c_str(), "a");
fprintf(randomSeedFile, "%u\n", randomSeed);
@@ -135,15 +134,13 @@ TEST(FecTest, FecTest) {
randomSeedFile = NULL;
uint16_t seqNum = 0;
- uint32_t timeStamp = static_cast<uint32_t>(rand());
- const uint32_t ssrc = static_cast<uint32_t>(rand());
+ uint32_t timeStamp = random.Rand<uint32_t>();
+ const uint32_t ssrc = random.Rand(1u, 0xfffffffe);
// Loop over the mask types: random and bursty.
for (int mask_type_idx = 0; mask_type_idx < kNumFecMaskTypes;
++mask_type_idx) {
-
for (uint32_t lossRateIdx = 0; lossRateIdx < lossRateSize; ++lossRateIdx) {
-
printf("Loss rate: %.2f, Mask type %d \n", lossRate[lossRateIdx],
mask_type_idx);
@@ -159,14 +156,12 @@ TEST(FecTest, FecTest) {
for (uint32_t numFecPackets = 1;
numFecPackets <= numMediaPackets && numFecPackets <= packetMaskMax;
numFecPackets++) {
-
// Loop over numImpPackets: usually <= (0.3*numMediaPackets).
// For this test we check up to ~ (numMediaPackets / 4).
uint32_t maxNumImpPackets = numMediaPackets / 4 + 1;
for (uint32_t numImpPackets = 0; numImpPackets <= maxNumImpPackets &&
- numImpPackets <= packetMaskMax;
+ numImpPackets <= packetMaskMax;
numImpPackets++) {
-
uint8_t protectionFactor =
static_cast<uint8_t>(numFecPackets * 255 / numMediaPackets);
@@ -181,10 +176,11 @@ TEST(FecTest, FecTest) {
mask_table, packetMask);
#ifdef VERBOSE_OUTPUT
- printf("%u media packets, %u FEC packets, %u numImpPackets, "
- "loss rate = %.2f \n",
- numMediaPackets, numFecPackets, numImpPackets,
- lossRate[lossRateIdx]);
+ printf(
+ "%u media packets, %u FEC packets, %u numImpPackets, "
+ "loss rate = %.2f \n",
+ numMediaPackets, numFecPackets, numImpPackets,
+ lossRate[lossRateIdx]);
printf("Packet mask matrix \n");
#endif
@@ -232,16 +228,15 @@ TEST(FecTest, FecTest) {
for (uint32_t i = 0; i < numMediaPackets; ++i) {
mediaPacket = new ForwardErrorCorrection::Packet;
mediaPacketList.push_back(mediaPacket);
- mediaPacket->length = static_cast<size_t>(
- (static_cast<float>(rand()) / RAND_MAX) *
- (IP_PACKET_SIZE - 12 - 28 -
- ForwardErrorCorrection::PacketOverhead()));
- if (mediaPacket->length < 12) {
- mediaPacket->length = 12;
- }
+ const uint32_t kMinPacketSize = 12;
+ const uint32_t kMaxPacketSize = static_cast<uint32_t>(
+ IP_PACKET_SIZE - 12 - 28 -
+ ForwardErrorCorrection::PacketOverhead());
+ mediaPacket->length = random.Rand(kMinPacketSize, kMaxPacketSize);
+
// Generate random values for the first 2 bytes.
- mediaPacket->data[0] = static_cast<uint8_t>(rand() % 256);
- mediaPacket->data[1] = static_cast<uint8_t>(rand() % 256);
+ mediaPacket->data[0] = random.Rand<uint8_t>();
+ mediaPacket->data[1] = random.Rand<uint8_t>();
// The first two bits are assumed to be 10 by the
// FEC encoder. In fact the FEC decoder will set the
@@ -266,7 +261,7 @@ TEST(FecTest, FecTest) {
ByteWriter<uint32_t>::WriteBigEndian(&mediaPacket->data[8], ssrc);
// Generate random values for payload
for (size_t j = 12; j < mediaPacket->length; ++j) {
- mediaPacket->data[j] = static_cast<uint8_t>(rand() % 256);
+ mediaPacket->data[j] = random.Rand<uint8_t>();
}
seqNum++;
}
@@ -289,8 +284,7 @@ TEST(FecTest, FecTest) {
while (mediaPacketListItem != mediaPacketList.end()) {
mediaPacket = *mediaPacketListItem;
// We want a value between 0 and 1.
- const float lossRandomVariable =
- (static_cast<float>(rand()) / (RAND_MAX));
+ const float lossRandomVariable = random.Rand<float>();
if (lossRandomVariable >= lossRate[lossRateIdx]) {
mediaLossMask[mediaPacketIdx] = 1;
@@ -315,8 +309,7 @@ TEST(FecTest, FecTest) {
uint32_t fecPacketIdx = 0;
while (fecPacketListItem != fecPacketList.end()) {
fecPacket = *fecPacketListItem;
- const float lossRandomVariable =
- (static_cast<float>(rand()) / (RAND_MAX));
+ const float lossRandomVariable = random.Rand<float>();
if (lossRandomVariable >= lossRate[lossRateIdx]) {
fecLossMask[fecPacketIdx] = 1;
receivedPacket = new ForwardErrorCorrection::ReceivedPacket;
@@ -387,18 +380,15 @@ TEST(FecTest, FecTest) {
// For error-checking frame completion.
bool fecPacketReceived = false;
while (!receivedPacketList.empty()) {
- uint32_t numPacketsToDecode = static_cast<uint32_t>(
- (static_cast<float>(rand()) / RAND_MAX) *
- receivedPacketList.size() + 0.5);
- if (numPacketsToDecode < 1) {
- numPacketsToDecode = 1;
- }
+ size_t numPacketsToDecode = random.Rand(
+ 1u, static_cast<uint32_t>(receivedPacketList.size()));
ReceivePackets(&toDecodeList, &receivedPacketList,
- numPacketsToDecode, reorderRate, duplicateRate);
+ numPacketsToDecode, reorderRate, duplicateRate,
+ &random);
if (fecPacketReceived == false) {
ForwardErrorCorrection::ReceivedPacketList::iterator
- toDecodeIt = toDecodeList.begin();
+ toDecodeIt = toDecodeList.begin();
while (toDecodeIt != toDecodeList.end()) {
receivedPacket = *toDecodeIt;
if (receivedPacket->is_fec) {
@@ -418,11 +408,11 @@ TEST(FecTest, FecTest) {
if (mediaLossMask[mediaPacketIdx] == 1) {
// Should have recovered this packet.
ForwardErrorCorrection::RecoveredPacketList::iterator
- recoveredPacketListItem = recoveredPacketList.begin();
+ recoveredPacketListItem = recoveredPacketList.begin();
- ASSERT_FALSE(
- recoveredPacketListItem == recoveredPacketList.end())
- << "Insufficient number of recovered packets.";
+ ASSERT_FALSE(recoveredPacketListItem ==
+ recoveredPacketList.end())
+ << "Insufficient number of recovered packets.";
mediaPacket = *mediaPacketListItem;
ForwardErrorCorrection::RecoveredPacket* recoveredPacket =
*recoveredPacketListItem;
@@ -462,7 +452,7 @@ TEST(FecTest, FecTest) {
// Delete received packets we didn't pass to DecodeFEC(), due to
// early frame completion.
ForwardErrorCorrection::ReceivedPacketList::iterator
- receivedPacketIt = receivedPacketList.begin();
+ receivedPacketIt = receivedPacketList.begin();
while (receivedPacketIt != receivedPacketList.end()) {
receivedPacket = *receivedPacketIt;
delete receivedPacket;
@@ -476,11 +466,11 @@ TEST(FecTest, FecTest) {
}
timeStamp += 90000 / 30;
} // loop over numImpPackets
- } // loop over FecPackets
- } // loop over numMediaPackets
+ } // loop over FecPackets
+ } // loop over numMediaPackets
delete[] packetMask;
} // loop over loss rates
- } // loop over mask types
+ } // loop over mask types
// Have DecodeFEC free allocated memory.
fec.ResetState(&recoveredPacketList);
diff --git a/webrtc/modules/rtp_rtcp/test/testFec/test_packet_masks_metrics.cc b/webrtc/modules/rtp_rtcp/test/testFec/test_packet_masks_metrics.cc
index 843a7f77f5..466214c740 100644
--- a/webrtc/modules/rtp_rtcp/test/testFec/test_packet_masks_metrics.cc
+++ b/webrtc/modules/rtp_rtcp/test/testFec/test_packet_masks_metrics.cc
@@ -59,13 +59,6 @@ enum { kMaxNumberMediaPackets = 48 };
// Maximum number of media packets allowed for each mask type.
const uint16_t kMaxMediaPackets[] = {kMaxNumberMediaPackets, 12};
-// Maximum number of media packets allowed in this test. The burst mask types
-// are currently defined up to (k=12,m=12).
-const int kMaxMediaPacketsTest = 12;
-
-// Maximum number of FEC codes considered in this test.
-const int kNumberCodes = kMaxMediaPacketsTest * (kMaxMediaPacketsTest + 1) / 2;
-
// Maximum gap size for characterizing the consecutiveness of the loss.
const int kMaxGapSize = 2 * kMaxMediaPacketsTest;
@@ -407,7 +400,7 @@ class FecPacketMaskMetricsTest : public ::testing::Test {
// Loop over all loss configurations for the symbol sequence of length
// |tot_num_packets|. In this version we process up to (k=12, m=12) codes,
// and get exact expressions for the residual loss.
- // TODO (marpan): For larger codes, loop over some random sample of loss
+ // TODO(marpan): For larger codes, loop over some random sample of loss
// configurations, sampling driven by the underlying statistical loss model
// (importance sampling).
@@ -427,7 +420,7 @@ class FecPacketMaskMetricsTest : public ::testing::Test {
// Map configuration number to a loss state.
for (int j = 0; j < tot_num_packets; j++) {
- state[j]=0; // Received state.
+ state[j] = 0; // Received state.
int bit_value = i >> (tot_num_packets - j - 1) & 1;
if (bit_value == 1) {
state[j] = 1; // Lost state.
@@ -860,9 +853,9 @@ TEST_F(FecPacketMaskMetricsTest, FecXorVsRS) {
EXPECT_GE(kMetricsXorBursty[code_index].average_residual_loss[k],
kMetricsReedSolomon[code_index].average_residual_loss[k]);
}
- // TODO (marpan): There are some cases (for high loss rates and/or
- // burst loss models) where XOR is better than RS. Is there some pattern
- // we can identify and enforce as a constraint?
+ // TODO(marpan): There are some cases (for high loss rates and/or
+ // burst loss models) where XOR is better than RS. Is there some pattern
+ // we can identify and enforce as a constraint?
}
}
}
@@ -874,7 +867,7 @@ TEST_F(FecPacketMaskMetricsTest, FecXorVsRS) {
TEST_F(FecPacketMaskMetricsTest, FecTrendXorVsRsLossRate) {
SetLossModels();
SetCodeParams();
- // TODO (marpan): Examine this further to see if the condition can be strictly
+ // TODO(marpan): Examine this further to see if the condition can be strictly
// satisfied (i.e., scale = 1.0) for all codes with different/better masks.
double scale = 0.90;
int num_loss_rates = sizeof(kAverageLossRate) /
@@ -898,7 +891,7 @@ TEST_F(FecPacketMaskMetricsTest, FecTrendXorVsRsLossRate) {
kMetricsXorRandom[code_index].average_residual_loss[k+1];
EXPECT_GE(diff_rs_xor_random_loss1, scale * diff_rs_xor_random_loss2);
}
- // TODO (marpan): Investigate the cases for the bursty mask where
+ // TODO(marpan): Investigate the cases for the bursty mask where
// this trend is not strictly satisfied.
}
}
@@ -937,7 +930,7 @@ TEST_F(FecPacketMaskMetricsTest, FecBehaviorViaProtectionLevelAndLength) {
EXPECT_LT(
kMetricsReedSolomon[code_index2].average_residual_loss[k],
kMetricsReedSolomon[code_index1].average_residual_loss[k]);
- // TODO (marpan): There are some corner cases where this is not
+ // TODO(marpan): There are some corner cases where this is not
// satisfied with the current packet masks. Look into updating
// these cases to see if this behavior should/can be satisfied,
// with overall lower residual loss for those XOR codes.
@@ -963,7 +956,7 @@ TEST_F(FecPacketMaskMetricsTest, FecVarianceBehaviorXorVsRs) {
SetCodeParams();
// The condition is not strictly satisfied with the current masks,
// i.e., for some codes, the variance of XOR may be slightly higher than RS.
- // TODO (marpan): Examine this further to see if the condition can be strictly
+ // TODO(marpan): Examine this further to see if the condition can be strictly
// satisfied (i.e., scale = 1.0) for all codes with different/better masks.
double scale = 0.95;
for (int code_index = 0; code_index < max_num_codes_; code_index++) {
@@ -998,7 +991,7 @@ TEST_F(FecPacketMaskMetricsTest, FecXorBurstyPerfectRecoveryConsecutiveLoss) {
// bursty mask type, for random loss models at low loss rates.
// The XOR codes with bursty mask types are generally better than the one with
// random mask type, for bursty loss models and/or high loss rates.
-// TODO (marpan): Enable this test when some of the packet masks are updated.
+// TODO(marpan): Enable this test when some of the packet masks are updated.
// Some isolated cases of the codes don't pass this currently.
/*
TEST_F(FecPacketMaskMetricsTest, FecXorRandomVsBursty) {