From c64ed83378aad32f0f4d875147de494b963fbef3 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 22 Oct 2013 19:38:14 +0800 Subject: [PATCH] add shared ptr to video/audio/data --- trunk/src/core/srs_core_error.hpp | 1 + trunk/src/core/srs_core_protocol.cpp | 122 +++++++++++++++++++++++++-- trunk/src/core/srs_core_protocol.hpp | 79 +++++++++++++++-- 3 files changed, 189 insertions(+), 13 deletions(-) diff --git a/trunk/src/core/srs_core_error.hpp b/trunk/src/core/srs_core_error.hpp index f18c4e44a..44a69dfcd 100755 --- a/trunk/src/core/srs_core_error.hpp +++ b/trunk/src/core/srs_core_error.hpp @@ -65,5 +65,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_SYSTEM_STREAM_INIT 400 #define ERROR_SYSTEM_PACKET_INVALID 401 #define ERROR_SYSTEM_CLIENT_INVALID 402 +#define ERROR_SYSTEM_ASSERT_FAILED 403 #endif \ No newline at end of file diff --git a/trunk/src/core/srs_core_protocol.cpp b/trunk/src/core/srs_core_protocol.cpp index 55421ee80..994817d1f 100755 --- a/trunk/src/core/srs_core_protocol.cpp +++ b/trunk/src/core/srs_core_protocol.cpp @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include /**************************************************************************** ***************************************************************************** @@ -319,10 +320,13 @@ int SrsProtocol::recv_message(SrsMessage** pmsg) return ret; } -int SrsProtocol::send_message(SrsMessage* msg) +int SrsProtocol::send_message(SrsOutputableMessage* msg) { int ret = ERROR_SUCCESS; + // free msg whatever return value. + SrsAutoFree(SrsOutputableMessage, msg, false); + if ((ret = msg->encode_packet()) != ERROR_SUCCESS) { srs_error("encode packet to message payload failed. ret=%d", ret); return ret; @@ -475,15 +479,21 @@ int SrsProtocol::on_recv_message(SrsMessage* msg) return ret; } -int SrsProtocol::on_send_message(SrsMessage* msg) +int SrsProtocol::on_send_message(SrsOutputableMessage* msg) { int ret = ERROR_SUCCESS; - srs_assert(msg != NULL); + SrsMessage* common_msg = dynamic_cast(msg); + if (!msg) { + srs_verbose("ignore the shared ptr message."); + return ret; + } - switch (msg->header.message_type) { + srs_assert(common_msg != NULL); + + switch (common_msg->header.message_type) { case RTMP_MSG_SetChunkSize: { - SrsSetChunkSizePacket* pkt = dynamic_cast(msg->get_packet()); + SrsSetChunkSizePacket* pkt = dynamic_cast(common_msg->get_packet()); srs_assert(pkt != NULL); out_chunk_size = pkt->chunk_size; @@ -917,17 +927,30 @@ SrsChunkStream::~SrsChunkStream() srs_freep(msg); } +SrsOutputableMessage::SrsOutputableMessage() +{ + payload = NULL; + size = 0; +} + +SrsOutputableMessage::~SrsOutputableMessage() +{ + free_payload(); +} + +void SrsOutputableMessage::free_payload() +{ + srs_freepa(payload); +} + SrsMessage::SrsMessage() { - size = 0; stream = NULL; - payload = NULL; packet = NULL; } SrsMessage::~SrsMessage() { - srs_freep(payload); srs_freep(packet); srs_freep(stream); } @@ -1089,14 +1112,97 @@ int SrsMessage::encode_packet() return packet->encode(size, (char*&)payload); } +SrsSharedMessage::SrsSharedPtr::SrsSharedPtr() +{ + payload = NULL; + size = 0; + perfer_cid = 0; + shared_count = 0; +} + +SrsSharedMessage::SrsSharedPtr::~SrsSharedPtr() +{ + srs_freepa(payload); +} + SrsSharedMessage::SrsSharedMessage() { + ptr = NULL; } SrsSharedMessage::~SrsSharedMessage() { } +void SrsSharedMessage::free_payload() +{ + if (ptr) { + if (ptr->shared_count == 0) { + srs_freep(ptr); + } else { + ptr->shared_count--; + } + } +} + +int SrsSharedMessage::initialize(SrsMessageHeader* header, char* payload, int size, int perfer_cid) +{ + int ret = ERROR_SUCCESS; + + super::header = *header; + + if (ptr) { + ret = ERROR_SYSTEM_ASSERT_FAILED; + srs_error("should not set the payload twice. ret=%d", ret); + srs_assert(false); + + return ret; + } + + ptr = new SrsSharedPtr(); + ptr->payload = payload; + ptr->size = size; + ptr->perfer_cid = perfer_cid; + + super::payload = (int8_t*)ptr->payload; + super::size = ptr->size; + + return ret; +} + +SrsSharedMessage* SrsSharedMessage::copy() +{ + if (!ptr) { + srs_error("invoke initialize to initialize the ptr."); + srs_assert(false); + return NULL; + } + + SrsSharedMessage* copy = new SrsSharedMessage(); + copy->ptr = ptr; + ptr->shared_count++; + + copy->payload = (int8_t*)ptr->payload; + copy->size = ptr->size; + + return copy; +} + +int SrsSharedMessage::get_perfer_cid() +{ + if (!ptr) { + return 0; + } + + return ptr->perfer_cid; +} + +int SrsSharedMessage::encode_packet() +{ + srs_verbose("shared message ignore the encode method."); + return ERROR_SUCCESS; +} + SrsPacket::SrsPacket() { } diff --git a/trunk/src/core/srs_core_protocol.hpp b/trunk/src/core/srs_core_protocol.hpp index 569ae5b4b..76fc5dd55 100755 --- a/trunk/src/core/srs_core_protocol.hpp +++ b/trunk/src/core/srs_core_protocol.hpp @@ -47,6 +47,7 @@ class SrsChunkStream; class SrsAmf0Object; class SrsAmf0Null; class SrsAmf0Undefined; +class SrsOutputableMessage; // convert class name to string. #define CLASS_NAME_STRING(className) #className @@ -111,7 +112,7 @@ public: * then sendout over socket. * @msg this method will free it whatever return value. */ - virtual int send_message(SrsMessage* msg); + virtual int send_message(SrsOutputableMessage* msg); private: /** * when recv message, update the context. @@ -120,7 +121,7 @@ private: /** * when message sentout, update the context. */ - virtual int on_send_message(SrsMessage* msg); + virtual int on_send_message(SrsOutputableMessage* msg); /** * try to recv interlaced message from peer, * return error if error occur and nerver set the pmsg, @@ -232,9 +233,9 @@ public: }; /** -* common RTMP message defines in rtmp.part2.Message-Formats.pdf. +* message to output. */ -class SrsMessage +class SrsOutputableMessage { // 4.1. Message Header public: @@ -249,6 +250,34 @@ public: */ int32_t size; int8_t* payload; +public: + SrsOutputableMessage(); + virtual ~SrsOutputableMessage(); +protected: + virtual void free_payload(); +/** +* encode functions. +*/ +public: + /** + * get the perfered cid(chunk stream id) which sendout over. + */ + virtual int get_perfer_cid() = 0; + /** + * encode the packet to message payload bytes. + * @remark there exists empty packet, so maybe the payload is NULL. + */ + virtual int encode_packet() = 0; +}; + +/** +* common RTMP message defines in rtmp.part2.Message-Formats.pdf. +* cannbe parse and decode. +*/ +class SrsMessage : public SrsOutputableMessage +{ +private: + typedef SrsOutputableMessage super; // decoded message payload. private: SrsStream* stream; @@ -256,6 +285,9 @@ private: public: SrsMessage(); virtual ~SrsMessage(); +/** +* decode functions. +*/ public: /** * decode packet from message payload. @@ -266,6 +298,9 @@ public: * @remark, user never free the pkt, the message will auto free it. */ virtual SrsPacket* get_packet(); +/** +* encode functions. +*/ public: /** * get the perfered cid(chunk stream id) which sendout over. @@ -287,12 +322,46 @@ public: /** * shared ptr message. * for audio/video/data message that need less memory copy. +* and only for output. */ -class SrsSharedMessage : public SrsMessage +class SrsSharedMessage : public SrsOutputableMessage { +private: + typedef SrsOutputableMessage super; +private: + struct SrsSharedPtr + { + char* payload; + int size; + int perfer_cid; + int shared_count; + + SrsSharedPtr(); + virtual ~SrsSharedPtr(); + }; + SrsSharedPtr* ptr; public: SrsSharedMessage(); virtual ~SrsSharedMessage(); +protected: + virtual void free_payload(); +public: + /** + * set the shared payload. + */ + virtual int initialize(SrsMessageHeader* header, char* payload, int size, int perfer_cid); + virtual SrsSharedMessage* copy(); +public: + /** + * get the perfered cid(chunk stream id) which sendout over. + */ + virtual int get_perfer_cid(); + /** + * ignored. + * for shared message, nothing should be done. + * use initialize() to set the data. + */ + virtual int encode_packet(); }; /**