blob: 91ed2ca2c73fa2b954737696932a889dee7c7a72 [file] [log] [blame]
nisseeed52bf2017-05-19 06:15:19 -07001/*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/call/rtx_receive_stream.h"
Danil Chapovalov84b4d2c2017-06-12 15:05:44 +020012#include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h"
nisseeed52bf2017-05-19 06:15:19 -070013#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
Danil Chapovalov84b4d2c2017-06-12 15:05:44 +020014#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
nisseeed52bf2017-05-19 06:15:19 -070015#include "webrtc/test/gmock.h"
16#include "webrtc/test/gtest.h"
17
18namespace webrtc {
19
20namespace {
21
22using ::testing::_;
23using ::testing::StrictMock;
24
25class MockRtpPacketSink : public RtpPacketSinkInterface {
26 public:
27 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&));
28};
29
30constexpr int kMediaPayloadType = 100;
31constexpr int kRtxPayloadType = 98;
32constexpr uint32_t kMediaSSRC = 0x3333333;
33constexpr uint16_t kMediaSeqno = 0x5657;
34
35constexpr uint8_t kRtxPacket[] = {
36 0x80, // Version 2.
37 98, // Payload type.
38 0x12, 0x34, // Seqno.
39 0x11, 0x11, 0x11, 0x11, // Timestamp.
40 0x22, 0x22, 0x22, 0x22, // SSRC.
41 // RTX header.
42 0x56, 0x57, // Orig seqno.
43 // Payload.
44 0xee,
45};
46
47constexpr uint8_t kRtxPacketWithCVO[] = {
48 0x90, // Version 2, X set.
49 98, // Payload type.
50 0x12, 0x34, // Seqno.
51 0x11, 0x11, 0x11, 0x11, // Timestamp.
52 0x22, 0x22, 0x22, 0x22, // SSRC.
53 0xbe, 0xde, 0x00, 0x01, // Extension header.
54 0x30, 0x01, 0x00, 0x00, // 90 degree rotation.
55 // RTX header.
56 0x56, 0x57, // Orig seqno.
57 // Payload.
58 0xee,
59};
60
61std::map<int, int> PayloadTypeMapping() {
62 std::map<int, int> m;
63 m[kRtxPayloadType] = kMediaPayloadType;
64 return m;
65}
66
67template <typename T>
68rtc::ArrayView<T> Truncate(rtc::ArrayView<T> a, size_t drop) {
69 return a.subview(0, a.size() - drop);
70}
71
72} // namespace
73
74TEST(RtxReceiveStreamTest, RestoresPacketPayload) {
75 StrictMock<MockRtpPacketSink> media_sink;
76 RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
77 RtpPacketReceived rtx_packet;
78 EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacket)));
79
80 EXPECT_CALL(media_sink, OnRtpPacket(_)).WillOnce(testing::Invoke(
81 [](const RtpPacketReceived& packet) {
82 EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
83 EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
84 EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
85 EXPECT_THAT(packet.payload(), testing::ElementsAre(0xee));
86 }));
87
88 rtx_sink.OnRtpPacket(rtx_packet);
89}
90
91TEST(RtxReceiveStreamTest, IgnoresUnknownPayloadType) {
92 StrictMock<MockRtpPacketSink> media_sink;
93 RtxReceiveStream rtx_sink(&media_sink, std::map<int, int>(), kMediaSSRC);
94 RtpPacketReceived rtx_packet;
95 EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacket)));
96 rtx_sink.OnRtpPacket(rtx_packet);
97}
98
99TEST(RtxReceiveStreamTest, IgnoresTruncatedPacket) {
100 StrictMock<MockRtpPacketSink> media_sink;
101 RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
102 RtpPacketReceived rtx_packet;
103 EXPECT_TRUE(
104 rtx_packet.Parse(Truncate(rtc::ArrayView<const uint8_t>(kRtxPacket), 2)));
105 rtx_sink.OnRtpPacket(rtx_packet);
106}
107
108TEST(RtxReceiveStreamTest, CopiesRtpHeaderExtensions) {
109 StrictMock<MockRtpPacketSink> media_sink;
110 RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
111 RtpHeaderExtensionMap extension_map;
112 extension_map.RegisterByType(3, kRtpExtensionVideoRotation);
113 RtpPacketReceived rtx_packet(&extension_map);
114 EXPECT_TRUE(rtx_packet.Parse(
115 rtc::ArrayView<const uint8_t>(kRtxPacketWithCVO)));
116
117 VideoRotation rotation = kVideoRotation_0;
118 EXPECT_TRUE(rtx_packet.GetExtension<VideoOrientation>(&rotation));
119 EXPECT_EQ(kVideoRotation_90, rotation);
120
121 EXPECT_CALL(media_sink, OnRtpPacket(_)).WillOnce(testing::Invoke(
122 [](const RtpPacketReceived& packet) {
123 EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
124 EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
125 EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
126 EXPECT_THAT(packet.payload(), testing::ElementsAre(0xee));
127 VideoRotation rotation = kVideoRotation_0;
128 EXPECT_TRUE(packet.GetExtension<VideoOrientation>(&rotation));
129 EXPECT_EQ(rotation, kVideoRotation_90);
130 }));
131
132 rtx_sink.OnRtpPacket(rtx_packet);
133}
134
135} // namespace webrtc