Commit 700a16c7 by xiongziliang

大幅提升接收推流性能以及降低内存占用

parent 5c7a08eb
Subproject commit d4d4ac1e9866ef4d025b8189264efe5ec8fa201c Subproject commit 17c445fd1f42cddeeccdc6a06aa56cf2ffcfc99f
...@@ -161,7 +161,7 @@ public: ...@@ -161,7 +161,7 @@ public:
public: public:
CodecId _codec_id = CodecInvalid; CodecId _codec_id = CodecInvalid;
string _buffer; BufferLikeString _buffer;
uint32_t _dts = 0; uint32_t _dts = 0;
uint32_t _pts = 0; uint32_t _pts = 0;
uint32_t _prefix_size = 0; uint32_t _prefix_size = 0;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
namespace mediakit{ namespace mediakit{
const char *HttpChunkedSplitter::onSearchPacketTail(const char *data, int len) { const char *HttpChunkedSplitter::onSearchPacketTail(const char *data, uint64_t len) {
auto pos = strstr(data,"\r\n"); auto pos = strstr(data,"\r\n");
if(!pos){ if(!pos){
return nullptr; return nullptr;
......
...@@ -30,7 +30,7 @@ public: ...@@ -30,7 +30,7 @@ public:
protected: protected:
int64_t onRecvHeader(const char *data,uint64_t len) override; int64_t onRecvHeader(const char *data,uint64_t len) override;
void onRecvContent(const char *data,uint64_t len) override; void onRecvContent(const char *data,uint64_t len) override;
const char *onSearchPacketTail(const char *data,int len) override; const char *onSearchPacketTail(const char *data,uint64_t len) override;
protected: protected:
virtual void onRecvChunk(const char *data,uint64_t len){ virtual void onRecvChunk(const char *data,uint64_t len){
if(_onChunkData){ if(_onChunkData){
......
...@@ -99,9 +99,6 @@ void HttpClient::onConnect(const SockException &ex) { ...@@ -99,9 +99,6 @@ void HttpClient::onConnect(const SockException &ex) {
return; return;
} }
//先假设http客户端只会接收一点点数据(只接受http头,节省内存)
getSock()->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
_totalBodySize = 0; _totalBodySize = 0;
_recvedBodySize = 0; _recvedBodySize = 0;
HttpRequestSplitter::reset(); HttpRequestSplitter::reset();
...@@ -156,9 +153,6 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) { ...@@ -156,9 +153,6 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
} }
if(_parser["Transfer-Encoding"] == "chunked"){ if(_parser["Transfer-Encoding"] == "chunked"){
//我们认为这种情况下后面应该有大量的数据过来,加大接收缓存提高性能
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
//如果Transfer-Encoding字段等于chunked,则认为后续的content是不限制长度的 //如果Transfer-Encoding字段等于chunked,则认为后续的content是不限制长度的
_totalBodySize = -1; _totalBodySize = -1;
_chunkedSplitter = std::make_shared<HttpChunkedSplitter>([this](const char *data,uint64_t len){ _chunkedSplitter = std::make_shared<HttpChunkedSplitter>([this](const char *data,uint64_t len){
...@@ -183,13 +177,6 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) { ...@@ -183,13 +177,6 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
//但是由于我们没必要等content接收完毕才回调onRecvContent(因为这样浪费内存并且要多次拷贝数据) //但是由于我们没必要等content接收完毕才回调onRecvContent(因为这样浪费内存并且要多次拷贝数据)
//所以返回-1代表我们接下来分段接收content //所以返回-1代表我们接下来分段接收content
_recvedBodySize = 0; _recvedBodySize = 0;
if(_totalBodySize > 0){
//根据_totalBodySize设置接收缓存大小
getSock()->setReadBuffer(std::make_shared<BufferRaw>(MIN(_totalBodySize + 1,256 * 1024)));
}else{
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
}
return -1; return -1;
} }
......
...@@ -39,6 +39,9 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) { ...@@ -39,6 +39,9 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
const char *index = nullptr; const char *index = nullptr;
_remain_data_size = len; _remain_data_size = len;
while (_content_len == 0 && _remain_data_size > 0 && (index = onSearchPacketTail(ptr,_remain_data_size)) != nullptr) { while (_content_len == 0 && _remain_data_size > 0 && (index = onSearchPacketTail(ptr,_remain_data_size)) != nullptr) {
if(index == ptr){
break;
}
//_content_len == 0,这是请求头 //_content_len == 0,这是请求头
const char *header_ptr = ptr; const char *header_ptr = ptr;
int64_t header_size = index - ptr; int64_t header_size = index - ptr;
...@@ -61,8 +64,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) { ...@@ -61,8 +64,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
if(_content_len == 0){ if(_content_len == 0){
//尚未找到http头,缓存定位到剩余数据部分 //尚未找到http头,缓存定位到剩余数据部分
string str(ptr,_remain_data_size); _remain_data.assign(ptr,_remain_data_size);
_remain_data = str;
return; return;
} }
...@@ -71,8 +73,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) { ...@@ -71,8 +73,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
//数据按照固定长度content处理 //数据按照固定长度content处理
if(_remain_data_size < _content_len){ if(_remain_data_size < _content_len){
//数据不够,缓存定位到剩余数据部分 //数据不够,缓存定位到剩余数据部分
string str(ptr,_remain_data_size); _remain_data.assign(ptr, _remain_data_size);
_remain_data = str;
return; return;
} }
//收到content数据,并且接受content完毕 //收到content数据,并且接受content完毕
...@@ -85,9 +86,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) { ...@@ -85,9 +86,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
if(_remain_data_size > 0){ if(_remain_data_size > 0){
//还有数据没有处理完毕 //还有数据没有处理完毕
string str(ptr,_remain_data_size); _remain_data.assign(ptr,_remain_data_size);
_remain_data = str;
data = ptr = (char *)_remain_data.data(); data = ptr = (char *)_remain_data.data();
len = _remain_data.size(); len = _remain_data.size();
goto splitPacket; goto splitPacket;
...@@ -112,7 +111,7 @@ void HttpRequestSplitter::reset() { ...@@ -112,7 +111,7 @@ void HttpRequestSplitter::reset() {
_remain_data.clear(); _remain_data.clear();
} }
const char *HttpRequestSplitter::onSearchPacketTail(const char *data,int len) { const char *HttpRequestSplitter::onSearchPacketTail(const char *data,uint64_t len) {
auto pos = strstr(data,"\r\n\r\n"); auto pos = strstr(data,"\r\n\r\n");
if(pos == nullptr){ if(pos == nullptr){
return nullptr; return nullptr;
......
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
#define ZLMEDIAKIT_HTTPREQUESTSPLITTER_H #define ZLMEDIAKIT_HTTPREQUESTSPLITTER_H
#include <string> #include <string>
#include "Network/Buffer.h"
using namespace std; using namespace std;
using namespace toolkit;
namespace mediakit { namespace mediakit {
...@@ -54,7 +56,7 @@ protected: ...@@ -54,7 +56,7 @@ protected:
* @param len 数据长度 * @param len 数据长度
* @return nullptr代表未找到包位,否则返回包尾指针 * @return nullptr代表未找到包位,否则返回包尾指针
*/ */
virtual const char *onSearchPacketTail(const char *data,int len); virtual const char *onSearchPacketTail(const char *data, uint64_t len);
/** /**
* 设置content len * 设置content len
...@@ -71,7 +73,7 @@ protected: ...@@ -71,7 +73,7 @@ protected:
*/ */
int64_t remainDataSize(); int64_t remainDataSize();
private: private:
string _remain_data; BufferLikeString _remain_data;
int64_t _content_len = 0; int64_t _content_len = 0;
int64_t _remain_data_size = 0; int64_t _remain_data_size = 0;
}; };
......
...@@ -24,8 +24,6 @@ HttpSession::HttpSession(const Socket::Ptr &pSock) : TcpSession(pSock) { ...@@ -24,8 +24,6 @@ HttpSession::HttpSession(const Socket::Ptr &pSock) : TcpSession(pSock) {
TraceP(this); TraceP(this);
GET_CONFIG(uint32_t,keep_alive_sec,Http::kKeepAliveSecond); GET_CONFIG(uint32_t,keep_alive_sec,Http::kKeepAliveSecond);
pSock->setSendTimeOutSecond(keep_alive_sec); pSock->setSendTimeOutSecond(keep_alive_sec);
//起始接收buffer缓存设置为4K,节省内存
pSock->setReadBuffer(std::make_shared<BufferRaw>(4 * 1024));
} }
HttpSession::~HttpSession() { HttpSession::~HttpSession() {
...@@ -638,14 +636,6 @@ void HttpSession::Handle_Req_POST(int64_t &content_len) { ...@@ -638,14 +636,6 @@ void HttpSession::Handle_Req_POST(int64_t &content_len) {
return; return;
} }
//根据Content-Length设置接收缓存大小
if(totalContentLen > 0){
getSock()->setReadBuffer(std::make_shared<BufferRaw>(MIN(totalContentLen + 1,256 * 1024)));
}else{
//不定长度的Content-Length
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
}
if(totalContentLen > 0 && totalContentLen < maxReqSize ){ if(totalContentLen > 0 && totalContentLen < maxReqSize ){
//返回固定长度的content //返回固定长度的content
content_len = totalContentLen; content_len = totalContentLen;
...@@ -738,9 +728,9 @@ void HttpSession::onWrite(const Buffer::Ptr &buffer, bool flush) { ...@@ -738,9 +728,9 @@ void HttpSession::onWrite(const Buffer::Ptr &buffer, bool flush) {
} }
} }
void HttpSession::onWebSocketEncodeData(const Buffer::Ptr &buffer){ void HttpSession::onWebSocketEncodeData(Buffer::Ptr buffer){
_total_bytes_usage += buffer->size(); _total_bytes_usage += buffer->size();
send(buffer); send(std::move(buffer));
} }
void HttpSession::onWebSocketDecodeComplete(const WebSocketHeader &header_in){ void HttpSession::onWebSocketDecodeComplete(const WebSocketHeader &header_in){
......
...@@ -92,7 +92,7 @@ protected: ...@@ -92,7 +92,7 @@ protected:
* 发送数据进行websocket协议打包后回调 * 发送数据进行websocket协议打包后回调
* @param buffer websocket协议数据 * @param buffer websocket协议数据
*/ */
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override; void onWebSocketEncodeData(Buffer::Ptr buffer) override;
/** /**
* 接收到完整的一个webSocket数据包后回调 * 接收到完整的一个webSocket数据包后回调
......
...@@ -43,11 +43,11 @@ protected: ...@@ -43,11 +43,11 @@ protected:
/** /**
* 发送前拦截并打包为websocket协议 * 发送前拦截并打包为websocket协议
*/ */
int send(const Buffer::Ptr &buf) override{ int send(Buffer::Ptr buf) override{
if(_beforeSendCB){ if(_beforeSendCB){
return _beforeSendCB(buf); return _beforeSendCB(buf);
} }
return ClientType::send(buf); return ClientType::send(std::move(buf));
} }
/** /**
...@@ -287,8 +287,8 @@ protected: ...@@ -287,8 +287,8 @@ protected:
* @param ptr 数据指针 * @param ptr 数据指针
* @param len 数据指针长度 * @param len 数据指针长度
*/ */
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override{ void onWebSocketEncodeData(Buffer::Ptr buffer) override{
HttpClientImp::send(buffer); HttpClientImp::send(std::move(buffer));
} }
private: private:
......
...@@ -53,11 +53,11 @@ protected: ...@@ -53,11 +53,11 @@ protected:
* @param buf 需要截取的数据 * @param buf 需要截取的数据
* @return 数据字节数 * @return 数据字节数
*/ */
int send(const Buffer::Ptr &buf) override { int send(Buffer::Ptr buf) override {
if (_beforeSendCB) { if (_beforeSendCB) {
return _beforeSendCB(buf); return _beforeSendCB(buf);
} }
return TcpSessionType::send(buf); return TcpSessionType::send(std::move(buf));
} }
string getIdentifier() const override { string getIdentifier() const override {
...@@ -219,8 +219,8 @@ protected: ...@@ -219,8 +219,8 @@ protected:
/** /**
* 发送数据进行websocket协议打包后回调 * 发送数据进行websocket协议打包后回调
*/ */
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override{ void onWebSocketEncodeData(Buffer::Ptr buffer) override{
HttpSessionType::send(buffer); HttpSessionType::send(std::move(buffer));
} }
private: private:
......
...@@ -132,7 +132,7 @@ protected: ...@@ -132,7 +132,7 @@ protected:
* @param ptr 数据指针 * @param ptr 数据指针
* @param len 数据指针长度 * @param len 数据指针长度
*/ */
virtual void onWebSocketEncodeData(const Buffer::Ptr &buffer){}; virtual void onWebSocketEncodeData(Buffer::Ptr buffer){};
private: private:
void onPayloadData(uint8_t *data, uint64_t len); void onPayloadData(uint8_t *data, uint64_t len);
......
...@@ -101,7 +101,8 @@ void MP4MuxerInterface::inputFrame(const Frame::Ptr &frame) { ...@@ -101,7 +101,8 @@ void MP4MuxerInterface::inputFrame(const Frame::Ptr &frame) {
if (_frameCached.size() != 1) { if (_frameCached.size() != 1) {
//缓存中有多帧,需要按照mp4格式合并一起 //缓存中有多帧,需要按照mp4格式合并一起
string merged; BufferLikeString merged;
merged.reserve(back->size() + 1024);
_frameCached.for_each([&](const Frame::Ptr &frame) { _frameCached.for_each([&](const Frame::Ptr &frame) {
uint32_t nalu_size = frame->size() - frame->prefixSize(); uint32_t nalu_size = frame->size() - frame->prefixSize();
nalu_size = htonl(nalu_size); nalu_size = htonl(nalu_size);
......
...@@ -107,7 +107,8 @@ void TsMuxer::inputFrame(const Frame::Ptr &frame) { ...@@ -107,7 +107,8 @@ void TsMuxer::inputFrame(const Frame::Ptr &frame) {
Frame::Ptr back = _frameCached.back(); Frame::Ptr back = _frameCached.back();
Buffer::Ptr merged_frame = back; Buffer::Ptr merged_frame = back;
if (_frameCached.size() != 1) { if (_frameCached.size() != 1) {
string merged; BufferLikeString merged;
merged.reserve(back->size() + 1024);
_frameCached.for_each([&](const Frame::Ptr &frame) { _frameCached.for_each([&](const Frame::Ptr &frame) {
if (frame->prefixSize()) { if (frame->prefixSize()) {
merged.append(frame->data(), frame->size()); merged.append(frame->data(), frame->size());
...@@ -119,7 +120,7 @@ void TsMuxer::inputFrame(const Frame::Ptr &frame) { ...@@ -119,7 +120,7 @@ void TsMuxer::inputFrame(const Frame::Ptr &frame) {
_is_idr_fast_packet = true; _is_idr_fast_packet = true;
} }
}); });
merged_frame = std::make_shared<BufferString>(std::move(merged)); merged_frame = std::make_shared<BufferOffset<BufferLikeString> >(std::move(merged));
} }
track_info.stamp.revise(back->dts(), back->pts(), dts_out, pts_out); track_info.stamp.revise(back->dts(), back->pts(), dts_out, pts_out);
//取视频时间戳为TS的时间戳 //取视频时间戳为TS的时间戳
......
...@@ -136,7 +136,7 @@ public: ...@@ -136,7 +136,7 @@ public:
uint32_t ts_field = 0; uint32_t ts_field = 0;
uint32_t stream_index; uint32_t stream_index;
uint32_t chunk_id; uint32_t chunk_id;
std::string buffer; BufferLikeString buffer;
public: public:
char *data() const override{ char *data() const override{
......
...@@ -58,8 +58,8 @@ protected: ...@@ -58,8 +58,8 @@ protected:
//from RtmpProtocol //from RtmpProtocol
void onRtmpChunk(RtmpPacket &chunk_data) override; void onRtmpChunk(RtmpPacket &chunk_data) override;
void onStreamDry(uint32_t stream_index) override; void onStreamDry(uint32_t stream_index) override;
void onSendRawData(const Buffer::Ptr &buffer) override { void onSendRawData(Buffer::Ptr buffer) override {
send(buffer); send(std::move(buffer));
} }
template<typename FUNC> template<typename FUNC>
......
...@@ -21,23 +21,24 @@ ...@@ -21,23 +21,24 @@
#include "Util/TimeTicker.h" #include "Util/TimeTicker.h"
#include "Network/Socket.h" #include "Network/Socket.h"
#include "Util/ResourcePool.h" #include "Util/ResourcePool.h"
#include "Http/HttpRequestSplitter.h"
using namespace std; using namespace std;
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
class RtmpProtocol { class RtmpProtocol : public HttpRequestSplitter{
public: public:
RtmpProtocol(); RtmpProtocol();
virtual ~RtmpProtocol(); virtual ~RtmpProtocol();
void onParseRtmp(const char *data, int size); void onParseRtmp(const char *data, uint64_t size);
//作为客户端发送c0c1,等待s0s1s2并且回调 //作为客户端发送c0c1,等待s0s1s2并且回调
void startClientSession(const function<void()> &cb); void startClientSession(const function<void()> &cb);
protected: protected:
virtual void onSendRawData(const Buffer::Ptr &buffer) = 0; virtual void onSendRawData(Buffer::Ptr buffer) = 0;
virtual void onRtmpChunk(RtmpPacket &chunk_data) = 0; virtual void onRtmpChunk(RtmpPacket &chunk_data) = 0;
virtual void onStreamBegin(uint32_t stream_index){ virtual void onStreamBegin(uint32_t stream_index){
_stream_index = stream_index; _stream_index = stream_index;
...@@ -46,6 +47,11 @@ protected: ...@@ -46,6 +47,11 @@ protected:
virtual void onStreamDry(uint32_t stream_index){}; virtual void onStreamDry(uint32_t stream_index){};
protected: protected:
//// HttpRequestSplitter override ////
int64_t onRecvHeader(const char *data,uint64_t len) override { return 0; }
const char *onSearchPacketTail(const char *data,uint64_t len) override;
protected:
void reset(); void reset();
BufferRaw::Ptr obtainBuffer(); BufferRaw::Ptr obtainBuffer();
BufferRaw::Ptr obtainBuffer(const void *data, int len); BufferRaw::Ptr obtainBuffer(const void *data, int len);
...@@ -66,20 +72,20 @@ protected: ...@@ -66,20 +72,20 @@ protected:
void sendRtmp(uint8_t type, uint32_t stream_index, const Buffer::Ptr &buffer, uint32_t stamp, int chunk_id); void sendRtmp(uint8_t type, uint32_t stream_index, const Buffer::Ptr &buffer, uint32_t stamp, int chunk_id);
private: private:
void handle_S0S1S2(const function<void()> &func); void handle_C1_simple(const char *data);
void handle_C0C1();
void handle_C1_simple();
#ifdef ENABLE_OPENSSL #ifdef ENABLE_OPENSSL
void handle_C1_complex(); void handle_C1_complex(const char *data);
string get_C1_digest(const uint8_t *ptr,char **digestPos); string get_C1_digest(const uint8_t *ptr,char **digestPos);
string get_C1_key(const uint8_t *ptr); string get_C1_key(const uint8_t *ptr);
void check_C1_Digest(const string &digest,const string &data); void check_C1_Digest(const string &digest,const string &data);
void send_complex_S0S1S2(int schemeType,const string &digest); void send_complex_S0S1S2(int schemeType,const string &digest);
#endif //ENABLE_OPENSSL #endif //ENABLE_OPENSSL
void handle_C2(); const char* handle_S0S1S2(const char *data, uint64_t len, const function<void()> &func);
void handle_rtmp(); const char* handle_C0C1(const char *data, uint64_t len);
void handle_rtmpChunk(RtmpPacket &chunk_data); const char* handle_C2(const char *data, uint64_t len);
const char* handle_rtmp(const char *data, uint64_t len);
void handle_chunk(RtmpPacket &chunk_data);
protected: protected:
int _send_req_id = 0; int _send_req_id = 0;
...@@ -100,8 +106,7 @@ private: ...@@ -100,8 +106,7 @@ private:
uint32_t _bandwidth = 2500000; uint32_t _bandwidth = 2500000;
uint8_t _band_limit_type = 2; uint8_t _band_limit_type = 2;
//////////Rtmp parser////////// //////////Rtmp parser//////////
string _recv_data_buf; function<const char * (const char *data, uint64_t len)> _next_step_func;
function<void()> _next_step_func;
////////////Chunk//////////// ////////////Chunk////////////
unordered_map<int, RtmpPacket> _map_chunk_data; unordered_map<int, RtmpPacket> _map_chunk_data;
}; };
......
...@@ -119,9 +119,6 @@ void RtmpPusher::onConnect(const SockException &err){ ...@@ -119,9 +119,6 @@ void RtmpPusher::onConnect(const SockException &err){
onPublishResult(err, false); onPublishResult(err, false);
return; return;
} }
//推流器不需要多大的接收缓存,节省内存占用
getSock()->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
weak_ptr<RtmpPusher> weak_self = dynamic_pointer_cast<RtmpPusher>(shared_from_this()); weak_ptr<RtmpPusher> weak_self = dynamic_pointer_cast<RtmpPusher>(shared_from_this());
startClientSession([weak_self]() { startClientSession([weak_self]() {
auto strong_self = weak_self.lock(); auto strong_self = weak_self.lock();
......
...@@ -43,8 +43,8 @@ protected: ...@@ -43,8 +43,8 @@ protected:
//for RtmpProtocol override //for RtmpProtocol override
void onRtmpChunk(RtmpPacket &chunk_data) override; void onRtmpChunk(RtmpPacket &chunk_data) override;
void onSendRawData(const Buffer::Ptr &buffer) override{ void onSendRawData(Buffer::Ptr buffer) override{
send(buffer); send(std::move(buffer));
} }
private: private:
......
...@@ -17,8 +17,6 @@ RtmpSession::RtmpSession(const Socket::Ptr &sock) : TcpSession(sock) { ...@@ -17,8 +17,6 @@ RtmpSession::RtmpSession(const Socket::Ptr &sock) : TcpSession(sock) {
DebugP(this); DebugP(this);
GET_CONFIG(uint32_t,keep_alive_sec,Rtmp::kKeepAliveSecond); GET_CONFIG(uint32_t,keep_alive_sec,Rtmp::kKeepAliveSecond);
sock->setSendTimeOutSecond(keep_alive_sec); sock->setSendTimeOutSecond(keep_alive_sec);
//起始接收buffer缓存设置为4K,节省内存
sock->setReadBuffer(std::make_shared<BufferRaw>(4 * 1024));
} }
RtmpSession::~RtmpSession() { RtmpSession::~RtmpSession() {
...@@ -151,9 +149,6 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) { ...@@ -151,9 +149,6 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
_publisher_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this())); _publisher_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
//设置转协议 //设置转协议
_publisher_src->setProtocolTranslation(enableHls, enableMP4); _publisher_src->setProtocolTranslation(enableHls, enableMP4);
//如果是rtmp推流客户端,那么加大TCP接收缓存,这样能提升接收性能
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
setSocketFlags(); setSocketFlags();
}; };
......
...@@ -56,9 +56,9 @@ private: ...@@ -56,9 +56,9 @@ private:
void setMetaData(AMFDecoder &dec); void setMetaData(AMFDecoder &dec);
void onSendMedia(const RtmpPacket::Ptr &pkt); void onSendMedia(const RtmpPacket::Ptr &pkt);
void onSendRawData(const Buffer::Ptr &buffer) override{ void onSendRawData(Buffer::Ptr buffer) override{
_total_bytes += buffer->size(); _total_bytes += buffer->size();
send(buffer); send(std::move(buffer));
} }
void onRtmpChunk(RtmpPacket &chunk_data) override; void onRtmpChunk(RtmpPacket &chunk_data) override;
......
...@@ -539,7 +539,7 @@ std::string AMFDecoder::load<std::string>() { ...@@ -539,7 +539,7 @@ std::string AMFDecoder::load<std::string>() {
if (pos + str_len > buf.size()) { if (pos + str_len > buf.size()) {
throw std::runtime_error("Not enough data"); throw std::runtime_error("Not enough data");
} }
std::string s(buf, pos, str_len); std::string s = buf.substr(pos, str_len);
pos += str_len; pos += str_len;
return s; return s;
} }
...@@ -612,7 +612,7 @@ std::string AMFDecoder::load_key() { ...@@ -612,7 +612,7 @@ std::string AMFDecoder::load_key() {
if (pos + str_len > buf.size()) { if (pos + str_len > buf.size()) {
throw std::runtime_error("Not enough data"); throw std::runtime_error("Not enough data");
} }
std::string s(buf, pos, str_len); std::string s = buf.substr(pos, str_len);
pos += str_len; pos += str_len;
return s; return s;
...@@ -680,7 +680,7 @@ AMFValue AMFDecoder::load_arr() { ...@@ -680,7 +680,7 @@ AMFValue AMFDecoder::load_arr() {
return object; return object;
} }
AMFDecoder::AMFDecoder(const std::string &buf_in, size_t pos_in, int version_in) : AMFDecoder::AMFDecoder(const BufferLikeString &buf_in, size_t pos_in, int version_in) :
buf(buf_in), pos(pos_in), version(version_in) { buf(buf_in), pos(pos_in), version(version_in) {
} }
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
#include <map> #include <map>
#include <stdexcept> #include <stdexcept>
#include <functional> #include <functional>
#include "Network/Buffer.h"
using namespace std; using namespace std;
using namespace toolkit;
enum AMFType { enum AMFType {
AMF_NUMBER, AMF_NUMBER,
...@@ -81,7 +83,7 @@ private: ...@@ -81,7 +83,7 @@ private:
class AMFDecoder { class AMFDecoder {
public: public:
AMFDecoder(const std::string &buf, size_t pos, int version = 0); AMFDecoder(const BufferLikeString &buf, size_t pos, int version = 0);
template<typename TP> template<typename TP>
TP load(); TP load();
private: private:
...@@ -92,7 +94,7 @@ private: ...@@ -92,7 +94,7 @@ private:
uint8_t front(); uint8_t front();
uint8_t pop_front(); uint8_t pop_front();
private: private:
const std::string &buf; const BufferLikeString &buf;
size_t pos; size_t pos;
int version; int version;
}; };
......
...@@ -102,11 +102,12 @@ void FrameMerger::inputFrame(const Frame::Ptr &frame,const function<void(uint32_ ...@@ -102,11 +102,12 @@ void FrameMerger::inputFrame(const Frame::Ptr &frame,const function<void(uint32_
Frame::Ptr back = _frameCached.back(); Frame::Ptr back = _frameCached.back();
Buffer::Ptr merged_frame = back; Buffer::Ptr merged_frame = back;
if(_frameCached.size() != 1){ if(_frameCached.size() != 1){
string merged; BufferLikeString merged;
merged.reserve(back->size() + 1024);
_frameCached.for_each([&](const Frame::Ptr &frame){ _frameCached.for_each([&](const Frame::Ptr &frame){
merged.append(frame->data(),frame->size()); merged.append(frame->data(),frame->size());
}); });
merged_frame = std::make_shared<BufferString>(std::move(merged)); merged_frame = std::make_shared<BufferOffset<BufferLikeString> >(std::move(merged));
} }
cb(back->dts(),back->pts(),merged_frame); cb(back->dts(),back->pts(),merged_frame);
_frameCached.clear(); _frameCached.clear();
......
...@@ -69,7 +69,7 @@ void GB28181Process::onRtpSorted(const RtpPacket::Ptr &rtp, int) { ...@@ -69,7 +69,7 @@ void GB28181Process::onRtpSorted(const RtpPacket::Ptr &rtp, int) {
_rtp_decoder->inputRtp(rtp, false); _rtp_decoder->inputRtp(rtp, false);
} }
const char *GB28181Process::onSearchPacketTail(const char *packet,int bytes){ const char *GB28181Process::onSearchPacketTail(const char *packet,uint64_t bytes){
try { try {
auto ret = _decoder->input((uint8_t *) packet, bytes); auto ret = _decoder->input((uint8_t *) packet, bytes);
if (ret > 0) { if (ret > 0) {
......
...@@ -37,7 +37,7 @@ public: ...@@ -37,7 +37,7 @@ public:
protected: protected:
void onRtpSorted(const RtpPacket::Ptr &rtp, int track_index) override ; void onRtpSorted(const RtpPacket::Ptr &rtp, int track_index) override ;
const char *onSearchPacketTail(const char *data,int len) override; const char *onSearchPacketTail(const char *data,uint64_t len) override;
int64_t onRecvHeader(const char *data,uint64_t len) override { return 0; }; int64_t onRecvHeader(const char *data,uint64_t len) override { return 0; };
private: private:
......
...@@ -129,7 +129,8 @@ void PSEncoder::inputFrame(const Frame::Ptr &frame) { ...@@ -129,7 +129,8 @@ void PSEncoder::inputFrame(const Frame::Ptr &frame) {
Frame::Ptr back = _frameCached.back(); Frame::Ptr back = _frameCached.back();
Buffer::Ptr merged_frame = back; Buffer::Ptr merged_frame = back;
if (_frameCached.size() != 1) { if (_frameCached.size() != 1) {
string merged; BufferLikeString merged;
merged.reserve(back->size() + 1024);
_frameCached.for_each([&](const Frame::Ptr &frame) { _frameCached.for_each([&](const Frame::Ptr &frame) {
if (frame->prefixSize()) { if (frame->prefixSize()) {
merged.append(frame->data(), frame->size()); merged.append(frame->data(), frame->size());
...@@ -138,7 +139,7 @@ void PSEncoder::inputFrame(const Frame::Ptr &frame) { ...@@ -138,7 +139,7 @@ void PSEncoder::inputFrame(const Frame::Ptr &frame) {
merged.append(frame->data(), frame->size()); merged.append(frame->data(), frame->size());
} }
}); });
merged_frame = std::make_shared<BufferString>(std::move(merged)); merged_frame = std::make_shared<BufferOffset<BufferLikeString> >(std::move(merged));
} }
track_info.stamp.revise(back->dts(), back->pts(), dts_out, pts_out); track_info.stamp.revise(back->dts(), back->pts(), dts_out, pts_out);
_timestamp = dts_out; _timestamp = dts_out;
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
*/ */
#if defined(ENABLE_RTPPROXY) #if defined(ENABLE_RTPPROXY)
#include <netinet/in.h>
#include <string.h> #include <string.h>
#include "RtpSplitter.h" #include "RtpSplitter.h"
namespace mediakit{ namespace mediakit{
...@@ -35,14 +34,14 @@ int64_t RtpSplitter::onRecvHeader(const char *data,uint64_t len){ ...@@ -35,14 +34,14 @@ int64_t RtpSplitter::onRecvHeader(const char *data,uint64_t len){
return 0; return 0;
} }
static bool isEhome(const char *data, int len){ static bool isEhome(const char *data, uint64_t len){
if (len < 4) { if (len < 4) {
return false; return false;
} }
return memcmp(data, kEHOME_MAGIC, sizeof(kEHOME_MAGIC) - 1) == 0; return memcmp(data, kEHOME_MAGIC, sizeof(kEHOME_MAGIC) - 1) == 0;
} }
const char *RtpSplitter::onSearchPacketTail(const char *data, int len) { const char *RtpSplitter::onSearchPacketTail(const char *data, uint64_t len) {
if (len < 4) { if (len < 4) {
//数据不够 //数据不够
return nullptr; return nullptr;
...@@ -70,7 +69,7 @@ const char *RtpSplitter::onSearchPacketTail(const char *data, int len) { ...@@ -70,7 +69,7 @@ const char *RtpSplitter::onSearchPacketTail(const char *data, int len) {
return onSearchPacketTail_l(data, len); return onSearchPacketTail_l(data, len);
} }
const char *RtpSplitter::onSearchPacketTail_l(const char *data, int len) { const char *RtpSplitter::onSearchPacketTail_l(const char *data, uint64_t len) {
//这是rtp包 //这是rtp包
uint16_t length = (((uint8_t *) data)[0] << 8) | ((uint8_t *) data)[1]; uint16_t length = (((uint8_t *) data)[0] << 8) | ((uint8_t *) data)[1];
if (len < length + 2) { if (len < length + 2) {
......
...@@ -31,8 +31,8 @@ protected: ...@@ -31,8 +31,8 @@ protected:
protected: protected:
int64_t onRecvHeader(const char *data, uint64_t len) override; int64_t onRecvHeader(const char *data, uint64_t len) override;
const char *onSearchPacketTail(const char *data, int len) override; const char *onSearchPacketTail(const char *data, uint64_t len) override;
const char *onSearchPacketTail_l(const char *data, int len); const char *onSearchPacketTail_l(const char *data, uint64_t len);
private: private:
int _offset = 0; int _offset = 0;
......
...@@ -28,7 +28,7 @@ int64_t TSSegment::onRecvHeader(const char *data, uint64_t len) { ...@@ -28,7 +28,7 @@ int64_t TSSegment::onRecvHeader(const char *data, uint64_t len) {
return 0; return 0;
} }
const char *TSSegment::onSearchPacketTail(const char *data, int len) { const char *TSSegment::onSearchPacketTail(const char *data, uint64_t len) {
if (len < _size + 1) { if (len < _size + 1) {
if (len == _size && ((uint8_t *) data)[0] == TS_SYNC_BYTE) { if (len == _size && ((uint8_t *) data)[0] == TS_SYNC_BYTE) {
return data + _size; return data + _size;
......
...@@ -31,7 +31,7 @@ public: ...@@ -31,7 +31,7 @@ public:
static bool isTSPacket(const char *data, int len); static bool isTSPacket(const char *data, int len);
protected: protected:
int64_t onRecvHeader(const char *data, uint64_t len) override ; int64_t onRecvHeader(const char *data, uint64_t len) override ;
const char *onSearchPacketTail(const char *data, int len) override ; const char *onSearchPacketTail(const char *data, uint64_t len) override ;
private: private:
int _size; int _size;
onSegment _onSegment; onSegment _onSegment;
......
...@@ -704,7 +704,8 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC ...@@ -704,7 +704,8 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
for (auto &pr : header){ for (auto &pr : header){
printer << pr.first << ": " << pr.second << "\r\n"; printer << pr.first << ": " << pr.second << "\r\n";
} }
SockSender::send(printer << "\r\n"); printer << "\r\n";
SockSender::send(std::move(printer));
} }
void RtspPlayer::onRecvRTP_l(const RtpPacket::Ptr &rtp, const SdpTrack::Ptr &track) { void RtspPlayer::onRecvRTP_l(const RtpPacket::Ptr &rtp, const SdpTrack::Ptr &track) {
......
...@@ -121,8 +121,6 @@ void RtspPusher::onConnect(const SockException &err) { ...@@ -121,8 +121,6 @@ void RtspPusher::onConnect(const SockException &err) {
onPublishResult(err, false); onPublishResult(err, false);
return; return;
} }
//推流器不需要多大的接收缓存,节省内存占用
getSock()->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
sendAnnounce(); sendAnnounce();
} }
...@@ -318,7 +316,7 @@ inline void RtspPusher::sendRtpPacket(const RtspMediaSource::RingDataType &pkt) ...@@ -318,7 +316,7 @@ inline void RtspPusher::sendRtpPacket(const RtspMediaSource::RingDataType &pkt)
setSendFlushFlag(true); setSendFlushFlag(true);
} }
BufferRtp::Ptr buffer(new BufferRtp(rtp)); BufferRtp::Ptr buffer(new BufferRtp(rtp));
send(buffer); send(std::move(buffer));
}); });
break; break;
} }
...@@ -335,7 +333,7 @@ inline void RtspPusher::sendRtpPacket(const RtspMediaSource::RingDataType &pkt) ...@@ -335,7 +333,7 @@ inline void RtspPusher::sendRtpPacket(const RtspMediaSource::RingDataType &pkt)
} }
BufferRtp::Ptr buffer(new BufferRtp(rtp, 4)); BufferRtp::Ptr buffer(new BufferRtp(rtp, 4));
pSock->send(buffer, nullptr, 0, ++i == size); pSock->send(std::move(buffer), nullptr, 0, ++i == size);
}); });
break; break;
} }
...@@ -475,7 +473,7 @@ void RtspPusher::sendRtspRequest(const string &cmd, const string &url,const StrC ...@@ -475,7 +473,7 @@ void RtspPusher::sendRtspRequest(const string &cmd, const string &url,const StrC
if (!sdp.empty()) { if (!sdp.empty()) {
printer << sdp; printer << sdp;
} }
SockSender::send(printer); SockSender::send(std::move(printer));
} }
......
...@@ -60,8 +60,6 @@ RtspSession::RtspSession(const Socket::Ptr &sock) : TcpSession(sock) { ...@@ -60,8 +60,6 @@ RtspSession::RtspSession(const Socket::Ptr &sock) : TcpSession(sock) {
DebugP(this); DebugP(this);
GET_CONFIG(uint32_t,keep_alive_sec,Rtsp::kKeepAliveSecond); GET_CONFIG(uint32_t,keep_alive_sec,Rtsp::kKeepAliveSecond);
sock->setSendTimeOutSecond(keep_alive_sec); sock->setSendTimeOutSecond(keep_alive_sec);
//起始接收buffer缓存设置为4K,节省内存
sock->setReadBuffer(std::make_shared<BufferRaw>(4 * 1024));
} }
RtspSession::~RtspSession() { RtspSession::~RtspSession() {
...@@ -270,8 +268,7 @@ void RtspSession::handleReq_RECORD(const Parser &parser){ ...@@ -270,8 +268,7 @@ void RtspSession::handleReq_RECORD(const Parser &parser){
rtp_info.pop_back(); rtp_info.pop_back();
sendRtspResponse("200 OK", {"RTP-Info",rtp_info}); sendRtspResponse("200 OK", {"RTP-Info",rtp_info});
if(_rtp_type == Rtsp::RTP_TCP){ if(_rtp_type == Rtsp::RTP_TCP){
//如果是rtsp推流服务器,并且是TCP推流,那么加大TCP接收缓存,这样能提升接收性能 //如果是rtsp推流服务器,并且是TCP推流,设置socket flags,,这样能提升接收性能
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
setSocketFlags(); setSocketFlags();
} }
}; };
...@@ -1030,15 +1027,15 @@ bool RtspSession::sendRtspResponse(const string &res_code, const StrCaseMap &hea ...@@ -1030,15 +1027,15 @@ bool RtspSession::sendRtspResponse(const string &res_code, const StrCaseMap &hea
printer << sdp; printer << sdp;
} }
// DebugP(this) << printer; // DebugP(this) << printer;
return send(std::make_shared<BufferString>(printer)) > 0 ; return send(std::make_shared<BufferString>(std::move(printer))) > 0 ;
} }
int RtspSession::send(const Buffer::Ptr &pkt){ int RtspSession::send(Buffer::Ptr pkt){
// if(!_enableSendRtp){ // if(!_enableSendRtp){
// DebugP(this) << pkt->data(); // DebugP(this) << pkt->data();
// } // }
_bytes_usage += pkt->size(); _bytes_usage += pkt->size();
return TcpSession::send(pkt); return TcpSession::send(std::move(pkt));
} }
bool RtspSession::sendRtspResponse(const string &res_code, const std::initializer_list<string> &header, const string &sdp, const char *protocol) { bool RtspSession::sendRtspResponse(const string &res_code, const std::initializer_list<string> &header, const string &sdp, const char *protocol) {
...@@ -1162,7 +1159,7 @@ void RtspSession::sendRtpPacket(const RtspMediaSource::RingDataType &pkt) { ...@@ -1162,7 +1159,7 @@ void RtspSession::sendRtpPacket(const RtspMediaSource::RingDataType &pkt) {
} }
BufferRtp::Ptr buffer(new BufferRtp(rtp, 4)); BufferRtp::Ptr buffer(new BufferRtp(rtp, 4));
_bytes_usage += buffer->size(); _bytes_usage += buffer->size();
pSock->send(buffer, nullptr, 0, ++i == size); pSock->send(std::move(buffer), nullptr, 0, ++i == size);
}); });
} }
break; break;
......
...@@ -93,7 +93,7 @@ protected: ...@@ -93,7 +93,7 @@ protected:
std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override; std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override;
/////TcpSession override//// /////TcpSession override////
int send(const Buffer::Ptr &pkt) override; int send(Buffer::Ptr pkt) override;
//收到RTCP包回调 //收到RTCP包回调
virtual void onRtcpPacket(int track_idx, SdpTrack::Ptr &track, unsigned char *data, unsigned int len); virtual void onRtcpPacket(int track_idx, SdpTrack::Ptr &track, unsigned char *data, unsigned int len);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
namespace mediakit{ namespace mediakit{
const char *RtspSplitter::onSearchPacketTail(const char *data, int len) { const char *RtspSplitter::onSearchPacketTail(const char *data, uint64_t len) {
auto ret = onSearchPacketTail_l(data, len); auto ret = onSearchPacketTail_l(data, len);
if(ret){ if(ret){
return ret; return ret;
...@@ -32,7 +32,7 @@ const char *RtspSplitter::onSearchPacketTail(const char *data, int len) { ...@@ -32,7 +32,7 @@ const char *RtspSplitter::onSearchPacketTail(const char *data, int len) {
return ret; return ret;
} }
const char *RtspSplitter::onSearchPacketTail_l(const char *data, int len) { const char *RtspSplitter::onSearchPacketTail_l(const char *data, uint64_t len) {
if(!_enableRecvRtp || data[0] != '$'){ if(!_enableRecvRtp || data[0] != '$'){
//这是rtsp包 //这是rtsp包
_isRtpPacket = false; _isRtpPacket = false;
......
...@@ -47,8 +47,8 @@ protected: ...@@ -47,8 +47,8 @@ protected:
*/ */
virtual int64_t getContentLength(Parser &parser); virtual int64_t getContentLength(Parser &parser);
protected: protected:
const char *onSearchPacketTail(const char *data,int len) override ; const char *onSearchPacketTail(const char *data,uint64_t len) override ;
const char *onSearchPacketTail_l(const char *data,int len) ; const char *onSearchPacketTail_l(const char *data,uint64_t len) ;
int64_t onRecvHeader(const char *data,uint64_t len) override; int64_t onRecvHeader(const char *data,uint64_t len) override;
void onRecvContent(const char *data,uint64_t len) override; void onRecvContent(const char *data,uint64_t len) override;
private: private:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论