8322 lines
224 KiB
C++
8322 lines
224 KiB
C++
//
|
|
// Copyright (c) 2013-2025 The SRS Authors
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
//
|
|
#include <srs_utest_manual_protocol2.hpp>
|
|
|
|
using namespace std;
|
|
|
|
#include <srs_app_st.hpp>
|
|
#include <srs_core_autofree.hpp>
|
|
#include <srs_kernel_buffer.hpp>
|
|
#include <srs_kernel_error.hpp>
|
|
#include <srs_kernel_utility.hpp>
|
|
#include <srs_protocol_amf0.hpp>
|
|
#include <srs_protocol_http_conn.hpp>
|
|
#include <srs_protocol_protobuf.hpp>
|
|
#include <srs_protocol_rtmp_msg_array.hpp>
|
|
#include <srs_protocol_rtmp_stack.hpp>
|
|
#include <srs_protocol_utility.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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x10, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x20, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x10, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x20, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x10, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x20, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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));
|
|
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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));
|
|
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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));
|
|
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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));
|
|
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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));
|
|
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
// 0xCX without extended timestamp.
|
|
EXPECT_EQ(0x00010203, msg->header_.timestamp_);
|
|
}
|
|
|
|
/**
|
|
* 2 audio and video packet, fmt 1/2
|
|
* first audio packet: dts:10000
|
|
* first video packet: dts:11000
|
|
* second audio packet: dts : 16787216 delta: 16777216
|
|
* second video packet: dts : 16787216 delta: 16776216
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvAVExtTimedeltaStream)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// audio message
|
|
uint8_t audio_data1[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03, // fmt 0
|
|
0x00,
|
|
0x27,
|
|
0x10, // timestamp 10000
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x08, // 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,
|
|
};
|
|
|
|
uint8_t audio_data2[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43, // fmt 1
|
|
0xff,
|
|
0xff,
|
|
0xff, // means extended timestamp
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x08, // message_type
|
|
0x01,
|
|
0x00,
|
|
0x00,
|
|
0x00, // extended timestamp delta:16777216
|
|
// 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,
|
|
};
|
|
|
|
// video message
|
|
uint8_t video_data1[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04, // fmt 0
|
|
0x00,
|
|
0x2a,
|
|
0xf8, // timestamp 11000
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x09, // message_type
|
|
0x00,
|
|
0x00,
|
|
0x00,
|
|
0x01, // 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,
|
|
};
|
|
|
|
uint8_t video_data2[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x44, // fmt 1
|
|
0xff,
|
|
0xff,
|
|
0xff, // means extended timestamp
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x09, // message_type
|
|
0x00,
|
|
0xff,
|
|
0xfc,
|
|
0x18, // extended timestamp delta:16776216
|
|
// 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,
|
|
};
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)audio_data1, sizeof(audio_data1));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x00002710, msg->header_.timestamp_);
|
|
}
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)video_data1, sizeof(video_data1));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x00002af8, msg->header_.timestamp_);
|
|
}
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)audio_data2, sizeof(audio_data2));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x01002710, msg->header_.timestamp_);
|
|
}
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)video_data2, sizeof(video_data2));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x01002710, msg->header_.timestamp_);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 2 audio packet, fmt 1/2
|
|
* first audio packet: dts:10000
|
|
* second audio packet: dts : 16787216 delta: 16777216
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvAVExtTimedeltaAudio)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// audio message
|
|
uint8_t audio_data1[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x03, // fmt 0
|
|
0x00,
|
|
0x27,
|
|
0x10, // timestamp 10000
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x08, // 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,
|
|
};
|
|
|
|
uint8_t audio_data2[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x43, // fmt 1
|
|
0xff,
|
|
0xff,
|
|
0xff, // means extended timestamp
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x08, // message_type
|
|
0x01,
|
|
0x00,
|
|
0x00,
|
|
0x00, // extended timestamp delta:16777216
|
|
// 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,
|
|
};
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)audio_data1, sizeof(audio_data1));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x00002710, msg->header_.timestamp_);
|
|
}
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)audio_data2, sizeof(audio_data2));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x01002710, msg->header_.timestamp_);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 2 video packet, fmt 1/2
|
|
* first video packet: dts:11000
|
|
* second video packet: dts : 16787216 delta: 16776216
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvAVExtTimedeltaVideo)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// video message
|
|
uint8_t video_data1[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04, // fmt 0
|
|
0x00,
|
|
0x2a,
|
|
0xf8, // timestamp 11000
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x09, // message_type
|
|
0x00,
|
|
0x00,
|
|
0x00,
|
|
0x01, // 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,
|
|
};
|
|
|
|
uint8_t video_data2[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x44, // fmt 1
|
|
0xff,
|
|
0xff,
|
|
0xff, // means extended timestamp
|
|
0x00,
|
|
0x00,
|
|
0x80, // length, 128
|
|
0x09, // message_type
|
|
0x00,
|
|
0xff,
|
|
0xfc,
|
|
0x18, // extended timestamp delta:16776216
|
|
// 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,
|
|
};
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)video_data1, sizeof(video_data1));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x00002af8, msg->header_.timestamp_);
|
|
}
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)video_data2, sizeof(video_data2));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x01002710, msg->header_.timestamp_);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 2 video packet, fmt 3
|
|
* first video packet: dts:11000
|
|
* second video packet: dts : 16787216 delta: 16776216
|
|
*/
|
|
VOID TEST(ProtocolStackTest, ProtocolRecvAVExtTimedeltaVideoFmt3)
|
|
{
|
|
srs_error_t err = srs_success;
|
|
|
|
MockBufferIO bio;
|
|
SrsProtocol proto(&bio);
|
|
|
|
// video message
|
|
uint8_t video_data1[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x04, // fmt 0
|
|
0x00,
|
|
0x2a,
|
|
0xf8, // timestamp 11000
|
|
0x00,
|
|
0x01,
|
|
0x00, // length, 256
|
|
0x09, // message_type
|
|
0x00,
|
|
0x00,
|
|
0x00,
|
|
0x01, // 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
|
|
0xC4, // fmt 3
|
|
/*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,
|
|
};
|
|
|
|
uint8_t video_data2[] = {
|
|
// 12bytes header, 1byts chunk header, 11bytes msg heder
|
|
0x44, // fmt 1
|
|
0xff, 0xff, 0xff, // means extended timestamp
|
|
0x00, 0x01, 0x10, // length, 272
|
|
0x09, // message_type
|
|
0x00, 0xff, 0xfc, 0x18, // extended timestamp delta:16776216
|
|
// 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
|
|
0xC4, // fmt 3
|
|
0x00, 0xff, 0xfc, 0x18, // extended timestamp delta:16776216
|
|
/*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
|
|
0xC4,
|
|
/*next chunk.*/
|
|
0x00, 0xff, 0xfc, 0x18, // extended timestamp delta:16776216
|
|
0x2e, 0x73, 0x77, 0x66, 0x3f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x31, 0x2e};
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)video_data1, sizeof(video_data1));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x00002af8, msg->header_.timestamp_);
|
|
}
|
|
|
|
if (true) {
|
|
bio.in_buffer.append((char *)video_data2, sizeof(video_data2));
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x01002710, 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));
|
|
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, Connections)
|
|
{
|
|
if (true) {
|
|
MockWallClock *clock = new MockWallClock();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsKbps *kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsKbps> kbps_uptr(kbps);
|
|
|
|
SrsNetworkDelta *delta = new SrsNetworkDelta();
|
|
SrsUniquePtr<SrsNetworkDelta> delta_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsKbps *kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsKbps> kbps_uptr(kbps);
|
|
|
|
SrsNetworkDelta *delta = new SrsNetworkDelta();
|
|
SrsUniquePtr<SrsNetworkDelta> delta_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsKbps *kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsKbps> kbps_uptr(kbps);
|
|
|
|
SrsNetworkDelta *delta = new SrsNetworkDelta();
|
|
SrsUniquePtr<SrsNetworkDelta> delta_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkDelta *delta = new SrsNetworkDelta();
|
|
SrsUniquePtr<SrsNetworkDelta> delta_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkDelta *delta = new SrsNetworkDelta();
|
|
SrsUniquePtr<SrsNetworkDelta> delta_uptr(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));
|
|
SrsUniquePtr<SrsKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkDelta *delta = new SrsNetworkDelta();
|
|
SrsUniquePtr<SrsNetworkDelta> delta_uptr(delta);
|
|
delta->set_io(io, io);
|
|
|
|
SrsKbps *kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
|
|
SrsKbps *kbps = new SrsKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkDelta *delta = new SrsNetworkDelta();
|
|
SrsUniquePtr<SrsNetworkDelta> delta_uptr(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;
|
|
SrsProtocolUtility utility;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(utility.write_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;
|
|
SrsProtocolUtility utility;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(utility.write_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;
|
|
SrsProtocolUtility utility;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(utility.write_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;
|
|
SrsProtocolUtility utility;
|
|
ssize_t nn = 0;
|
|
HELPER_EXPECT_SUCCESS(utility.write_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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkKbps *kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsNetworkKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkKbps *kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsNetworkKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkKbps *kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsNetworkKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
// Kbps without io, gather delta.
|
|
SrsNetworkKbps *kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsNetworkKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
MockStatistic *io = new MockStatistic();
|
|
SrsUniquePtr<MockStatistic> io_uptr(io);
|
|
|
|
SrsNetworkKbps *kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsNetworkKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockWallClock> clock_uptr(clock);
|
|
|
|
SrsNetworkKbps *kbps = new SrsNetworkKbps(clock->set_clock(0));
|
|
SrsUniquePtr<SrsNetworkKbps> kbps_uptr(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();
|
|
SrsUniquePtr<MockStatistic> io_uptr(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_net_url_encode_sid("", "live", "livestream").c_str());
|
|
EXPECT_STREQ("/live/livestream", srs_net_url_encode_sid("", "live", "livestream.flv").c_str());
|
|
EXPECT_STREQ("/live/livestream", srs_net_url_encode_sid("", "live", "livestream.m3u8").c_str());
|
|
EXPECT_STREQ("/live/livestream", srs_net_url_encode_sid("__defaultVhost__", "live", "livestream").c_str());
|
|
|
|
EXPECT_STREQ("ossrs.io/live/livestream", srs_net_url_encode_sid("ossrs.io", "live", "livestream").c_str());
|
|
EXPECT_STREQ("ossrs.io/live/livestream", srs_net_url_encode_sid("ossrs.io", "live", "livestream.flv").c_str());
|
|
EXPECT_STREQ("ossrs.io/live/livestream", srs_net_url_encode_sid("ossrs.io", "live", "livestream.m3u8").c_str());
|
|
}
|
|
|
|
// Reproduce bug from issue 4011: Stream names with dots get truncated incorrectly
|
|
// https://github.com/ossrs/srs/issues/4011
|
|
// The filepath_filename() function removes everything after the LAST dot in the stream name.
|
|
// This was intended to strip extensions like .flv, but it breaks stream names that contain
|
|
// dots as part of the identifier (like WavMain.exe_rooms_290_20240402).
|
|
// This causes edge servers to treat different streams as the same source.
|
|
//
|
|
// This test FAILS to demonstrate the bug - when the bug is fixed, this test should PASS.
|
|
VOID TEST(ProtocolKbpsTest, StreamIdentifyWithDotsInName_Issue4011)
|
|
{
|
|
// Case 1: THE ACTUAL BUG from issue 4011
|
|
// Stream names like "WavMain.exe_rooms_290_20240402" contain a dot in ".exe"
|
|
// Expected: Each stream should have a unique source URL preserving the full name
|
|
// Actual (BUG): filepath_filename() strips everything after the dot in ".exe"
|
|
std::string url1 = srs_net_url_encode_sid("", "imlive", "WavMain.exe_rooms_290_20240402");
|
|
std::string url2 = srs_net_url_encode_sid("", "imlive", "WavMain.exe_rooms_311_20240402");
|
|
std::string url3 = srs_net_url_encode_sid("", "imlive", "WavMain.exe_rooms_222_20240402");
|
|
|
|
// EXPECTED: Each stream should preserve its full name
|
|
EXPECT_STREQ("/imlive/WavMain.exe_rooms_290_20240402", url1.c_str());
|
|
EXPECT_STREQ("/imlive/WavMain.exe_rooms_311_20240402", url2.c_str());
|
|
EXPECT_STREQ("/imlive/WavMain.exe_rooms_222_20240402", url3.c_str());
|
|
|
|
// EXPECTED: Different streams should have different URLs
|
|
EXPECT_STRNE(url1.c_str(), url2.c_str());
|
|
EXPECT_STRNE(url1.c_str(), url3.c_str());
|
|
EXPECT_STRNE(url2.c_str(), url3.c_str());
|
|
|
|
// Case 2: Stream names with multiple dots should preserve the full name
|
|
// (only strip known extensions like .flv, .m3u8, not arbitrary suffixes)
|
|
EXPECT_STREQ("/live/test.backup.stream", srs_net_url_encode_sid("", "live", "test.backup.stream").c_str());
|
|
EXPECT_STREQ("/live/my.stream.v2", srs_net_url_encode_sid("", "live", "my.stream.v2").c_str());
|
|
EXPECT_STREQ("/live/camera.1.hd", srs_net_url_encode_sid("", "live", "camera.1.hd").c_str());
|
|
|
|
// Case 3: Different streams with same prefix should be different
|
|
std::string backup1 = srs_net_url_encode_sid("", "live", "test.backup.stream");
|
|
std::string backup2 = srs_net_url_encode_sid("", "live", "test.backup.stream2");
|
|
EXPECT_STRNE(backup1.c_str(), backup2.c_str()); // Should be different
|
|
|
|
// Case 4: The intended behavior - stripping ONLY known extensions
|
|
// These should work correctly (strip .flv and .m3u8)
|
|
EXPECT_STREQ("/live/livestream", srs_net_url_encode_sid("", "live", "livestream.flv").c_str());
|
|
EXPECT_STREQ("/live/livestream", srs_net_url_encode_sid("", "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;
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
SrsUniquePtr<ISrsHttpMessage> req_uptr(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;
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
SrsUniquePtr<ISrsHttpMessage> req_uptr(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;
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
SrsUniquePtr<ISrsHttpMessage> req_uptr(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;
|
|
HELPER_ASSERT_SUCCESS(hp.parse_message(&bio, &req));
|
|
SrsUniquePtr<ISrsHttpMessage> req_uptr(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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_equal(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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x10, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x20, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x10, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x20, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x10, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x20, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
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) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x10, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_audio());
|
|
EXPECT_EQ(0x15, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x20, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
if (true) {
|
|
SrsRtmpCommonMessage *msg_raw = NULL;
|
|
HELPER_ASSERT_SUCCESS(proto.recv_message(&msg_raw));
|
|
SrsUniquePtr<SrsRtmpCommonMessage> msg(msg_raw);
|
|
|
|
EXPECT_TRUE(msg->header_.is_video());
|
|
EXPECT_EQ(0x30, msg->header_.timestamp_);
|
|
EXPECT_EQ(0x01, msg->header_.stream_id_);
|
|
}
|
|
}
|
|
|
|
struct MockStage {
|
|
llhttp_t parser;
|
|
const char *at;
|
|
size_t length;
|
|
|
|
MockStage(llhttp_t *from);
|
|
};
|
|
|
|
MockStage::MockStage(llhttp_t *from)
|
|
{
|
|
parser = *from;
|
|
at = NULL;
|
|
length = 0;
|
|
}
|
|
|
|
class MockParser
|
|
{
|
|
// clang-format off
|
|
SRS_DECLARE_PRIVATE: // clang-format on
|
|
llhttp_settings_t settings;
|
|
llhttp_t *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);
|
|
|
|
// clang-format off
|
|
SRS_DECLARE_PRIVATE: // clang-format on
|
|
static int on_message_begin(llhttp_t *parser);
|
|
static int on_url(llhttp_t *parser, const char *at, size_t length);
|
|
static int on_status(llhttp_t *parser, const char *at, size_t length);
|
|
static int on_header_field(llhttp_t *parser, const char *at, size_t length);
|
|
static int on_header_value(llhttp_t *parser, const char *at, size_t length);
|
|
static int on_headers_complete(llhttp_t *parser);
|
|
static int on_body(llhttp_t *parser, const char *at, size_t length);
|
|
static int on_message_complete(llhttp_t *parser);
|
|
static int on_chunk_header(llhttp_t *parser);
|
|
static int on_chunk_complete(llhttp_t *parser);
|
|
};
|
|
|
|
MockParser::MockParser()
|
|
{
|
|
parser = new llhttp_t();
|
|
llhttp_init(parser, HTTP_REQUEST, &settings);
|
|
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(llhttp_t *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(llhttp_t *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(llhttp_t *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(llhttp_t *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(llhttp_t *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(llhttp_t *parser)
|
|
{
|
|
MockParser *obj = (MockParser *)parser->data;
|
|
srs_assert(obj);
|
|
|
|
srs_freep(obj->headers_complete);
|
|
obj->headers_complete = new MockStage(parser);
|
|
|
|
return HPE_PAUSED;
|
|
}
|
|
|
|
int MockParser::on_body(llhttp_t *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(llhttp_t *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(llhttp_t *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(llhttp_t *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;
|
|
|
|
parsed = 0;
|
|
|
|
const char *buf = (const char *)data.data();
|
|
size_t size = (size_t)data.length();
|
|
llhttp_errno_t code = llhttp_execute(parser, buf, size);
|
|
|
|
ssize_t consumed = 0;
|
|
if (code == HPE_OK) {
|
|
// No problem, all buffer should be consumed.
|
|
consumed = (int)data.size();
|
|
} else if (code == HPE_PAUSED) {
|
|
// We only consume the header, not message or body.
|
|
const char *error_pos = llhttp_get_error_pos(parser);
|
|
if (error_pos && error_pos < buf) {
|
|
return srs_error_new(-1, "llhttp error_pos=%p < data_start=%p", error_pos, buf);
|
|
}
|
|
|
|
if (error_pos && error_pos >= buf) {
|
|
consumed = error_pos - buf;
|
|
}
|
|
}
|
|
|
|
// Check for errors (but allow certain conditions that are normal)
|
|
// HPE_OK: success
|
|
// HPE_PAUSED: we use to skip body
|
|
if (code != HPE_OK && code != HPE_PAUSED) {
|
|
return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse %dB, nparsed=%d, err=%d/%s %s",
|
|
(int)data.size(), (int)consumed, code, llhttp_errno_name(code),
|
|
llhttp_get_error_reason(parser) ? llhttp_get_error_reason(parser) : "");
|
|
}
|
|
|
|
parsed = consumed;
|
|
|
|
return err;
|
|
}
|
|
|
|
VOID TEST(ProtocolHTTPTest, HTTPParser)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 79, nparsed = 0, 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(0, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int64_t)parser.parser->content_length);
|
|
}
|
|
|
|
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_TRUE(!parser.body);
|
|
EXPECT_TRUE(parser.headers_complete);
|
|
EXPECT_TRUE(!parser.message_complete);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 75, 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\nHello"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
EXPECT_TRUE(!parser.body);
|
|
EXPECT_TRUE(parser.headers_complete);
|
|
EXPECT_TRUE(!parser.message_complete);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 150, 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\nHelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
}
|
|
|
|
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(5, (int)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(5, (int)parser.parser->content_length);
|
|
|
|
// Reset for the next message.
|
|
parser.parser->content_length = 0;
|
|
|
|
// size = 80, nparsed = 70, nread = 0, content_length = 0, 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\nWorld"));
|
|
EXPECT_EQ(0, (int)parser.parsed);
|
|
EXPECT_EQ(0, (int)parser.parser->content_length);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 73, 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\nHel"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
EXPECT_EQ(5, (int)parser.parser->content_length);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 82, nparsed = 70, nread = 1, 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\nHello World!"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
EXPECT_EQ(5, (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);
|
|
|
|
// size = 41, nparsed = 36, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("st: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(36, (int)parser.parsed);
|
|
}
|
|
|
|
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);
|
|
|
|
// size = 34, nparsed = 29, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("rs.net\r\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(29, (int)parser.parsed);
|
|
}
|
|
|
|
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);
|
|
|
|
// size = 27, nparsed = 22, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("\nContent-Length: 5\r\n\r\nHello"));
|
|
EXPECT_EQ(22, (int)parser.parsed);
|
|
}
|
|
|
|
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);
|
|
|
|
// size = 7, nparsed = 2, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("\r\nHello"));
|
|
EXPECT_EQ(2, (int)parser.parsed);
|
|
}
|
|
|
|
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);
|
|
|
|
// size = 6, nparsed = 1, nread = 0
|
|
HELPER_EXPECT_SUCCESS(parser.parse("\nHello"));
|
|
EXPECT_EQ(1, (int)parser.parsed);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 75, 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\nHello"));
|
|
EXPECT_EQ(70, (int)parser.parsed);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// nparsed = 2, size = 2, nread = 2
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
|
|
EXPECT_EQ(2, (int)parser.parsed);
|
|
|
|
// size = 0, nparsed = 1, nread=2
|
|
HELPER_EXPECT_SUCCESS(parser.parse(""));
|
|
EXPECT_EQ(0, (int)parser.parsed);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 2, nparsed = 2, nread = 2
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
|
|
EXPECT_EQ(2, (int)parser.parsed);
|
|
|
|
// size = 1, nparsed = 0, nread = 3
|
|
HELPER_EXPECT_FAILED(parser.parse("X"));
|
|
EXPECT_EQ(0, (int)parser.parsed);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 2, nparsed = 2, nread = 2
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
|
|
EXPECT_EQ(2, (int)parser.parsed);
|
|
|
|
// size = 1, nparsed = 1, nread = 3
|
|
HELPER_EXPECT_SUCCESS(parser.parse("T"));
|
|
EXPECT_EQ(1, (int)parser.parsed);
|
|
}
|
|
|
|
if (true) {
|
|
MockParser parser;
|
|
// size = 3, nparsed = 3, nread = 3
|
|
HELPER_EXPECT_SUCCESS(parser.parse("GET"));
|
|
EXPECT_EQ(3, (int)parser.parsed);
|
|
}
|
|
}
|
|
|
|
VOID TEST(ProtocolKbpsTest, ParseUrlFailed)
|
|
{
|
|
if (true) {
|
|
string tcUrl = "rtmp://__defaultVhost__/live", stream = "livestream";
|
|
string schema, host, vhost, app, param;
|
|
int port = 0;
|
|
srs_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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_net_url_parse_tcurl(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);
|
|
}
|
|
}
|