/**
* test the stream utility, read 3bytes
*/
VOID TEST(KernelStreamTest, StreamRead3Bytes)
{
    SrsStream s;
    char data[1024];
    
    EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024));
    
    data[0] = 0x01;
    data[1] = 0x02;
    data[2] = 0x03;
    data[3] = 0x04;
    data[4] = 0x05;
    data[5] = 0x06;
    data[6] = 0x07;
    data[7] = 0x08;
    data[8] = 0x09;
    data[9] = 0x0a;
    
    EXPECT_EQ(0x010203, s.read_3bytes());
    EXPECT_EQ(0x040506, s.read_3bytes());

    s.skip(-1 * s.pos());
    s.skip(5);
    EXPECT_EQ(0x060708, s.read_3bytes());
}
예제 #2
0
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);
    }
}
예제 #3
0
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;
}