1 /*
2 * Copyright (c) 2012 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 "modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h"
12
13 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
14 #include "test/gmock.h"
15 #include "test/gtest.h"
16
17 namespace webrtc {
18 namespace {
19
20 using ::testing::ElementsAreArray;
21
22 constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
23
24 // Payload descriptor
25 // 0 1 2 3 4 5 6 7
26 // +-+-+-+-+-+-+-+-+
27 // |X|R|N|S|PartID | (REQUIRED)
28 // +-+-+-+-+-+-+-+-+
29 // X: |I|L|T|K| RSV | (OPTIONAL)
30 // +-+-+-+-+-+-+-+-+
31 // |M| PictureID |
32 // I: +-+-+-+-+-+-+-+-+ (OPTIONAL)
33 // | PictureID |
34 // +-+-+-+-+-+-+-+-+
35 // L: | TL0PICIDX | (OPTIONAL)
36 // +-+-+-+-+-+-+-+-+
37 // T/K: |TID|Y| KEYIDX | (OPTIONAL)
38 // +-+-+-+-+-+-+-+-+
39
Bit(uint8_t byte,int position)40 int Bit(uint8_t byte, int position) {
41 return (byte >> position) & 0x01;
42 }
43
44 } // namespace
45
RtpFormatVp8TestHelper(const RTPVideoHeaderVP8 * hdr,size_t payload_len)46 RtpFormatVp8TestHelper::RtpFormatVp8TestHelper(const RTPVideoHeaderVP8* hdr,
47 size_t payload_len)
48 : hdr_info_(hdr), payload_(payload_len) {
49 for (size_t i = 0; i < payload_.size(); ++i) {
50 payload_[i] = i;
51 }
52 }
53
54 RtpFormatVp8TestHelper::~RtpFormatVp8TestHelper() = default;
55
GetAllPacketsAndCheck(RtpPacketizerVp8 * packetizer,rtc::ArrayView<const size_t> expected_sizes)56 void RtpFormatVp8TestHelper::GetAllPacketsAndCheck(
57 RtpPacketizerVp8* packetizer,
58 rtc::ArrayView<const size_t> expected_sizes) {
59 EXPECT_EQ(packetizer->NumPackets(), expected_sizes.size());
60 const uint8_t* data_ptr = payload_.begin();
61 RtpPacketToSend packet(kNoExtensions);
62 for (size_t i = 0; i < expected_sizes.size(); ++i) {
63 EXPECT_TRUE(packetizer->NextPacket(&packet));
64 auto rtp_payload = packet.payload();
65 EXPECT_EQ(rtp_payload.size(), expected_sizes[i]);
66
67 int payload_offset = CheckHeader(rtp_payload, /*first=*/i == 0);
68 // Verify that the payload (i.e., after the headers) of the packet is
69 // identical to the expected (as found in data_ptr).
70 auto vp8_payload = rtp_payload.subview(payload_offset);
71 ASSERT_GE(payload_.end() - data_ptr, static_cast<int>(vp8_payload.size()));
72 EXPECT_THAT(vp8_payload, ElementsAreArray(data_ptr, vp8_payload.size()));
73 data_ptr += vp8_payload.size();
74 }
75 EXPECT_EQ(payload_.end() - data_ptr, 0);
76 }
77
CheckHeader(rtc::ArrayView<const uint8_t> buffer,bool first)78 int RtpFormatVp8TestHelper::CheckHeader(rtc::ArrayView<const uint8_t> buffer,
79 bool first) {
80 int x_bit = Bit(buffer[0], 7);
81 EXPECT_EQ(Bit(buffer[0], 6), 0); // Reserved.
82 EXPECT_EQ(Bit(buffer[0], 5), hdr_info_->nonReference ? 1 : 0);
83 EXPECT_EQ(Bit(buffer[0], 4), first ? 1 : 0);
84 EXPECT_EQ(buffer[0] & 0x0f, 0); // RtpPacketizerVp8 always uses partition 0.
85
86 int payload_offset = 1;
87 if (hdr_info_->pictureId != kNoPictureId ||
88 hdr_info_->temporalIdx != kNoTemporalIdx ||
89 hdr_info_->tl0PicIdx != kNoTl0PicIdx || hdr_info_->keyIdx != kNoKeyIdx) {
90 EXPECT_EQ(x_bit, 1);
91 ++payload_offset;
92 CheckPictureID(buffer, &payload_offset);
93 CheckTl0PicIdx(buffer, &payload_offset);
94 CheckTIDAndKeyIdx(buffer, &payload_offset);
95 EXPECT_EQ(buffer[1] & 0x07, 0); // Reserved.
96 } else {
97 EXPECT_EQ(x_bit, 0);
98 }
99
100 return payload_offset;
101 }
102
103 // Verify that the I bit and the PictureID field are both set in accordance
104 // with the information in hdr_info_->pictureId.
CheckPictureID(rtc::ArrayView<const uint8_t> buffer,int * offset)105 void RtpFormatVp8TestHelper::CheckPictureID(
106 rtc::ArrayView<const uint8_t> buffer,
107 int* offset) {
108 int i_bit = Bit(buffer[1], 7);
109 if (hdr_info_->pictureId != kNoPictureId) {
110 EXPECT_EQ(i_bit, 1);
111 int two_byte_picture_id = Bit(buffer[*offset], 7);
112 EXPECT_EQ(two_byte_picture_id, 1);
113 EXPECT_EQ(buffer[*offset] & 0x7F, (hdr_info_->pictureId >> 8) & 0x7F);
114 EXPECT_EQ(buffer[(*offset) + 1], hdr_info_->pictureId & 0xFF);
115 (*offset) += 2;
116 } else {
117 EXPECT_EQ(i_bit, 0);
118 }
119 }
120
121 // Verify that the L bit and the TL0PICIDX field are both set in accordance
122 // with the information in hdr_info_->tl0PicIdx.
CheckTl0PicIdx(rtc::ArrayView<const uint8_t> buffer,int * offset)123 void RtpFormatVp8TestHelper::CheckTl0PicIdx(
124 rtc::ArrayView<const uint8_t> buffer,
125 int* offset) {
126 int l_bit = Bit(buffer[1], 6);
127 if (hdr_info_->tl0PicIdx != kNoTl0PicIdx) {
128 EXPECT_EQ(l_bit, 1);
129 EXPECT_EQ(buffer[*offset], hdr_info_->tl0PicIdx);
130 ++*offset;
131 } else {
132 EXPECT_EQ(l_bit, 0);
133 }
134 }
135
136 // Verify that the T bit and the TL0PICIDX field, and the K bit and KEYIDX
137 // field are all set in accordance with the information in
138 // hdr_info_->temporalIdx and hdr_info_->keyIdx, respectively.
CheckTIDAndKeyIdx(rtc::ArrayView<const uint8_t> buffer,int * offset)139 void RtpFormatVp8TestHelper::CheckTIDAndKeyIdx(
140 rtc::ArrayView<const uint8_t> buffer,
141 int* offset) {
142 int t_bit = Bit(buffer[1], 5);
143 int k_bit = Bit(buffer[1], 4);
144 if (hdr_info_->temporalIdx == kNoTemporalIdx &&
145 hdr_info_->keyIdx == kNoKeyIdx) {
146 EXPECT_EQ(t_bit, 0);
147 EXPECT_EQ(k_bit, 0);
148 return;
149 }
150 int temporal_id = (buffer[*offset] & 0xC0) >> 6;
151 int y_bit = Bit(buffer[*offset], 5);
152 int key_idx = buffer[*offset] & 0x1f;
153 if (hdr_info_->temporalIdx != kNoTemporalIdx) {
154 EXPECT_EQ(t_bit, 1);
155 EXPECT_EQ(temporal_id, hdr_info_->temporalIdx);
156 EXPECT_EQ(y_bit, hdr_info_->layerSync ? 1 : 0);
157 } else {
158 EXPECT_EQ(t_bit, 0);
159 EXPECT_EQ(temporal_id, 0);
160 EXPECT_EQ(y_bit, 0);
161 }
162 if (hdr_info_->keyIdx != kNoKeyIdx) {
163 EXPECT_EQ(k_bit, 1);
164 EXPECT_EQ(key_idx, hdr_info_->keyIdx);
165 } else {
166 EXPECT_EQ(k_bit, 0);
167 EXPECT_EQ(key_idx, 0);
168 }
169 ++*offset;
170 }
171
172 } // namespace webrtc
173