blob: 0088ff8f31ec9e9c83882b7216a9c458d69d8fbb [file] [log] [blame]
henrik.lundin@webrtc.org00e73072011-12-21 08:51:361/*
phoglund@webrtc.org78088c22012-02-07 14:56:452 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
henrik.lundin@webrtc.org00e73072011-12-21 08:51:363 *
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
Mirko Bonadei92ea95e2017-09-15 04:47:3111#include "modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h"
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3612
Danil Chapovalov8a3c1662018-08-30 18:54:5813#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
14#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3115#include "test/gtest.h"
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3616
Emil Lundmark575498f2021-08-27 15:01:5617// VP8 payload descriptor
18// https://datatracker.ietf.org/doc/html/rfc7741#section-4.2
19//
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3620// 0 1 2 3 4 5 6 7
21// +-+-+-+-+-+-+-+-+
Emil Lundmark575498f2021-08-27 15:01:5622// |X|R|N|S|R| PID | (REQUIRED)
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3623// +-+-+-+-+-+-+-+-+
Emil Lundmark575498f2021-08-27 15:01:5624// X: |I|L|T|K| RSV | (OPTIONAL)
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3625// +-+-+-+-+-+-+-+-+
Emil Lundmark575498f2021-08-27 15:01:5626// I: |M| PictureID | (OPTIONAL)
27// +-+-+-+-+-+-+-+-+
Danil Chapovalov8a3c1662018-08-30 18:54:5828// | PictureID |
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3629// +-+-+-+-+-+-+-+-+
30// L: | TL0PICIDX | (OPTIONAL)
31// +-+-+-+-+-+-+-+-+
Danil Chapovalov8a3c1662018-08-30 18:54:5832// T/K: |TID|Y| KEYIDX | (OPTIONAL)
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3633// +-+-+-+-+-+-+-+-+
34
Emil Lundmark575498f2021-08-27 15:01:5635namespace webrtc {
36namespace {
37
38using ::testing::ElementsAreArray;
39
40constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
41
Danil Chapovalov8a3c1662018-08-30 18:54:5842int Bit(uint8_t byte, int position) {
43 return (byte >> position) & 0x01;
44}
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3645
Danil Chapovalov8a3c1662018-08-30 18:54:5846} // namespace
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3647
Danil Chapovalov8a3c1662018-08-30 18:54:5848RtpFormatVp8TestHelper::RtpFormatVp8TestHelper(const RTPVideoHeaderVP8* hdr,
49 size_t payload_len)
50 : hdr_info_(hdr), payload_(payload_len) {
51 for (size_t i = 0; i < payload_.size(); ++i) {
52 payload_[i] = i;
53 }
54}
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3655
Danil Chapovalov8a3c1662018-08-30 18:54:5856RtpFormatVp8TestHelper::~RtpFormatVp8TestHelper() = default;
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3657
Danil Chapovalov8a3c1662018-08-30 18:54:5858void RtpFormatVp8TestHelper::GetAllPacketsAndCheck(
59 RtpPacketizerVp8* packetizer,
60 rtc::ArrayView<const size_t> expected_sizes) {
61 EXPECT_EQ(packetizer->NumPackets(), expected_sizes.size());
62 const uint8_t* data_ptr = payload_.begin();
63 RtpPacketToSend packet(kNoExtensions);
64 for (size_t i = 0; i < expected_sizes.size(); ++i) {
65 EXPECT_TRUE(packetizer->NextPacket(&packet));
66 auto rtp_payload = packet.payload();
67 EXPECT_EQ(rtp_payload.size(), expected_sizes[i]);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3668
Danil Chapovalov8a3c1662018-08-30 18:54:5869 int payload_offset = CheckHeader(rtp_payload, /*first=*/i == 0);
70 // Verify that the payload (i.e., after the headers) of the packet is
71 // identical to the expected (as found in data_ptr).
72 auto vp8_payload = rtp_payload.subview(payload_offset);
73 ASSERT_GE(payload_.end() - data_ptr, static_cast<int>(vp8_payload.size()));
74 EXPECT_THAT(vp8_payload, ElementsAreArray(data_ptr, vp8_payload.size()));
75 data_ptr += vp8_payload.size();
76 }
77 EXPECT_EQ(payload_.end() - data_ptr, 0);
78}
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3679
Danil Chapovalov8a3c1662018-08-30 18:54:5880int RtpFormatVp8TestHelper::CheckHeader(rtc::ArrayView<const uint8_t> buffer,
81 bool first) {
82 int x_bit = Bit(buffer[0], 7);
83 EXPECT_EQ(Bit(buffer[0], 6), 0); // Reserved.
84 EXPECT_EQ(Bit(buffer[0], 5), hdr_info_->nonReference ? 1 : 0);
85 EXPECT_EQ(Bit(buffer[0], 4), first ? 1 : 0);
86 EXPECT_EQ(buffer[0] & 0x0f, 0); // RtpPacketizerVp8 always uses partition 0.
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3687
Danil Chapovalov8a3c1662018-08-30 18:54:5888 int payload_offset = 1;
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3689 if (hdr_info_->pictureId != kNoPictureId ||
90 hdr_info_->temporalIdx != kNoTemporalIdx ||
Yves Gerey665174f2018-06-19 13:03:0591 hdr_info_->tl0PicIdx != kNoTl0PicIdx || hdr_info_->keyIdx != kNoKeyIdx) {
Danil Chapovalov8a3c1662018-08-30 18:54:5892 EXPECT_EQ(x_bit, 1);
93 ++payload_offset;
94 CheckPictureID(buffer, &payload_offset);
95 CheckTl0PicIdx(buffer, &payload_offset);
96 CheckTIDAndKeyIdx(buffer, &payload_offset);
97 EXPECT_EQ(buffer[1] & 0x07, 0); // Reserved.
henrik.lundin@webrtc.org00e73072011-12-21 08:51:3698 } else {
Danil Chapovalov8a3c1662018-08-30 18:54:5899 EXPECT_EQ(x_bit, 0);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36100 }
101
Danil Chapovalov8a3c1662018-08-30 18:54:58102 return payload_offset;
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36103}
104
105// Verify that the I bit and the PictureID field are both set in accordance
106// with the information in hdr_info_->pictureId.
Danil Chapovalov8a3c1662018-08-30 18:54:58107void RtpFormatVp8TestHelper::CheckPictureID(
108 rtc::ArrayView<const uint8_t> buffer,
109 int* offset) {
110 int i_bit = Bit(buffer[1], 7);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36111 if (hdr_info_->pictureId != kNoPictureId) {
Danil Chapovalov8a3c1662018-08-30 18:54:58112 EXPECT_EQ(i_bit, 1);
113 int two_byte_picture_id = Bit(buffer[*offset], 7);
114 EXPECT_EQ(two_byte_picture_id, 1);
115 EXPECT_EQ(buffer[*offset] & 0x7F, (hdr_info_->pictureId >> 8) & 0x7F);
116 EXPECT_EQ(buffer[(*offset) + 1], hdr_info_->pictureId & 0xFF);
117 (*offset) += 2;
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36118 } else {
Danil Chapovalov8a3c1662018-08-30 18:54:58119 EXPECT_EQ(i_bit, 0);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36120 }
121}
122
123// Verify that the L bit and the TL0PICIDX field are both set in accordance
124// with the information in hdr_info_->tl0PicIdx.
Danil Chapovalov8a3c1662018-08-30 18:54:58125void RtpFormatVp8TestHelper::CheckTl0PicIdx(
126 rtc::ArrayView<const uint8_t> buffer,
127 int* offset) {
128 int l_bit = Bit(buffer[1], 6);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36129 if (hdr_info_->tl0PicIdx != kNoTl0PicIdx) {
Danil Chapovalov8a3c1662018-08-30 18:54:58130 EXPECT_EQ(l_bit, 1);
131 EXPECT_EQ(buffer[*offset], hdr_info_->tl0PicIdx);
132 ++*offset;
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36133 } else {
Danil Chapovalov8a3c1662018-08-30 18:54:58134 EXPECT_EQ(l_bit, 0);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36135 }
136}
137
138// Verify that the T bit and the TL0PICIDX field, and the K bit and KEYIDX
139// field are all set in accordance with the information in
140// hdr_info_->temporalIdx and hdr_info_->keyIdx, respectively.
Danil Chapovalov8a3c1662018-08-30 18:54:58141void RtpFormatVp8TestHelper::CheckTIDAndKeyIdx(
142 rtc::ArrayView<const uint8_t> buffer,
143 int* offset) {
144 int t_bit = Bit(buffer[1], 5);
145 int k_bit = Bit(buffer[1], 4);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36146 if (hdr_info_->temporalIdx == kNoTemporalIdx &&
147 hdr_info_->keyIdx == kNoKeyIdx) {
Danil Chapovalov8a3c1662018-08-30 18:54:58148 EXPECT_EQ(t_bit, 0);
149 EXPECT_EQ(k_bit, 0);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36150 return;
151 }
Danil Chapovalov8a3c1662018-08-30 18:54:58152 int temporal_id = (buffer[*offset] & 0xC0) >> 6;
153 int y_bit = Bit(buffer[*offset], 5);
154 int key_idx = buffer[*offset] & 0x1f;
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36155 if (hdr_info_->temporalIdx != kNoTemporalIdx) {
Danil Chapovalov8a3c1662018-08-30 18:54:58156 EXPECT_EQ(t_bit, 1);
157 EXPECT_EQ(temporal_id, hdr_info_->temporalIdx);
158 EXPECT_EQ(y_bit, hdr_info_->layerSync ? 1 : 0);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36159 } else {
Danil Chapovalov8a3c1662018-08-30 18:54:58160 EXPECT_EQ(t_bit, 0);
161 EXPECT_EQ(temporal_id, 0);
162 EXPECT_EQ(y_bit, 0);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36163 }
164 if (hdr_info_->keyIdx != kNoKeyIdx) {
Danil Chapovalov8a3c1662018-08-30 18:54:58165 EXPECT_EQ(k_bit, 1);
166 EXPECT_EQ(key_idx, hdr_info_->keyIdx);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36167 } else {
Danil Chapovalov8a3c1662018-08-30 18:54:58168 EXPECT_EQ(k_bit, 0);
169 EXPECT_EQ(key_idx, 0);
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36170 }
Danil Chapovalov8a3c1662018-08-30 18:54:58171 ++*offset;
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36172}
173
henrik.lundin@webrtc.org00e73072011-12-21 08:51:36174} // namespace webrtc