winlin

add shared ptr to video/audio/data

... ... @@ -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
... ...
... ... @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_socket.hpp>
#include <srs_core_buffer.hpp>
#include <srs_core_stream.hpp>
#include <srs_core_auto_free.hpp>
/****************************************************************************
*****************************************************************************
... ... @@ -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<SrsMessage*>(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<SrsSetChunkSizePacket*>(msg->get_packet());
SrsSetChunkSizePacket* pkt = dynamic_cast<SrsSetChunkSizePacket*>(common_msg->get_packet());
srs_assert(pkt != NULL);
out_chunk_size = pkt->chunk_size;
... ... @@ -917,17 +927,30 @@ SrsChunkStream::~SrsChunkStream()
srs_freep(msg);
}
SrsMessage::SrsMessage()
SrsOutputableMessage::SrsOutputableMessage()
{
payload = NULL;
size = 0;
}
SrsOutputableMessage::~SrsOutputableMessage()
{
free_payload();
}
void SrsOutputableMessage::free_payload()
{
srs_freepa(payload);
}
SrsMessage::SrsMessage()
{
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()
{
}
... ...
... ... @@ -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();
};
/**
... ...