1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00
srs/trunk/src/utest/srs_utest_kernel2.cpp
Winlin 5a420ece3b
GB28181: Support GB28181-2016 protocol. v5.0.74 (#3201)
01. Support GB config as StreamCaster.
02. Support disable GB by --gb28181=off.
03. Add utests for SIP examples.
04. Wireshark plugin to decode TCP/9000 as rtp.rfc4571
05. Support MPEGPS program stream codec.
06. Add utest for PS stream codec.
07. Decode MPEGPS packet stream.
08. Carry RTP and PS packet as helper in PS message.
09. Support recover from error mode.
10. Support process by a pack of PS/TS messages.
11. Add statistic for recovered and msgs dropped.
12. Recover from err position fastly.
13. Define state machine for GB session.
14. Bind context to GB session.
15. Re-invite when media disconnected.
16. Update GitHub actions with GB28181.
17. Support parse CANDIDATE by env or pip.
18. Support mux GB28181 to RTMP.
19. Support regression test by srs-bench.
2022-10-06 17:40:58 +08:00

315 lines
14 KiB
C++

//
// Copyright (c) 2013-2022 The SRS Authors
//
// SPDX-License-Identifier: MIT or MulanPSL-2.0
//
#include <srs_utest_kernel2.hpp>
#include <srs_kernel_ps.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_rtc_rtcp.hpp>
#include <srs_app_gb28181.hpp>
VOID TEST(KernelPSTest, PsPacketDecodeNormal)
{
srs_error_t err = srs_success;
MockPsHandler handler;
SrsPsContext context;
// Payload of GB28181 camera PS stream, the first packet:
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=0, Time=0
if (true) {
SrsRtpPacket rtp;
if (true) {
string raw = string(
"\x80\x60\x00\x00\x00\x00\x00\x00\x0b\xeb\xdf\xa1\x00\x00\x01\xba" \
"\x44\x68\x6e\x4c\x94\x01\x01\x30\x13\xfe\xff\xff\x00\x00\xa0\x05" \
"\x00\x00\x01\xbb\x00\x12\x80\x98\x09\x04\xe1\x7f\xe0\xe0\x80\xc0" \
"\xc0\x08\xbd\xe0\x80\xbf\xe0\x80\x00\x00\x01\xbc\x00\x5e\xfc\xff" \
"\x00\x24\x40\x0e\x48\x4b\x01\x00\x16\x9b\xa5\x22\x2e\xf7\x00\xff" \
"\xff\xff\x41\x12\x48\x4b\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09" \
"\x0a\x0b\x0c\x0d\x0e\x0f\x00\x30\x1b\xe0\x00\x1c\x42\x0e\x07\x10" \
"\x10\xea\x02\x80\x01\xe0\x11\x30\x00\x00\x1c\x20\x2a\x0a\x7f\xff" \
"\x00\x00\x07\x08\x1f\xfe\x50\x3c\x0f\xc0\x00\x0c\x43\x0a\x00\x90" \
"\xfe\x02\xb1\x13\x01\xf4\x03\xff\xcb\x85\x54\xb9\x00\x00\x01\xe0" \
"\x00\x26\x8c\x80\x07\x21\x1a\x1b\x93\x25\xff\xfc\x00\x00\x00\x01" \
"\x67\x4d\x00\x1e\x9d\xa8\x28\x0f\x69\xb8\x08\x08\x0a\x00\x00\x03" \
"\x00\x02\x00\x00\x03\x00\x65\x08\x00\x00\x01\xe0\x00\x0e\x8c\x00" \
"\x03\xff\xff\xfc\x00\x00\x00\x01\x68\xee\x3c\x80\x00\x00\x01\xe0" \
"\x00\x0e\x8c\x00\x02\xff\xfc\x00\x00\x00\x01\x06\xe5\x01\xba\x80" \
"\x00\x00\x01\xe0\x35\x62\x8c\x00\x02\xff\xf8\x00\x00\x00\x01\x65", 256) + string(1156, 'x');
SrsBuffer b((char*)raw.data(), raw.length());
HELPER_ASSERT_SUCCESS(rtp.decode(&b));
}
SrsRtpRawPayload* rtp_raw = dynamic_cast<SrsRtpRawPayload*>(rtp.payload());
SrsBuffer b((char*)rtp_raw->payload, rtp_raw->nn_payload);
// There should be three video messages.
HELPER_ASSERT_SUCCESS(context.decode(&b, &handler));
EXPECT_EQ(3, handler.msgs_.size());
}
// We use the first packet bytes to mock the RTP packet seq 1 to 8.
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=1, Time=0
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=2, Time=0
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=3, Time=0
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=4, Time=0
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=5, Time=0
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=6, Time=0
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=7, Time=0
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=8, Time=0
for (int i = 0; i < 8; i++) {
SrsRtpPacket rtp;
if (true) {
string raw = string("\x80\x60\x00\x01\x00\x00\x00\x00\x0b\xeb\xdf\xa1", 12) + string(1400, 'x');
SrsBuffer b((char*)raw.data(), raw.length());
HELPER_ASSERT_SUCCESS(rtp.decode(&b));
}
SrsRtpRawPayload* rtp_raw = dynamic_cast<SrsRtpRawPayload*>(rtp.payload());
SrsBuffer b((char*)rtp_raw->payload, rtp_raw->nn_payload);
// Bytes continuity for the large video frame, got nothing message yet.
HELPER_ASSERT_SUCCESS(context.decode(&b, handler.clear()));
EXPECT_EQ(0, handler.msgs_.size());
}
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=9, Time=0
if (true) {
SrsRtpPacket rtp;
if (true) {
string raw = string("\x80\x60\x00\x09\x00\x00\x00\x00\x0b\xeb\xdf\xa1", 12) + string(1300, 'x')
+ string("\x00\x00\x01\xbd\x00\x6a\x8c\x80\x07\x21\x1a\x1b\x93\x25\xff\xf8" \
"\x00\x02\x00\x17\x00\x01\x80\x00\x00\xff\xa0\x05\xe0\xf1\xf0\x50" \
"\x18\x52\xd6\x5c\xa2\x78\x90\x23\xf9\xf6\x64\xba\xc7\x90\x5e\xd3" \
"\x80\x2f\x29\xad\x06\xee\x14\x62\xec\x6f\x77\xaa\x71\x80\xb3\x50" \
"\xb8\xd1\x85\x7f\x44\x30\x4f\x44\xfd\xcd\x21\xe6\x55\x36\x08\x6c" \
"\xb8\xd1\x85\x7f\x44\x30\x4f\x44\xfd\xcd\x21\xe6\x55\x36\x08\x6c" \
"\xc9\xf6\x5c\x74", 100);
SrsBuffer b((char*)raw.data(), raw.length());
HELPER_ASSERT_SUCCESS(rtp.decode(&b));
}
SrsRtpRawPayload* rtp_raw = dynamic_cast<SrsRtpRawPayload*>(rtp.payload());
SrsBuffer b((char*)rtp_raw->payload, rtp_raw->nn_payload);
// There should be one large video message, might be an I frame.
HELPER_ASSERT_SUCCESS(context.decode(&b, handler.clear()));
EXPECT_EQ(1, handler.msgs_.size());
}
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=10, Time=0
if (true) {
SrsRtpPacket rtp;
if (true) {
string raw("\x80\x60\x00\x0a\x00\x00\x00\x00\x0b\xeb\xdf\xa1" \
"\x57\xb3\xa3\xbc\x16\x2c\x3c\x9e\x69\x89\x48\xa4", 24);
SrsBuffer b((char*)raw.data(), raw.length());
HELPER_ASSERT_SUCCESS(rtp.decode(&b));
}
SrsRtpRawPayload* rtp_raw = dynamic_cast<SrsRtpRawPayload*>(rtp.payload());
SrsBuffer b((char*)rtp_raw->payload, rtp_raw->nn_payload);
// There should be a message of private stream, we ignore it, so we won't get it in callback.
HELPER_ASSERT_SUCCESS(context.decode(&b, handler.clear()));
EXPECT_EQ(0, handler.msgs_.size());
}
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=11, Time=3600
if (true) {
SrsRtpPacket rtp;
if (true) {
string raw = string("\x80\x60\x00\x0b\x00\x00\x0e\x10\x0b\xeb\xdf\xa1", 12)
+ string("\x00\x00\x01\xc0" \
"\x00\x82\x8c\x80\x09\x21\x1a\x1b\xa3\x51\xff\xff\xff\xf8\xff\xf9" \
"\x50\x40\x0e\xdf\xfc\x01\x2c\x2e\x84\x28\x23\x0a\x85\x82\xa2\x40" \
"\x90\x50\x2c\x14\x0b\x05\x42\x41\x30\x90\x44\x28\x16\x08\x84\x82", 52)
+ string(84, 'x');
SrsBuffer b((char*)raw.data(), raw.length());
HELPER_ASSERT_SUCCESS(rtp.decode(&b));
}
SrsRtpRawPayload* rtp_raw = dynamic_cast<SrsRtpRawPayload*>(rtp.payload());
SrsBuffer b((char*)rtp_raw->payload, rtp_raw->nn_payload);
// There should be one audio message.
HELPER_ASSERT_SUCCESS(context.decode(&b, handler.clear()));
EXPECT_EQ(1, handler.msgs_.size());
}
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=12, Time=3600
if (true) {
SrsRtpPacket rtp;
if (true) {
string raw = string("\x80\x60\x00\x0c\x00\x00\x0e\x10\x0b\xeb\xdf\xa1", 12)
+ string("\x00\x00\x01\xc0" \
"\x00\x8a\x8c\x80\x09\x21\x1a\x1b\xb3\x7d\xff\xff\xff\xf8\xff\xf9" \
"\x50\x40\x0f\xdf\xfc\x01\x2c\x2e\x88\x2a\x13\x0a\x09\x82\x41\x10" \
"\x90\x58\x26\x14\x13\x05\x02\xc2\x10\xa0\x58\x4a\x14\x0a\x85\x02", 52)
+ string(92, 'x');
SrsBuffer b((char*)raw.data(), raw.length());
HELPER_ASSERT_SUCCESS(rtp.decode(&b));
}
SrsRtpRawPayload* rtp_raw = dynamic_cast<SrsRtpRawPayload*>(rtp.payload());
SrsBuffer b((char*)rtp_raw->payload, rtp_raw->nn_payload);
// There should be another audio message.
HELPER_ASSERT_SUCCESS(context.decode(&b, handler.clear()));
EXPECT_EQ(1, handler.msgs_.size());
}
// PT=DynamicRTP-Type-96, SSRC=0xBEBDFA1, Seq=13, Time=3600
if (true) {
SrsRtpPacket rtp;
if (true) {
string raw = string("\x80\x60\x00\x0d\x00\x00\x0e\x10\x0b\xeb\xdf\xa1", 12)
+ string("\x00\x00\x01\xba" \
"\x44\x68\x6e\xbd\x14\x01\x01\x30\x13\xfe\xff\xff\x00\x00\xa0\x06" \
"\x00\x00\x01\xe0\x03\x4a\x8c\x80\x08\x21\x1a\x1b\xaf\x45\xff\xff" \
"\xf8\x00\x00\x00\x01\x61\xe0\x08\xbf\x3c\xb6\x63\x68\x4b\x7f\xea", 52)
+ string(816, 'x');
SrsBuffer b((char*)raw.data(), raw.length());
HELPER_ASSERT_SUCCESS(rtp.decode(&b));
}
SrsRtpRawPayload* rtp_raw = dynamic_cast<SrsRtpRawPayload*>(rtp.payload());
SrsBuffer b((char*)rtp_raw->payload, rtp_raw->nn_payload);
// There should be another audio message.
HELPER_ASSERT_SUCCESS(context.decode(&b, handler.clear()));
EXPECT_EQ(1, handler.msgs_.size());
}
}
VOID TEST(KernelPSTest, PsPacketHeaderClockDecode)
{
srs_error_t err = srs_success;
SrsPsContext context;
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x44\x68\x6e\x4c\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x00686c992, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x64\x68\x6e\x4c\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x10686c992, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\x68\x6e\x4c\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18686c992, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe8\x6e\x4c\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e86c992, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\x6e\x4c\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e96c992, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\x4c\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9ec992, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xcc\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9ed992, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdc\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edb92, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdd\x94\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edbb2, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdd\x9c\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edbb3, pkt.system_clock_reference_base_);
EXPECT_EQ(0, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdd\x9e\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edbb3, pkt.system_clock_reference_base_);
EXPECT_EQ(0x100, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdd\x9f\x01"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edbb3, pkt.system_clock_reference_base_);
EXPECT_EQ(0x180, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdd\x9f\x11"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edbb3, pkt.system_clock_reference_base_);
EXPECT_EQ(0x188, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdd\x9f\x19"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edbb3, pkt.system_clock_reference_base_);
EXPECT_EQ(0x18c, pkt.system_clock_reference_extension_);
}
if(true) {
SrsPsPacket pkt(&context);
SrsBuffer b((char*)"\x00\x00\x01\xba"/*start*/ "\x74\xe9\xee\xdd\x9f\x1b"/*clock*/ "\x01\x30\x13\xf8"/*mux*/, 14);
HELPER_ASSERT_SUCCESS(pkt.decode(&b));
EXPECT_EQ(0x18e9edbb3, pkt.system_clock_reference_base_);
EXPECT_EQ(0x18d, pkt.system_clock_reference_extension_);
}
}