/** * test the stream utility, write 8bytes */ VOID TEST(KernelStreamTest, StreamWrite8Bytes) { SrsStream s; char data[1024]; EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024)); s.write_8bytes(0x1011121314151617); s.write_8bytes(0x1819202122232425); s.skip(-1 * s.pos()); EXPECT_EQ(0x10, s.read_1bytes()); s.skip(2); EXPECT_EQ(0x13, s.read_1bytes()); s.skip(5); EXPECT_EQ(0x19, s.read_1bytes()); }
/** * test the stream utility, write 1bytes */ VOID TEST(KernelStreamTest, StreamWrite1Bytes) { SrsStream s; char data[1024]; EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024)); s.write_1bytes(0x10); s.write_1bytes(0x11); s.write_1bytes(0x12); s.write_1bytes(0x13); s.skip(-1 * s.pos()); EXPECT_EQ(0x10, s.read_1bytes()); s.skip(2); EXPECT_EQ(0x13, s.read_1bytes()); }
/** * test the stream utility, read 1bytes */ VOID TEST(KernelStreamTest, StreamRead1Bytes) { SrsStream s; char data[1024]; EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024)); data[0] = 0x12; data[99] = 0x13; data[100] = 0x14; data[101] = 0x15; EXPECT_EQ(0x12, s.read_1bytes()); s.skip(-1 * s.pos()); s.skip(100); EXPECT_EQ(0x14, s.read_1bytes()); }
/** * test the stream utility, write bytes */ VOID TEST(KernelStreamTest, StreamWriteBytes) { SrsStream s; char data[1024]; EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024)); char str[] = { (char)0x10, (char)0x11, (char)0x12, (char)0x13, (char)0x14, (char)0x15, (char)0x16, (char)0x17, (char)0x18, (char)0x19, (char)0x20, (char)0x21 }; s.write_bytes(str, 12); s.skip(-1 * s.pos()); EXPECT_EQ(0x10, s.read_1bytes()); s.skip(2); EXPECT_EQ(0x13, s.read_1bytes()); s.skip(5); EXPECT_EQ(0x19, s.read_1bytes()); }
VOID TEST(AMF0Test, ApiAnyIO) { SrsStream s; SrsAmf0Any* o = NULL; char buf[1024]; memset(buf, 0, sizeof(buf)); EXPECT_EQ(ERROR_SUCCESS, s.initialize(buf, sizeof(buf))); // object eof if (true) { s.reset(); s.current()[2] = 0x09; o = SrsAmf0Any::object_eof(); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->read(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_EQ(3, s.pos()); s.reset(); s.current()[0] = 0x01; EXPECT_NE(ERROR_SUCCESS, o->read(&s)); } if (true) { s.reset(); o = SrsAmf0Any::object_eof(); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_EQ(3, s.pos()); s.skip(-3); EXPECT_EQ(0x09, s.read_3bytes()); } // string if (true) { s.reset(); o = SrsAmf0Any::str("winlin"); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); EXPECT_EQ(2, s.read_1bytes()); EXPECT_EQ(6, s.read_2bytes()); EXPECT_EQ('w', s.current()[0]); EXPECT_EQ('n', s.current()[5]); s.reset(); s.current()[3] = 'x'; EXPECT_EQ(ERROR_SUCCESS, o->read(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_STREQ("xinlin", o->to_str().c_str()); } // number if (true) { s.reset(); o = SrsAmf0Any::number(10); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); EXPECT_EQ(0, s.read_1bytes()); s.reset(); EXPECT_EQ(ERROR_SUCCESS, o->read(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_DOUBLE_EQ(10, o->to_number()); } // boolean if (true) { s.reset(); o = SrsAmf0Any::boolean(true); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); EXPECT_EQ(1, s.read_1bytes()); s.reset(); EXPECT_EQ(ERROR_SUCCESS, o->read(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_TRUE(o->to_boolean()); } if (true) { s.reset(); o = SrsAmf0Any::boolean(false); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); EXPECT_EQ(1, s.read_1bytes()); s.reset(); EXPECT_EQ(ERROR_SUCCESS, o->read(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_FALSE(o->to_boolean()); } // null if (true) { s.reset(); o = SrsAmf0Any::null(); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); EXPECT_EQ(5, s.read_1bytes()); s.reset(); EXPECT_EQ(ERROR_SUCCESS, o->read(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_TRUE(o->is_null()); } // undefined if (true) { s.reset(); o = SrsAmf0Any::undefined(); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); EXPECT_EQ(6, s.read_1bytes()); s.reset(); EXPECT_EQ(ERROR_SUCCESS, o->read(&s)); EXPECT_EQ(o->total_size(), s.pos()); EXPECT_TRUE(o->is_undefined()); } // any: string if (true) { s.reset(); o = SrsAmf0Any::str("winlin"); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); SrsAmf0Any* po = NULL; EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); SrsAutoFree(SrsAmf0Any, po); ASSERT_TRUE(po->is_string()); EXPECT_STREQ("winlin", po->to_str().c_str()); } // any: number if (true) { s.reset(); o = SrsAmf0Any::number(10); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); SrsAmf0Any* po = NULL; EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); SrsAutoFree(SrsAmf0Any, po); ASSERT_TRUE(po->is_number()); EXPECT_DOUBLE_EQ(10, po->to_number()); } // any: boolean if (true) { s.reset(); o = SrsAmf0Any::boolean(true); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); SrsAmf0Any* po = NULL; EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); SrsAutoFree(SrsAmf0Any, po); ASSERT_TRUE(po->is_boolean()); EXPECT_TRUE(po->to_boolean()); } // any: null if (true) { s.reset(); o = SrsAmf0Any::null(); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); SrsAmf0Any* po = NULL; EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); SrsAutoFree(SrsAmf0Any, po); ASSERT_TRUE(po->is_null()); } // any: undefined if (true) { s.reset(); o = SrsAmf0Any::undefined(); SrsAutoFree(SrsAmf0Any, o); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(o->total_size(), s.pos()); s.reset(); SrsAmf0Any* po = NULL; EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); SrsAutoFree(SrsAmf0Any, po); ASSERT_TRUE(po->is_undefined()); } // mixed any if (true) { s.reset(); o = SrsAmf0Any::str("winlin"); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); srs_freep(o); o = SrsAmf0Any::number(10); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); srs_freep(o); o = SrsAmf0Any::boolean(true); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); srs_freep(o); o = SrsAmf0Any::null(); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); srs_freep(o); o = SrsAmf0Any::undefined(); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); srs_freep(o); s.reset(); SrsAmf0Any* po = NULL; EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); ASSERT_TRUE(po->is_string()); EXPECT_STREQ("winlin", po->to_str().c_str()); srs_freep(po); EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); ASSERT_TRUE(po->is_number()); EXPECT_DOUBLE_EQ(10, po->to_number()); srs_freep(po); EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); ASSERT_TRUE(po->is_boolean()); EXPECT_TRUE(po->to_boolean()); srs_freep(po); EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); ASSERT_TRUE(po->is_null()); srs_freep(po); EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &po)); ASSERT_TRUE(NULL != po); ASSERT_TRUE(po->is_undefined()); srs_freep(po); } }
VOID TEST(AMF0Test, ApiStrictArray) { SrsStream s; char buf[1024]; memset(buf, 0, sizeof(buf)); EXPECT_EQ(ERROR_SUCCESS, s.initialize(buf, sizeof(buf))); SrsAmf0StrictArray* o = NULL; // append property if (true) { o = SrsAmf0Any::strict_array(); SrsAutoFree(SrsAmf0StrictArray, o); o->append(SrsAmf0Any::number(100)); EXPECT_DOUBLE_EQ(100, o->at(0)->to_number()); o->append(SrsAmf0Any::number(101)); EXPECT_DOUBLE_EQ(101, o->at(1)->to_number()); o->append(SrsAmf0Any::str("winlin")); EXPECT_STREQ("winlin", o->at(2)->to_str().c_str()); } // count if (true) { o = SrsAmf0Any::strict_array(); SrsAutoFree(SrsAmf0StrictArray, o); EXPECT_EQ(0, o->count()); o->append(SrsAmf0Any::boolean()); EXPECT_EQ(1, o->count()); o->append(SrsAmf0Any::boolean()); EXPECT_EQ(2, o->count()); o->clear(); EXPECT_EQ(0, o->count()); } // io if (true) { o = SrsAmf0Any::strict_array(); SrsAutoFree(SrsAmf0StrictArray, o); s.reset(); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(5, s.pos()); s.reset(); EXPECT_EQ(0x0a, s.read_1bytes()); EXPECT_EQ(0x00, s.read_4bytes()); } if (true) { o = SrsAmf0Any::strict_array(); SrsAutoFree(SrsAmf0StrictArray, o); o->append(SrsAmf0Any::number(0)); s.reset(); EXPECT_EQ(ERROR_SUCCESS, o->write(&s)); EXPECT_EQ(5 + SrsAmf0Size::number(), s.pos()); } }
int SrsSource::on_aggregate(SrsMessage* msg) { int ret = ERROR_SUCCESS; SrsStream* stream = aggregate_stream; if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) { return ret; } while (!stream->empty()) { if (!stream->require(1)) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message type. ret=%d", ret); return ret; } int8_t type = stream->read_1bytes(); if (!stream->require(3)) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message size. ret=%d", ret); return ret; } int32_t data_size = stream->read_3bytes(); if (data_size < 0) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message size(negative). ret=%d", ret); return ret; } if (!stream->require(3)) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message time. ret=%d", ret); return ret; } int32_t timestamp = stream->read_3bytes(); if (!stream->require(1)) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message time(high). ret=%d", ret); return ret; } int32_t time_h = stream->read_1bytes(); timestamp |= time_h<<24; timestamp &= 0x7FFFFFFF; if (!stream->require(3)) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message stream_id. ret=%d", ret); return ret; } int32_t stream_id = stream->read_3bytes(); if (data_size > 0 && !stream->require(data_size)) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message data. ret=%d", ret); return ret; } // to common message. SrsCommonMessage __o; SrsMessage& o = __o; o.header.message_type = type; o.header.payload_length = data_size; o.header.timestamp_delta = timestamp; o.header.timestamp = timestamp; o.header.stream_id = stream_id; o.header.perfer_cid = msg->header.perfer_cid; if (data_size > 0) { o.size = data_size; o.payload = new char[o.size]; stream->read_bytes(o.payload, o.size); } if (!stream->require(4)) { ret = ERROR_RTMP_AGGREGATE; srs_error("invalid aggregate message previous tag size. ret=%d", ret); return ret; } stream->read_4bytes(); // process parsed message if (o.header.is_audio()) { if ((ret = on_audio(&o)) != ERROR_SUCCESS) { return ret; } } else if (o.header.is_video()) { if ((ret = on_video(&o)) != ERROR_SUCCESS) { return ret; } } } return ret; }