mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
3738 lines
160 KiB
C++
3738 lines
160 KiB
C++
//
|
|
// Copyright (c) 2013-2023 The SRS Authors
|
|
//
|
|
// SPDX-License-Identifier: MIT or MulanPSL-2.0
|
|
//
|
|
#include <srs_utest_protocol2.hpp>
|
|
|
|
using namespace std;
|
|
|
|
#include <srs_kernel_error.hpp>
|
|
#include <srs_core_autofree.hpp>
|
|
#include <srs_protocol_utility.hpp>
|
|
#include <srs_protocol_rtmp_msg_array.hpp>
|
|
#include <srs_protocol_rtmp_stack.hpp>
|
|
#include <srs_kernel_utility.hpp>
|
|
#include <srs_app_st.hpp>
|
|
#include <srs_protocol_amf0.hpp>
|
|
#include <srs_protocol_rtmp_stack.hpp>
|
|
#include <srs_protocol_http_conn.hpp>
|
|
#include <srs_protocol_protobuf.hpp>
|
|
#include <srs_kernel_buffer.hpp>
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
* the continue chunks use fmt=1, last video with fmt=1 header
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x20, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x40, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
* the continue chunks use fmt=1, last video with fmt=1 header,
|
|
* last video changed length
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11Length)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x20, // length, 288
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x20, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x40, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
* the continue chunks use fmt=1, last video with fmt=2 header
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x83,
|
|
0x00, 0x00, 0x20, // timestamp
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x40, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
* the continue chunks use fmt=1, last video with fmt=2 header,
|
|
* last video changed length
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12Length)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x20, // length, 288
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x83,
|
|
0x00, 0x00, 0x20, // timestamp
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
EXPECT_EQ(0x110, msg->header.payload_length);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
EXPECT_EQ(0x120, msg->header.payload_length);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x40, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
EXPECT_EQ(0x120, msg->header.payload_length);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, with extended timestamp.
|
|
* small timestamp < 0xffffff
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0xff, 0xff, 0xff, // timestamp
|
|
0x00, 0x00, 0x04, // length
|
|
0x09, // message_type
|
|
0x00, 0x00, 0x00, 0x00, // stream_id
|
|
0x00, 0x00, 0x00, 0x10, // extended timestamp
|
|
// msg payload start
|
|
0x00, 0x00, 0x07, 0x63
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
}
|
|
|
|
/**
|
|
* recv video, with extended timestamp.
|
|
* big timestamp > 0xffffff
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage2)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0xff, 0xff, 0xff, // timestamp
|
|
0x00, 0x00, 0x04, // length
|
|
0x09, // message_type
|
|
0x00, 0x00, 0x00, 0x00, // stream_id
|
|
0x7f, 0x01, 0x02, 0x03, // extended timestamp
|
|
// msg payload start
|
|
0x00, 0x00, 0x07, 0x63
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x7f010203, msg->header.timestamp);
|
|
}
|
|
|
|
/**
|
|
* recv video, with extended timestamp.
|
|
* always use 31bits timestamp.
|
|
*/
|
|
// always use 31bits timestamp, for some server may use 32bits extended timestamp.
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage3)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0xff, 0xff, 0xff, // timestamp
|
|
0x00, 0x00, 0x04, // length
|
|
0x09, // message_type
|
|
0x00, 0x00, 0x00, 0x00, // stream_id
|
|
0xff, 0x01, 0x02, 0x03, // extended timestamp
|
|
// msg payload start
|
|
0x00, 0x00, 0x07, 0x63
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
// always use 31bits timestamp
|
|
EXPECT_EQ(0x7f010203, msg->header.timestamp);
|
|
}
|
|
|
|
/**
|
|
* recv video, with extended timestamp, in 2 chunks packet.
|
|
* always send extended timestamp in 0xCX chunk packets.
|
|
*/
|
|
/**
|
|
* RTMP specification and ffmpeg/librtmp is false,
|
|
* but, adobe changed the specification, so flash/FMLE/FMS always true.
|
|
* default to true to support flash/FMLE/FMS.
|
|
*
|
|
* ffmpeg/librtmp may donot send this filed, need to detect the value.
|
|
* @see also: http://blog.csdn.net/win_lin/article/details/13363699
|
|
* compare to the chunk timestamp, which is set by chunk message header
|
|
* type 0,1 or 2.
|
|
*
|
|
* @remark, nginx send the extended-timestamp in sequence-header,
|
|
* and timestamp delta in continue C1 chunks, and so compatible with ffmpeg,
|
|
* that is, there is no continue chunks and extended-timestamp in nginx-rtmp.
|
|
*
|
|
* @remark, srs always send the extended-timestamp, to keep simple,
|
|
* and compatible with adobe products.
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// video message
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0xff, 0xff, 0xff, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x00, 0x00, 0x00, 0x00, // stream_id
|
|
0x00, 0x01, 0x02, 0x03, // extended timestamp
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c,
|
|
// chunk #2
|
|
0xC3,
|
|
0x00, 0x01, 0x02, 0x03, // extended timestamp
|
|
/*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// chunk #2
|
|
0xC3,
|
|
0x00, 0x01, 0x02, 0x03, // extended timestamp
|
|
/*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
// 0xCX with extended timestamp.
|
|
EXPECT_EQ(0x00010203, msg->header.timestamp);
|
|
}
|
|
|
|
/**
|
|
* recv video, with extended timestamp, in 2 chunks packet.
|
|
* never send extended timestamp in 0xCX chunk packets.
|
|
*/
|
|
// FFMPEG/librtmp, RTMP specification standard protocol.
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk2)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// video message
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0xff, 0xff, 0xff, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x00, 0x00, 0x00, 0x00, // stream_id
|
|
0x00, 0x01, 0x02, 0x03, // extended timestamp
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c,
|
|
// chunk #2
|
|
0xC3,
|
|
/*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// chunk #2
|
|
0xC3,
|
|
/*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
// 0xCX without extended timestamp.
|
|
EXPECT_EQ(0x00010203, msg->header.timestamp);
|
|
}
|
|
|
|
/**
|
|
* a video message, in 2 chunks packet.
|
|
* use 1B chunk header, min chunk id is 2.
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BMin)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// video message
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x02,
|
|
0x00, 0x00, 0x00, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x00, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c,
|
|
// chunk #2
|
|
0xC2, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// chunk #2
|
|
0xC2, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
// 1B cid(6bits), min is 2
|
|
EXPECT_EQ(0x02, msg->header.perfer_cid);
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, Connections)
|
|
{
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsKbps* kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsKbps, kbps);
|
|
|
|
SrsNetworkDelta* delta = new SrsNetworkDelta();
|
|
SrsAutoFree(SrsNetworkDelta, delta);
|
|
delta->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(30 * 100 * 1000)->set_out(30 * 100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 300s.
|
|
clock->set_clock(330 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(330 * 100 * 1000)->set_out(330 * 100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_5m());
|
|
}
|
|
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsKbps* kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsKbps, kbps);
|
|
|
|
SrsNetworkDelta* delta = new SrsNetworkDelta();
|
|
SrsAutoFree(SrsNetworkDelta, delta);
|
|
delta->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(30 * 100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 300s.
|
|
clock->set_clock(330 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(330 * 100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
}
|
|
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsKbps* kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsKbps, kbps);
|
|
|
|
SrsNetworkDelta* delta = new SrsNetworkDelta();
|
|
SrsAutoFree(SrsNetworkDelta, delta);
|
|
delta->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_out(30 * 100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 300s.
|
|
clock->set_clock(330 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_out(330 * 100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_5m());
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, Delta)
|
|
{
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkDelta* delta = new SrsNetworkDelta();
|
|
SrsAutoFree(SrsNetworkDelta, delta);
|
|
delta->set_io(io, io);
|
|
|
|
// No data.
|
|
int64_t in, out;
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(0, in);
|
|
EXPECT_EQ(0, out);
|
|
|
|
// 800kb.
|
|
io->set_in(100 * 1000)->set_out(100 * 1000);
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(100 * 1000, in);
|
|
EXPECT_EQ(100 * 1000, out);
|
|
|
|
// No data.
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(0, in);
|
|
EXPECT_EQ(0, out);
|
|
}
|
|
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkDelta* delta = new SrsNetworkDelta();
|
|
SrsAutoFree(SrsNetworkDelta, delta);
|
|
delta->set_io(io, io);
|
|
|
|
// No data.
|
|
int64_t in, out;
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(0, in);
|
|
EXPECT_EQ(0, out);
|
|
|
|
// 800kb.
|
|
io->set_in(100 * 1000)->set_out(100 * 1000);
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(100 * 1000, in);
|
|
EXPECT_EQ(100 * 1000, out);
|
|
|
|
// Kbps without io, gather delta.
|
|
SrsKbps* kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsKbps, kbps);
|
|
|
|
// No data, 0kbps.
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
kbps->add_delta(30 * in, 30 * out);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, RAWStatistic)
|
|
{
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkDelta* delta = new SrsNetworkDelta();
|
|
SrsAutoFree(SrsNetworkDelta, delta);
|
|
delta->set_io(io, io);
|
|
|
|
SrsKbps* kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsKbps, kbps);
|
|
|
|
// No data, 0kbps.
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_out(30 * 100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
}
|
|
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
|
|
SrsKbps* kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsKbps, kbps);
|
|
|
|
// No io, no data.
|
|
EXPECT_EQ(0, kbps->get_recv_bytes());
|
|
EXPECT_EQ(0, kbps->get_send_bytes());
|
|
|
|
// With io, zero data.
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkDelta* delta = new SrsNetworkDelta();
|
|
SrsAutoFree(SrsNetworkDelta, delta);
|
|
delta->set_io(io, io);
|
|
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
EXPECT_EQ(0, kbps->get_recv_bytes());
|
|
EXPECT_EQ(0, kbps->get_send_bytes());
|
|
|
|
// With io with data.
|
|
io->set_in(100 * 1000)->set_out(100 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
EXPECT_EQ(100 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(100 * 1000, kbps->get_send_bytes());
|
|
|
|
// No io, cached data.
|
|
delta->set_io(NULL, NULL);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
EXPECT_EQ(100 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(100 * 1000, kbps->get_send_bytes());
|
|
|
|
// Use the same IO, but as a fresh io.
|
|
delta->set_io(io, io);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
EXPECT_EQ(200 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(200 * 1000, kbps->get_send_bytes());
|
|
|
|
io->set_in(150 * 1000)->set_out(150 * 1000);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
EXPECT_EQ(250 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(250 * 1000, kbps->get_send_bytes());
|
|
|
|
// No io, cached data.
|
|
delta->set_io(NULL, NULL);
|
|
kbps->add_delta(delta);
|
|
kbps->sample();
|
|
EXPECT_EQ(250 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(250 * 1000, kbps->get_send_bytes());
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, WriteLargeIOVs)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
iovec iovs[1];
|
|
iovs[0].iov_base = (char*)"Hello";
|
|
iovs[0].iov_len = 5;
|
|
|
|
MockBufferIO io;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(srs_write_large_iovs(&io, iovs, 1, &nn));
|
|
EXPECT_EQ(5, nn);
|
|
EXPECT_EQ(5, io.sbytes);
|
|
}
|
|
|
|
if (true) {
|
|
iovec iovs[1024];
|
|
int nn_iovs = (int)(sizeof(iovs)/sizeof(iovec));
|
|
for (int i = 0; i < nn_iovs; i++) {
|
|
iovs[i].iov_base = (char*)"Hello";
|
|
iovs[i].iov_len = 5;
|
|
}
|
|
|
|
MockBufferIO io;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(srs_write_large_iovs(&io, iovs, nn_iovs, &nn));
|
|
EXPECT_EQ(5 * nn_iovs, nn);
|
|
EXPECT_EQ(5 * nn_iovs, io.sbytes);
|
|
}
|
|
|
|
if (true) {
|
|
iovec iovs[1025];
|
|
int nn_iovs = (int)(sizeof(iovs)/sizeof(iovec));
|
|
for (int i = 0; i < nn_iovs; i++) {
|
|
iovs[i].iov_base = (char*)"Hello";
|
|
iovs[i].iov_len = 5;
|
|
}
|
|
|
|
MockBufferIO io;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(srs_write_large_iovs(&io, iovs, nn_iovs, &nn));
|
|
EXPECT_EQ(5 * nn_iovs, nn);
|
|
EXPECT_EQ(5 * nn_iovs, io.sbytes);
|
|
}
|
|
|
|
if (true) {
|
|
iovec iovs[4096];
|
|
int nn_iovs = (int)(sizeof(iovs)/sizeof(iovec));
|
|
for (int i = 0; i < nn_iovs; i++) {
|
|
iovs[i].iov_base = (char*)"Hello";
|
|
iovs[i].iov_len = 5;
|
|
}
|
|
|
|
MockBufferIO io;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(srs_write_large_iovs(&io, iovs, nn_iovs, &nn));
|
|
EXPECT_EQ(5 * nn_iovs, nn);
|
|
EXPECT_EQ(5 * nn_iovs, io.sbytes);
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, ConnectionsSugar)
|
|
{
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkKbps* kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsNetworkKbps, kbps);
|
|
kbps->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(30 * 100 * 1000)->set_out(30 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 300s.
|
|
clock->set_clock(330 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(330 * 100 * 1000)->set_out(330 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_5m());
|
|
}
|
|
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkKbps* kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsNetworkKbps, kbps);
|
|
kbps->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(30 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 300s.
|
|
clock->set_clock(330 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(330 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
}
|
|
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkKbps* kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsNetworkKbps, kbps);
|
|
kbps->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_out(30 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 300s.
|
|
clock->set_clock(330 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_out(330 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_5m());
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, DeltaSugar)
|
|
{
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
// Kbps without io, gather delta.
|
|
SrsNetworkKbps* kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsNetworkKbps, kbps);
|
|
kbps->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_in(30 * 100 * 1000)->set_out(30 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(800, kbps->get_recv_kbps());
|
|
EXPECT_EQ(800, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, RAWStatisticSugar)
|
|
{
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
|
|
SrsNetworkKbps* kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsNetworkKbps, kbps);
|
|
kbps->set_io(io, io);
|
|
|
|
// No data, 0kbps.
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(0, kbps->get_send_kbps());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
|
|
// 800kbps in 30s.
|
|
clock->set_clock(30 * 1000 * SRS_UTIME_MILLISECONDS);
|
|
io->set_out(30 * 100 * 1000);
|
|
kbps->sample();
|
|
|
|
EXPECT_EQ(0, kbps->get_recv_kbps());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_recv_kbps_5m());
|
|
|
|
EXPECT_EQ(800, kbps->get_send_kbps());
|
|
EXPECT_EQ(800, kbps->get_send_kbps_30s());
|
|
EXPECT_EQ(0, kbps->get_send_kbps_5m());
|
|
}
|
|
|
|
if (true) {
|
|
MockWallClock* clock = new MockWallClock();
|
|
SrsAutoFree(MockWallClock, clock);
|
|
|
|
SrsNetworkKbps* kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsAutoFree(SrsNetworkKbps, kbps);
|
|
|
|
// No io, no data.
|
|
EXPECT_EQ(0, kbps->get_recv_bytes());
|
|
EXPECT_EQ(0, kbps->get_send_bytes());
|
|
|
|
// With io, zero data.
|
|
MockStatistic* io = new MockStatistic();
|
|
SrsAutoFree(MockStatistic, io);
|
|
kbps->set_io(io, io);
|
|
|
|
kbps->sample();
|
|
EXPECT_EQ(0, kbps->get_recv_bytes());
|
|
EXPECT_EQ(0, kbps->get_send_bytes());
|
|
|
|
// With io with data.
|
|
io->set_in(100 * 1000)->set_out(100 * 1000);
|
|
kbps->sample();
|
|
EXPECT_EQ(100 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(100 * 1000, kbps->get_send_bytes());
|
|
|
|
// No io, cached data.
|
|
kbps->set_io(NULL, NULL);
|
|
kbps->sample();
|
|
EXPECT_EQ(100 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(100 * 1000, kbps->get_send_bytes());
|
|
|
|
// Use the same IO, but as a fresh io.
|
|
kbps->set_io(io, io);
|
|
kbps->sample();
|
|
EXPECT_EQ(200 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(200 * 1000, kbps->get_send_bytes());
|
|
|
|
io->set_in(150 * 1000)->set_out(150 * 1000);
|
|
kbps->sample();
|
|
EXPECT_EQ(250 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(250 * 1000, kbps->get_send_bytes());
|
|
|
|
// No io, cached data.
|
|
kbps->set_io(NULL, NULL);
|
|
kbps->sample();
|
|
EXPECT_EQ(250 * 1000, kbps->get_recv_bytes());
|
|
EXPECT_EQ(250 * 1000, kbps->get_send_bytes());
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, StreamIdentify)
|
|
{
|
|
EXPECT_STREQ("/live/livestream", srs_generate_stream_url("", "live", "livestream").c_str());
|
|
EXPECT_STREQ("/live/livestream", srs_generate_stream_url("", "live", "livestream.flv").c_str());
|
|
EXPECT_STREQ("/live/livestream", srs_generate_stream_url("", "live", "livestream.m3u8").c_str());
|
|
EXPECT_STREQ("/live/livestream", srs_generate_stream_url("__defaultVhost__", "live", "livestream").c_str());
|
|
|
|
EXPECT_STREQ("ossrs.io/live/livestream", srs_generate_stream_url("ossrs.io", "live", "livestream").c_str());
|
|
EXPECT_STREQ("ossrs.io/live/livestream", srs_generate_stream_url("ossrs.io", "live", "livestream.flv").c_str());
|
|
EXPECT_STREQ("ossrs.io/live/livestream", srs_generate_stream_url("ossrs.io", "live", "livestream.m3u8").c_str());
|
|
}
|
|
|
|
VOID TEST(ProtocolHTTPTest, ParseHTTPMessage)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
if (true) {
|
|
MockBufferIO bio;
|
|
SrsHttpParser hp;
|
|
|
|
bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
|
|
HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
|
|
ISrsHttpMessage* req = NULL;
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
|
|
// We should read body, or next parsing message will fail.
|
|
// @see https://github.com/ossrs/srs/issues/1181
|
|
EXPECT_FALSE(req->body_reader()->eof());
|
|
srs_freep(req);
|
|
|
|
// Got new packet, notice that previous body still exists in bio.
|
|
bio.append("GET /gslb/v2/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
|
|
|
|
// Should fail because there is body which not read.
|
|
// @see https://github.com/ossrs/srs/issues/1181
|
|
HELPER_ASSERT_FAILED(hp.parse_message(&bio, &req));
|
|
srs_freep(req);
|
|
}
|
|
|
|
if (true) {
|
|
MockBufferIO bio;
|
|
SrsHttpParser hp;
|
|
|
|
bio.append("GET");
|
|
HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
|
|
// Should fail if not completed message.
|
|
ISrsHttpMessage* req = NULL;
|
|
HELPER_ASSERT_FAILED(hp.parse_message(&bio, &req));
|
|
srs_freep(req);
|
|
}
|
|
|
|
if (true) {
|
|
MockBufferIO bio;
|
|
SrsHttpParser hp;
|
|
|
|
bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
|
|
HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
|
|
ISrsHttpMessage* req = NULL;
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
|
|
char v[64] = {0};
|
|
HELPER_ASSERT_SUCCESS(req->body_reader()->read(v, sizeof(v), NULL));
|
|
EXPECT_TRUE(string("Hello") == string(v));
|
|
|
|
EXPECT_TRUE(req->body_reader()->eof());
|
|
}
|
|
|
|
if (true) {
|
|
MockBufferIO bio;
|
|
SrsHttpParser hp;
|
|
|
|
bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 0\r\n\r\n");
|
|
HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
|
|
ISrsHttpMessage* req = NULL;
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
}
|
|
|
|
if (true) {
|
|
MockBufferIO bio;
|
|
SrsHttpParser hp;
|
|
|
|
bio.append("GET /gslb/v1/versions HTTP/1.1\r\n\r\n");
|
|
HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
|
|
ISrsHttpMessage* req = NULL;
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
}
|
|
|
|
if (true) {
|
|
MockBufferIO bio;
|
|
SrsHttpParser hp;
|
|
|
|
bio.append("GET /gslb/v1/versions HTTP/1.1\r\n\r\n");
|
|
HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
|
|
ISrsHttpMessage* req = NULL;
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolProtobufTest, VarintsSize)
|
|
{
|
|
EXPECT_EQ(1, SrsProtobufVarints::sizeof_varint( 0x00));
|
|
EXPECT_EQ(1, SrsProtobufVarints::sizeof_varint( 0x70));
|
|
EXPECT_EQ(1, SrsProtobufVarints::sizeof_varint( 0x7f));
|
|
EXPECT_EQ(2, SrsProtobufVarints::sizeof_varint( 0x80));
|
|
EXPECT_EQ(2, SrsProtobufVarints::sizeof_varint( 0x3ff0));
|
|
EXPECT_EQ(2, SrsProtobufVarints::sizeof_varint( 0x3fff));
|
|
EXPECT_EQ(3, SrsProtobufVarints::sizeof_varint( 0x4000));
|
|
EXPECT_EQ(3, SrsProtobufVarints::sizeof_varint( 0x1ffff0));
|
|
EXPECT_EQ(3, SrsProtobufVarints::sizeof_varint( 0x1fffff));
|
|
EXPECT_EQ(4, SrsProtobufVarints::sizeof_varint( 0x200000));
|
|
EXPECT_EQ(4, SrsProtobufVarints::sizeof_varint( 0x0ffffff0));
|
|
EXPECT_EQ(4, SrsProtobufVarints::sizeof_varint( 0x0fffffff));
|
|
EXPECT_EQ(5, SrsProtobufVarints::sizeof_varint( 0x10000000));
|
|
EXPECT_EQ(5, SrsProtobufVarints::sizeof_varint( 0x7fffffff0));
|
|
EXPECT_EQ(5, SrsProtobufVarints::sizeof_varint( 0x7ffffffff));
|
|
EXPECT_EQ(6, SrsProtobufVarints::sizeof_varint( 0x800000000));
|
|
EXPECT_EQ(6, SrsProtobufVarints::sizeof_varint( 0x3fffffffff0));
|
|
EXPECT_EQ(6, SrsProtobufVarints::sizeof_varint( 0x3ffffffffff));
|
|
EXPECT_EQ(7, SrsProtobufVarints::sizeof_varint( 0x40000000000));
|
|
EXPECT_EQ(7, SrsProtobufVarints::sizeof_varint( 0x1fffffffffff0));
|
|
EXPECT_EQ(7, SrsProtobufVarints::sizeof_varint( 0x1ffffffffffff));
|
|
EXPECT_EQ(8, SrsProtobufVarints::sizeof_varint( 0x2000000000000));
|
|
EXPECT_EQ(8, SrsProtobufVarints::sizeof_varint( 0x0fffffffffffff0));
|
|
EXPECT_EQ(8, SrsProtobufVarints::sizeof_varint( 0x0ffffffffffffff));
|
|
EXPECT_EQ(9, SrsProtobufVarints::sizeof_varint( 0x100000000000000));
|
|
EXPECT_EQ(9, SrsProtobufVarints::sizeof_varint( 0x7ffffffffffffff0));
|
|
EXPECT_EQ(9, SrsProtobufVarints::sizeof_varint( 0x7fffffffffffffff));
|
|
EXPECT_EQ(10, SrsProtobufVarints::sizeof_varint(0x8000000000000000));
|
|
EXPECT_EQ(10, SrsProtobufVarints::sizeof_varint(0xfffffffffffffff0));
|
|
EXPECT_EQ(10, SrsProtobufVarints::sizeof_varint(0xffffffffffffffff));
|
|
}
|
|
|
|
VOID TEST(ProtocolProtobufTest, VarintsEncode)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
static char buf[128];
|
|
|
|
if (true) {
|
|
SrsBuffer b(buf, 1); uint8_t expect[] = {0x00};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 1); uint8_t expect[] = {0x70};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x70)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 1); uint8_t expect[] = {0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7f)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 2); uint8_t expect[] = {0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x80)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 2); uint8_t expect[] = {0xf0, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3ff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 2); uint8_t expect[] = {0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3fff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 3); uint8_t expect[] = {0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x4000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 3); uint8_t expect[] = {0xf0, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1ffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 3); uint8_t expect[] = {0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1fffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 4); uint8_t expect[] = {0x80, 0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x200000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 4); uint8_t expect[] = {0xf0, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 4); uint8_t expect[] = {0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xfffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 5); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x10000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 5); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7fffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 5); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7ffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 6); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x800000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 6); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3fffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 6); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3ffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 7); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x40000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 7); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1fffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 7); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1ffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 8); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x2000000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 8); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xfffffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 8); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xffffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 9); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x100000000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 9); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7ffffffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 9); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7fffffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 10); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x8000000000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 10); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xfffffffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
if (true) {
|
|
SrsBuffer b(buf, 10); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01};
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xffffffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolProtobufTest, String)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
static char buf[128];
|
|
|
|
if (true) {
|
|
EXPECT_EQ(1 + 10, SrsProtobufString::sizeof_string("HelloWorld"));
|
|
|
|
SrsBuffer b(buf, 1 + 10);
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufString::encode(&b, "HelloWorld"));
|
|
|
|
uint8_t expect[] = {0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64};
|
|
EXPECT_TRUE(srs_bytes_equals(buf, (char *) expect, sizeof(expect)));
|
|
}
|
|
|
|
if (true) {
|
|
EXPECT_EQ(1, SrsProtobufString::sizeof_string(""));
|
|
|
|
SrsBuffer b(buf, 1);
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufString::encode(&b, ""));
|
|
|
|
uint8_t expect[] = {0x00};
|
|
EXPECT_TRUE(srs_bytes_equals(buf, (char *) expect, sizeof(expect)));
|
|
}
|
|
}
|
|
|
|
class MockProtobufObject : public ISrsEncoder
|
|
{
|
|
public:
|
|
uint64_t nb_bytes() {
|
|
return 1;
|
|
}
|
|
srs_error_t encode(SrsBuffer* b) {
|
|
b->write_1bytes(0x0f);
|
|
return srs_success;
|
|
}
|
|
};
|
|
|
|
VOID TEST(ProtocolProtobufTest, FieldKey)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
static char buf[128];
|
|
|
|
EXPECT_EQ(2, SrsProtobufFieldString);
|
|
EXPECT_EQ(2, SrsProtobufFieldBytes);
|
|
EXPECT_EQ(2, SrsProtobufFieldObject);
|
|
EXPECT_EQ(2, SrsProtobufFieldLengthDelimited);
|
|
|
|
EXPECT_EQ(1, SrsProtobufKey::sizeof_key());
|
|
|
|
MockProtobufObject obj;
|
|
EXPECT_EQ(2, SrsProtobufObject::sizeof_object(&obj));
|
|
if (true) {
|
|
SrsBuffer b(buf, 2);
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufObject::encode(&b, &obj));
|
|
EXPECT_EQ(0x01, buf[0]); EXPECT_EQ(0x0f, buf[1]);
|
|
}
|
|
|
|
// Encode the field key as [ID=1, TYPE=2(Length delimited)]
|
|
if (true) {
|
|
SrsBuffer b(buf, 1);
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 1, SrsProtobufFieldLengthDelimited));
|
|
EXPECT_EQ(0x0a, buf[0]);
|
|
}
|
|
|
|
// Encode the field value as [ID=2, TYPE=2(Length delimited)]
|
|
if (true) {
|
|
SrsBuffer b(buf, 1);
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 2, SrsProtobufFieldLengthDelimited));
|
|
EXPECT_EQ(0x12, buf[0]);
|
|
}
|
|
|
|
// Encode the field time as [ID=1, TYPE=0(Varint)]
|
|
if (true) {
|
|
SrsBuffer b(buf, 1);
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 1, SrsProtobufFieldVarint));
|
|
EXPECT_EQ(0x08, buf[0]);
|
|
}
|
|
|
|
// Encode the field source as [ID=4, TYPE=2(Length delimited)]
|
|
if (true) {
|
|
SrsBuffer b(buf, 1);
|
|
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 4, SrsProtobufFieldLengthDelimited));
|
|
EXPECT_EQ(0x22, buf[0]);
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, NewDelta)
|
|
{
|
|
if (true) {
|
|
SrsEphemeralDelta ed;
|
|
|
|
ISrsKbpsDelta* delta = (ISrsKbpsDelta*)&ed;
|
|
int64_t in, out;
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(0, in);
|
|
EXPECT_EQ(0, out);
|
|
|
|
ed.add_delta(100 * 1000, 100 * 1000);
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(100 * 1000, in);
|
|
EXPECT_EQ(100 * 1000, out);
|
|
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(0, in);
|
|
EXPECT_EQ(0, out);
|
|
}
|
|
|
|
if (true) {
|
|
SrsNetworkDelta nd;
|
|
|
|
ISrsKbpsDelta* delta = (ISrsKbpsDelta*)&nd;
|
|
int64_t in, out;
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(0, in);
|
|
EXPECT_EQ(0, out);
|
|
|
|
MockStatistic ms;
|
|
ms.set_in(100 * 1000)->set_out(100*1000);
|
|
nd.set_io(&ms, &ms);
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(100 * 1000, in);
|
|
EXPECT_EQ(100 * 1000, out);
|
|
|
|
ms.add_in(10 * 1000)->add_out(10 * 1000);
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(10 * 1000, in);
|
|
EXPECT_EQ(10 * 1000, out);
|
|
|
|
delta->remark(&in, &out);
|
|
EXPECT_EQ(0, in);
|
|
EXPECT_EQ(0, out);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVMessage)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x20, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x30, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x30, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
* the continue chunks use fmt=1 header
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt1)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x30, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
* the continue chunks use fmt=2 header
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt2)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x83,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x83,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x30, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* recv video, audio, video and video, interlaced in chunks.
|
|
* the continue chunks use fmt=3 header
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt3)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
/**
|
|
* parse the message header.
|
|
* 3bytes: timestamp delta, fmt=0,1,2
|
|
* 3bytes: payload length, fmt=0,1
|
|
* 1bytes: message type, fmt=0,1
|
|
* 4bytes: stream id, fmt=0
|
|
* where:
|
|
* fmt=0, 0x0X
|
|
* fmt=1, 0x4X
|
|
* fmt=2, 0x8X
|
|
* fmt=3, 0xCX
|
|
*/
|
|
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03,
|
|
0x00, 0x00, 0x10, // timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04,
|
|
0x00, 0x00, 0x15, // timestamp
|
|
0x00, 0x00, 0x90, // length, 144
|
|
0x08, // message_type
|
|
0x01, 0x00, 0x00, 0x00, // stream_id
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0xC3,
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// audio message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC4, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#1
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0xC3,
|
|
// msg payload start
|
|
0x02, 0x00, 0x07, 0x63,
|
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
|
0x00, 0x03, 0x61, 0x70, 0x70, 0x02, 0x00, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x00, 0x08, 0x66, 0x6c,
|
|
0x61, 0x73, 0x68, 0x56, 0x65, 0x72, 0x02, 0x00, 0x0d, 0x57, 0x49, 0x4e, 0x20, 0x31, 0x32, 0x2c,
|
|
0x30, 0x2c, 0x30, 0x2c, 0x34, 0x31, 0x00, 0x06, 0x73, 0x77, 0x66, 0x55, 0x72, 0x6c, 0x02, 0x00,
|
|
0x51, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x73, 0x73, 0x72,
|
|
0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x35, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x65,
|
|
0x72, 0x73, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x72, 0x65,
|
|
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x72, 0x73, 0x5f, 0x70, 0x6c
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#2
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/ 0x61, 0x79, 0x65, 0x72,
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e,
|
|
0x32, 0x33, 0x00, 0x05, 0x74, 0x63, 0x55, 0x72, 0x6c, 0x02, 0x00, 0x14, 0x72, 0x74, 0x6d, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x76, 0x3a, 0x31, 0x39, 0x33, 0x35, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
|
0x00, 0x04, 0x66, 0x70, 0x61, 0x64, 0x01, 0x00, 0x00, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
|
|
0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x00, 0x40, 0x6d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x73, 0x00, 0x40, 0xab, 0xee,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65,
|
|
0x63, 0x73, 0x00, 0x40, 0x6f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
// video message, chunk#3
|
|
if (true) {
|
|
uint8_t data[] = {
|
|
0xC3, /*next chunk.*/
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e
|
|
};
|
|
bio.in_buffer.append((char*)data, sizeof(data));
|
|
}
|
|
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x10, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_audio());
|
|
EXPECT_EQ(0x15, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x20, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
if (true) {
|
|
SrsCommonMessage* msg = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg));
|
|
SrsAutoFree(SrsCommonMessage, msg);
|
|
EXPECT_TRUE(msg->header.is_video());
|
|
EXPECT_EQ(0x30, msg->header.timestamp);
|
|
EXPECT_EQ(0x01, msg->header.stream_id);
|
|
}
|
|
}
|
|
|
|
struct MockStage
|
|
{
|
|
http_parser parser;
|
|
const char* at;
|
|
size_t length;
|
|
|
|
MockStage(http_parser* from);
|
|
};
|
|
|
|
MockStage::MockStage(http_parser* from)
|
|
{
|
|
parser = *from;
|
|
at = NULL;
|
|
length = 0;
|
|
}
|
|
|
|
class MockParser
|
|
{
|
|
private:
|
|
http_parser_settings settings;
|
|
http_parser* parser;
|
|
size_t parsed;
|
|
public:
|
|
MockStage* message_begin;
|
|
MockStage* url;
|
|
MockStage* status;
|
|
MockStage* header_field;
|
|
MockStage* header_value;
|
|
MockStage* headers_complete;
|
|
MockStage* body;
|
|
MockStage* message_complete;
|
|
MockStage* chunk_header;
|
|
MockStage* chunk_complete;
|
|
public:
|
|
MockParser();
|
|
virtual ~MockParser();
|
|
public:
|
|
srs_error_t parse(string data);
|
|
private:
|
|
static int on_message_begin(http_parser* parser);
|
|
static int on_url(http_parser* parser, const char* at, size_t length);
|
|
static int on_status(http_parser* parser, const char* at, size_t length);
|
|
static int on_header_field(http_parser* parser, const char* at, size_t length);
|
|
static int on_header_value(http_parser* parser, const char* at, size_t length);
|
|
static int on_headers_complete(http_parser* parser);
|
|
static int on_body(http_parser* parser, const char* at, size_t length);
|
|
static int on_message_complete(http_parser* parser);
|
|
static int on_chunk_header(http_parser* parser);
|
|
static int on_chunk_complete(http_parser* parser);
|
|
};
|
|
|
|
MockParser::MockParser()
|
|
{
|
|
parser = new http_parser();
|
|
http_parser_init(parser, HTTP_REQUEST);
|
|
parser->data = (void*)this;
|
|
parsed = 0;
|
|
|
|
memset(&settings, 0, sizeof(settings));
|
|
settings.on_message_begin = on_message_begin;
|
|
settings.on_url = on_url;
|
|
settings.on_status = on_status;
|
|
settings.on_header_field = on_header_field;
|
|
settings.on_header_value = on_header_value;
|
|
settings.on_headers_complete = on_headers_complete;
|
|
settings.on_body = on_body;
|
|
settings.on_message_complete = on_message_complete;
|
|
settings.on_chunk_header = on_chunk_header;
|
|
settings.on_chunk_complete = on_chunk_complete;
|
|
|
|
message_begin = NULL;
|
|
url = NULL;
|
|
status = NULL;
|
|
header_field = NULL;
|
|
header_value = NULL;
|
|
headers_complete = NULL;
|
|
body = NULL;
|
|
message_complete = NULL;
|
|
chunk_header = NULL;
|
|
chunk_complete = NULL;
|
|
}
|
|
|
|
MockParser::~MockParser()
|
|
{
|
|
srs_freep(parser);
|
|
|
|
srs_freep(message_begin);
|
|
srs_freep(url);
|
|
srs_freep(status);
|
|
srs_freep(header_field);
|
|
srs_freep(header_value);
|
|
srs_freep(headers_complete);
|
|
srs_freep(body);
|
|
srs_freep(message_complete);
|
|
srs_freep(chunk_header);
|
|
srs_freep(chunk_complete);
|
|
}
|
|
|
|
int MockParser::on_message_begin(http_parser* parser)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->message_begin);
|
|
obj->message_begin = new MockStage(parser);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_url(http_parser* parser, const char* at, size_t length)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->url);
|
|
obj->url = new MockStage(parser);
|
|
obj->url->at = at;
|
|
obj->url->length = length;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_status(http_parser* parser, const char* at, size_t length)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->status);
|
|
obj->status = new MockStage(parser);
|
|
obj->status->at = at;
|
|
obj->status->length = length;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_header_field(http_parser* parser, const char* at, size_t length)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->header_field);
|
|
obj->header_field = new MockStage(parser);
|
|
obj->header_field->at = at;
|
|
obj->header_field->length = length;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_header_value(http_parser* parser, const char* at, size_t length)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->header_value);
|
|
obj->header_value = new MockStage(parser);
|
|
obj->header_value->at = at;
|
|
obj->header_value->length = length;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_headers_complete(http_parser* parser)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->headers_complete);
|
|
obj->headers_complete = new MockStage(parser);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_body(http_parser* parser, const char* at, size_t length)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->body);
|
|
obj->body = new MockStage(parser);
|
|
obj->body->at = at;
|
|
obj->body->length = length;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_message_complete(http_parser* parser)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->message_complete);
|
|
obj->message_complete = new MockStage(parser);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_chunk_header(http_parser* parser)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->chunk_header);
|
|
obj->chunk_header = new MockStage(parser);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int MockParser::on_chunk_complete(http_parser* parser)
|
|
{
|
|
MockParser* obj = (MockParser*)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->chunk_complete);
|
|
obj->chunk_complete = new MockStage(parser);
|
|
|
|
return 0;
|
|
}
|
|
|
|
srs_error_t MockParser::parse(string data)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
const char* buf = (const char*)data.data();
|
|
size_t size = (size_t)data.length();
|
|
size_t nparsed = http_parser_execute(parser, &settings, buf, size);
|
|
parsed = nparsed;
|
|
|
|
if (nparsed != size) {
|
|
return srs_error_new(-1, "nparsed=%d, size=%d", nparsed, size);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
VOID TEST(ProtocolHTTPTest, HTTPParser)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 70, nparsed = 70, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
EXPECT_TRUE(!parser.body);
|
|
EXPECT_TRUE(parser.headers_complete);
|
|
EXPECT_TRUE(!parser.message_complete);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 75, nparsed = 75, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(75, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
EXPECT_TRUE(parser.body && 5 == parser.body->length);
|
|
EXPECT_TRUE(parser.headers_complete);
|
|
EXPECT_TRUE(parser.message_complete);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 150, nparsed = 150, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld"));
|
|
EXPECT_EQ(150, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5)
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
EXPECT_EQ(5, (int)parser.parser->content_length);
|
|
|
|
// size = 79, nparsed = 5, nread = 1, content_length = -1, Header("Content-Length", 5)
|
|
HELPER_EXPECT_FAILED(parser.parse("elloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(5, (int)parser.parsed);
|
|
EXPECT_EQ(1, (int)parser.parser->nread);
|
|
EXPECT_EQ(-1, (int64_t)parser.parser->content_length);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5)
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
EXPECT_EQ(5, (int)parser.parser->content_length);
|
|
|
|
// size = 80, nparsed = 70, nread = 0, content_length = 0, Header("Content-Length", 5)
|
|
HELPER_EXPECT_SUCCESS(parser.parse("HelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld"));
|
|
EXPECT_EQ(80, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
EXPECT_EQ(0, (int)parser.parser->content_length);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 73, nparsed = 73, nread = 0, content_length = 2, Header("Content-Length", 5)
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHel"));
|
|
EXPECT_EQ(73, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
EXPECT_EQ(2, (int)parser.parser->content_length);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 82, nparsed = 75, nread = 1, content_length = -1, Header("Content-Length", 5)
|
|
HELPER_EXPECT_FAILED(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello World!"));
|
|
EXPECT_EQ(75, (int)parser.parsed);
|
|
EXPECT_EQ(1, (int)parser.parser->nread);
|
|
EXPECT_EQ(-1, (int64_t)parser.parser->content_length);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 34, nparsed = 34, nread = 34
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHo"));
|
|
EXPECT_EQ(34, (int)parser.parsed);
|
|
EXPECT_EQ(34, (int)parser.parser->nread);
|
|
|
|
// size = 41, nparsed = 41, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("st: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(41, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 41, nparsed = 41, nread = 41
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: oss"));
|
|
EXPECT_EQ(41, (int)parser.parsed);
|
|
EXPECT_EQ(41, (int)parser.parser->nread);
|
|
|
|
// size = 34, nparsed = 34, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("rs.net\r\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(34, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 48, nparsed = 48, nread = 48
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r"));
|
|
EXPECT_EQ(48, (int)parser.parsed);
|
|
EXPECT_EQ(48, (int)parser.parser->nread);
|
|
|
|
// size = 27, nparsed = 27, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(27, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 68, nparsed = 68, nread = 68
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n"));
|
|
EXPECT_EQ(68, (int)parser.parsed);
|
|
EXPECT_EQ(68, (int)parser.parser->nread);
|
|
|
|
// size = 7, nparsed = 7, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("\r\nHello"));
|
|
EXPECT_EQ(7, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 69, nparsed = 69, nread = 69
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r"));
|
|
EXPECT_EQ(69, (int)parser.parsed);
|
|
EXPECT_EQ(69, (int)parser.parser->nread);
|
|
|
|
// size = 6, nparsed = 6, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("\nHello"));
|
|
EXPECT_EQ(6, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 75, nparsed = 75, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(75, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// nparsed = 2, size = 2, nread = 2
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
|
|
EXPECT_EQ(2, (int)parser.parsed);
|
|
EXPECT_EQ(2, (int)parser.parser->nread);
|
|
|
|
// size = 0, nparsed = 1, nread=2
|
|
HELPER_EXPECT_FAILED(parser.parse(""));
|
|
EXPECT_EQ(1, (int)parser.parsed);
|
|
EXPECT_EQ(2, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 2, nparsed = 2, nread = 2
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
|
|
EXPECT_EQ(2, (int)parser.parsed);
|
|
EXPECT_EQ(2, (int)parser.parser->nread);
|
|
|
|
// size = 1, nparsed = 0, nread = 3
|
|
HELPER_EXPECT_FAILED(parser.parse("X"));
|
|
EXPECT_EQ(0, (int)parser.parsed);
|
|
EXPECT_EQ(3, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 2, nparsed = 2, nread = 2
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
|
|
EXPECT_EQ(2, (int)parser.parsed);
|
|
EXPECT_EQ(2, (int)parser.parser->nread);
|
|
|
|
// size = 1, nparsed = 1, nread = 3
|
|
HELPER_EXPECT_SUCCESS(parser.parse("T"));
|
|
EXPECT_EQ(1, (int)parser.parsed);
|
|
EXPECT_EQ(3, (int)parser.parser->nread);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 3, nparsed = 3, nread = 3
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET"));
|
|
EXPECT_EQ(3, (int)parser.parsed);
|
|
EXPECT_EQ(3, (int)parser.parser->nread);
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, ParseUrlFailed)
|
|
{
|
|
if (true) {
|
|
string tcUrl = "rtmp://__defaultVhost__/live", stream = "livestream";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("rtmp", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(1935, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "rtmp://__defaultVhost__:1936/live", stream = "livestream";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("rtmp", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(1936, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "http://__defaultVhost__/live", stream = "livestream.flv";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("http", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(80, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "http://__defaultVhost__/live", stream = "livestream.m3u8";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("http", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(80, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "http://__defaultVhost__:8080/live", stream = "livestream.m3u8";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("http", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(8080, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "https://__defaultVhost__/live", stream = "livestream.flv";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("https", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(443, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "https://__defaultVhost__/live", stream = "livestream.m3u8";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("https", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(443, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "https://__defaultVhost__:8088/live", stream = "livestream.m3u8";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("https", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(8088, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "webrtc://__defaultVhost__/live", stream = "livestream";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("webrtc", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(80, port);
|
|
}
|
|
|
|
if (true) {
|
|
string tcUrl = "webrtc://__defaultVhost__:8080/live", stream = "livestream";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param);
|
|
EXPECT_STREQ("webrtc", schema.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", host.c_str());
|
|
EXPECT_STREQ("__defaultVhost__", vhost.c_str());
|
|
EXPECT_EQ(8080, port);
|
|
}
|
|
}
|
|
|