mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
add miss files. fix bug #60: support aggregate message
This commit is contained in:
parent
f6dd1371bf
commit
8388da6325
12 changed files with 247 additions and 3 deletions
|
@ -690,4 +690,4 @@ echo "" >> $SRS_AUTO_HEADERS_H
|
|||
#####################################################################################
|
||||
# generated the test script
|
||||
#####################################################################################
|
||||
rm -rf ${SRS_OBJS}/srs.test && ln -sf `pwd`/scripts/test_configure.sh objs/srs.test
|
||||
rm -rf ${SRS_OBJS}/srs.test && ln -sf `pwd`/scripts/srs.test objs/srs.test
|
||||
|
|
93
trunk/research/code-statistic/csr.py
Executable file
93
trunk/research/code-statistic/csr.py
Executable file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/python
|
||||
'''
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2014 winlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
'''
|
||||
|
||||
#################################################################################
|
||||
# to stat the code and comments lines
|
||||
#################################################################################
|
||||
import sys, os, cs
|
||||
from cs import info, trace
|
||||
|
||||
if __name__ != "__main__":
|
||||
print "donot support lib"
|
||||
sys.exit(-1)
|
||||
|
||||
filters="*.*pp,*.h,*.c,*.cc"
|
||||
except_filters="utest,doc"
|
||||
if len(sys.argv) <= 1:
|
||||
print "to stat the code and comments lines"
|
||||
print "Usage: python %s <dir> [filters] [except_filters]"%(sys.argv[0])
|
||||
print " dir: the dir contains the files to stat"
|
||||
print " filters: the file filters, default: *.*pp,*.h,*.c,*.cc"
|
||||
print " filters: the except file filters, default: utest,doc"
|
||||
print "Example:"
|
||||
print " python %s src"%(sys.argv[0])
|
||||
print " python %s src *.*pp,*.cc utest"%(sys.argv[0])
|
||||
sys.exit(-1)
|
||||
|
||||
dir = sys.argv[1]
|
||||
if len(sys.argv) > 2:
|
||||
filters = sys.argv[2]
|
||||
if len(sys.argv) > 3:
|
||||
except_filters = sys.argv[3]
|
||||
info("stat dir:%s, filters:%s, except_filters:%s"%(dir, filters, except_filters))
|
||||
|
||||
# filters to array
|
||||
filters = filters.split(",")
|
||||
except_filters = except_filters.split(",")
|
||||
|
||||
# find src -name "*.*pp"|grep -v utest
|
||||
(totals, stat_codes, commentss, stat_block_commentss, stat_line_commentss) = (0, 0, 0, 0, 0)
|
||||
for filter in filters:
|
||||
cmd = 'find %s -name "%s"'%(dir, filter)
|
||||
for ef in except_filters:
|
||||
cmd = '%s|%s'%(cmd, 'grep -v "%s"'%(ef))
|
||||
cmd = "%s 2>&1"%(cmd)
|
||||
info("scan dir, cmd:%s"%cmd)
|
||||
|
||||
pipe = os.popen(cmd)
|
||||
files = pipe.read()
|
||||
info("scan dir, files:%s"%files)
|
||||
pipe.close()
|
||||
|
||||
files = files.split("\n")
|
||||
for file in files:
|
||||
file = file.strip()
|
||||
if len(file) == 0:
|
||||
continue;
|
||||
info("start stat file:%s"%file)
|
||||
(code, total, stat_code, comments, stat_block_comments, stat_line_comments, code_file) = cs.do_stat(file)
|
||||
if code != 0:
|
||||
continue;
|
||||
totals += total
|
||||
stat_codes += stat_code
|
||||
commentss += comments
|
||||
stat_block_commentss += stat_block_comments
|
||||
stat_line_commentss += stat_line_comments
|
||||
|
||||
if totals == 0:
|
||||
trace("no code or comments found.")
|
||||
else:
|
||||
trace("total:%s code:%s comments:%s(%.2f%%) block:%s line:%s"%(
|
||||
totals, stat_codes, commentss, commentss * 100.0 / totals, stat_block_commentss, stat_line_commentss
|
||||
))
|
5
trunk/scripts/srs.test
Executable file
5
trunk/scripts/srs.test
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
bash scripts/test_configure.sh && ./objs/srs_utest
|
||||
ret=$?; if [[ 0 -ne $ret ]]; then echo "configure test and utest failed."; exit $ret; fi
|
||||
echo "configure test and utest success";
|
|
@ -214,6 +214,15 @@ int SrsEdgeIngester::process_publish_message(SrsMessage* msg)
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// process aggregate packet
|
||||
if (msg->header.is_aggregate()) {
|
||||
if ((ret = source->on_aggregate(msg)) != ERROR_SUCCESS) {
|
||||
srs_error("source process aggregate message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// process onMetaData
|
||||
if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
|
||||
|
|
|
@ -724,6 +724,15 @@ int SrsRtmpConn::process_publish_message(SrsSource* source, SrsMessage* msg, boo
|
|||
return ret;
|
||||
}
|
||||
|
||||
// process aggregate packet
|
||||
if (msg->header.is_aggregate()) {
|
||||
if ((ret = source->on_aggregate(msg)) != ERROR_SUCCESS) {
|
||||
srs_error("source process aggregate message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// process onMetaData
|
||||
if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
|
||||
SrsPacket* pkt = NULL;
|
||||
|
|
|
@ -469,6 +469,7 @@ SrsSource::SrsSource(SrsRequest* req)
|
|||
play_edge = new SrsPlayEdge();
|
||||
publish_edge = new SrsPublishEdge();
|
||||
gop_cache = new SrsGopCache();
|
||||
aggregate_stream = new SrsStream();
|
||||
|
||||
_srs_config->subscribe(this);
|
||||
atc = _srs_config->get_atc(_req->vhost);
|
||||
|
@ -498,6 +499,7 @@ SrsSource::~SrsSource()
|
|||
srs_freep(play_edge);
|
||||
srs_freep(publish_edge);
|
||||
srs_freep(gop_cache);
|
||||
srs_freep(aggregate_stream);
|
||||
|
||||
#ifdef SRS_AUTO_HLS
|
||||
srs_freep(hls);
|
||||
|
@ -1069,6 +1071,105 @@ int SrsSource::on_video(SrsMessage* video)
|
|||
return ret;
|
||||
}
|
||||
|
||||
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 int8_t[o.size];
|
||||
stream->read_bytes((char*)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;
|
||||
}
|
||||
|
||||
int SrsSource::on_publish()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
|
|
@ -57,6 +57,7 @@ class SrsDvr;
|
|||
#ifdef SRS_AUTO_TRANSCODE
|
||||
class SrsEncoder;
|
||||
#endif
|
||||
class SrsStream;
|
||||
|
||||
/**
|
||||
* time jitter detect and correct,
|
||||
|
@ -251,6 +252,8 @@ private:
|
|||
SrsGopCache* gop_cache;
|
||||
// to forward stream to other servers
|
||||
std::vector<SrsForwarder*> forwarders;
|
||||
// for aggregate message
|
||||
SrsStream* aggregate_stream;
|
||||
private:
|
||||
/**
|
||||
* the sample rate of audio in metadata.
|
||||
|
@ -307,6 +310,7 @@ public:
|
|||
virtual int on_meta_data(SrsMessage* msg, SrsOnMetaDataPacket* metadata);
|
||||
virtual int on_audio(SrsMessage* audio);
|
||||
virtual int on_video(SrsMessage* video);
|
||||
virtual int on_aggregate(SrsMessage* msg);
|
||||
/**
|
||||
* publish stream event notify.
|
||||
* @param _req the request from client, the source will deep copy it,
|
||||
|
|
|
@ -83,6 +83,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_RTMP_EDGE_PUBLISH_STATE 321
|
||||
#define ERROR_RTMP_EDGE_PROXY_PULL 322
|
||||
#define ERROR_RTMP_EDGE_RELOAD 323
|
||||
// aggregate message parse failed.
|
||||
#define ERROR_RTMP_AGGREGATE 324
|
||||
|
||||
#define ERROR_SYSTEM_STREAM_INIT 400
|
||||
#define ERROR_SYSTEM_PACKET_INVALID 401
|
||||
|
|
|
@ -23,6 +23,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include <srs_kernel_stream.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <srs_kernel_log.hpp>
|
||||
#include <srs_kernel_error.hpp>
|
||||
|
||||
|
@ -160,7 +162,7 @@ int64_t SrsStream::read_8bytes()
|
|||
return value;
|
||||
}
|
||||
|
||||
std::string SrsStream::read_string(int len)
|
||||
string SrsStream::read_string(int len)
|
||||
{
|
||||
srs_assert(require(len));
|
||||
|
||||
|
@ -172,6 +174,15 @@ std::string SrsStream::read_string(int len)
|
|||
return value;
|
||||
}
|
||||
|
||||
void SrsStream::read_bytes(char* data, int size)
|
||||
{
|
||||
srs_assert(require(size));
|
||||
|
||||
memcpy(data, p, size);
|
||||
|
||||
p += size;
|
||||
}
|
||||
|
||||
void SrsStream::write_1bytes(int8_t value)
|
||||
{
|
||||
srs_assert(require(1));
|
||||
|
@ -224,7 +235,7 @@ void SrsStream::write_8bytes(int64_t value)
|
|||
*p++ = pp[0];
|
||||
}
|
||||
|
||||
void SrsStream::write_string(std::string value)
|
||||
void SrsStream::write_string(string value)
|
||||
{
|
||||
srs_assert(require(value.length()));
|
||||
|
||||
|
|
|
@ -104,6 +104,10 @@ public:
|
|||
* get string from stream, length specifies by param len.
|
||||
*/
|
||||
virtual std::string read_string(int len);
|
||||
/**
|
||||
* get bytes from stream, length specifies by param len.
|
||||
*/
|
||||
virtual void read_bytes(char* data, int size);
|
||||
public:
|
||||
/**
|
||||
* write 1bytes char to stream.
|
||||
|
|
|
@ -1477,6 +1477,11 @@ bool SrsMessageHeader::is_user_control_message()
|
|||
return message_type == RTMP_MSG_UserControlMessage;
|
||||
}
|
||||
|
||||
bool SrsMessageHeader::is_aggregate()
|
||||
{
|
||||
return message_type == RTMP_MSG_AggregateMessage;
|
||||
}
|
||||
|
||||
void SrsMessageHeader::initialize_amf0_script(int size, int stream)
|
||||
{
|
||||
message_type = RTMP_MSG_AMF0DataMessage;
|
||||
|
|
|
@ -277,6 +277,7 @@ public:
|
|||
bool is_ackledgement();
|
||||
bool is_set_chunk_size();
|
||||
bool is_user_control_message();
|
||||
bool is_aggregate();
|
||||
|
||||
void initialize_amf0_script(int size, int stream);
|
||||
void initialize_audio(int size, u_int32_t time, int stream);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue