#include "common.hpp"
#include "helpers.hpp"
#include "RTC/RtpPacket.hpp"
#include <catch2/catch.hpp>
#include <cstring>
#include <string>
#include <vector>
using namespace RTC;
static uint8_t buffer[65536];
SCENARIO("parse RTP packets", "[parser][rtp]")
{
SECTION("parse packet1.raw")
{
size_t len;
uint8_t extenLen;
uint8_t* extenValue;
std::string rid;
if (!helpers::readBinaryFile("data/packet1.raw", buffer, &len))
FAIL("cannot open file");
RtpPacket* packet = RtpPacket::Parse(buffer, len);
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetPayloadType() == 111);
REQUIRE(packet->GetSequenceNumber() == 23617);
REQUIRE(packet->GetTimestamp() == 1660241882);
REQUIRE(packet->GetSsrc() == 2674985186);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 4);
REQUIRE(packet->HasOneByteExtensions());
REQUIRE(packet->HasTwoBytesExtensions() == false);
packet->SetRidExtensionId(10);
extenValue = packet->GetExtension(10, extenLen);
REQUIRE(packet->HasExtension(10) == false);
REQUIRE(extenLen == 0);
REQUIRE(extenValue == nullptr);
REQUIRE(packet->ReadRid(rid) == false);
REQUIRE(rid == "");
delete packet;
}
SECTION("parse packet2.raw")
{
size_t len;
if (!helpers::readBinaryFile("data/packet2.raw", buffer, &len))
FAIL("cannot open file");
RtpPacket* packet = RtpPacket::Parse(buffer, len);
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == false);
REQUIRE(packet->GetPayloadType() == 100);
REQUIRE(packet->GetSequenceNumber() == 28478);
REQUIRE(packet->GetTimestamp() == 172320136);
REQUIRE(packet->GetSsrc() == 3316375386);
REQUIRE(packet->GetHeaderExtensionId() == 0);
REQUIRE(packet->GetHeaderExtensionLength() == 0);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions() == false);
delete packet;
}
SECTION("parse packet3.raw")
{
size_t len;
uint8_t extenLen;
uint8_t* extenValue;
bool voice;
uint8_t volume;
uint32_t absSendTime;
if (!helpers::readBinaryFile("data/packet3.raw", buffer, &len))
FAIL("cannot open file");
RtpPacket* packet = RtpPacket::Parse(buffer, len);
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetPayloadType() == 111);
REQUIRE(packet->GetSequenceNumber() == 19354);
REQUIRE(packet->GetTimestamp() == 863466045);
REQUIRE(packet->GetSsrc() == 235797202);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 8);
REQUIRE(packet->HasOneByteExtensions());
REQUIRE(packet->HasTwoBytesExtensions() == false);
packet->SetSsrcAudioLevelExtensionId(1);
extenValue = packet->GetExtension(1, extenLen);
REQUIRE(packet->HasExtension(1) == true);
REQUIRE(extenLen == 1);
REQUIRE(extenValue);
REQUIRE(extenValue[0] == 0xd0);
REQUIRE(packet->ReadSsrcAudioLevel(volume, voice) == true);
REQUIRE(volume == 0b1010000);
REQUIRE(voice == true);
packet->SetAbsSendTimeExtensionId(3);
extenValue = packet->GetExtension(3, extenLen);
REQUIRE(packet->HasExtension(3) == true);
REQUIRE(extenLen == 3);
REQUIRE(extenValue);
REQUIRE(extenValue[0] == 0x65);
REQUIRE(extenValue[1] == 0x34);
REQUIRE(extenValue[2] == 0x1e);
REQUIRE(packet->ReadAbsSendTime(absSendTime) == true);
REQUIRE(absSendTime == 0x65341e);
auto* clonedPacket = packet->Clone();
std::memset(buffer, '0', sizeof(buffer));
REQUIRE(clonedPacket->HasMarker() == false);
REQUIRE(clonedPacket->HasHeaderExtension() == true);
REQUIRE(clonedPacket->GetPayloadType() == 111);
REQUIRE(clonedPacket->GetSequenceNumber() == 19354);
REQUIRE(clonedPacket->GetTimestamp() == 863466045);
REQUIRE(clonedPacket->GetSsrc() == 235797202);
REQUIRE(clonedPacket->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(clonedPacket->GetHeaderExtensionLength() == 8);
REQUIRE(clonedPacket->HasOneByteExtensions());
REQUIRE(clonedPacket->HasTwoBytesExtensions() == false);
extenValue = clonedPacket->GetExtension(1, extenLen);
REQUIRE(packet->HasExtension(1) == false);
REQUIRE(extenLen == 1);
REQUIRE(extenValue);
REQUIRE(extenValue[0] == 0xd0);
REQUIRE(clonedPacket->ReadSsrcAudioLevel(volume, voice) == true);
REQUIRE(volume == 0b1010000);
REQUIRE(voice == true);
extenValue = clonedPacket->GetExtension(3, extenLen);
REQUIRE(packet->HasExtension(3) == false);
REQUIRE(extenLen == 3);
REQUIRE(extenValue);
REQUIRE(extenValue[0] == 0x65);
REQUIRE(extenValue[1] == 0x34);
REQUIRE(extenValue[2] == 0x1e);
REQUIRE(clonedPacket->ReadAbsSendTime(absSendTime) == true);
REQUIRE(absSendTime == 0x65341e);
delete packet;
delete clonedPacket;
}
SECTION("create RtpPacket without header extension")
{
uint8_t buffer[] =
{
0b10000000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5
};
RtpPacket* packet = RtpPacket::Parse(buffer, sizeof(buffer));
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == false);
REQUIRE(packet->GetPayloadType() == 1);
REQUIRE(packet->GetSequenceNumber() == 8);
REQUIRE(packet->GetTimestamp() == 4);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetSsrc() == 5);
delete packet;
}
SECTION("create RtpPacket with One-Byte header extension")
{
uint8_t buffer[] =
{
0b10010000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5,
0xBE, 0xDE, 0, 3, 0b00010000, 0xFF, 0b00100001, 0xFF,
0xFF, 0, 0, 0b00110011,
0xFF, 0xFF, 0xFF, 0xFF
};
RtpPacket* packet = RtpPacket::Parse(buffer, sizeof(buffer));
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetPayloadType() == 1);
REQUIRE(packet->GetSequenceNumber() == 8);
REQUIRE(packet->GetTimestamp() == 4);
REQUIRE(packet->GetSsrc() == 5);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 12);
REQUIRE(packet->HasOneByteExtensions());
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 0);
REQUIRE(packet->GetSize() == 28);
packet->SetPayloadLength(1000);
REQUIRE(packet->GetPayloadLength() == 1000);
REQUIRE(packet->GetSize() == 1028);
delete packet;
}
SECTION("create RtpPacket with Two-Bytes header extension")
{
uint8_t buffer[] =
{
0b10010000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5,
0b00010000, 0, 0, 4, 0, 0, 1, 0,
2, 1, 0x42, 0,
3, 2, 0x11, 0x22,
0, 0, 4, 0
};
uint8_t extenLen;
uint8_t* extenValue;
RtpPacket* packet = RtpPacket::Parse(buffer, sizeof(buffer));
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetPayloadType() == 1);
REQUIRE(packet->GetSequenceNumber() == 8);
REQUIRE(packet->GetTimestamp() == 4);
REQUIRE(packet->GetSsrc() == 5);
REQUIRE(packet->GetHeaderExtensionLength() == 16);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions());
REQUIRE(packet->GetPayloadLength() == 0);
extenValue = packet->GetExtension(1, extenLen);
REQUIRE(packet->HasExtension(1) == false);
REQUIRE(extenValue == nullptr);
REQUIRE(extenLen == 0);
extenValue = packet->GetExtension(2, extenLen);
REQUIRE(packet->HasExtension(2) == true);
REQUIRE(extenValue != nullptr);
REQUIRE(extenLen == 1);
REQUIRE(extenValue[0] == 0x42);
extenValue = packet->GetExtension(3, extenLen);
REQUIRE(packet->HasExtension(3) == true);
REQUIRE(extenValue != nullptr);
REQUIRE(extenLen == 2);
REQUIRE(extenValue[0] == 0x11);
REQUIRE(extenValue[1] == 0x22);
extenValue = packet->GetExtension(4, extenLen);
REQUIRE(packet->HasExtension(4) == false);
REQUIRE(extenValue == nullptr);
REQUIRE(extenLen == 0);
extenValue = packet->GetExtension(5, extenLen);
REQUIRE(packet->HasExtension(5) == false);
REQUIRE(extenValue == nullptr);
REQUIRE(extenLen == 0);
delete packet;
}
SECTION("rtx encryption-decryption")
{
uint8_t buffer[] =
{
0b10010000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5,
0b00010000, 0, 0, 3, 1, 0, 2, 1,
0xFF, 0, 3, 4,
0xFF, 0xFF, 0xFF, 0xFF,
0x11, 0x11, 0x11, 0x11 };
uint8_t rtxPayloadType{ 102 };
uint32_t rtxSsrc{ 6 };
uint16_t rtxSeq{ 80 };
RtpPacket* packet = RtpPacket::Parse(buffer, sizeof(buffer));
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetPayloadType() == 1);
REQUIRE(packet->GetSequenceNumber() == 8);
REQUIRE(packet->GetTimestamp() == 4);
REQUIRE(packet->GetSsrc() == 5);
REQUIRE(packet->GetPayloadLength() == 4);
REQUIRE(packet->GetHeaderExtensionLength() == 12);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions());
auto rtxPacket = packet->Clone();
delete packet;
std::memset(buffer, '0', sizeof(buffer));
rtxPacket->RtxEncode(rtxPayloadType, rtxSsrc, rtxSeq);
REQUIRE(rtxPacket->HasMarker() == false);
REQUIRE(rtxPacket->HasHeaderExtension() == true);
REQUIRE(rtxPacket->GetPayloadType() == rtxPayloadType);
REQUIRE(rtxPacket->GetSequenceNumber() == rtxSeq);
REQUIRE(rtxPacket->GetTimestamp() == 4);
REQUIRE(rtxPacket->GetSsrc() == rtxSsrc);
REQUIRE(rtxPacket->GetPayloadLength() == 6);
REQUIRE(rtxPacket->GetHeaderExtensionLength() == 12);
REQUIRE(rtxPacket->HasOneByteExtensions() == false);
REQUIRE(rtxPacket->HasTwoBytesExtensions());
rtxPacket->RtxDecode(1, 5);
REQUIRE(rtxPacket->HasMarker() == false);
REQUIRE(rtxPacket->HasHeaderExtension() == true);
REQUIRE(rtxPacket->GetPayloadType() == 1);
REQUIRE(rtxPacket->GetSequenceNumber() == 8);
REQUIRE(rtxPacket->GetTimestamp() == 4);
REQUIRE(rtxPacket->GetSsrc() == 5);
REQUIRE(rtxPacket->GetPayloadLength() == 4);
REQUIRE(rtxPacket->GetHeaderExtensionLength() == 12);
REQUIRE(rtxPacket->HasOneByteExtensions() == false);
REQUIRE(rtxPacket->HasTwoBytesExtensions());
delete rtxPacket;
}
SECTION("create RtpPacket and apply payload shift to it")
{
uint8_t buffer[] =
{
0b10110000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5,
0xBE, 0xDE, 0, 3, 0b00010000, 0xFF, 0b00100001, 0xFF,
0xFF, 0, 0, 0b00110011,
0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
size_t len = 40;
RtpPacket* packet = RtpPacket::Parse(buffer, len);
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->GetPayloadType() == 1);
REQUIRE(packet->GetSequenceNumber() == 8);
REQUIRE(packet->GetTimestamp() == 4);
REQUIRE(packet->GetSsrc() == 5);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 12);
REQUIRE(packet->HasOneByteExtensions());
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 8);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetSize() == 40);
auto* payload = packet->GetPayload();
REQUIRE(payload[0] == 0x00);
REQUIRE(payload[1] == 0x01);
REQUIRE(payload[2] == 0x02);
REQUIRE(payload[3] == 0x03);
REQUIRE(payload[4] == 0x04);
REQUIRE(payload[5] == 0x05);
REQUIRE(payload[6] == 0x06);
REQUIRE(payload[7] == 0x07);
packet->ShiftPayload(0, 2, true);
REQUIRE(packet->GetPayloadLength() == 10);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetSize() == 42);
REQUIRE(payload[2] == 0x00);
REQUIRE(payload[3] == 0x01);
REQUIRE(payload[4] == 0x02);
REQUIRE(payload[5] == 0x03);
REQUIRE(payload[6] == 0x04);
REQUIRE(payload[7] == 0x05);
REQUIRE(payload[8] == 0x06);
REQUIRE(payload[9] == 0x07);
packet->ShiftPayload(0, 2, false);
REQUIRE(packet->GetPayloadLength() == 8);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetSize() == 40);
REQUIRE(payload[0] == 0x00);
REQUIRE(payload[1] == 0x01);
REQUIRE(payload[2] == 0x02);
REQUIRE(payload[3] == 0x03);
REQUIRE(payload[4] == 0x04);
REQUIRE(payload[5] == 0x05);
REQUIRE(payload[6] == 0x06);
REQUIRE(payload[7] == 0x07);
packet->SetPayloadLength(14);
REQUIRE(packet->GetPayloadLength() == 16);
REQUIRE(packet->GetPayloadPadding() == 0);
REQUIRE(packet->GetSize() == 44);
packet->ShiftPayload(4, 4, true);
REQUIRE(packet->GetPayloadLength() == 20);
REQUIRE(packet->GetPayloadPadding() == 0);
REQUIRE(packet->GetSize() == 48);
REQUIRE(payload[0] == 0x00);
REQUIRE(payload[1] == 0x01);
REQUIRE(payload[2] == 0x02);
REQUIRE(payload[3] == 0x03);
REQUIRE(payload[8] == 0x04);
REQUIRE(payload[9] == 0x05);
REQUIRE(payload[10] == 0x06);
REQUIRE(payload[11] == 0x07);
packet->SetPayloadLength(1000);
REQUIRE(packet->GetPayloadLength() == 1000);
REQUIRE(packet->GetPayloadPadding() == 0);
REQUIRE(packet->GetSize() == 1028);
delete packet;
}
SECTION("set One-Byte header extensions")
{
uint8_t buffer[] =
{
0b10100000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5,
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xAA, 0xBB, 0xCC,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
RtpPacket* packet = RtpPacket::Parse(buffer, 28);
std::vector<RTC::RtpPacket::GenericExtension> extensions;
uint8_t extenLen;
uint8_t* extenValue;
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->GetSize() == 28);
REQUIRE(packet->HasHeaderExtension() == false);
REQUIRE(packet->GetHeaderExtensionId() == 0);
REQUIRE(packet->GetHeaderExtensionLength() == 0);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
extensions.clear();
packet->SetExtensions(1, extensions);
REQUIRE(packet->GetSize() == 32);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 0);
REQUIRE(packet->HasOneByteExtensions() == true);
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
extensions.clear();
uint8_t value1[] = { 0x01, 0x02, 0x03, 0x04 };
extensions.emplace_back(
0, 4, value1 );
extensions.emplace_back(
15, 4, value1 );
extensions.emplace_back(
22, 4, value1 );
extensions.emplace_back(
1, 4, value1 );
uint8_t value2[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11 };
extensions.emplace_back(
2, 11, value2 );
packet->SetExtensions(1, extensions);
REQUIRE(packet->GetSize() == 52); REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 20); REQUIRE(packet->HasOneByteExtensions() == true);
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
REQUIRE(packet->GetExtension(0, extenLen) == nullptr);
REQUIRE(packet->HasExtension(0) == false);
REQUIRE(packet->GetExtension(15, extenLen) == nullptr);
REQUIRE(packet->HasExtension(15) == false);
REQUIRE(packet->GetExtension(22, extenLen) == nullptr);
REQUIRE(packet->HasExtension(22) == false);
REQUIRE(packet->GetExtension(1, extenLen));
REQUIRE(packet->HasExtension(1) == true);
REQUIRE(extenLen == 4);
REQUIRE(packet->GetExtension(2, extenLen));
REQUIRE(packet->HasExtension(2) == true);
REQUIRE(extenLen == 11);
extensions.clear();
uint8_t value3[] = { 0x01, 0x02, 0x03, 0x04 };
extensions.emplace_back(
14, 4, value3 );
packet->SetExtensions(1, extensions);
REQUIRE(packet->GetSize() == 40);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 8); REQUIRE(packet->HasOneByteExtensions() == true);
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
REQUIRE(packet->GetExtension(1, extenLen) == nullptr);
REQUIRE(packet->HasExtension(1) == false);
REQUIRE(packet->GetExtension(2, extenLen) == nullptr);
REQUIRE(packet->HasExtension(2) == false);
REQUIRE((extenValue = packet->GetExtension(14, extenLen)));
REQUIRE(packet->HasExtension(14) == true);
REQUIRE(extenLen == 4);
REQUIRE(extenValue[0] == 0x01);
REQUIRE(extenValue[1] == 0x02);
REQUIRE(extenValue[2] == 0x03);
REQUIRE(extenValue[3] == 0x04);
REQUIRE(packet->SetExtensionLength(14, 3) == true);
REQUIRE((extenValue = packet->GetExtension(14, extenLen)));
REQUIRE(packet->HasExtension(14) == true);
REQUIRE(extenLen == 3);
REQUIRE(extenValue[0] == 0x01);
REQUIRE(extenValue[1] == 0x02);
REQUIRE(extenValue[2] == 0x03);
REQUIRE(extenValue[3] == 0x00);
delete packet;
}
SECTION("set Two-Bytes header extensions")
{
uint8_t buffer[] =
{
0b10100000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5,
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xAA, 0xBB, 0xCC,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
RtpPacket* packet = RtpPacket::Parse(buffer, 28);
std::vector<RTC::RtpPacket::GenericExtension> extensions;
uint8_t extenLen;
uint8_t* extenValue;
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->GetSize() == 28);
REQUIRE(packet->HasHeaderExtension() == false);
REQUIRE(packet->GetHeaderExtensionId() == 0);
REQUIRE(packet->GetHeaderExtensionLength() == 0);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
extensions.clear();
packet->SetExtensions(2, extensions);
REQUIRE(packet->GetSize() == 32);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetHeaderExtensionId() == 0b0001000000000000);
REQUIRE(packet->GetHeaderExtensionLength() == 0);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions() == true);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
extensions.clear();
uint8_t value1[] = { 0x01, 0x02, 0x03, 0x04 };
extensions.emplace_back(
0, 4, value1 );
extensions.emplace_back(
1, 4, value1 );
uint8_t value2[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11 };
extensions.emplace_back(
22, 11, value2 );
packet->SetExtensions(2, extensions);
REQUIRE(packet->GetSize() == 52); REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetHeaderExtensionId() == 0b0001000000000000);
REQUIRE(packet->GetHeaderExtensionLength() == 20); REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions() == true);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
REQUIRE(packet->GetExtension(0, extenLen) == nullptr);
REQUIRE(packet->HasExtension(0) == false);
REQUIRE((extenValue = packet->GetExtension(1, extenLen)));
REQUIRE(packet->HasExtension(1) == true);
REQUIRE(extenLen == 4);
REQUIRE(extenValue[0] == 0x01);
REQUIRE(extenValue[1] == 0x02);
REQUIRE(extenValue[2] == 0x03);
REQUIRE(extenValue[3] == 0x04);
REQUIRE(packet->SetExtensionLength(1, 2) == true);
REQUIRE((extenValue = packet->GetExtension(1, extenLen)));
REQUIRE(packet->HasExtension(1) == true);
REQUIRE(extenLen == 2);
REQUIRE(extenValue[0] == 0x01);
REQUIRE(extenValue[1] == 0x02);
REQUIRE(extenValue[2] == 0x00);
REQUIRE(extenValue[3] == 0x00);
REQUIRE(packet->GetExtension(22, extenLen));
REQUIRE(packet->HasExtension(22) == true);
REQUIRE(extenLen == 11);
extensions.clear();
uint8_t value3[] = { 0x01, 0x02, 0x03, 0x04 };
extensions.emplace_back(
24, 4, value3 );
packet->SetExtensions(2, extensions);
REQUIRE(packet->GetSize() == 40);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetHeaderExtensionId() == 0b0001000000000000);
REQUIRE(packet->GetHeaderExtensionLength() == 8);
REQUIRE(packet->HasOneByteExtensions() == false);
REQUIRE(packet->HasTwoBytesExtensions() == true);
REQUIRE(packet->GetPayloadLength() == 12);
REQUIRE(packet->GetPayloadPadding() == 4);
REQUIRE(packet->GetPayload()[0] == 0x11);
REQUIRE(packet->GetPayload()[packet->GetPayloadLength() - 1] == 0xCC);
REQUIRE(packet->GetExtension(1, extenLen) == nullptr);
REQUIRE(packet->HasExtension(1) == false);
REQUIRE(packet->GetExtension(22, extenLen) == nullptr);
REQUIRE(packet->HasExtension(22) == false);
REQUIRE(packet->GetExtension(24, extenLen));
REQUIRE(packet->HasExtension(24) == true);
REQUIRE(extenLen == 4);
delete packet;
}
SECTION("read frame-marking extension")
{
uint8_t buffer[] =
{
0b10010000, 0b00000001, 0, 8,
0, 0, 0, 4,
0, 0, 0, 5,
0xBE, 0xDE, 0, 1, 0b00110010, 0b10101011, 1, 5,
1, 2, 3, 4
};
RtpPacket* packet = RtpPacket::Parse(buffer, sizeof(buffer));
if (!packet)
FAIL("not a RTP packet");
REQUIRE(packet->HasMarker() == false);
REQUIRE(packet->HasHeaderExtension() == true);
REQUIRE(packet->GetPayloadType() == 1);
REQUIRE(packet->GetSequenceNumber() == 8);
REQUIRE(packet->GetTimestamp() == 4);
REQUIRE(packet->GetSsrc() == 5);
REQUIRE(packet->GetHeaderExtensionId() == 0xBEDE);
REQUIRE(packet->GetHeaderExtensionLength() == 4);
REQUIRE(packet->HasOneByteExtensions());
REQUIRE(packet->HasTwoBytesExtensions() == false);
REQUIRE(packet->GetPayloadLength() == 4);
packet->SetFrameMarkingExtensionId(3);
RtpPacket::FrameMarking* frameMarking;
uint8_t frameMarkingLen;
REQUIRE(packet->ReadFrameMarking(&frameMarking, frameMarkingLen) == true);
REQUIRE(frameMarkingLen == 3);
REQUIRE(frameMarking->start == 1);
REQUIRE(frameMarking->end == 0);
REQUIRE(frameMarking->independent == 1);
REQUIRE(frameMarking->discardable == 0);
REQUIRE(frameMarking->base == 1);
REQUIRE(frameMarking->tid == 3);
REQUIRE(frameMarking->lid == 1);
REQUIRE(frameMarking->tl0picidx == 5);
delete packet;
}
}